Skip to content

Commit

Permalink
Rollup merge of rust-lang#90930 - Nilstrieb:fix-non-const-value-ice, …
Browse files Browse the repository at this point in the history
…r=estebank

Fix `non-constant value` ICE (rust-lang#90878)

This also fixes the same suggestion, which was kind of broken, because it just searched for the last occurence of `const` to replace with a `let`. This works great in some cases, but when there is no const and a leading space to the file, it doesn't work and panic with overflow because it thought that it had found a const.

I also changed the suggestion to only trigger if the `const` and the non-constant value are on the same line, because if they aren't, the suggestion is very likely to be wrong.

Also don't trigger the suggestion if the found `const` is on line 0, because that triggers the ICE.

Asking Esteban to review since he was the last one to change the relevant code.

r? `@estebank`

Fixes rust-lang#90878
  • Loading branch information
matthiaskrgr committed Nov 16, 2021
2 parents 2b75b61 + d64aea6 commit 614c2ba
Show file tree
Hide file tree
Showing 8 changed files with 100 additions and 1 deletion.
16 changes: 15 additions & 1 deletion compiler/rustc_resolve/src/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -450,9 +450,23 @@ impl<'a> Resolver<'a> {
// let foo =...
// ^^^ given this Span
// ------- get this Span to have an applicable suggestion

// edit:
// only do this if the const and usage of the non-constant value are on the same line
// the further the two are apart, the higher the chance of the suggestion being wrong
// also make sure that this line isn't the first one (ICE #90878)

let sp =
self.session.source_map().span_extend_to_prev_str(ident.span, current, true);
if sp.lo().0 == 0 {

let is_first_line = self
.session
.source_map()
.lookup_line(sp.lo())
.map(|file_and_line| file_and_line.line == 0)
.unwrap_or(true);

if sp.lo().0 == 0 || self.session.source_map().is_multiline(sp) || is_first_line {
err.span_label(ident.span, &format!("this would need to be a `{}`", sugg));
} else {
let sp = sp.with_lo(BytePos(sp.lo().0 - current.len() as u32));
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_span/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1935,6 +1935,7 @@ pub struct Loc {
#[derive(Debug)]
pub struct SourceFileAndLine {
pub sf: Lrc<SourceFile>,
/// Index of line, starting from 0.
pub line: usize,
}
#[derive(Debug)]
Expand Down
12 changes: 12 additions & 0 deletions src/test/ui/consts/issue-90878-2.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#![l=|x|[b;x ]] //~ ERROR unexpected token: `|x| [b; x]`
//~^ ERROR cannot find attribute `l` in this scope
//~^^ ERROR attempt to use a non-constant value in a constant [E0435]
//~^^^ ERROR cannot find value `b` in this scope [E0425]

// notice the space at the start,
// we can't attach any attributes to this file because it needs to be at the start

// this example has been slightly modified (adding ]] at the end), so that it actually works here
// it still produces the same issue though

fn main() {}
30 changes: 30 additions & 0 deletions src/test/ui/consts/issue-90878-2.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
error: unexpected token: `|x| [b; x]`
--> $DIR/issue-90878-2.rs:1:7
|
LL | #![l=|x|[b;x ]]
| ^^^^^^^^^

error: cannot find attribute `l` in this scope
--> $DIR/issue-90878-2.rs:1:5
|
LL | #![l=|x|[b;x ]]
| ^

error[E0435]: attempt to use a non-constant value in a constant
--> $DIR/issue-90878-2.rs:1:13
|
LL | #![l=|x|[b;x ]]
| - ^
| |
| this would need to be a `const`

error[E0425]: cannot find value `b` in this scope
--> $DIR/issue-90878-2.rs:1:11
|
LL | #![l=|x|[b;x ]]
| ^ help: a local variable with a similar name exists: `x`

error: aborting due to 4 previous errors

Some errors have detailed explanations: E0425, E0435.
For more information about an error, try `rustc --explain E0425`.
4 changes: 4 additions & 0 deletions src/test/ui/consts/issue-90878.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
fn main() {
|x: usize| [0; x]; //~ ERROR attempt to use a non-constant value in a constant [E0435]
// (note the space before "fn")
}
11 changes: 11 additions & 0 deletions src/test/ui/consts/issue-90878.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
error[E0435]: attempt to use a non-constant value in a constant
--> $DIR/issue-90878.rs:2:20
|
LL | |x: usize| [0; x];
| - ^
| |
| this would need to be a `const`

error: aborting due to previous error

For more information about this error, try `rustc --explain E0435`.
7 changes: 7 additions & 0 deletions src/test/ui/consts/non-const-value-in-const.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
fn main() {
let x = 5;
const Y: i32 = x; //~ ERROR attempt to use a non-constant value in a constant [E0435]

let x = 5;
let _ = [0; x]; //~ ERROR attempt to use a non-constant value in a constant [E0435]
}
20 changes: 20 additions & 0 deletions src/test/ui/consts/non-const-value-in-const.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
error[E0435]: attempt to use a non-constant value in a constant
--> $DIR/non-const-value-in-const.rs:3:20
|
LL | const Y: i32 = x;
| ------- ^ non-constant value
| |
| help: consider using `let` instead of `const`: `let Y`

error[E0435]: attempt to use a non-constant value in a constant
--> $DIR/non-const-value-in-const.rs:6:17
|
LL | let x = 5;
| ----- help: consider using `const` instead of `let`: `const x`
...
LL | let _ = [0; x];
| ^ non-constant value

error: aborting due to 2 previous errors

For more information about this error, try `rustc --explain E0435`.

0 comments on commit 614c2ba

Please sign in to comment.