-
Notifications
You must be signed in to change notification settings - Fork 12.9k
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
Soundness regression with for<'lt>
closure having an implied bound from return type
#114936
Comments
WG-prioritization assigning priority (Zulip discussion). @rustbot label -I-prioritize +P-high +T-compiler -needs-triage |
Oh, neat it did turn out to be a new soundness bug instead of a dupe of #25860. Thanks for figuring out this was a regression, @danielhenrymantilla. |
for fn whoops<'a, F: for<'s> FnOnce(&'s str) -> (&'static str, [&'static &'s (); 0])>(
s: &'a str,
f: F,
) -> &'static str
{
f(s).0
} we have a terminator calling This does not include the implied bounds. Checking that |
This soundness bug is effectively only reproducible via the There is an assumption that all it takes for an assoc type to be wf is the where clauses on it and the impl hold, and that all arguments in the traitref are wf. The builtin When calling It is generally an invariant of the type system that A simple fix (albeit hacky until we make implied bounds desugared to actual bounds) would be to make us also check |
…=<try> Check normalized call signature for WF in mir typeck Unfortunately we don't check that the built-in implementations for `Fn*` traits are actually well-formed in the same way that we do for user-provided impls. Essentially, when checking a call terminator, we end up with a signature that references an unnormalized `<[closure] as FnOnce<...>>::Output` in its output. That output type, due to the built-in impl, doesn't follow the expected rule that `WF(ty)` implies `WF(normalized(ty))`. We fix this by also checking the normalized signature here. **See** boxy's detailed and useful explanation comment which explains this in more detail: rust-lang#114936 (comment) Fixes rust-lang#114936 Fixes rust-lang#118876 r? types cc `@BoxyUwU` `@lcnr`
…=<try> Check normalized call signature for WF in mir typeck Unfortunately we don't check that the built-in implementations for `Fn*` traits are actually well-formed in the same way that we do for user-provided impls. Essentially, when checking a call terminator, we end up with a signature that references an unnormalized `<[closure] as FnOnce<...>>::Output` in its output. That output type, due to the built-in impl, doesn't follow the expected rule that `WF(ty)` implies `WF(normalized(ty))`. We fix this by also checking the normalized signature here. **See** boxy's detailed and useful explanation comment which explains this in more detail: rust-lang#114936 (comment) Fixes rust-lang#114936 Fixes rust-lang#118876 r? types cc `@BoxyUwU` `@lcnr`
…=<try> Check normalized call signature for WF in mir typeck Unfortunately we don't check that the built-in implementations for `Fn*` traits are actually well-formed in the same way that we do for user-provided impls. Essentially, when checking a call terminator, we end up with a signature that references an unnormalized `<[closure] as FnOnce<...>>::Output` in its output. That output type, due to the built-in impl, doesn't follow the expected rule that `WF(ty)` implies `WF(normalized(ty))`. We fix this by also checking the normalized signature here. **See** boxy's detailed and useful explanation comment which explains this in more detail: rust-lang#114936 (comment) Fixes rust-lang#114936 Fixes rust-lang#118876 r? types cc `@BoxyUwU` `@lcnr`
… r=lcnr Check normalized call signature for WF in mir typeck Unfortunately we don't check that the built-in implementations for `Fn*` traits are actually well-formed in the same way that we do for user-provided impls. Essentially, when checking a call terminator, we end up with a signature that references an unnormalized `<[closure] as FnOnce<...>>::Output` in its output. That output type, due to the built-in impl, doesn't follow the expected rule that `WF(ty)` implies `WF(normalized(ty))`. We fix this by also checking the normalized signature here. **See** boxy's detailed and useful explanation comment which explains this in more detail: rust-lang#114936 (comment) Fixes rust-lang#114936 Fixes rust-lang#118876 r? types cc `@BoxyUwU` `@lcnr`
Rollup merge of rust-lang#118882 - compiler-errors:normalized-sig-wf, r=lcnr Check normalized call signature for WF in mir typeck Unfortunately we don't check that the built-in implementations for `Fn*` traits are actually well-formed in the same way that we do for user-provided impls. Essentially, when checking a call terminator, we end up with a signature that references an unnormalized `<[closure] as FnOnce<...>>::Output` in its output. That output type, due to the built-in impl, doesn't follow the expected rule that `WF(ty)` implies `WF(normalized(ty))`. We fix this by also checking the normalized signature here. **See** boxy's detailed and useful explanation comment which explains this in more detail: rust-lang#114936 (comment) Fixes rust-lang#114936 Fixes rust-lang#118876 r? types cc ``@BoxyUwU`` ``@lcnr``
Bug originally found by @ast-ral, over Discord, which I've then reduced.
Code
I tried this code:
I expected to see this happen:
Instead, this happened: code compiles successfully
Version it soundly rejected this code:
1.64.0
Version with soundness regression
1.65.0 and onwards
Proof of unsoundness:
@rustbot modify labels: +I-unsound +regression-from-stable-to-stable -regression-untriaged
Observations
This does not occur if the implied-lifetime-bounds array is in closure parameter position; so it looks like a bug w.r.t. not properly checking the closure output type implied bounds?
-Ztrait-solver=next
does not help (as of2023-08-16
)The text was updated successfully, but these errors were encountered: