about summary refs log tree commit diff
path: root/compiler
diff options
context:
space:
mode:
authorNilstrieb <48135649+Nilstrieb@users.noreply.github.com>2021-11-15 20:40:29 +0100
committerNilstrieb <48135649+Nilstrieb@users.noreply.github.com>2021-11-15 20:40:29 +0100
commitd64aea65ad3b994ed0e1503f836d82a9896ab468 (patch)
tree3199ceb46387dfbcbd8f8c73bc686dc9f6d9d6b5 /compiler
parenteab2d7519a3f1c11ddaff3d19f8b7727354c6362 (diff)
downloadrust-d64aea65ad3b994ed0e1503f836d82a9896ab468.tar.gz
rust-d64aea65ad3b994ed0e1503f836d82a9896ab468.zip
Fix `non-constant value` ICE (#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.
Diffstat (limited to 'compiler')
-rw-r--r--compiler/rustc_resolve/src/diagnostics.rs16
-rw-r--r--compiler/rustc_span/src/lib.rs1
2 files changed, 16 insertions, 1 deletions
diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs
index c46a18e5103..e9680aae3f8 100644
--- a/compiler/rustc_resolve/src/diagnostics.rs
+++ b/compiler/rustc_resolve/src/diagnostics.rs
@@ -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));
diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs
index dfc64f37e4c..1445c59710c 100644
--- a/compiler/rustc_span/src/lib.rs
+++ b/compiler/rustc_span/src/lib.rs
@@ -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)]