Skip to content

Commit d1949b1

Browse files
committed
expand: Do not overwrite existing ExpnInfo when injecting derive markers
Create a fresh expansion for them instead - this is the usual way to allow unstable features for generated/desugared code. Fixes rust-lang#52363
1 parent 0ec6ea7 commit d1949b1

File tree

2 files changed

+9
-4
lines changed

2 files changed

+9
-4
lines changed

src/libsyntax/ext/derive.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use crate::symbol::{Symbol, sym};
88
use crate::errors::Applicability;
99

1010
use syntax_pos::Span;
11-
11+
use syntax_pos::hygiene::{Mark, SyntaxContext};
1212
use rustc_data_structures::fx::FxHashSet;
1313

1414
pub fn collect_derives(cx: &mut ExtCtxt<'_>, attrs: &mut Vec<ast::Attribute>) -> Vec<ast::Path> {
@@ -55,12 +55,13 @@ pub fn add_derived_markers<T>(cx: &mut ExtCtxt<'_>, span: Span, traits: &[ast::P
5555
names.insert(unwrap_or!(path.segments.get(0), continue).ident.name);
5656
}
5757

58-
cx.current_expansion.mark.set_expn_info(ExpnInfo::with_unstable(
58+
let mark = Mark::fresh(cx.current_expansion.mark);
59+
mark.set_expn_info(ExpnInfo::with_unstable(
5960
ExpnKind::Macro(MacroKind::Derive, Symbol::intern(&pretty_name)), span,
6061
cx.parse_sess.edition, &[sym::rustc_attrs, sym::structural_match],
6162
));
6263

63-
let span = span.with_ctxt(cx.backtrace());
64+
let span = span.with_ctxt(SyntaxContext::empty().apply_mark(mark));
6465
item.visit_attrs(|attrs| {
6566
if names.contains(&sym::Eq) && names.contains(&sym::PartialEq) {
6667
let meta = cx.meta_word(span, sym::structural_match);

src/libsyntax_pos/hygiene.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,11 @@ impl Mark {
117117

118118
#[inline]
119119
pub fn set_expn_info(self, info: ExpnInfo) {
120-
HygieneData::with(|data| data.marks[self.0 as usize].expn_info = Some(info))
120+
HygieneData::with(|data| {
121+
let old_info = &mut data.marks[self.0 as usize].expn_info;
122+
assert!(old_info.is_none(), "expansion info is reset for a mark");
123+
*old_info = Some(info);
124+
})
121125
}
122126

123127
pub fn is_descendant_of(self, ancestor: Mark) -> bool {

0 commit comments

Comments
 (0)