Skip to content

Apply Recovery::Forbidden when reparsing pasted macro fragments. #139341

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Apr 5, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions compiler/rustc_ast_lowering/src/item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -676,12 +676,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
let ty =
self.lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::StaticTy));
let safety = self.lower_safety(*safety, hir::Safety::Unsafe);

// njn: where for this?
if define_opaque.is_some() {
self.dcx().span_err(i.span, "foreign statics cannot define opaque types");
}

(ident, hir::ForeignItemKind::Static(ty, *mutability, safety))
}
ForeignItemKind::TyAlias(box TyAlias { ident, .. }) => {
Expand Down
17 changes: 16 additions & 1 deletion compiler/rustc_parse/src/parser/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down
4 changes: 0 additions & 4 deletions tests/crashes/137874.rs

This file was deleted.

3 changes: 1 addition & 2 deletions tests/ui/associated-consts/issue-93835.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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() {}
32 changes: 9 additions & 23 deletions tests/ui/associated-consts/issue-93835.stderr
Original file line number Diff line number Diff line change
@@ -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
|
Expand All @@ -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
|
Expand All @@ -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 6 previous errors
error: aborting due to 5 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 changes: 12 additions & 0 deletions tests/ui/macros/failed-to-reparse-issue-137874.rs
Original file line number Diff line number Diff line change
@@ -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 changes: 10 additions & 0 deletions tests/ui/macros/failed-to-reparse-issue-137874.stderr
Original file line number Diff line number Diff line change
@@ -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