Rollup merge of #148783 - lcnr:add-soundness-test, r=BoxyUwU

add test for assoc type norm wf check

This is soundness critical 😁 sure is helpful to have tests for that. cc ``@rust-lang/types``

r? ``@BoxyUwU``
This commit is contained in:
Stuart Cook
2025-11-11 21:11:53 +11:00
committed by GitHub
5 changed files with 58 additions and 2 deletions
@@ -235,8 +235,9 @@ fn consider_impl_candidate(
// See <https://github.com/rust-lang/trait-system-refactor-initiative/issues/185>.
ecx.try_evaluate_added_goals()?;
// Add GAT where clauses from the trait's definition.
// FIXME: We don't need these, since these are the type's own WF obligations.
// Add GAT where clauses from the trait's definition. This is necessary
// for soundness until we properly handle implied bounds on binders,
// see tests/ui/generic-associated-types/must-prove-where-clauses-on-norm.rs.
ecx.add_goals(
GoalSource::AliasWellFormed,
cx.own_predicates_of(goal.predicate.def_id())
@@ -2055,6 +2055,9 @@ fn confirm_impl_candidate<'cx, 'tcx>(
// Get obligations corresponding to the predicates from the where-clause of the
// associated type itself.
//
// This is necessary for soundness until we properly handle implied bounds on binders.
// see tests/ui/generic-associated-types/must-prove-where-clauses-on-norm.rs.
// FIXME(mgca): While this supports constants, it is only used for types by default right now
fn assoc_term_own_obligations<'cx, 'tcx>(
selcx: &mut SelectionContext<'cx, 'tcx>,
@@ -0,0 +1,10 @@
error: higher-ranked lifetime error
--> $DIR/must-prove-where-clauses-on-norm.rs:23:61
|
LL | let func: for<'a, 'b> fn((), &'b str) -> &'static str = foo::<()>;
| ^^^^^^^^^
|
= note: could not normalize `for<'b> fn(<() as Trait>::Assoc<'_, 'b>, &'b str) -> &str`
error: aborting due to 1 previous error
@@ -0,0 +1,14 @@
error[E0308]: mismatched types
--> $DIR/must-prove-where-clauses-on-norm.rs:23:61
|
LL | let func: for<'a, 'b> fn((), &'b str) -> &'static str = foo::<()>;
| ------------------------------------------- ^^^^^^^^^ one type is more general than the other
| |
| expected due to this
|
= note: expected fn pointer `for<'b> fn((), &'b _) -> &'static _`
found fn item `for<'b> fn(<() as Trait>::Assoc<'_, 'b>, &'b _) -> &_ {foo::<'_, ()>}`
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0308`.
@@ -0,0 +1,28 @@
//@ revisions: current next
//@ ignore-compare-mode-next-solver (explicit revisions)
//@[next] compile-flags: -Znext-solver
// We have to prove implied bounds of higher-ranked types at some point.
// Normalizing associated types can drop requirements. This means we need
// to prove well-formedness when normalizing them, at least as long as
// implied bounds are implicit.
trait Trait {
type Assoc<'a, 'b: 'a>;
}
impl Trait for () {
type Assoc<'a, 'b: 'a> = ();
}
fn foo<'a, 'b, T: Trait>(_: <T as Trait>::Assoc<'a, 'b>, x: &'b str) -> &'a str {
x
}
fn main() {
let func: for<'a, 'b> fn((), &'b str) -> &'static str = foo::<()>;
//[current]~^ ERROR higher-ranked lifetime error
//[next]~^^ ERROR mismatched types
let x: &'static str = func((), &String::from("temporary"));
println!("{x}");
}