-
Notifications
You must be signed in to change notification settings - Fork 13.6k
loop_match
: suggest extracting to a const
item
#143585
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,174 @@ | ||
#![allow(incomplete_features)] | ||
#![feature(loop_match)] | ||
#![feature(generic_const_items)] | ||
#![crate_type = "lib"] | ||
|
||
const fn const_fn() -> i32 { | ||
1 | ||
} | ||
|
||
#[unsafe(no_mangle)] | ||
fn suggest_const_block<const N: i32>() -> i32 { | ||
let mut state = 0; | ||
#[loop_match] | ||
loop { | ||
state = 'blk: { | ||
match state { | ||
0 => { | ||
#[const_continue] | ||
break 'blk const_fn(); | ||
//~^ ERROR could not determine the target branch for this `#[const_continue]` | ||
} | ||
1 => { | ||
#[const_continue] | ||
break 'blk const { const_fn() }; | ||
//~^ ERROR could not determine the target branch for this `#[const_continue]` | ||
} | ||
2 => { | ||
#[const_continue] | ||
break 'blk N; | ||
//~^ ERROR could not determine the target branch for this `#[const_continue]` | ||
} | ||
_ => { | ||
#[const_continue] | ||
break 'blk 1 + 1; | ||
//~^ ERROR could not determine the target branch for this `#[const_continue]` | ||
} | ||
} | ||
} | ||
} | ||
state | ||
} | ||
|
||
struct S; | ||
|
||
impl S { | ||
const M: usize = 42; | ||
|
||
fn g() { | ||
let mut state = 0; | ||
#[loop_match] | ||
loop { | ||
state = 'blk: { | ||
match state { | ||
0 => { | ||
#[const_continue] | ||
break 'blk Self::M; | ||
} | ||
_ => panic!(), | ||
} | ||
} | ||
} | ||
} | ||
} | ||
|
||
trait T { | ||
const N: usize; | ||
|
||
fn f() { | ||
let mut state = 0; | ||
#[loop_match] | ||
loop { | ||
state = 'blk: { | ||
match state { | ||
0 => { | ||
#[const_continue] | ||
break 'blk Self::N; | ||
//~^ ERROR could not determine the target branch for this `#[const_continue]` | ||
} | ||
_ => panic!(), | ||
} | ||
} | ||
} | ||
} | ||
} | ||
|
||
impl T for S { | ||
const N: usize = 1; | ||
} | ||
|
||
impl S { | ||
fn h() { | ||
let mut state = 0; | ||
#[loop_match] | ||
loop { | ||
state = 'blk: { | ||
match state { | ||
0 => { | ||
#[const_continue] | ||
break 'blk Self::N; | ||
} | ||
_ => panic!(), | ||
} | ||
} | ||
} | ||
} | ||
} | ||
|
||
trait T2<U> { | ||
const L: u32; | ||
|
||
fn p() { | ||
let mut state = 0; | ||
#[loop_match] | ||
loop { | ||
state = 'blk: { | ||
match state { | ||
0 => { | ||
#[const_continue] | ||
break 'blk Self::L; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Another test could be the same function as a free (generic) function, but using There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes that does appear to be the current behavior. |
||
//~^ ERROR could not determine the target branch for this `#[const_continue]` | ||
} | ||
_ => panic!(), | ||
} | ||
} | ||
} | ||
} | ||
} | ||
|
||
const SIZE_OF<T>: usize = size_of::<T>(); | ||
|
||
fn q<T>() { | ||
let mut state = 0; | ||
#[loop_match] | ||
loop { | ||
state = 'blk: { | ||
match state { | ||
0 => { | ||
#[const_continue] | ||
break 'blk SIZE_OF::<T>; | ||
//~^ ERROR could not determine the target branch for this `#[const_continue]` | ||
} | ||
_ => panic!(), | ||
} | ||
} | ||
} | ||
} | ||
|
||
trait Trait<T> { | ||
const X: usize = 9000; | ||
const Y: usize = size_of::<T>(); | ||
} | ||
|
||
impl<T> Trait<T> for () {} | ||
|
||
fn r<T>() { | ||
let mut state = 0; | ||
#[loop_match] | ||
loop { | ||
state = 'blk: { | ||
match state { | ||
0 => { | ||
#[const_continue] | ||
break 'blk <() as Trait<T>>::X; | ||
} | ||
1 => { | ||
#[const_continue] | ||
break 'blk <() as Trait<T>>::Y; | ||
//~^ ERROR could not determine the target branch for this `#[const_continue]` | ||
} | ||
_ => panic!(), | ||
} | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
error: could not determine the target branch for this `#[const_continue]` | ||
--> $DIR/suggest-const-item.rs:19:32 | ||
| | ||
LL | break 'blk const_fn(); | ||
| ^^^^^^^^^^ this value must be a literal or a monomorphic const | ||
| | ||
= help: try extracting the expression into a `const` item | ||
|
||
error: could not determine the target branch for this `#[const_continue]` | ||
--> $DIR/suggest-const-item.rs:24:32 | ||
| | ||
LL | break 'blk const { const_fn() }; | ||
| ^^^^^^^^^^^^^^^^^^^^ `const` blocks may use generics, and are not evaluated early enough | ||
| | ||
= help: try extracting the expression into a `const` item | ||
|
||
error: could not determine the target branch for this `#[const_continue]` | ||
--> $DIR/suggest-const-item.rs:29:32 | ||
| | ||
LL | break 'blk N; | ||
| ^ constant parameters may use generics, and are not evaluated early enough | ||
| | ||
= help: try extracting the expression into a `const` item | ||
|
||
error: could not determine the target branch for this `#[const_continue]` | ||
--> $DIR/suggest-const-item.rs:34:32 | ||
| | ||
LL | break 'blk 1 + 1; | ||
| ^^^^^ this value must be a literal or a monomorphic const | ||
| | ||
= help: try extracting the expression into a `const` item | ||
|
||
error: could not determine the target branch for this `#[const_continue]` | ||
--> $DIR/suggest-const-item.rs:76:36 | ||
| | ||
LL | break 'blk Self::N; | ||
| ^^^^^^^ this value is too generic | ||
|
||
error: could not determine the target branch for this `#[const_continue]` | ||
--> $DIR/suggest-const-item.rs:119:36 | ||
| | ||
LL | break 'blk Self::L; | ||
| ^^^^^^^ this value is too generic | ||
|
||
error: could not determine the target branch for this `#[const_continue]` | ||
--> $DIR/suggest-const-item.rs:139:32 | ||
| | ||
LL | break 'blk SIZE_OF::<T>; | ||
| ^^^^^^^^^^^^ this value is too generic | ||
|
||
error: could not determine the target branch for this `#[const_continue]` | ||
--> $DIR/suggest-const-item.rs:167:32 | ||
| | ||
LL | break 'blk <() as Trait<T>>::Y; | ||
| ^^^^^^^^^^^^^^^^^^^ this value is too generic | ||
|
||
error: aborting due to 8 previous errors | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Generic constant items will have the same problem, as you could specify them with arguments.
Please add a test for them and for associated consts
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not entirely sure what you mean, I added some extra test cases for the associated const scenarios I could think of. Did you have anything else in mind?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Associated consts of traits can use generics (either by being GATs or by having generic params on the trait). Associated consts of types can use generics I'd the type is generic
Generic const items are an unstable feature but can also explicitly use generics
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, well the examples I can come up with all fail well before any const evaluation would actually take place. Anyway, I've added what I think you mean.