Skip to content

Commit 66ccc4f

Browse files
authored
Rollup merge of #139341 - nnethercote:fix-137874, r=petrochenkov
Apply `Recovery::Forbidden` when reparsing pasted macro fragments. Fixes #137874. 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. r? ``@petrochenkov``
2 parents 6907e01 + b9e13cb commit 66ccc4f

File tree

7 files changed

+48
-33
lines changed

7 files changed

+48
-33
lines changed

compiler/rustc_ast_lowering/src/item.rs

-3
Original file line numberDiff line numberDiff line change
@@ -676,12 +676,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
676676
let ty =
677677
self.lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::StaticTy));
678678
let safety = self.lower_safety(*safety, hir::Safety::Unsafe);
679-
680-
// njn: where for this?
681679
if define_opaque.is_some() {
682680
self.dcx().span_err(i.span, "foreign statics cannot define opaque types");
683681
}
684-
685682
(ident, hir::ForeignItemKind::Static(ty, *mutability, safety))
686683
}
687684
ForeignItemKind::TyAlias(box TyAlias { ident, .. }) => {

compiler/rustc_parse/src/parser/mod.rs

+16-1
Original file line numberDiff line numberDiff line change
@@ -512,6 +512,14 @@ impl<'a> Parser<'a> {
512512
self
513513
}
514514

515+
#[inline]
516+
fn with_recovery<T>(&mut self, recovery: Recovery, f: impl FnOnce(&mut Self) -> T) -> T {
517+
let old = mem::replace(&mut self.recovery, recovery);
518+
let res = f(self);
519+
self.recovery = old;
520+
res
521+
}
522+
515523
/// Whether the parser is allowed to recover from broken code.
516524
///
517525
/// If this returns false, recovering broken code into valid code (especially if this recovery does lookahead)
@@ -770,7 +778,14 @@ impl<'a> Parser<'a> {
770778
&& match_mv_kind(mv_kind)
771779
{
772780
self.bump();
773-
let res = f(self).expect("failed to reparse {mv_kind:?}");
781+
782+
// Recovery is disabled when parsing macro arguments, so it must
783+
// also be disabled when reparsing pasted macro arguments,
784+
// otherwise we get inconsistent results (e.g. #137874).
785+
let res = self.with_recovery(Recovery::Forbidden, |this| {
786+
f(this).expect("failed to reparse {mv_kind:?}")
787+
});
788+
774789
if let token::CloseDelim(delim) = self.token.kind
775790
&& let Delimiter::Invisible(InvisibleOrigin::MetaVar(mv_kind)) = delim
776791
&& match_mv_kind(mv_kind)

tests/crashes/137874.rs

-4
This file was deleted.

tests/ui/associated-consts/issue-93835.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,10 @@
33
fn e() {
44
type_ascribe!(p, a<p:p<e=6>>);
55
//~^ ERROR cannot find type `a` in this scope
6-
//~| ERROR path separator must be a double colon
76
//~| ERROR cannot find value
87
//~| ERROR associated const equality
8+
//~| ERROR cannot find trait `p` in this scope
99
//~| ERROR associated const equality
10-
//~| ERROR failed to resolve: use of unresolved module or unlinked crate `p`
1110
}
1211

1312
fn main() {}
+9-23
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,3 @@
1-
error: path separator must be a double colon
2-
--> $DIR/issue-93835.rs:4:25
3-
|
4-
LL | type_ascribe!(p, a<p:p<e=6>>);
5-
| ^
6-
|
7-
= 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>
8-
help: use a double colon instead
9-
|
10-
LL | type_ascribe!(p, a<p::p<e=6>>);
11-
| +
12-
131
error[E0425]: cannot find value `p` in this scope
142
--> $DIR/issue-93835.rs:4:19
153
|
@@ -22,6 +10,12 @@ error[E0412]: cannot find type `a` in this scope
2210
LL | type_ascribe!(p, a<p:p<e=6>>);
2311
| ^ not found in this scope
2412

13+
error[E0405]: cannot find trait `p` in this scope
14+
--> $DIR/issue-93835.rs:4:26
15+
|
16+
LL | type_ascribe!(p, a<p:p<e=6>>);
17+
| ^ not found in this scope
18+
2519
error[E0658]: associated const equality is incomplete
2620
--> $DIR/issue-93835.rs:4:28
2721
|
@@ -43,15 +37,7 @@ LL | type_ascribe!(p, a<p:p<e=6>>);
4337
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
4438
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
4539

46-
error[E0433]: failed to resolve: use of unresolved module or unlinked crate `p`
47-
--> $DIR/issue-93835.rs:4:24
48-
|
49-
LL | type_ascribe!(p, a<p:p<e=6>>);
50-
| ^ use of unresolved module or unlinked crate `p`
51-
|
52-
= help: you might be missing a crate named `p`
53-
54-
error: aborting due to 6 previous errors
40+
error: aborting due to 5 previous errors
5541

56-
Some errors have detailed explanations: E0412, E0425, E0433, E0658.
57-
For more information about an error, try `rustc --explain E0412`.
42+
Some errors have detailed explanations: E0405, E0412, E0425, E0658.
43+
For more information about an error, try `rustc --explain E0405`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// This originally crashed because `Recovery::Forbidden` wasn't being applied
2+
// when fragments pasted by declarative macros were reparsed.
3+
4+
macro_rules! m {
5+
($p:pat) => {
6+
if let $p = 0 {}
7+
}
8+
}
9+
10+
fn main() {
11+
m!(0X0); //~ ERROR invalid base prefix for number literal
12+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
error: invalid base prefix for number literal
2+
--> $DIR/failed-to-reparse-issue-137874.rs:11:8
3+
|
4+
LL | m!(0X0);
5+
| ^^^ help: try making the prefix lowercase (notice the capitalization): `0x0`
6+
|
7+
= note: base prefixes (`0xff`, `0b1010`, `0o755`) are lowercase
8+
9+
error: aborting due to 1 previous error
10+

0 commit comments

Comments
 (0)