Skip to content

Commit 1d1c400

Browse files
authored
Rollup merge of #73639 - ayazhafiz:i/73553, r=davidtwco
Change heuristic for determining range literal Currently, rustc uses a heuristic to determine if a range expression is not a literal based on whether the expression looks like a function call or struct initialization. This fails for range literals whose lower/upper bounds are the results of function calls. A possibly-better heuristic is to check if the expression contains `..`, required in range literals. Of course, this is also not perfect; for example, if the range expression is a struct which includes some text with `..` this will fail, but in general I believe it is a better heuristic. A better alternative altogether is to add the `QPath::LangItem` enum variant suggested in #60607. I would be happy to do this as a precursor to this patch if someone is able to provide general suggestions on how usages of `QPath` need to be changed later in the compiler with the `LangItem` variant. Closes #73553
2 parents 38c85b7 + 7930f9a commit 1d1c400

File tree

3 files changed

+44
-7
lines changed

3 files changed

+44
-7
lines changed

src/librustc_hir/hir.rs

+1-7
Original file line numberDiff line numberDiff line change
@@ -1511,13 +1511,7 @@ pub fn is_range_literal(sm: &SourceMap, expr: &Expr<'_>) -> bool {
15111511
// Check whether a span corresponding to a range expression is a
15121512
// range literal, rather than an explicit struct or `new()` call.
15131513
fn is_lit(sm: &SourceMap, span: &Span) -> bool {
1514-
let end_point = sm.end_point(*span);
1515-
1516-
if let Ok(end_string) = sm.span_to_snippet(end_point) {
1517-
!(end_string.ends_with('}') || end_string.ends_with(')'))
1518-
} else {
1519-
false
1520-
}
1514+
sm.span_to_snippet(*span).map(|range_src| range_src.contains("..")).unwrap_or(false)
15211515
};
15221516

15231517
match expr.kind {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
type Range = std::ops::Range<usize>;
2+
3+
fn demo(r: &Range) {
4+
println!("{:?}", r);
5+
}
6+
7+
fn tell(x: usize) -> usize {
8+
x
9+
}
10+
11+
fn main() {
12+
demo(tell(1)..tell(10));
13+
//~^ ERROR mismatched types
14+
demo(1..10);
15+
//~^ ERROR mismatched types
16+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
error[E0308]: mismatched types
2+
--> $DIR/issue-73553-misinterp-range-literal.rs:12:10
3+
|
4+
LL | demo(tell(1)..tell(10));
5+
| ^^^^^^^^^^^^^^^^^
6+
| |
7+
| expected reference, found struct `std::ops::Range`
8+
| help: consider borrowing here: `&(tell(1)..tell(10))`
9+
|
10+
= note: expected reference `&std::ops::Range<usize>`
11+
found struct `std::ops::Range<usize>`
12+
13+
error[E0308]: mismatched types
14+
--> $DIR/issue-73553-misinterp-range-literal.rs:14:10
15+
|
16+
LL | demo(1..10);
17+
| ^^^^^
18+
| |
19+
| expected reference, found struct `std::ops::Range`
20+
| help: consider borrowing here: `&(1..10)`
21+
|
22+
= note: expected reference `&std::ops::Range<usize>`
23+
found struct `std::ops::Range<{integer}>`
24+
25+
error: aborting due to 2 previous errors
26+
27+
For more information about this error, try `rustc --explain E0308`.

0 commit comments

Comments
 (0)