Skip to content

Commit 561d0a1

Browse files
authored
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``
2 parents 2171eee + 2570c23 commit 561d0a1

File tree

5 files changed

+58
-2
lines changed

5 files changed

+58
-2
lines changed

compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -235,8 +235,9 @@ where
235235
// See <https://github.com/rust-lang/trait-system-refactor-initiative/issues/185>.
236236
ecx.try_evaluate_added_goals()?;
237237

238-
// Add GAT where clauses from the trait's definition.
239-
// FIXME: We don't need these, since these are the type's own WF obligations.
238+
// Add GAT where clauses from the trait's definition. This is necessary
239+
// for soundness until we properly handle implied bounds on binders,
240+
// see tests/ui/generic-associated-types/must-prove-where-clauses-on-norm.rs.
240241
ecx.add_goals(
241242
GoalSource::AliasWellFormed,
242243
cx.own_predicates_of(goal.predicate.def_id())

compiler/rustc_trait_selection/src/traits/project.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2055,6 +2055,9 @@ fn confirm_impl_candidate<'cx, 'tcx>(
20552055

20562056
// Get obligations corresponding to the predicates from the where-clause of the
20572057
// associated type itself.
2058+
//
2059+
// This is necessary for soundness until we properly handle implied bounds on binders.
2060+
// see tests/ui/generic-associated-types/must-prove-where-clauses-on-norm.rs.
20582061
// FIXME(mgca): While this supports constants, it is only used for types by default right now
20592062
fn assoc_term_own_obligations<'cx, 'tcx>(
20602063
selcx: &mut SelectionContext<'cx, 'tcx>,
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
error: higher-ranked lifetime error
2+
--> $DIR/must-prove-where-clauses-on-norm.rs:23:61
3+
|
4+
LL | let func: for<'a, 'b> fn((), &'b str) -> &'static str = foo::<()>;
5+
| ^^^^^^^^^
6+
|
7+
= note: could not normalize `for<'b> fn(<() as Trait>::Assoc<'_, 'b>, &'b str) -> &str`
8+
9+
error: aborting due to 1 previous error
10+
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
error[E0308]: mismatched types
2+
--> $DIR/must-prove-where-clauses-on-norm.rs:23:61
3+
|
4+
LL | let func: for<'a, 'b> fn((), &'b str) -> &'static str = foo::<()>;
5+
| ------------------------------------------- ^^^^^^^^^ one type is more general than the other
6+
| |
7+
| expected due to this
8+
|
9+
= note: expected fn pointer `for<'b> fn((), &'b _) -> &'static _`
10+
found fn item `for<'b> fn(<() as Trait>::Assoc<'_, 'b>, &'b _) -> &_ {foo::<'_, ()>}`
11+
12+
error: aborting due to 1 previous error
13+
14+
For more information about this error, try `rustc --explain E0308`.
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
//@ revisions: current next
2+
//@ ignore-compare-mode-next-solver (explicit revisions)
3+
//@[next] compile-flags: -Znext-solver
4+
5+
// We have to prove implied bounds of higher-ranked types at some point.
6+
// Normalizing associated types can drop requirements. This means we need
7+
// to prove well-formedness when normalizing them, at least as long as
8+
// implied bounds are implicit.
9+
10+
trait Trait {
11+
type Assoc<'a, 'b: 'a>;
12+
}
13+
14+
impl Trait for () {
15+
type Assoc<'a, 'b: 'a> = ();
16+
}
17+
18+
fn foo<'a, 'b, T: Trait>(_: <T as Trait>::Assoc<'a, 'b>, x: &'b str) -> &'a str {
19+
x
20+
}
21+
22+
fn main() {
23+
let func: for<'a, 'b> fn((), &'b str) -> &'static str = foo::<()>;
24+
//[current]~^ ERROR higher-ranked lifetime error
25+
//[next]~^^ ERROR mismatched types
26+
let x: &'static str = func((), &String::from("temporary"));
27+
println!("{x}");
28+
}

0 commit comments

Comments
 (0)