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 https://github.com/rust-lang/rust/issues/52363
This commit is contained in:
parent
0ec6ea7333
commit
d1949b1ab0
@ -8,7 +8,7 @@ use crate::symbol::{Symbol, sym};
|
|||||||
use crate::errors::Applicability;
|
use crate::errors::Applicability;
|
||||||
|
|
||||||
use syntax_pos::Span;
|
use syntax_pos::Span;
|
||||||
|
use syntax_pos::hygiene::{Mark, SyntaxContext};
|
||||||
use rustc_data_structures::fx::FxHashSet;
|
use rustc_data_structures::fx::FxHashSet;
|
||||||
|
|
||||||
pub fn collect_derives(cx: &mut ExtCtxt<'_>, attrs: &mut Vec<ast::Attribute>) -> Vec<ast::Path> {
|
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
|
|||||||
names.insert(unwrap_or!(path.segments.get(0), continue).ident.name);
|
names.insert(unwrap_or!(path.segments.get(0), continue).ident.name);
|
||||||
}
|
}
|
||||||
|
|
||||||
cx.current_expansion.mark.set_expn_info(ExpnInfo::with_unstable(
|
let mark = Mark::fresh(cx.current_expansion.mark);
|
||||||
|
mark.set_expn_info(ExpnInfo::with_unstable(
|
||||||
ExpnKind::Macro(MacroKind::Derive, Symbol::intern(&pretty_name)), span,
|
ExpnKind::Macro(MacroKind::Derive, Symbol::intern(&pretty_name)), span,
|
||||||
cx.parse_sess.edition, &[sym::rustc_attrs, sym::structural_match],
|
cx.parse_sess.edition, &[sym::rustc_attrs, sym::structural_match],
|
||||||
));
|
));
|
||||||
|
|
||||||
let span = span.with_ctxt(cx.backtrace());
|
let span = span.with_ctxt(SyntaxContext::empty().apply_mark(mark));
|
||||||
item.visit_attrs(|attrs| {
|
item.visit_attrs(|attrs| {
|
||||||
if names.contains(&sym::Eq) && names.contains(&sym::PartialEq) {
|
if names.contains(&sym::Eq) && names.contains(&sym::PartialEq) {
|
||||||
let meta = cx.meta_word(span, sym::structural_match);
|
let meta = cx.meta_word(span, sym::structural_match);
|
||||||
|
@ -117,7 +117,11 @@ impl Mark {
|
|||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn set_expn_info(self, info: ExpnInfo) {
|
pub fn set_expn_info(self, info: ExpnInfo) {
|
||||||
HygieneData::with(|data| data.marks[self.0 as usize].expn_info = Some(info))
|
HygieneData::with(|data| {
|
||||||
|
let old_info = &mut data.marks[self.0 as usize].expn_info;
|
||||||
|
assert!(old_info.is_none(), "expansion info is reset for a mark");
|
||||||
|
*old_info = Some(info);
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_descendant_of(self, ancestor: Mark) -> bool {
|
pub fn is_descendant_of(self, ancestor: Mark) -> bool {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user