Repository navigation
broken MIR in DefId(...) (NoSolution) #110534
Description
Activity
- addedC-bugCategory: This is a bug.Category: This is a bug.I-ICEIssue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.Relevant to the compiler team, which will review and decide on the PR/issue.
on Apr 19, 2023 Note that while there is a
coherence_leak_checkwarning here, Niko's last comment on the issue says:Update: I've posted #72493. It affects this tracking issue in that it makes some patterns into hard-errors. However, the patterns we've seen reported thus far (which are actually the same pattern) still work with a warning. The MCP rust-lang/compiler-team#295 describes my overall plan here and my hope is to keep those patterns working long term.
@rustbot label regression-from-stable-to-stable
- addedregression-from-stable-to-stablePerformance or correctness regression from one stable version to another.Performance or correctness regression from one stable version to another.I-prioritizeIssue needs a team member to assess the impact. Will be replaced by P-{low,medium,high,critical}Issue needs a team member to assess the impact. Will be replaced by P-{low,medium,high,critical}
on Jun 14, 2023 WG-prioritization assigning priority (Zulip discussion).
@rustbot label -I-prioritize +P-medium
- addedP-mediumMedium priorityMedium priorityand removedI-prioritizeIssue needs a team member to assess the impact. Will be replaced by P-{low,medium,high,critical}Issue needs a team member to assess the impact. Will be replaced by P-{low,medium,high,critical}
on Jun 14, 2023 - addedglacierICE tracked in rust-lang/glacier.ICE tracked in rust-lang/glacier.
on Jun 25, 2023 Wow that's a wild one... not sure whom to Cc here. @tmiasko @compiler-errors for some general MIR knowledge, and @lcnr since traits seem involved somehow.
The error is a bit different on latest stable
error: internal compiler error: error performing ParamEnvAnd { param_env: ParamEnv { caller_bounds: [], reveal: UserFacing }, value: ProvePredicate { predicate: Binder { value: TraitPredicate(<fn(std::cell::Ref<'_, u32>) as IntoSystem>, polarity:Positive), bound_vars: [] } } } --> src/main.rs:37:18 | 37 | let _sys_c = (sys_ref as fn(_)).into_system(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: delayed at /rustc/eb45c844407968ea54df0d9870ebce9e3235b706/compiler/rustc_trait_selection/src/traits/query/type_op/mod.rs:165:29Huh. I'm surprised that this doesn't cause a trait error in HIR typeck. It does if we use a type alias to avoid introducing a higher ranked fn ptr and actually ascribe the
fn(Ref<'?0, u32>)...:type Fun<A> = fn(A); fn main() { fn sys_ref(_age: Ref<u32>) {} let _sys_c = (sys_ref as Fun<Ref<'_, u32>>).into_system(); //~^ ERROR no method named `into_system` found for fn pointer `fn(Ref<'_, u32>)` in the current scopeWoo, this is due to a lot of fun things.
Firstly, we defer the cast of
sys_ref as fn(_)until after the rest of typeck, which means that we only know that the receiver of.into_system()isfn(?0). That registers afn(?0): IntoSystemgoal, which does pass the leak check in method probing because we haven't constrained?0.After we apply the cast, we do end up with
fn(Ref<'?1, u32>): IntoSystemgoal, which itself doesn't do any leak check because this is fulfillment and not evaluation.- addedfixed-by-next-solverFixed by the next-generation trait solver, `-Znext-solver`.Fixed by the next-generation trait solver, `-Znext-solver`.
on Mar 18, 2024 Also, I guess this also has nothing to do with method probing technically:
// Borrowing the trait definitions from above above fn foo<T>(_: Option<T>) where T: IntoSystem {} fn main() { let x = None::<fn(_)>; foo(x); let y: Option<fn(Ref<'static, u32>)> = x; }
... which still ICEs during mir borrowck.
we may want to leak check at the end of hir typeck. Feels like the easiest fix 😁
minimized:
trait Trait {} impl<T: for<'a> LeakErr<'a>> Trait for T {} impl<U: for<'a> LeakErr<'a>> Trait for Option<U> {} trait LeakErr<'a> {} impl<T> LeakErr<'static> for T {} fn impls_trait<T: Trait>(x: T) -> T { x } fn main() { let y = impls_trait(None); let _: Option<u32> = y; }
What's happening here is the following:
- evaluation uses the leak check in
evaluation_probe - selection uses evaluation only if there are multiple applicable candidates
- fulfillment never uses the leak check
In HIR typeck, we select
Option<?x>: Traitwhich has two applicable candidates, causing us to useevaluate_candidate.for<'a> Option<?x>: LeakErr<'a>of the first impl causes a leak check error.for<'a> ?x: LeakErr<'a>of the second impl remains ambiguous. This causes us to select the second impl. We then only provefor<'a> u32: LeakErr<'a>in fulfillment which does not use the leak check. THis causes HIR typeck to pass.In MIR typeck, we select
Option<u32>: Traitwhich has two applicable candidates, causing us to useevaluate_candidate. However, now both candidates fail the leak check, causing us to have no applicable impl, causing a selection error.Reacted by Ali MJ Al-Nasrawy- evaluation uses the leak check in
- addedS-bug-has-testStatus: This bug is tracked inside the repo by a `known-bug` test.Status: This bug is tracked inside the repo by a `known-bug` test.
on Apr 15, 2024 - added a commit that references this issue
on Oct 5, 2026 - added a commit that references this issue
on Oct 8, 2026
Code
Playground.
Meta
Playground:
It wasn't an ICE in 1.62.
Error output