diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index b4107bd4a2bad..38679aedb94a6 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -503,7 +503,7 @@ struct DiagCtxtInner { } /// A key denoting where from a diagnostic was stashed. -#[derive(Copy, Clone, PartialEq, Eq, Hash)] +#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] pub enum StashKey { ItemNoType, UnderscoreForArrayLengths, @@ -780,7 +780,7 @@ impl DiagCtxt { // We delay a bug here so that `-Ztreat-err-as-bug -Zeagerly-emit-delayed-bugs` // can be used to create a backtrace at the stashing site insted of whenever the // diagnostic context is dropped and thus delayed bugs are emitted. - Error => Some(self.span_delayed_bug(span, "stashing {key:?}")), + Error => Some(self.span_delayed_bug(span, format!("stashing {key:?}"))), DelayedBug => return self.inner.borrow_mut().emit_diagnostic(diag), ForceWarning(_) | Warning | Note | OnceNote | Help | OnceHelp | FailureNote | Allow | Expect(_) => None, diff --git a/compiler/rustc_hir_typeck/src/intrinsicck.rs b/compiler/rustc_hir_typeck/src/intrinsicck.rs index 62711e40049a4..23f6a1f391fe5 100644 --- a/compiler/rustc_hir_typeck/src/intrinsicck.rs +++ b/compiler/rustc_hir_typeck/src/intrinsicck.rs @@ -47,12 +47,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let from = normalize(from); let to = normalize(to); trace!(?from, ?to); + if from.has_non_region_infer() || to.has_non_region_infer() { - // Note: this path is currently not reached in any test, so any - // example that triggers this would be worth minimizing and - // converting into a test. - tcx.dcx().span_bug(span, "argument to transmute has inference variables"); + // An argument may have an infer var in it but *not* trigger an + // ambiguity error yet... See `ambiguity-in-closure-arg.rs` test. + tcx.dcx().span_delayed_bug(span, "argument to transmute has inference variables"); + return; } + // Transmutes that are only changing lifetimes are always ok. if from == to { return; diff --git a/tests/ui/transmute/ambiguity-in-closure-arg.rs b/tests/ui/transmute/ambiguity-in-closure-arg.rs new file mode 100644 index 0000000000000..4c2d1ce2ad463 --- /dev/null +++ b/tests/ui/transmute/ambiguity-in-closure-arg.rs @@ -0,0 +1,11 @@ +// Minimized test for . + +struct Unconstrained(T); + +fn main() { + unsafe { std::mem::transmute::<_, ()>(|o_b: Unconstrained<_>| {}) }; + //~^ ERROR type annotations needed + // We unfortunately don't check `Wf(Unconstrained<_>)`, so we won't + // hit an ambiguity error before checking the transmute. That means + // we still may have inference variables in our transmute src. +} diff --git a/tests/ui/transmute/ambiguity-in-closure-arg.stderr b/tests/ui/transmute/ambiguity-in-closure-arg.stderr new file mode 100644 index 0000000000000..1b9140936bb12 --- /dev/null +++ b/tests/ui/transmute/ambiguity-in-closure-arg.stderr @@ -0,0 +1,9 @@ +error[E0282]: type annotations needed + --> $DIR/ambiguity-in-closure-arg.rs:6:14 + | +LL | unsafe { std::mem::transmute::<_, ()>(|o_b: Unconstrained<_>| {}) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type for fn item `unsafe extern "rust-intrinsic" fn({closure@$DIR/ambiguity-in-closure-arg.rs:6:43: 6:66}) {transmute::<{closure@$DIR/ambiguity-in-closure-arg.rs:6:43: 6:66}, ()>}` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0282`.