Skip to content

Commit

Permalink
Validate associated type bounds on ?
Browse files Browse the repository at this point in the history
  • Loading branch information
compiler-errors committed Oct 31, 2024
1 parent e356279 commit 06a49b6
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 13 deletions.
38 changes: 25 additions & 13 deletions compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
};
Expand All @@ -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
Expand Down Expand Up @@ -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.
Expand Down
12 changes: 12 additions & 0 deletions tests/ui/trait-bounds/maybe-bound-with-assoc.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
trait HasAssoc {
type Assoc;
}
fn hasassoc<T: ?HasAssoc<Assoc = ()>>() {}
//~^ WARN relaxing a default bound

trait NoAssoc {}
fn noassoc<T: ?NoAssoc<Missing = ()>>() {}
//~^ WARN relaxing a default bound
//~| ERROR associated type `Missing` not found for `NoAssoc`

fn main() {}
21 changes: 21 additions & 0 deletions tests/ui/trait-bounds/maybe-bound-with-assoc.stderr
Original file line number Diff line number Diff line change
@@ -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<T: ?HasAssoc<Assoc = ()>>() {}
| ^^^^^^^^^^^^^^^^^^^^^

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<T: ?NoAssoc<Missing = ()>>() {}
| ^^^^^^^^^^^^^^^^^^^^^^

error[E0220]: associated type `Missing` not found for `NoAssoc`
--> $DIR/maybe-bound-with-assoc.rs:8:24
|
LL | fn noassoc<T: ?NoAssoc<Missing = ()>>() {}
| ^^^^^^^ 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`.

0 comments on commit 06a49b6

Please sign in to comment.