Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Emit diagnostic when using const storing Fn as pattern #41434

Closed
wants to merge 1 commit into from

Conversation

estebank
Copy link
Contributor

fn f1() { println!("1"); }
fn f2() { println!("2"); }

struct S(fn());
const CONST: S = S(f1);

fn main() {
    let x = S(f2);

    match x {
        CONST => {
            println!("match");
        }
        _ => {}
    }
}
error: pattern contains `Fn`, use pattern guard instead
  --> <anon>.rs:14:9
   |
13 |         CONST => {
   |         ^^^^^ pattern contains `Fn`
   |
help: use a pattern guard instead:
   |         x if x == CONST => {

Fix #40657.

```rust
fn f1() { println!("1"); }
fn f2() { println!("2"); }

struct S(fn());
const CONST: S = S(f1);

fn main() {
    let x = S(f2);

    match x {
        CONST => {
            println!("match");
        }
        _ => {}
    }
}
```

```rust
error: pattern contains `Fn`, use pattern guard instead
  --> <anon>.rs:14:9
   |
13 |         CONST => {
   |         ^^^^^ pattern contains `Fn`
   |
help: use a pattern guard instead:
   |         x if x == CONST => {
```

Fix ICE.
@rust-highfive
Copy link
Collaborator

r? @eddyb

(rust_highfive has picked a reviewer for you, use r? to override)

@eddyb eddyb requested a review from nikomatsakis April 21, 2017 00:11
@durka
Copy link
Contributor

durka commented Apr 21, 2017

The error message seems vague and confusing to me. What's the reason why a function can't be in a match pattern?

@estebank
Copy link
Contributor Author

@durka the current compiler output is an ICE. Only reason I see to disallow it is not to change behaviour.

@petrochenkov
Copy link
Contributor

@estebank
You can add checks for raw pointers in constants and fix #34784 as well.

@shepmaster shepmaster added the S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. label Apr 21, 2017
@nikomatsakis
Copy link
Contributor

nikomatsakis commented Apr 21, 2017

I"m not sure if this check is in quite the right spot. I think I would expect it to be in the lower_path() function instead...although, reading through the code, this seems like a not terrible place as well. What I had in mind feels somehow strictly more correct, but would involve copying a non-trivial number of patterns over into lower_path() (i.e., those cases where lower_variant_or_leaf() is a non-bug).

@durka
Copy link
Contributor

durka commented Apr 21, 2017

I guess I don't understand why the example program at the top is an unreasonable program. What's wrong with checking which fn I have in a variable? As a user, with this PR I get:

  1. an inscrutable error message
  2. suggested code that doesn't compile

Yes it's better than an ICE, but this is not a good situation.

@arielb1
Copy link
Contributor

arielb1 commented Apr 22, 2017

@estebank

This should be using lowercase-f fn rather than uppercase-f Fn.

@eddyb
Copy link
Member

eddyb commented Apr 22, 2017

Why can't we handle this as fn pointers not being "structurally matchable"?

EDIT: Or, you know, we could implement it. Although I'm not sure we support raw pointer comparisons right now?

EDIT2: Nevermind, an explicit fn cast is a const-evaluation error. This should be handled in const-eval (there's a coercion that is completely ignored right now), it's not pattern-specific.

@eddyb
Copy link
Member

eddyb commented Apr 22, 2017

i.e. just before evaluating an expression we should check for a reification adjustment on that expression and signal!(e, UnimplementedConstVal("casting fn pointers")) like for as casts.

@arielb1
Copy link
Contributor

arielb1 commented Apr 22, 2017

@eddyb

Why don't we want to support reifying fn pointers in const-eval? With MIRI, we'll have to, and still face this problem.

@eddyb
Copy link
Member

eddyb commented Apr 22, 2017

@arielb1 It really comes down to whether we want to allow it in patterns - if we don't, we should ban it through "structural match", if we want to fix it so it works it's relatively straight-forward.

@arielb1
Copy link
Contributor

arielb1 commented Apr 22, 2017

Where structural_match = altering lower_const_expr?

@eddyb
Copy link
Member

eddyb commented Apr 22, 2017

I mean that constants of types that contain function pointers can't be matched on - same thing with floats.

@arielb1 arielb1 added the T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. label Apr 25, 2017
@alexcrichton
Copy link
Member

Hey @estebank thanks again for the PR! It sounds like there's a few changes requested, though, do you think you'll have a chance to look into them?

@estebank
Copy link
Contributor Author

estebank commented May 4, 2017

@alexcrichton I will, but probably not before the weekend. Would you prefer to keep this PR open for the comment history or creating a clean PR when I get back to this?

@alexcrichton
Copy link
Member

Oh yeah it's fine to keep open, just doing some PR triaging this morning :)

@alexcrichton
Copy link
Member

Ah ok coming back around to this, I'm gonna close this for now to help clear out the queue, but @estebank please feel free to resubmit!

@estebank
Copy link
Contributor Author

@alexcrichton I spent the last weekend looking into this, and hit a wall as the amount of code needed for getting it to work appropriately was getting bigger and bigger. I'll probably get back to this sometime in the future, but I can help if somebody else wants to take it before then.

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

9 participants