diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs index 9b0d21bc00943..738b31331284f 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -681,11 +681,32 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { Some(self_ty), ); + let tcx = self.tcx(); + let bound_vars = tcx.late_bound_vars(trait_ref.hir_ref_id); + debug!(?bound_vars); + + let poly_trait_ref = ty::Binder::bind_with_vars( + ty::TraitRef::new_from_args(tcx, trait_def_id, generic_args), + bound_vars, + ); + let polarity = match polarity { rustc_ast::BoundPolarity::Positive => ty::PredicatePolarity::Positive, rustc_ast::BoundPolarity::Negative(_) => ty::PredicatePolarity::Negative, rustc_ast::BoundPolarity::Maybe(_) => { - // No-op. + // Validate associated type at least. We may want to reject these + // outright in the future... + for constraint in trait_segment.args().constraints { + let _ = self.lower_assoc_item_constraint( + trait_ref.hir_ref_id, + poly_trait_ref, + constraint, + &mut Default::default(), + &mut Default::default(), + constraint.span, + predicate_filter, + ); + } return arg_count; } }; @@ -699,15 +720,6 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { }); } - let tcx = self.tcx(); - let bound_vars = tcx.late_bound_vars(trait_ref.hir_ref_id); - debug!(?bound_vars); - - let poly_trait_ref = ty::Binder::bind_with_vars( - ty::TraitRef::new_from_args(tcx, trait_def_id, generic_args), - bound_vars, - ); - match predicate_filter { PredicateFilter::All | PredicateFilter::SelfOnly @@ -758,11 +770,11 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { // since we should have emitted an error for them earlier, and they // would not be well-formed! if polarity != ty::PredicatePolarity::Positive { - assert!( - self.dcx().has_errors().is_some(), + self.dcx().span_delayed_bug( + constraint.span, "negative trait bounds should not have assoc item constraints", ); - continue; + break; } // Specify type to assert that error was already reported in `Err` case. diff --git a/tests/ui/trait-bounds/maybe-bound-with-assoc.rs b/tests/ui/trait-bounds/maybe-bound-with-assoc.rs new file mode 100644 index 0000000000000..b6b2551e4638e --- /dev/null +++ b/tests/ui/trait-bounds/maybe-bound-with-assoc.rs @@ -0,0 +1,12 @@ +trait HasAssoc { + type Assoc; +} +fn hasassoc>() {} +//~^ WARN relaxing a default bound + +trait NoAssoc {} +fn noassoc>() {} +//~^ WARN relaxing a default bound +//~| ERROR associated type `Missing` not found for `NoAssoc` + +fn main() {} diff --git a/tests/ui/trait-bounds/maybe-bound-with-assoc.stderr b/tests/ui/trait-bounds/maybe-bound-with-assoc.stderr new file mode 100644 index 0000000000000..91d78e59cd5a7 --- /dev/null +++ b/tests/ui/trait-bounds/maybe-bound-with-assoc.stderr @@ -0,0 +1,21 @@ +warning: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default + --> $DIR/maybe-bound-with-assoc.rs:4:16 + | +LL | fn hasassoc>() {} + | ^^^^^^^^^^^^^^^^^^^^^ + +warning: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default + --> $DIR/maybe-bound-with-assoc.rs:8:15 + | +LL | fn noassoc>() {} + | ^^^^^^^^^^^^^^^^^^^^^^ + +error[E0220]: associated type `Missing` not found for `NoAssoc` + --> $DIR/maybe-bound-with-assoc.rs:8:24 + | +LL | fn noassoc>() {} + | ^^^^^^^ associated type `Missing` not found + +error: aborting due to 1 previous error; 2 warnings emitted + +For more information about this error, try `rustc --explain E0220`.