Skip to content

Commit

Permalink
Rollup merge of rust-lang#91273 - Badel2:ice-index-str, r=estebank
Browse files Browse the repository at this point in the history
Fix ICE rust-lang#91268 by checking that the snippet ends with a `)`

Fix rust-lang#91268

Previously it was assumed that the last character of `snippet` will be a `)`, so using `snippet.len() - 1` as an index should be safe. However as we see in the test, it is possible to enter that branch without a closing `)`, and it will trigger the panic if the last character happens to be multibyte.

The fix is to ensure that the snippet ends with `)`, and skip the suggestion otherwise.
  • Loading branch information
matthiaskrgr authored Dec 3, 2021
2 parents 538beef + 0da3a0f commit 7af2859
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 9 deletions.
22 changes: 13 additions & 9 deletions compiler/rustc_ast_lowering/src/path.rs
Original file line number Diff line number Diff line change
Expand Up @@ -229,15 +229,19 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
if let Ok(snippet) = self.sess.source_map().span_to_snippet(data.span) {
// Do not suggest going from `Trait()` to `Trait<>`
if !data.inputs.is_empty() {
if let Some(split) = snippet.find('(') {
let trait_name = &snippet[0..split];
let args = &snippet[split + 1..snippet.len() - 1];
err.span_suggestion(
data.span,
"use angle brackets instead",
format!("{}<{}>", trait_name, args),
Applicability::MaybeIncorrect,
);
// Suggest replacing `(` and `)` with `<` and `>`
// The snippet may be missing the closing `)`, skip that case
if snippet.ends_with(')') {
if let Some(split) = snippet.find('(') {
let trait_name = &snippet[0..split];
let args = &snippet[split + 1..snippet.len() - 1];
err.span_suggestion(
data.span,
"use angle brackets instead",
format!("{}<{}>", trait_name, args),
Applicability::MaybeIncorrect,
);
}
}
}
};
Expand Down
9 changes: 9 additions & 0 deletions src/test/ui/type/issue-91268.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// error-pattern: this file contains an unclosed delimiter
// error-pattern: cannot find type `ţ` in this scope
// error-pattern: parenthesized type parameters may only be used with a `Fn` trait
// error-pattern: type arguments are not allowed for this type
// error-pattern: mismatched types
// ignore-tidy-trailing-newlines
// `ţ` must be the last character in this file, it cannot be followed by a newline
fn main() {
0: u8(ţ
50 changes: 50 additions & 0 deletions src/test/ui/type/issue-91268.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
error: this file contains an unclosed delimiter
--> $DIR/issue-91268.rs:9:12
|
LL | fn main() {
| - unclosed delimiter
LL | 0: u8(ţ
| - ^
| |
| unclosed delimiter

error: this file contains an unclosed delimiter
--> $DIR/issue-91268.rs:9:12
|
LL | fn main() {
| - unclosed delimiter
LL | 0: u8(ţ
| - ^
| |
| unclosed delimiter

error[E0412]: cannot find type `ţ` in this scope
--> $DIR/issue-91268.rs:9:11
|
LL | 0: u8(ţ
| ^ expecting a type here because of type ascription

error[E0214]: parenthesized type parameters may only be used with a `Fn` trait
--> $DIR/issue-91268.rs:9:8
|
LL | 0: u8(ţ
| ^^^^ only `Fn` traits may use parentheses

error[E0109]: type arguments are not allowed for this type
--> $DIR/issue-91268.rs:9:11
|
LL | 0: u8(ţ
| ^ type argument not allowed

error[E0308]: mismatched types
--> $DIR/issue-91268.rs:9:5
|
LL | fn main() {
| - expected `()` because of default return type
LL | 0: u8(ţ
| ^^^^^^^ expected `()`, found `u8`

error: aborting due to 6 previous errors

Some errors have detailed explanations: E0109, E0214, E0308, E0412.
For more information about an error, try `rustc --explain E0109`.

0 comments on commit 7af2859

Please sign in to comment.