-
Notifications
You must be signed in to change notification settings - Fork 12.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
implied bounds from associated types may not actually get implied pt 2. #98543
Comments
Unlike #91068, these code examples compile “successfully” all the way since Rust 1.7.0. |
WG-prioritization assigning priority (Zulip discussion). @rustbot label -I-prioritize +P-high |
while this currently does not work, we should also add a test for something like this. If we get stronger implied bounds, simply requiring the caller to prove wf for all projection components won't be enough anymore #![feature(generic_associated_types)]
trait Trait<'a> {
type Type
where
Self: 'a;
}
impl<'a, T> Trait<'a> for T {
type Type = ()
where
Self: 'a; // once this bound gets implied, we have UB again
}
fn f<'a, 'b>(s: &'b str, _: <&'b () as Trait<'a>>::Type) -> &'a str
where
&'b (): Trait<'a>, // <- adding this bound is the change from #91068
{
s
}
fn main() {
let x = String::from("Hello World!");
let y = f(&x, ());
drop(x);
println!("{}", y);
} trait Trait<'a>: 'a {
type Type;
}
impl<'a, T> Trait<'a> for T
where
T: 'a // if this bound get's implied we would probably get ub here again
{
type Type = ();
}
fn f<'a, 'b>(s: &'b str, _: <&'b () as Trait<'a>>::Type) -> &'a str
where
&'b (): Trait<'a>, // <- adding this bound is the change from #91068
{
s
}
fn main() {
let x = String::from("Hello World!");
let y = f(&x, ());
drop(x);
println!("{}", y);
} |
There's a PR open that fixes this. |
consider unnormalized types for implied bounds extracted, and slightly modified, from rust-lang#98900 The idea here is that generally, rustc is split into things which can assume its inputs are well formed[^1], and things which have verify that themselves. Generally most predicates should only deal with well formed inputs, e.g. a `&'a &'b (): Trait` predicate should be able to assume that `'b: 'a` holds. Normalization can loosen wf requirements (see rust-lang#91068) and must therefore not be used in places which still have to check well formedness. The only such place should hopefully be `WellFormed` predicates fixes rust-lang#87748 and rust-lang#98543 r? `@jackh726` cc `@rust-lang/types` [^1]: These places may still encounter non-wf inputs and have to deal with them without causing an ICE as we may check for well formedness out of order.
fixed by #99217 |
revives #91068 which has been fixed by only considering implied bounds from projections if they don't normalize while typechecking the function itself
rust/compiler/rustc_borrowck/src/type_check/free_region_relations.rs
Lines 256 to 289 in 7125846
This does not mean that the projection won't normalize when getting called:
The added bound prevents
<&'a &'b () as Trait>::Type
from getting normalized while borrowcheckingf
, as we prefer param candidates over impl candidates. When callingf
, we don't have the&'a &'b (): Trait
in ourparam_env
, so we can now freely use the impl candidate to normalize the projection. The caller therefore doesn't have to prove that&'a &'b ()
is well formed, causing unsoundness.I am a bit surprised that the caller doesn't have to prove that the
&'a &'b (): Trait
obligation is well formed, which would cause this example to not be unsound. It doesn't remove the general unsoundness here though. Here's an alternative test where that isn't enough:The text was updated successfully, but these errors were encountered: