Skip to content

Commit a5ee722

Browse files
authored
Rollup merge of #91273 - Badel2:ice-index-str, r=estebank
Fix ICE #91268 by checking that the snippet ends with a `)` Fix #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.
2 parents 0ccd566 + 0da3a0f commit a5ee722

File tree

3 files changed

+72
-9
lines changed

3 files changed

+72
-9
lines changed

compiler/rustc_ast_lowering/src/path.rs

+13-9
Original file line numberDiff line numberDiff line change
@@ -229,15 +229,19 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
229229
if let Ok(snippet) = self.sess.source_map().span_to_snippet(data.span) {
230230
// Do not suggest going from `Trait()` to `Trait<>`
231231
if !data.inputs.is_empty() {
232-
if let Some(split) = snippet.find('(') {
233-
let trait_name = &snippet[0..split];
234-
let args = &snippet[split + 1..snippet.len() - 1];
235-
err.span_suggestion(
236-
data.span,
237-
"use angle brackets instead",
238-
format!("{}<{}>", trait_name, args),
239-
Applicability::MaybeIncorrect,
240-
);
232+
// Suggest replacing `(` and `)` with `<` and `>`
233+
// The snippet may be missing the closing `)`, skip that case
234+
if snippet.ends_with(')') {
235+
if let Some(split) = snippet.find('(') {
236+
let trait_name = &snippet[0..split];
237+
let args = &snippet[split + 1..snippet.len() - 1];
238+
err.span_suggestion(
239+
data.span,
240+
"use angle brackets instead",
241+
format!("{}<{}>", trait_name, args),
242+
Applicability::MaybeIncorrect,
243+
);
244+
}
241245
}
242246
}
243247
};

src/test/ui/type/issue-91268.rs

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// error-pattern: this file contains an unclosed delimiter
2+
// error-pattern: cannot find type `ţ` in this scope
3+
// error-pattern: parenthesized type parameters may only be used with a `Fn` trait
4+
// error-pattern: type arguments are not allowed for this type
5+
// error-pattern: mismatched types
6+
// ignore-tidy-trailing-newlines
7+
// `ţ` must be the last character in this file, it cannot be followed by a newline
8+
fn main() {
9+
0: u8(ţ

src/test/ui/type/issue-91268.stderr

+50
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
error: this file contains an unclosed delimiter
2+
--> $DIR/issue-91268.rs:9:12
3+
|
4+
LL | fn main() {
5+
| - unclosed delimiter
6+
LL | 0: u8(ţ
7+
| - ^
8+
| |
9+
| unclosed delimiter
10+
11+
error: this file contains an unclosed delimiter
12+
--> $DIR/issue-91268.rs:9:12
13+
|
14+
LL | fn main() {
15+
| - unclosed delimiter
16+
LL | 0: u8(ţ
17+
| - ^
18+
| |
19+
| unclosed delimiter
20+
21+
error[E0412]: cannot find type `ţ` in this scope
22+
--> $DIR/issue-91268.rs:9:11
23+
|
24+
LL | 0: u8(ţ
25+
| ^ expecting a type here because of type ascription
26+
27+
error[E0214]: parenthesized type parameters may only be used with a `Fn` trait
28+
--> $DIR/issue-91268.rs:9:8
29+
|
30+
LL | 0: u8(ţ
31+
| ^^^^ only `Fn` traits may use parentheses
32+
33+
error[E0109]: type arguments are not allowed for this type
34+
--> $DIR/issue-91268.rs:9:11
35+
|
36+
LL | 0: u8(ţ
37+
| ^ type argument not allowed
38+
39+
error[E0308]: mismatched types
40+
--> $DIR/issue-91268.rs:9:5
41+
|
42+
LL | fn main() {
43+
| - expected `()` because of default return type
44+
LL | 0: u8(ţ
45+
| ^^^^^^^ expected `()`, found `u8`
46+
47+
error: aborting due to 6 previous errors
48+
49+
Some errors have detailed explanations: E0109, E0214, E0308, E0412.
50+
For more information about an error, try `rustc --explain E0109`.

0 commit comments

Comments
 (0)