-
Notifications
You must be signed in to change notification settings - Fork 12.7k
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
ICE when trying to match on non-PartialEq slice. #61188
Comments
CC #53708 |
Ah ha! If you add Which may be something a user might infer from the message ...
... but probably not 🤣 |
triage: P-high; removing nomination. I want to know why we are not catching the failure to fulfill |
I suspect EDIT: I should've read more carefully, looks like |
assigning to self with intent to try to mentor. |
I started looking at this, with the intent of writing mentorship notes. I'm going to try to jot down notes on my process as I go, with the intent of showing a mentee what kinds of experiments one might do to figure out how to narrow down the code to the point of interest for finding a fix. To be clear, I don't consider myself an expert in the MIR generation code; I've done some work in it, but I am at a point where I need to reacquaint myself with it before I'd feel comfortable hacking on it. So, here's the steps I've done so far:
Look at that comment (added back in df3de7b, many thanks @matthewjasper!); the fact that you see three types that really can be hard-coded into the compiler, and then one special case of That's where I decided I wanted to start taking some notes, since arguably I was supposed to be making mentorship instructions for this, but if I get further into the weeds without documenting the context, I won't be able to make sensible instructions. |
To be clear, the reason that I saw the Either:
|
And reading over rust-lang/rfcs#1445 led me to find that the current code (linked below) for linting use of rust/src/librustc_mir/hair/pattern/mod.rs Lines 988 to 1012 in ef064d2
|
Filed #62307 to track the insufficient check for |
(the change suggested in PR #62339 fixes this and has a regression test for it.) |
…l-match-check, r=nikomatsakis use visitor for #[structural_match] check This changes the code so that we recur down the structure of a type of a const (rather than just inspecting at a shallow one or two levels) when we are looking to see if it has an ADT that did not derive `PartialEq` and `Eq`. Fix #61188 Fix #62307 Cc #62336
Reopening because there are still cases where we ICE: #![deny(indirect_structural_match)]
#[derive(PartialEq, Eq)]
enum O<T> {
Some(*const T), // Can also use PhantomData<T>
None,
}
struct B;
const C: &[O<B>] = &[O::None];
pub fn foo() {
let x = O::None;
match &[x][..] {
C => (),
_ => (),
}
} We might want to move to a trait based approach as in #63248 (comment) |
visiting for triage. I agree with @matthewjasper about potentially moving to a trait-based approach. part of me is tempted to jump into implementing that. But it probably makes more sense for me to write up mentorship instructions, maybe. |
triage: this is probably easy to resolve but I have not had time myself to write up mentorship instructions. Marking bug accordingly (i.e. "need-mentor" is to be interpreted as "if you are willing to help make some instructions, I'd love it...") |
Note: moving to a trait-based approach alone won't resolve every ICE. Not without regressing other stable code, least. In particular:
I discovered this while exploring cases related to #63438 and #63479 Here is a concrete example (play): fn assert_partialeq<T: PartialEq>(_: &T) {}
fn rquux(_: &()) { }
const RQ: fn(&()) = rquux;
const LRQ: &[fn(&())] = &[];
fn main() {
// assert_partialeq(&RQ); (RQ isn't PartialEq, and this will say so.)
match RQ {
RQ => println!("RQ"),
_ => {}
};
let input: &[fn(&())] = &[][..];
match input {
LRQ => println!("LRQ"), // compiles if you comment this out
&[] => println!("matched inlined pattern"),
_ => {}
};
} (The "obvious solution" of just requiring const patterns to always implement |
…ructural` trait. As far as I can tell this preserves previous observable stable behavior, *including* the ICE from rust-lang#61188. (In other words, further work is necessary to reap benefits of switching to a trait.)
…ewjasper's example. specific example is from [comment][]: [comment]: rust-lang#61188 (comment) ```rust #![deny(indirect_structural_match)] #[derive(PartialEq, Eq)] enum O<T> { Some(*const T), // Can also use PhantomData<T> None, } struct B; const C: &[O<B>] = &[O::None]; pub fn foo() { let x = O::None; match &[x][..] { C => (), _ => (), } } ```
(closing this bug so we can let issue #65466 be dedicated to tracking the more subtle problem laid out in @matthewjasper 's comment above.) |
The following code will result in an ICE in
codegenMIR construction:playground
Error and Backtrace
The text was updated successfully, but these errors were encountered: