implied bounds from projections in function signatures can be unsound #129005
Description
Related to #100051, but the underlying reason is slightly different. The full fix will be the same however and is blocked on the new trait solver.
trait ToArg<T> {
type Arg;
}
impl<T, U> ToArg<T> for U {
type Arg = T;
}
fn extend_inner<'a, 'b>(x: &'a str) -> <&'b &'a () as ToArg<&'b str>>::Arg { x }
fn extend<'a, 'b>(x: &'a str) -> &'b str {
(extend_inner as fn(_) -> _)(x)
}
fn main() {
let y = extend(&String::from("Hello World"));
println!("{}", y);
}
Introduced by #99217. The idea of that PR was that we check that the unnormalized function signature is well-formed when calling a function. We previously only checked the normalized signature, causing another unsoundness #98543 by having an associated type which we're able to normalize in the definition, but not the use. Checking that the unnormalized signature is well-formed, without assuming that it is well-formed, resulted in breaking changes. Because of this, we changed it to both check, and assume, that the unnormalized function signature is well-formed. This would be sound, except that we can first cast the function to a function pointer, discarding its unnormalized signature, and then call it.
We may be able to partially fix this by checking that the unnormalized signature is well-formed when casting function definitions to function pointers. This still leaves us with the general set of unsound higher-ranked implied bounds, cc #100051 #84591 #25860, which can only really be fixed by supporting implications in the type systems. cc @rust-lang/types
Metadata
Assignees
Labels
Type
Projects
Status
new solver everywhere
Activity