Rollup merge of #132209 - compiler-errors:modifiers, r=fmease
Fix validation when lowering `?` trait bounds Pass the unlowered (`rustc_hir`) polarity to `lower_poly_trait_ref`. This allows us to actually *validate* that generic args are actually valid on `?Trait` paths. This actually regressed in #113671 because that PR changed the behavior where we were inadvertently re-lowering paths as `BoundPolarity::Positive`, which was also coincidentally the only place we were enforcing the generics on `?Trait` paths were correct.
This commit is contained in:
commit
e31988cfc9
13 changed files with 119 additions and 58 deletions
|
@ -168,12 +168,6 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
match hir_bound {
|
||||
hir::GenericBound::Trait(poly_trait_ref) => {
|
||||
let hir::TraitBoundModifiers { constness, polarity } = poly_trait_ref.modifiers;
|
||||
let polarity = match polarity {
|
||||
rustc_ast::BoundPolarity::Positive => ty::PredicatePolarity::Positive,
|
||||
rustc_ast::BoundPolarity::Negative(_) => ty::PredicatePolarity::Negative,
|
||||
rustc_ast::BoundPolarity::Maybe(_) => continue,
|
||||
};
|
||||
|
||||
let _ = self.lower_poly_trait_ref(
|
||||
&poly_trait_ref.trait_ref,
|
||||
poly_trait_ref.span,
|
||||
|
|
|
@ -51,7 +51,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
&trait_bound.trait_ref,
|
||||
trait_bound.span,
|
||||
hir::BoundConstness::Never,
|
||||
ty::PredicatePolarity::Positive,
|
||||
hir::BoundPolarity::Positive,
|
||||
dummy_self,
|
||||
&mut bounds,
|
||||
PredicateFilter::SelfOnly,
|
||||
|
|
|
@ -668,7 +668,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
trait_ref: &hir::TraitRef<'tcx>,
|
||||
span: Span,
|
||||
constness: hir::BoundConstness,
|
||||
polarity: ty::PredicatePolarity,
|
||||
polarity: hir::BoundPolarity,
|
||||
self_ty: Ty<'tcx>,
|
||||
bounds: &mut Bounds<'tcx>,
|
||||
predicate_filter: PredicateFilter,
|
||||
|
@ -690,15 +690,6 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
Some(self_ty),
|
||||
);
|
||||
|
||||
if let hir::BoundConstness::Always(span) | hir::BoundConstness::Maybe(span) = constness
|
||||
&& !self.tcx().is_const_trait(trait_def_id)
|
||||
{
|
||||
self.dcx().emit_err(crate::errors::ConstBoundForNonConstTrait {
|
||||
span,
|
||||
modifier: constness.as_str(),
|
||||
});
|
||||
}
|
||||
|
||||
let tcx = self.tcx();
|
||||
let bound_vars = tcx.late_bound_vars(trait_ref.hir_ref_id);
|
||||
debug!(?bound_vars);
|
||||
|
@ -708,6 +699,36 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
bound_vars,
|
||||
);
|
||||
|
||||
let polarity = match polarity {
|
||||
rustc_ast::BoundPolarity::Positive => ty::PredicatePolarity::Positive,
|
||||
rustc_ast::BoundPolarity::Negative(_) => ty::PredicatePolarity::Negative,
|
||||
rustc_ast::BoundPolarity::Maybe(_) => {
|
||||
// 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;
|
||||
}
|
||||
};
|
||||
|
||||
if let hir::BoundConstness::Always(span) | hir::BoundConstness::Maybe(span) = constness
|
||||
&& !self.tcx().is_const_trait(trait_def_id)
|
||||
{
|
||||
self.dcx().emit_err(crate::errors::ConstBoundForNonConstTrait {
|
||||
span,
|
||||
modifier: constness.as_str(),
|
||||
});
|
||||
}
|
||||
|
||||
match predicate_filter {
|
||||
PredicateFilter::All
|
||||
| PredicateFilter::SelfOnly
|
||||
|
@ -763,11 +784,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.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue