Skip to content

Commit 06a49b6

Browse files
Validate associated type bounds on ?
1 parent e356279 commit 06a49b6

File tree

3 files changed

+58
-13
lines changed

3 files changed

+58
-13
lines changed

compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs

+25-13
Original file line numberDiff line numberDiff line change
@@ -681,11 +681,32 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
681681
Some(self_ty),
682682
);
683683

684+
let tcx = self.tcx();
685+
let bound_vars = tcx.late_bound_vars(trait_ref.hir_ref_id);
686+
debug!(?bound_vars);
687+
688+
let poly_trait_ref = ty::Binder::bind_with_vars(
689+
ty::TraitRef::new_from_args(tcx, trait_def_id, generic_args),
690+
bound_vars,
691+
);
692+
684693
let polarity = match polarity {
685694
rustc_ast::BoundPolarity::Positive => ty::PredicatePolarity::Positive,
686695
rustc_ast::BoundPolarity::Negative(_) => ty::PredicatePolarity::Negative,
687696
rustc_ast::BoundPolarity::Maybe(_) => {
688-
// No-op.
697+
// Validate associated type at least. We may want to reject these
698+
// outright in the future...
699+
for constraint in trait_segment.args().constraints {
700+
let _ = self.lower_assoc_item_constraint(
701+
trait_ref.hir_ref_id,
702+
poly_trait_ref,
703+
constraint,
704+
&mut Default::default(),
705+
&mut Default::default(),
706+
constraint.span,
707+
predicate_filter,
708+
);
709+
}
689710
return arg_count;
690711
}
691712
};
@@ -699,15 +720,6 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
699720
});
700721
}
701722

702-
let tcx = self.tcx();
703-
let bound_vars = tcx.late_bound_vars(trait_ref.hir_ref_id);
704-
debug!(?bound_vars);
705-
706-
let poly_trait_ref = ty::Binder::bind_with_vars(
707-
ty::TraitRef::new_from_args(tcx, trait_def_id, generic_args),
708-
bound_vars,
709-
);
710-
711723
match predicate_filter {
712724
PredicateFilter::All
713725
| PredicateFilter::SelfOnly
@@ -758,11 +770,11 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
758770
// since we should have emitted an error for them earlier, and they
759771
// would not be well-formed!
760772
if polarity != ty::PredicatePolarity::Positive {
761-
assert!(
762-
self.dcx().has_errors().is_some(),
773+
self.dcx().span_delayed_bug(
774+
constraint.span,
763775
"negative trait bounds should not have assoc item constraints",
764776
);
765-
continue;
777+
break;
766778
}
767779

768780
// Specify type to assert that error was already reported in `Err` case.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
trait HasAssoc {
2+
type Assoc;
3+
}
4+
fn hasassoc<T: ?HasAssoc<Assoc = ()>>() {}
5+
//~^ WARN relaxing a default bound
6+
7+
trait NoAssoc {}
8+
fn noassoc<T: ?NoAssoc<Missing = ()>>() {}
9+
//~^ WARN relaxing a default bound
10+
//~| ERROR associated type `Missing` not found for `NoAssoc`
11+
12+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
warning: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
2+
--> $DIR/maybe-bound-with-assoc.rs:4:16
3+
|
4+
LL | fn hasassoc<T: ?HasAssoc<Assoc = ()>>() {}
5+
| ^^^^^^^^^^^^^^^^^^^^^
6+
7+
warning: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
8+
--> $DIR/maybe-bound-with-assoc.rs:8:15
9+
|
10+
LL | fn noassoc<T: ?NoAssoc<Missing = ()>>() {}
11+
| ^^^^^^^^^^^^^^^^^^^^^^
12+
13+
error[E0220]: associated type `Missing` not found for `NoAssoc`
14+
--> $DIR/maybe-bound-with-assoc.rs:8:24
15+
|
16+
LL | fn noassoc<T: ?NoAssoc<Missing = ()>>() {}
17+
| ^^^^^^^ associated type `Missing` not found
18+
19+
error: aborting due to 1 previous error; 2 warnings emitted
20+
21+
For more information about this error, try `rustc --explain E0220`.

0 commit comments

Comments
 (0)