diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs index 5e27ace4cbe4a..e2bc893c2f784 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs @@ -1,4 +1,4 @@ -use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet}; +use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap, FxIndexSet}; use rustc_errors::codes::*; use rustc_errors::struct_span_code_err; use rustc_hir as hir; @@ -62,6 +62,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { let mut trait_bounds = vec![]; let mut projection_bounds = vec![]; + let mut uwu = FxHashMap::default(); + for (pred, span) in bounds.clauses() { let bound_pred = pred.kind(); match bound_pred.skip_binder() { @@ -71,6 +73,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { } ty::ClauseKind::Projection(proj) => { projection_bounds.push((bound_pred.rebind(proj), span)); + uwu.insert(proj.def_id(), (bound_pred.rebind(proj.term), span)); } ty::ClauseKind::TypeOutlives(_) => { // Do nothing, we deal with regions separately @@ -176,6 +179,20 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { projection_bounds.push((pred, original_span)); } + if !references_self + && let Some(&(user_written, span)) = uwu.get(&pred.projection_def_id()) + { + let user_written = tcx.anonymize_bound_vars(user_written); + let elaborated = + tcx.anonymize_bound_vars(pred.map_bound(|pred| pred.term)); + if user_written != elaborated { + self.dcx().span_err( + span, + format!("expected {user_written}, found {elaborated}"), + ); + } + } + self.check_elaborated_projection_mentions_input_lifetimes( pred, original_span, diff --git a/tests/ui/associated-types/associated-types-overridden-binding-2.stderr b/tests/ui/associated-types/associated-types-overridden-binding-2.stderr index 4dfd275a19058..51542e6fc0890 100644 --- a/tests/ui/associated-types/associated-types-overridden-binding-2.stderr +++ b/tests/ui/associated-types/associated-types-overridden-binding-2.stderr @@ -1,3 +1,9 @@ +error: expected u32, found i32 + --> $DIR/associated-types-overridden-binding-2.rs:6:29 + | +LL | let _: &dyn I32Iterator = &vec![42].into_iter(); + | ^^^^^^^^^^ + error[E0271]: expected `IntoIter` to be an iterator that yields `i32`, but it yields `u32` --> $DIR/associated-types-overridden-binding-2.rs:6:43 | @@ -6,6 +12,6 @@ LL | let _: &dyn I32Iterator = &vec![42].into_iter(); | = note: required for the cast from `&std::vec::IntoIter` to `&dyn Iterator` -error: aborting due to 1 previous error +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0271`. diff --git a/tests/ui/associated-types/associated-types-overridden-binding.stderr b/tests/ui/associated-types/associated-types-overridden-binding.stderr index dc087e4185fb6..3a9e28a674d0c 100644 --- a/tests/ui/associated-types/associated-types-overridden-binding.stderr +++ b/tests/ui/associated-types/associated-types-overridden-binding.stderr @@ -22,6 +22,12 @@ note: required by a bound in `I32Iterator` LL | trait I32Iterator = Iterator; | ^^^^^^^^^^ required by this bound in `I32Iterator` -error: aborting due to 2 previous errors +error: expected u32, found i32 + --> $DIR/associated-types-overridden-binding.rs:10:29 + | +LL | let _: &dyn I32Iterator; + | ^^^^^^^^^^ + +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0284`. diff --git a/tests/ui/traits/object/pretty.stderr b/tests/ui/traits/object/pretty.stderr index af941e69c5f84..4b30ca2504bb7 100644 --- a/tests/ui/traits/object/pretty.stderr +++ b/tests/ui/traits/object/pretty.stderr @@ -1,3 +1,15 @@ +error: expected u16, found u8 + --> $DIR/pretty.rs:28:34 + | +LL | fn dyn_fixed_multi(x: &dyn Fixed) { x } + | ^^^^^^^^^^^ + +error: expected &'a u8, found for<'a> &'a u8 + --> $DIR/pretty.rs:36:62 + | +LL | fn dyn_fixed_generic_multi(x: &dyn for<'a> FixedGeneric1<'a, Assoc2 = &u8>) { x } + | ^^^^^^^^^^^^ + warning: unnecessary associated type bound for dyn-incompatible associated type --> $DIR/pretty.rs:41:35 | @@ -161,6 +173,6 @@ LL | fn dyn_has_gat(x: &dyn HasGat = ()>) { x } = note: expected unit type `()` found reference `&dyn HasGat = ()>` -error: aborting due to 14 previous errors; 1 warning emitted +error: aborting due to 16 previous errors; 1 warning emitted For more information about this error, try `rustc --explain E0308`.