Skip to content

Commit

Permalink
Fix non-constant value ICE (rust-lang#90878)
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
Noratrieb committed Nov 15, 2021
1 parent eab2d75 commit d64aea6
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 d64aea6

Please sign in to comment.