Apply Recovery::Forbidden
when reparsing pasted macro fragments.
Fixes #137874. Removes `tests/crashes/137874.rs`; the new test is simpler (defines its own macro) but tests the same thing. The changes to the output of `tests/ui/associated-consts/issue-93835.rs` partly undo the changes seen when `NtTy` was removed in #133436, which is good.
This commit is contained in:
parent
aa1b7bf070
commit
b9e13cb539
6 changed files with 48 additions and 30 deletions
|
@ -512,6 +512,14 @@ impl<'a> Parser<'a> {
|
|||
self
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn with_recovery<T>(&mut self, recovery: Recovery, f: impl FnOnce(&mut Self) -> T) -> T {
|
||||
let old = mem::replace(&mut self.recovery, recovery);
|
||||
let res = f(self);
|
||||
self.recovery = old;
|
||||
res
|
||||
}
|
||||
|
||||
/// Whether the parser is allowed to recover from broken code.
|
||||
///
|
||||
/// If this returns false, recovering broken code into valid code (especially if this recovery does lookahead)
|
||||
|
@ -770,7 +778,14 @@ impl<'a> Parser<'a> {
|
|||
&& match_mv_kind(mv_kind)
|
||||
{
|
||||
self.bump();
|
||||
let res = f(self).expect("failed to reparse {mv_kind:?}");
|
||||
|
||||
// Recovery is disabled when parsing macro arguments, so it must
|
||||
// also be disabled when reparsing pasted macro arguments,
|
||||
// otherwise we get inconsistent results (e.g. #137874).
|
||||
let res = self.with_recovery(Recovery::Forbidden, |this| {
|
||||
f(this).expect("failed to reparse {mv_kind:?}")
|
||||
});
|
||||
|
||||
if let token::CloseDelim(delim) = self.token.kind
|
||||
&& let Delimiter::Invisible(InvisibleOrigin::MetaVar(mv_kind)) = delim
|
||||
&& match_mv_kind(mv_kind)
|
||||
|
|
|
@ -1,4 +0,0 @@
|
|||
//@ known-bug: #137874
|
||||
fn a() {
|
||||
match b { deref !(0c) };
|
||||
}
|
|
@ -3,11 +3,10 @@
|
|||
fn e() {
|
||||
type_ascribe!(p, a<p:p<e=6>>);
|
||||
//~^ ERROR cannot find type `a` in this scope
|
||||
//~| ERROR path separator must be a double colon
|
||||
//~| ERROR cannot find value
|
||||
//~| ERROR associated const equality
|
||||
//~| ERROR cannot find trait `p` in this scope
|
||||
//~| ERROR associated const equality
|
||||
//~| ERROR failed to resolve: use of unresolved module or unlinked crate `p`
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
|
@ -1,15 +1,3 @@
|
|||
error: path separator must be a double colon
|
||||
--> $DIR/issue-93835.rs:4:25
|
||||
|
|
||||
LL | type_ascribe!(p, a<p:p<e=6>>);
|
||||
| ^
|
||||
|
|
||||
= note: if you meant to annotate an expression with a type, the type ascription syntax has been removed, see issue #101728 <https://github.com/rust-lang/rust/issues/101728>
|
||||
help: use a double colon instead
|
||||
|
|
||||
LL | type_ascribe!(p, a<p::p<e=6>>);
|
||||
| +
|
||||
|
||||
error[E0425]: cannot find value `p` in this scope
|
||||
--> $DIR/issue-93835.rs:4:19
|
||||
|
|
||||
|
@ -22,6 +10,12 @@ error[E0412]: cannot find type `a` in this scope
|
|||
LL | type_ascribe!(p, a<p:p<e=6>>);
|
||||
| ^ not found in this scope
|
||||
|
||||
error[E0405]: cannot find trait `p` in this scope
|
||||
--> $DIR/issue-93835.rs:4:26
|
||||
|
|
||||
LL | type_ascribe!(p, a<p:p<e=6>>);
|
||||
| ^ not found in this scope
|
||||
|
||||
error[E0658]: associated const equality is incomplete
|
||||
--> $DIR/issue-93835.rs:4:28
|
||||
|
|
||||
|
@ -43,15 +37,7 @@ LL | type_ascribe!(p, a<p:p<e=6>>);
|
|||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||
|
||||
error[E0433]: failed to resolve: use of unresolved module or unlinked crate `p`
|
||||
--> $DIR/issue-93835.rs:4:24
|
||||
|
|
||||
LL | type_ascribe!(p, a<p:p<e=6>>);
|
||||
| ^ use of unresolved module or unlinked crate `p`
|
||||
|
|
||||
= help: you might be missing a crate named `p`
|
||||
error: aborting due to 5 previous errors
|
||||
|
||||
error: aborting due to 6 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0412, E0425, E0433, E0658.
|
||||
For more information about an error, try `rustc --explain E0412`.
|
||||
Some errors have detailed explanations: E0405, E0412, E0425, E0658.
|
||||
For more information about an error, try `rustc --explain E0405`.
|
||||
|
|
12
tests/ui/macros/failed-to-reparse-issue-137874.rs
Normal file
12
tests/ui/macros/failed-to-reparse-issue-137874.rs
Normal file
|
@ -0,0 +1,12 @@
|
|||
// This originally crashed because `Recovery::Forbidden` wasn't being applied
|
||||
// when fragments pasted by declarative macros were reparsed.
|
||||
|
||||
macro_rules! m {
|
||||
($p:pat) => {
|
||||
if let $p = 0 {}
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
m!(0X0); //~ ERROR invalid base prefix for number literal
|
||||
}
|
10
tests/ui/macros/failed-to-reparse-issue-137874.stderr
Normal file
10
tests/ui/macros/failed-to-reparse-issue-137874.stderr
Normal file
|
@ -0,0 +1,10 @@
|
|||
error: invalid base prefix for number literal
|
||||
--> $DIR/failed-to-reparse-issue-137874.rs:11:8
|
||||
|
|
||||
LL | m!(0X0);
|
||||
| ^^^ help: try making the prefix lowercase (notice the capitalization): `0x0`
|
||||
|
|
||||
= note: base prefixes (`0xff`, `0b1010`, `0o755`) are lowercase
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue