Auto merge of #61253 - nnethercote:avoid-hygiene_data-lookups, r=petrochenkov
Avoid `hygiene_data` lookups These commits mostly introduce compound operations that allow two close adjacent `hygiene_data` lookups to be combined. r? @petrochenkov
This commit is contained in:
commit
0bfbaa6e8d
21 changed files with 100 additions and 62 deletions
|
@ -113,7 +113,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TyTyKind {
|
||||||
.help("try using `Ty` instead")
|
.help("try using `Ty` instead")
|
||||||
.emit();
|
.emit();
|
||||||
} else {
|
} else {
|
||||||
if ty.span.ctxt().outer().expn_info().is_some() {
|
if ty.span.ctxt().outer_expn_info().is_some() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if let Some(t) = is_ty_or_ty_ctxt(cx, ty) {
|
if let Some(t) = is_ty_or_ty_ctxt(cx, ty) {
|
||||||
|
|
|
@ -880,7 +880,7 @@ pub fn provide(providers: &mut Providers<'_>) {
|
||||||
/// This is used to test whether a lint should not even begin to figure out whether it should
|
/// This is used to test whether a lint should not even begin to figure out whether it should
|
||||||
/// be reported on the current node.
|
/// be reported on the current node.
|
||||||
pub fn in_external_macro(sess: &Session, span: Span) -> bool {
|
pub fn in_external_macro(sess: &Session, span: Span) -> bool {
|
||||||
let info = match span.ctxt().outer().expn_info() {
|
let info = match span.ctxt().outer_expn_info() {
|
||||||
Some(info) => info,
|
Some(info) => info,
|
||||||
// no ExpnInfo means this span doesn't come from a macro
|
// no ExpnInfo means this span doesn't come from a macro
|
||||||
None => return false,
|
None => return false,
|
||||||
|
@ -908,7 +908,7 @@ pub fn in_external_macro(sess: &Session, span: Span) -> bool {
|
||||||
|
|
||||||
/// Returns whether `span` originates in a derive macro's expansion
|
/// Returns whether `span` originates in a derive macro's expansion
|
||||||
pub fn in_derive_expansion(span: Span) -> bool {
|
pub fn in_derive_expansion(span: Span) -> bool {
|
||||||
let info = match span.ctxt().outer().expn_info() {
|
let info = match span.ctxt().outer_expn_info() {
|
||||||
Some(info) => info,
|
Some(info) => info,
|
||||||
// no ExpnInfo means this span doesn't come from a macro
|
// no ExpnInfo means this span doesn't come from a macro
|
||||||
None => return false,
|
None => return false,
|
||||||
|
|
|
@ -65,7 +65,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
||||||
format: ExpnFormat::CompilerDesugaring(_),
|
format: ExpnFormat::CompilerDesugaring(_),
|
||||||
def_site: Some(def_span),
|
def_site: Some(def_span),
|
||||||
..
|
..
|
||||||
}) = span.ctxt().outer().expn_info() {
|
}) = span.ctxt().outer_expn_info() {
|
||||||
span = def_span;
|
span = def_span;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2886,7 +2886,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
||||||
|
|
||||||
pub fn find_field_index(self, ident: Ident, variant: &VariantDef) -> Option<usize> {
|
pub fn find_field_index(self, ident: Ident, variant: &VariantDef) -> Option<usize> {
|
||||||
variant.fields.iter().position(|field| {
|
variant.fields.iter().position(|field| {
|
||||||
self.adjust_ident(ident, variant.def_id, hir::DUMMY_HIR_ID).0 == field.ident.modern()
|
self.hygienic_eq(ident, field.ident, variant.def_id)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3085,19 +3085,32 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
||||||
/// its supposed definition name (`def_name`). The method also needs `DefId` of the supposed
|
/// its supposed definition name (`def_name`). The method also needs `DefId` of the supposed
|
||||||
/// definition's parent/scope to perform comparison.
|
/// definition's parent/scope to perform comparison.
|
||||||
pub fn hygienic_eq(self, use_name: Ident, def_name: Ident, def_parent_def_id: DefId) -> bool {
|
pub fn hygienic_eq(self, use_name: Ident, def_name: Ident, def_parent_def_id: DefId) -> bool {
|
||||||
self.adjust_ident(use_name, def_parent_def_id, hir::DUMMY_HIR_ID).0 == def_name.modern()
|
// We could use `Ident::eq` here, but we deliberately don't. The name
|
||||||
|
// comparison fails frequently, and we want to avoid the expensive
|
||||||
|
// `modern()` calls required for the span comparison whenever possible.
|
||||||
|
use_name.name == def_name.name &&
|
||||||
|
self.adjust_ident(use_name, def_parent_def_id).span.ctxt() == def_name.modern().span.ctxt()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn adjust_ident(self, mut ident: Ident, scope: DefId, block: hir::HirId) -> (Ident, DefId) {
|
fn expansion_that_defined(self, scope: DefId) -> Mark {
|
||||||
ident = ident.modern();
|
match scope.krate {
|
||||||
let target_expansion = match scope.krate {
|
|
||||||
LOCAL_CRATE => self.hir().definitions().expansion_that_defined(scope.index),
|
LOCAL_CRATE => self.hir().definitions().expansion_that_defined(scope.index),
|
||||||
_ => Mark::root(),
|
_ => Mark::root(),
|
||||||
};
|
}
|
||||||
let scope = match ident.span.adjust(target_expansion) {
|
}
|
||||||
|
|
||||||
|
pub fn adjust_ident(self, mut ident: Ident, scope: DefId) -> Ident {
|
||||||
|
ident = ident.modern();
|
||||||
|
ident.span.adjust(self.expansion_that_defined(scope));
|
||||||
|
ident
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn adjust_ident_and_get_scope(self, mut ident: Ident, scope: DefId, block: hir::HirId)
|
||||||
|
-> (Ident, DefId) {
|
||||||
|
ident = ident.modern();
|
||||||
|
let scope = match ident.span.adjust(self.expansion_that_defined(scope)) {
|
||||||
Some(actual_expansion) =>
|
Some(actual_expansion) =>
|
||||||
self.hir().definitions().parent_module_of_macro_def(actual_expansion),
|
self.hir().definitions().parent_module_of_macro_def(actual_expansion),
|
||||||
None if block == hir::DUMMY_HIR_ID => DefId::local(CRATE_DEF_INDEX), // Dummy DefId
|
|
||||||
None => self.hir().get_module_parent_by_hir_id(block),
|
None => self.hir().get_module_parent_by_hir_id(block),
|
||||||
};
|
};
|
||||||
(ident, scope)
|
(ident, scope)
|
||||||
|
|
|
@ -131,7 +131,7 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||||
// at the level above that.
|
// at the level above that.
|
||||||
let mut span = source_info.span;
|
let mut span = source_info.span;
|
||||||
while span.ctxt() != NO_EXPANSION && span.ctxt() != self.mir.span.ctxt() {
|
while span.ctxt() != NO_EXPANSION && span.ctxt() != self.mir.span.ctxt() {
|
||||||
if let Some(info) = span.ctxt().outer().expn_info() {
|
if let Some(info) = span.ctxt().outer_expn_info() {
|
||||||
span = info.call_site;
|
span = info.call_site;
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -158,7 +158,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NonShorthandFieldPatterns {
|
||||||
if fieldpat.node.is_shorthand {
|
if fieldpat.node.is_shorthand {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if fieldpat.span.ctxt().outer().expn_info().is_some() {
|
if fieldpat.span.ctxt().outer_expn_info().is_some() {
|
||||||
// Don't lint if this is a macro expansion: macro authors
|
// Don't lint if this is a macro expansion: macro authors
|
||||||
// shouldn't have to worry about this kind of style issue
|
// shouldn't have to worry about this kind of style issue
|
||||||
// (Issue #49588)
|
// (Issue #49588)
|
||||||
|
@ -1003,7 +1003,7 @@ impl UnreachablePub {
|
||||||
let mut applicability = Applicability::MachineApplicable;
|
let mut applicability = Applicability::MachineApplicable;
|
||||||
match vis.node {
|
match vis.node {
|
||||||
hir::VisibilityKind::Public if !cx.access_levels.is_reachable(id) => {
|
hir::VisibilityKind::Public if !cx.access_levels.is_reachable(id) => {
|
||||||
if span.ctxt().outer().expn_info().is_some() {
|
if span.ctxt().outer_expn_info().is_some() {
|
||||||
applicability = Applicability::MaybeIncorrect;
|
applicability = Applicability::MaybeIncorrect;
|
||||||
}
|
}
|
||||||
let def_span = cx.tcx.sess.source_map().def_span(span);
|
let def_span = cx.tcx.sess.source_map().def_span(span);
|
||||||
|
|
|
@ -391,9 +391,8 @@ impl EarlyLintPass for UnusedParens {
|
||||||
// trigger in situations that macro authors shouldn't have to care about, e.g.,
|
// trigger in situations that macro authors shouldn't have to care about, e.g.,
|
||||||
// when a parenthesized token tree matched in one macro expansion is matched as
|
// when a parenthesized token tree matched in one macro expansion is matched as
|
||||||
// an expression in another and used as a fn/method argument (Issue #47775)
|
// an expression in another and used as a fn/method argument (Issue #47775)
|
||||||
if e.span.ctxt().outer().expn_info()
|
if e.span.ctxt().outer_expn_info()
|
||||||
.map_or(false, |info| info.call_site.ctxt().outer()
|
.map_or(false, |info| info.call_site.ctxt().outer_expn_info().is_some()) {
|
||||||
.expn_info().is_some()) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let msg = format!("{} argument", call_kind);
|
let msg = format!("{} argument", call_kind);
|
||||||
|
|
|
@ -845,7 +845,7 @@ impl<'a, 'tcx> NamePrivacyVisitor<'a, 'tcx> {
|
||||||
field: &'tcx ty::FieldDef) { // definition of the field
|
field: &'tcx ty::FieldDef) { // definition of the field
|
||||||
let ident = Ident::new(kw::Invalid, use_ctxt);
|
let ident = Ident::new(kw::Invalid, use_ctxt);
|
||||||
let current_hir = self.current_item;
|
let current_hir = self.current_item;
|
||||||
let def_id = self.tcx.adjust_ident(ident, def.did, current_hir).1;
|
let def_id = self.tcx.adjust_ident_and_get_scope(ident, def.did, current_hir).1;
|
||||||
if !def.is_enum() && !field.vis.is_accessible_from(def_id, self.tcx) {
|
if !def.is_enum() && !field.vis.is_accessible_from(def_id, self.tcx) {
|
||||||
struct_span_err!(self.tcx.sess, span, E0451, "field `{}` of {} `{}` is private",
|
struct_span_err!(self.tcx.sess, span, E0451, "field `{}` of {} `{}` is private",
|
||||||
field.ident, def.variant_descr(), self.tcx.def_path_str(def.did))
|
field.ident, def.variant_descr(), self.tcx.def_path_str(def.did))
|
||||||
|
|
|
@ -762,7 +762,7 @@ impl<'tcx> Visitor<'tcx> for UsePlacementFinder {
|
||||||
ItemKind::Use(..) => {
|
ItemKind::Use(..) => {
|
||||||
// don't suggest placing a use before the prelude
|
// don't suggest placing a use before the prelude
|
||||||
// import or other generated ones
|
// import or other generated ones
|
||||||
if item.span.ctxt().outer().expn_info().is_none() {
|
if item.span.ctxt().outer_expn_info().is_none() {
|
||||||
self.span = Some(item.span.shrink_to_lo());
|
self.span = Some(item.span.shrink_to_lo());
|
||||||
self.found_use = true;
|
self.found_use = true;
|
||||||
return;
|
return;
|
||||||
|
@ -772,7 +772,7 @@ impl<'tcx> Visitor<'tcx> for UsePlacementFinder {
|
||||||
ItemKind::ExternCrate(_) => {}
|
ItemKind::ExternCrate(_) => {}
|
||||||
// but place them before the first other item
|
// but place them before the first other item
|
||||||
_ => if self.span.map_or(true, |span| item.span < span ) {
|
_ => if self.span.map_or(true, |span| item.span < span ) {
|
||||||
if item.span.ctxt().outer().expn_info().is_none() {
|
if item.span.ctxt().outer_expn_info().is_none() {
|
||||||
// don't insert between attributes and an item
|
// don't insert between attributes and an item
|
||||||
if item.attrs.is_empty() {
|
if item.attrs.is_empty() {
|
||||||
self.span = Some(item.span.shrink_to_lo());
|
self.span = Some(item.span.shrink_to_lo());
|
||||||
|
@ -2308,7 +2308,7 @@ impl<'a> Resolver<'a> {
|
||||||
|
|
||||||
fn hygienic_lexical_parent(&mut self, module: Module<'a>, span: &mut Span)
|
fn hygienic_lexical_parent(&mut self, module: Module<'a>, span: &mut Span)
|
||||||
-> Option<Module<'a>> {
|
-> Option<Module<'a>> {
|
||||||
if !module.expansion.is_descendant_of(span.ctxt().outer()) {
|
if !module.expansion.outer_is_descendant_of(span.ctxt()) {
|
||||||
return Some(self.macro_def_scope(span.remove_mark()));
|
return Some(self.macro_def_scope(span.remove_mark()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2344,7 +2344,7 @@ impl<'a> Resolver<'a> {
|
||||||
module.expansion.is_descendant_of(parent.expansion) {
|
module.expansion.is_descendant_of(parent.expansion) {
|
||||||
// The macro is a proc macro derive
|
// The macro is a proc macro derive
|
||||||
if module.expansion.looks_like_proc_macro_derive() {
|
if module.expansion.looks_like_proc_macro_derive() {
|
||||||
if parent.expansion.is_descendant_of(span.ctxt().outer()) {
|
if parent.expansion.outer_is_descendant_of(span.ctxt()) {
|
||||||
*poisoned = Some(node_id);
|
*poisoned = Some(node_id);
|
||||||
return module.parent;
|
return module.parent;
|
||||||
}
|
}
|
||||||
|
|
|
@ -413,7 +413,7 @@ impl<'a> Resolver<'a> {
|
||||||
|
|
||||||
// Possibly apply the macro helper hack
|
// Possibly apply the macro helper hack
|
||||||
if kind == MacroKind::Bang && path.len() == 1 &&
|
if kind == MacroKind::Bang && path.len() == 1 &&
|
||||||
path[0].ident.span.ctxt().outer().expn_info()
|
path[0].ident.span.ctxt().outer_expn_info()
|
||||||
.map_or(false, |info| info.local_inner_macros) {
|
.map_or(false, |info| info.local_inner_macros) {
|
||||||
let root = Ident::new(kw::DollarCrate, path[0].ident.span);
|
let root = Ident::new(kw::DollarCrate, path[0].ident.span);
|
||||||
path.insert(0, Segment::from_ident(root));
|
path.insert(0, Segment::from_ident(root));
|
||||||
|
|
|
@ -903,7 +903,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o {
|
||||||
}?;
|
}?;
|
||||||
|
|
||||||
let (assoc_ident, def_scope) =
|
let (assoc_ident, def_scope) =
|
||||||
tcx.adjust_ident(binding.item_name, candidate.def_id(), hir_ref_id);
|
tcx.adjust_ident_and_get_scope(binding.item_name, candidate.def_id(), hir_ref_id);
|
||||||
let assoc_ty = tcx.associated_items(candidate.def_id()).find(|i| {
|
let assoc_ty = tcx.associated_items(candidate.def_id()).find(|i| {
|
||||||
i.kind == ty::AssocKind::Type && i.ident.modern() == assoc_ident
|
i.kind == ty::AssocKind::Type && i.ident.modern() == assoc_ident
|
||||||
}).expect("missing associated type");
|
}).expect("missing associated type");
|
||||||
|
@ -1433,7 +1433,8 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o {
|
||||||
};
|
};
|
||||||
|
|
||||||
let trait_did = bound.def_id();
|
let trait_did = bound.def_id();
|
||||||
let (assoc_ident, def_scope) = tcx.adjust_ident(assoc_ident, trait_did, hir_ref_id);
|
let (assoc_ident, def_scope) =
|
||||||
|
tcx.adjust_ident_and_get_scope(assoc_ident, trait_did, hir_ref_id);
|
||||||
let item = tcx.associated_items(trait_did).find(|i| {
|
let item = tcx.associated_items(trait_did).find(|i| {
|
||||||
Namespace::from(i.kind) == Namespace::Type &&
|
Namespace::from(i.kind) == Namespace::Type &&
|
||||||
i.ident.modern() == assoc_ident
|
i.ident.modern() == assoc_ident
|
||||||
|
|
|
@ -1184,7 +1184,7 @@ https://doc.rust-lang.org/reference/types.html#trait-objects");
|
||||||
let mut inexistent_fields = vec![];
|
let mut inexistent_fields = vec![];
|
||||||
// Typecheck each field.
|
// Typecheck each field.
|
||||||
for &Spanned { node: ref field, span } in fields {
|
for &Spanned { node: ref field, span } in fields {
|
||||||
let ident = tcx.adjust_ident(field.ident, variant.def_id, self.body_id).0;
|
let ident = tcx.adjust_ident(field.ident, variant.def_id);
|
||||||
let field_ty = match used_fields.entry(ident) {
|
let field_ty = match used_fields.entry(ident) {
|
||||||
Occupied(occupied) => {
|
Occupied(occupied) => {
|
||||||
struct_span_err!(tcx.sess, span, E0025,
|
struct_span_err!(tcx.sess, span, E0025,
|
||||||
|
|
|
@ -331,7 +331,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||||
|
|
||||||
// Check the `expn_info()` to see if this is a macro; if so, it's hard to
|
// Check the `expn_info()` to see if this is a macro; if so, it's hard to
|
||||||
// extract the text and make a good suggestion, so don't bother.
|
// extract the text and make a good suggestion, so don't bother.
|
||||||
let is_macro = sp.ctxt().outer().expn_info().is_some();
|
let is_macro = sp.ctxt().outer_expn_info().is_some();
|
||||||
|
|
||||||
match (&expr.node, &expected.sty, &checked_ty.sty) {
|
match (&expr.node, &expected.sty, &checked_ty.sty) {
|
||||||
(_, &ty::Ref(_, exp, _), &ty::Ref(_, check, _)) => match (&exp.sty, &check.sty) {
|
(_, &ty::Ref(_, exp, _), &ty::Ref(_, check, _)) => match (&exp.sty, &check.sty) {
|
||||||
|
|
|
@ -510,7 +510,8 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> {
|
||||||
{
|
{
|
||||||
let is_accessible = if let Some(name) = self.method_name {
|
let is_accessible = if let Some(name) = self.method_name {
|
||||||
let item = candidate.item;
|
let item = candidate.item;
|
||||||
let def_scope = self.tcx.adjust_ident(name, item.container.id(), self.body_id).1;
|
let def_scope =
|
||||||
|
self.tcx.adjust_ident_and_get_scope(name, item.container.id(), self.body_id).1;
|
||||||
item.vis.is_accessible_from(def_scope, self.tcx)
|
item.vis.is_accessible_from(def_scope, self.tcx)
|
||||||
} else {
|
} else {
|
||||||
true
|
true
|
||||||
|
|
|
@ -892,7 +892,7 @@ impl<'a, 'tcx, 'gcx> hir::intravisit::Visitor<'tcx> for UsePlacementFinder<'a, '
|
||||||
hir::ItemKind::Use(..) => {
|
hir::ItemKind::Use(..) => {
|
||||||
// Don't suggest placing a `use` before the prelude
|
// Don't suggest placing a `use` before the prelude
|
||||||
// import or other generated ones.
|
// import or other generated ones.
|
||||||
if item.span.ctxt().outer().expn_info().is_none() {
|
if item.span.ctxt().outer_expn_info().is_none() {
|
||||||
self.span = Some(item.span.shrink_to_lo());
|
self.span = Some(item.span.shrink_to_lo());
|
||||||
self.found_use = true;
|
self.found_use = true;
|
||||||
return;
|
return;
|
||||||
|
@ -902,7 +902,7 @@ impl<'a, 'tcx, 'gcx> hir::intravisit::Visitor<'tcx> for UsePlacementFinder<'a, '
|
||||||
hir::ItemKind::ExternCrate(_) => {}
|
hir::ItemKind::ExternCrate(_) => {}
|
||||||
// ...but do place them before the first other item.
|
// ...but do place them before the first other item.
|
||||||
_ => if self.span.map_or(true, |span| item.span < span ) {
|
_ => if self.span.map_or(true, |span| item.span < span ) {
|
||||||
if item.span.ctxt().outer().expn_info().is_none() {
|
if item.span.ctxt().outer_expn_info().is_none() {
|
||||||
// Don't insert between attributes and an item.
|
// Don't insert between attributes and an item.
|
||||||
if item.attrs.is_empty() {
|
if item.attrs.is_empty() {
|
||||||
self.span = Some(item.span.shrink_to_lo());
|
self.span = Some(item.span.shrink_to_lo());
|
||||||
|
|
|
@ -3339,7 +3339,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||||
ty::Adt(base_def, substs) if !base_def.is_enum() => {
|
ty::Adt(base_def, substs) if !base_def.is_enum() => {
|
||||||
debug!("struct named {:?}", base_t);
|
debug!("struct named {:?}", base_t);
|
||||||
let (ident, def_scope) =
|
let (ident, def_scope) =
|
||||||
self.tcx.adjust_ident(field, base_def.did, self.body_id);
|
self.tcx.adjust_ident_and_get_scope(field, base_def.did, self.body_id);
|
||||||
let fields = &base_def.non_enum_variant().fields;
|
let fields = &base_def.non_enum_variant().fields;
|
||||||
if let Some(index) = fields.iter().position(|f| f.ident.modern() == ident) {
|
if let Some(index) = fields.iter().position(|f| f.ident.modern() == ident) {
|
||||||
let field = &fields[index];
|
let field = &fields[index];
|
||||||
|
@ -3510,7 +3510,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||||
|
|
||||||
fn available_field_names(&self, variant: &'tcx ty::VariantDef) -> Vec<ast::Name> {
|
fn available_field_names(&self, variant: &'tcx ty::VariantDef) -> Vec<ast::Name> {
|
||||||
variant.fields.iter().filter(|field| {
|
variant.fields.iter().filter(|field| {
|
||||||
let def_scope = self.tcx.adjust_ident(field.ident, variant.def_id, self.body_id).1;
|
let def_scope =
|
||||||
|
self.tcx.adjust_ident_and_get_scope(field.ident, variant.def_id, self.body_id).1;
|
||||||
field.vis.is_accessible_from(def_scope, self.tcx)
|
field.vis.is_accessible_from(def_scope, self.tcx)
|
||||||
})
|
})
|
||||||
.map(|field| field.ident.name)
|
.map(|field| field.ident.name)
|
||||||
|
@ -3628,7 +3629,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||||
|
|
||||||
// Type-check each field.
|
// Type-check each field.
|
||||||
for field in ast_fields {
|
for field in ast_fields {
|
||||||
let ident = tcx.adjust_ident(field.ident, variant.def_id, self.body_id).0;
|
let ident = tcx.adjust_ident(field.ident, variant.def_id);
|
||||||
let field_type = if let Some((i, v_field)) = remaining_fields.remove(&ident) {
|
let field_type = if let Some((i, v_field)) = remaining_fields.remove(&ident) {
|
||||||
seen_fields.insert(ident, field.span);
|
seen_fields.insert(ident, field.span);
|
||||||
self.write_field_index(field.hir_id, i);
|
self.write_field_index(field.hir_id, i);
|
||||||
|
|
|
@ -872,7 +872,7 @@ impl<'a> ExtCtxt<'a> {
|
||||||
let mut ctxt = self.backtrace();
|
let mut ctxt = self.backtrace();
|
||||||
let mut last_macro = None;
|
let mut last_macro = None;
|
||||||
loop {
|
loop {
|
||||||
if ctxt.outer().expn_info().map_or(None, |info| {
|
if ctxt.outer_expn_info().map_or(None, |info| {
|
||||||
if info.format.name() == sym::include {
|
if info.format.name() == sym::include {
|
||||||
// Stop going up the backtrace once include! is encountered
|
// Stop going up the backtrace once include! is encountered
|
||||||
return None;
|
return None;
|
||||||
|
|
|
@ -30,8 +30,8 @@ use errors::SourceMapper;
|
||||||
/// otherwise return the call site span up to the `enclosing_sp` by
|
/// otherwise return the call site span up to the `enclosing_sp` by
|
||||||
/// following the `expn_info` chain.
|
/// following the `expn_info` chain.
|
||||||
pub fn original_sp(sp: Span, enclosing_sp: Span) -> Span {
|
pub fn original_sp(sp: Span, enclosing_sp: Span) -> Span {
|
||||||
let call_site1 = sp.ctxt().outer().expn_info().map(|ei| ei.call_site);
|
let call_site1 = sp.ctxt().outer_expn_info().map(|ei| ei.call_site);
|
||||||
let call_site2 = enclosing_sp.ctxt().outer().expn_info().map(|ei| ei.call_site);
|
let call_site2 = enclosing_sp.ctxt().outer_expn_info().map(|ei| ei.call_site);
|
||||||
match (call_site1, call_site2) {
|
match (call_site1, call_site2) {
|
||||||
(None, _) => sp,
|
(None, _) => sp,
|
||||||
(Some(call_site1), Some(call_site2)) if call_site1 == call_site2 => sp,
|
(Some(call_site1), Some(call_site2)) if call_site1 == call_site2 => sp,
|
||||||
|
|
|
@ -680,7 +680,7 @@ impl server::Span for Rustc<'_> {
|
||||||
self.sess.source_map().lookup_char_pos(span.lo()).file
|
self.sess.source_map().lookup_char_pos(span.lo()).file
|
||||||
}
|
}
|
||||||
fn parent(&mut self, span: Self::Span) -> Option<Self::Span> {
|
fn parent(&mut self, span: Self::Span) -> Option<Self::Span> {
|
||||||
span.ctxt().outer().expn_info().map(|i| i.call_site)
|
span.ctxt().outer_expn_info().map(|i| i.call_site)
|
||||||
}
|
}
|
||||||
fn source(&mut self, span: Self::Span) -> Self::Span {
|
fn source(&mut self, span: Self::Span) -> Self::Span {
|
||||||
span.source_callsite()
|
span.source_callsite()
|
||||||
|
|
|
@ -112,16 +112,14 @@ impl Mark {
|
||||||
HygieneData::with(|data| data.marks[self.0 as usize].default_transparency = transparency)
|
HygieneData::with(|data| data.marks[self.0 as usize].default_transparency = transparency)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_descendant_of(mut self, ancestor: Mark) -> bool {
|
pub fn is_descendant_of(self, ancestor: Mark) -> bool {
|
||||||
HygieneData::with(|data| {
|
HygieneData::with(|data| data.is_descendant_of(self, ancestor))
|
||||||
while self != ancestor {
|
|
||||||
if self == Mark::root() {
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
self = data.marks[self.0 as usize].parent;
|
|
||||||
}
|
/// `mark.outer_is_descendant_of(ctxt)` is equivalent to but faster than
|
||||||
true
|
/// `mark.is_descendant_of(ctxt.outer())`.
|
||||||
})
|
pub fn outer_is_descendant_of(self, ctxt: SyntaxContext) -> bool {
|
||||||
|
HygieneData::with(|data| data.is_descendant_of(self, data.outer(ctxt)))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Computes a mark such that both input marks are descendants of (or equal to) the returned
|
/// Computes a mark such that both input marks are descendants of (or equal to) the returned
|
||||||
|
@ -201,6 +199,24 @@ impl HygieneData {
|
||||||
fn with<T, F: FnOnce(&mut HygieneData) -> T>(f: F) -> T {
|
fn with<T, F: FnOnce(&mut HygieneData) -> T>(f: F) -> T {
|
||||||
GLOBALS.with(|globals| f(&mut *globals.hygiene_data.borrow_mut()))
|
GLOBALS.with(|globals| f(&mut *globals.hygiene_data.borrow_mut()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn outer(&self, ctxt: SyntaxContext) -> Mark {
|
||||||
|
self.syntax_contexts[ctxt.0 as usize].outer_mark
|
||||||
|
}
|
||||||
|
|
||||||
|
fn expn_info(&self, mark: Mark) -> Option<ExpnInfo> {
|
||||||
|
self.marks[mark.0 as usize].expn_info.clone()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_descendant_of(&self, mut mark: Mark, ancestor: Mark) -> bool {
|
||||||
|
while mark != ancestor {
|
||||||
|
if mark == Mark::root() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
mark = self.marks[mark.0 as usize].parent;
|
||||||
|
}
|
||||||
|
true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn clear_markings() {
|
pub fn clear_markings() {
|
||||||
|
@ -416,7 +432,7 @@ impl SyntaxContext {
|
||||||
/// or `None` if we privacy check as usual (i.e., not w.r.t. a macro definition scope).
|
/// or `None` if we privacy check as usual (i.e., not w.r.t. a macro definition scope).
|
||||||
pub fn adjust(&mut self, expansion: Mark) -> Option<Mark> {
|
pub fn adjust(&mut self, expansion: Mark) -> Option<Mark> {
|
||||||
let mut scope = None;
|
let mut scope = None;
|
||||||
while !expansion.is_descendant_of(self.outer()) {
|
while !expansion.outer_is_descendant_of(*self) {
|
||||||
scope = Some(self.remove_mark());
|
scope = Some(self.remove_mark());
|
||||||
}
|
}
|
||||||
scope
|
scope
|
||||||
|
@ -450,7 +466,7 @@ impl SyntaxContext {
|
||||||
pub fn glob_adjust(&mut self, expansion: Mark, mut glob_ctxt: SyntaxContext)
|
pub fn glob_adjust(&mut self, expansion: Mark, mut glob_ctxt: SyntaxContext)
|
||||||
-> Option<Option<Mark>> {
|
-> Option<Option<Mark>> {
|
||||||
let mut scope = None;
|
let mut scope = None;
|
||||||
while !expansion.is_descendant_of(glob_ctxt.outer()) {
|
while !expansion.outer_is_descendant_of(glob_ctxt) {
|
||||||
scope = Some(glob_ctxt.remove_mark());
|
scope = Some(glob_ctxt.remove_mark());
|
||||||
if self.remove_mark() != scope.unwrap() {
|
if self.remove_mark() != scope.unwrap() {
|
||||||
return None;
|
return None;
|
||||||
|
@ -476,7 +492,7 @@ impl SyntaxContext {
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut marks = Vec::new();
|
let mut marks = Vec::new();
|
||||||
while !expansion.is_descendant_of(glob_ctxt.outer()) {
|
while !expansion.outer_is_descendant_of(glob_ctxt) {
|
||||||
marks.push(glob_ctxt.remove_mark());
|
marks.push(glob_ctxt.remove_mark());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -499,7 +515,14 @@ impl SyntaxContext {
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn outer(self) -> Mark {
|
pub fn outer(self) -> Mark {
|
||||||
HygieneData::with(|data| data.syntax_contexts[self.0 as usize].outer_mark)
|
HygieneData::with(|data| data.outer(self))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// `ctxt.outer_expn_info()` is equivalent to but faster than
|
||||||
|
/// `ctxt.outer().expn_info()`.
|
||||||
|
#[inline]
|
||||||
|
pub fn outer_expn_info(self) -> Option<ExpnInfo> {
|
||||||
|
HygieneData::with(|data| data.expn_info(data.outer(self)))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn dollar_crate_name(self) -> Symbol {
|
pub fn dollar_crate_name(self) -> Symbol {
|
||||||
|
|
|
@ -348,18 +348,18 @@ impl Span {
|
||||||
/// Returns the source span -- this is either the supplied span, or the span for
|
/// Returns the source span -- this is either the supplied span, or the span for
|
||||||
/// the macro callsite that expanded to it.
|
/// the macro callsite that expanded to it.
|
||||||
pub fn source_callsite(self) -> Span {
|
pub fn source_callsite(self) -> Span {
|
||||||
self.ctxt().outer().expn_info().map(|info| info.call_site.source_callsite()).unwrap_or(self)
|
self.ctxt().outer_expn_info().map(|info| info.call_site.source_callsite()).unwrap_or(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The `Span` for the tokens in the previous macro expansion from which `self` was generated,
|
/// The `Span` for the tokens in the previous macro expansion from which `self` was generated,
|
||||||
/// if any.
|
/// if any.
|
||||||
pub fn parent(self) -> Option<Span> {
|
pub fn parent(self) -> Option<Span> {
|
||||||
self.ctxt().outer().expn_info().map(|i| i.call_site)
|
self.ctxt().outer_expn_info().map(|i| i.call_site)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Edition of the crate from which this span came.
|
/// Edition of the crate from which this span came.
|
||||||
pub fn edition(self) -> edition::Edition {
|
pub fn edition(self) -> edition::Edition {
|
||||||
self.ctxt().outer().expn_info().map_or_else(|| {
|
self.ctxt().outer_expn_info().map_or_else(|| {
|
||||||
Edition::from_session()
|
Edition::from_session()
|
||||||
}, |einfo| einfo.edition)
|
}, |einfo| einfo.edition)
|
||||||
}
|
}
|
||||||
|
@ -381,19 +381,19 @@ impl Span {
|
||||||
/// corresponding to the source callsite.
|
/// corresponding to the source callsite.
|
||||||
pub fn source_callee(self) -> Option<ExpnInfo> {
|
pub fn source_callee(self) -> Option<ExpnInfo> {
|
||||||
fn source_callee(info: ExpnInfo) -> ExpnInfo {
|
fn source_callee(info: ExpnInfo) -> ExpnInfo {
|
||||||
match info.call_site.ctxt().outer().expn_info() {
|
match info.call_site.ctxt().outer_expn_info() {
|
||||||
Some(info) => source_callee(info),
|
Some(info) => source_callee(info),
|
||||||
None => info,
|
None => info,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.ctxt().outer().expn_info().map(source_callee)
|
self.ctxt().outer_expn_info().map(source_callee)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Checks if a span is "internal" to a macro in which `#[unstable]`
|
/// Checks if a span is "internal" to a macro in which `#[unstable]`
|
||||||
/// items can be used (that is, a macro marked with
|
/// items can be used (that is, a macro marked with
|
||||||
/// `#[allow_internal_unstable]`).
|
/// `#[allow_internal_unstable]`).
|
||||||
pub fn allows_unstable(&self, feature: Symbol) -> bool {
|
pub fn allows_unstable(&self, feature: Symbol) -> bool {
|
||||||
match self.ctxt().outer().expn_info() {
|
match self.ctxt().outer_expn_info() {
|
||||||
Some(info) => info
|
Some(info) => info
|
||||||
.allow_internal_unstable
|
.allow_internal_unstable
|
||||||
.map_or(false, |features| features.iter().any(|&f|
|
.map_or(false, |features| features.iter().any(|&f|
|
||||||
|
@ -405,7 +405,7 @@ impl Span {
|
||||||
|
|
||||||
/// Checks if this span arises from a compiler desugaring of kind `kind`.
|
/// Checks if this span arises from a compiler desugaring of kind `kind`.
|
||||||
pub fn is_compiler_desugaring(&self, kind: CompilerDesugaringKind) -> bool {
|
pub fn is_compiler_desugaring(&self, kind: CompilerDesugaringKind) -> bool {
|
||||||
match self.ctxt().outer().expn_info() {
|
match self.ctxt().outer_expn_info() {
|
||||||
Some(info) => match info.format {
|
Some(info) => match info.format {
|
||||||
ExpnFormat::CompilerDesugaring(k) => k == kind,
|
ExpnFormat::CompilerDesugaring(k) => k == kind,
|
||||||
_ => false,
|
_ => false,
|
||||||
|
@ -417,7 +417,7 @@ impl Span {
|
||||||
/// Returns the compiler desugaring that created this span, or `None`
|
/// Returns the compiler desugaring that created this span, or `None`
|
||||||
/// if this span is not from a desugaring.
|
/// if this span is not from a desugaring.
|
||||||
pub fn compiler_desugaring_kind(&self) -> Option<CompilerDesugaringKind> {
|
pub fn compiler_desugaring_kind(&self) -> Option<CompilerDesugaringKind> {
|
||||||
match self.ctxt().outer().expn_info() {
|
match self.ctxt().outer_expn_info() {
|
||||||
Some(info) => match info.format {
|
Some(info) => match info.format {
|
||||||
ExpnFormat::CompilerDesugaring(k) => Some(k),
|
ExpnFormat::CompilerDesugaring(k) => Some(k),
|
||||||
_ => None
|
_ => None
|
||||||
|
@ -430,7 +430,7 @@ impl Span {
|
||||||
/// can be used without triggering the `unsafe_code` lint
|
/// can be used without triggering the `unsafe_code` lint
|
||||||
// (that is, a macro marked with `#[allow_internal_unsafe]`).
|
// (that is, a macro marked with `#[allow_internal_unsafe]`).
|
||||||
pub fn allows_unsafe(&self) -> bool {
|
pub fn allows_unsafe(&self) -> bool {
|
||||||
match self.ctxt().outer().expn_info() {
|
match self.ctxt().outer_expn_info() {
|
||||||
Some(info) => info.allow_internal_unsafe,
|
Some(info) => info.allow_internal_unsafe,
|
||||||
None => false,
|
None => false,
|
||||||
}
|
}
|
||||||
|
@ -439,7 +439,7 @@ impl Span {
|
||||||
pub fn macro_backtrace(mut self) -> Vec<MacroBacktrace> {
|
pub fn macro_backtrace(mut self) -> Vec<MacroBacktrace> {
|
||||||
let mut prev_span = DUMMY_SP;
|
let mut prev_span = DUMMY_SP;
|
||||||
let mut result = vec![];
|
let mut result = vec![];
|
||||||
while let Some(info) = self.ctxt().outer().expn_info() {
|
while let Some(info) = self.ctxt().outer_expn_info() {
|
||||||
// Don't print recursive invocations.
|
// Don't print recursive invocations.
|
||||||
if !info.call_site.source_equal(&prev_span) {
|
if !info.call_site.source_equal(&prev_span) {
|
||||||
let (pre, post) = match info.format {
|
let (pre, post) = match info.format {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue