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
This commit is contained in:
commit
1d1c400324
@ -1511,13 +1511,7 @@ pub fn is_range_literal(sm: &SourceMap, expr: &Expr<'_>) -> bool {
|
||||
// Check whether a span corresponding to a range expression is a
|
||||
// range literal, rather than an explicit struct or `new()` call.
|
||||
fn is_lit(sm: &SourceMap, span: &Span) -> bool {
|
||||
let end_point = sm.end_point(*span);
|
||||
|
||||
if let Ok(end_string) = sm.span_to_snippet(end_point) {
|
||||
!(end_string.ends_with('}') || end_string.ends_with(')'))
|
||||
} else {
|
||||
false
|
||||
}
|
||||
sm.span_to_snippet(*span).map(|range_src| range_src.contains("..")).unwrap_or(false)
|
||||
};
|
||||
|
||||
match expr.kind {
|
||||
|
16
src/test/ui/range/issue-73553-misinterp-range-literal.rs
Normal file
16
src/test/ui/range/issue-73553-misinterp-range-literal.rs
Normal file
@ -0,0 +1,16 @@
|
||||
type Range = std::ops::Range<usize>;
|
||||
|
||||
fn demo(r: &Range) {
|
||||
println!("{:?}", r);
|
||||
}
|
||||
|
||||
fn tell(x: usize) -> usize {
|
||||
x
|
||||
}
|
||||
|
||||
fn main() {
|
||||
demo(tell(1)..tell(10));
|
||||
//~^ ERROR mismatched types
|
||||
demo(1..10);
|
||||
//~^ ERROR mismatched types
|
||||
}
|
27
src/test/ui/range/issue-73553-misinterp-range-literal.stderr
Normal file
27
src/test/ui/range/issue-73553-misinterp-range-literal.stderr
Normal file
@ -0,0 +1,27 @@
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/issue-73553-misinterp-range-literal.rs:12:10
|
||||
|
|
||||
LL | demo(tell(1)..tell(10));
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
| |
|
||||
| expected reference, found struct `std::ops::Range`
|
||||
| help: consider borrowing here: `&(tell(1)..tell(10))`
|
||||
|
|
||||
= note: expected reference `&std::ops::Range<usize>`
|
||||
found struct `std::ops::Range<usize>`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/issue-73553-misinterp-range-literal.rs:14:10
|
||||
|
|
||||
LL | demo(1..10);
|
||||
| ^^^^^
|
||||
| |
|
||||
| expected reference, found struct `std::ops::Range`
|
||||
| help: consider borrowing here: `&(1..10)`
|
||||
|
|
||||
= note: expected reference `&std::ops::Range<usize>`
|
||||
found struct `std::ops::Range<{integer}>`
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0308`.
|
Loading…
Reference in New Issue
Block a user