Immediately feed visibility on DefId creation

This commit is contained in:
Oli Scherer
2026-04-20 14:06:31 +02:00
parent af03b49b25
commit 3070ce9d1b
5 changed files with 115 additions and 94 deletions
+17
View File
@@ -702,6 +702,23 @@ pub fn feed_anon_const_type(self, key: LocalDefId, value: ty::EarlyBinder<'tcx,
pub fn feed_delayed_owner(self, key: LocalDefId, owner: MaybeOwner<'tcx>) {
TyCtxtFeed { tcx: self, key }.delayed_owner(owner);
}
// Trait impl item visibility is inherited from its trait when not specified
// explicitly. In that case we cannot determine it in early resolve,
// but instead are feeding it in late resolve, where we don't have access to the
// `TyCtxtFeed` anymore.
// To avoid having to hash the `LocalDefId` multiple times for inserting and removing the
// `TyCtxtFeed` from a hash table, we add this hack to feed the visibility.
// Do not use outside of the resolver query.
pub fn feed_visibility_for_trait_impl_item(self, key: LocalDefId, vis: ty::Visibility) {
if cfg!(debug_assertions) {
match self.def_kind(self.local_parent(key)) {
DefKind::Impl { of_trait: true } => {}
other => bug!("{key:?} is not an assoc item of a trait impl: {other:?}"),
}
}
TyCtxtFeed { tcx: self, key }.visibility(vis.to_def_id())
}
}
impl<'tcx, KEY: Copy> TyCtxtFeed<'tcx, KEY> {
@@ -21,7 +21,7 @@
use rustc_index::bit_set::DenseBitSet;
use rustc_metadata::creader::LoadedMacro;
use rustc_middle::metadata::{ModChild, Reexport};
use rustc_middle::ty::{Feed, Visibility};
use rustc_middle::ty::{TyCtxtFeed, Visibility};
use rustc_middle::{bug, span_bug};
use rustc_span::hygiene::{ExpnId, LocalExpnId, MacroKind};
use rustc_span::{Ident, Span, Symbol, kw, sym};
@@ -563,6 +563,7 @@ fn build_reduced_graph_for_use_tree(
item: &Item,
vis: Visibility,
root_span: Span,
feed: TyCtxtFeed<'tcx, LocalDefId>,
) {
debug!(
"build_reduced_graph_for_use_tree(parent_prefix={:?}, use_tree={:?}, nested={})",
@@ -572,7 +573,7 @@ fn build_reduced_graph_for_use_tree(
// Top level use tree reuses the item's id and list stems reuse their parent
// use tree's ids, so in both cases their visibilities are already filled.
if nested && !list_stem {
self.r.feed_visibility(self.r.feed(id), vis);
self.r.feed_visibility(feed, vis);
}
let mut prefix_iter = parent_prefix
@@ -735,11 +736,11 @@ fn build_reduced_graph_for_use_tree(
}
ast::UseTreeKind::Nested { ref items, .. } => {
for &(ref tree, id) in items {
self.create_def(id, None, DefKind::Use, use_tree.span());
let feed = self.create_def(id, None, DefKind::Use, use_tree.span());
self.build_reduced_graph_for_use_tree(
// This particular use tree
tree, id, &prefix, true, false, // The whole `use` item
item, vis, root_span,
item, vis, root_span, feed,
);
}
@@ -768,6 +769,7 @@ fn build_reduced_graph_for_use_tree(
self.parent_scope.module.nearest_parent_mod().expect_local(),
),
root_span,
feed,
);
}
}
@@ -778,7 +780,7 @@ fn build_reduced_graph_for_struct_variant(
&mut self,
fields: &[ast::FieldDef],
ident: Ident,
feed: Feed<'tcx, LocalDefId>,
feed: TyCtxtFeed<'tcx, LocalDefId>,
adt_res: Res,
adt_vis: Visibility,
adt_span: Span,
@@ -798,13 +800,12 @@ fn build_reduced_graph_for_struct_variant(
}
/// Constructs the reduced graph for one item.
fn build_reduced_graph_for_item(&mut self, item: &'a Item) {
fn build_reduced_graph_for_item(&mut self, item: &'a Item, feed: TyCtxtFeed<'tcx, LocalDefId>) {
let parent_scope = &self.parent_scope;
let parent = parent_scope.module.expect_local();
let expansion = parent_scope.expansion;
let sp = item.span;
let vis = self.resolve_visibility(&item.vis);
let feed = self.r.feed(item.id);
let local_def_id = feed.key();
let def_id = local_def_id.to_def_id();
let def_kind = self.r.tcx.def_kind(def_id);
@@ -825,6 +826,7 @@ fn build_reduced_graph_for_item(&mut self, item: &'a Item) {
item,
vis,
use_tree.span(),
feed,
);
}
@@ -867,7 +869,7 @@ fn build_reduced_graph_for_item(&mut self, item: &'a Item) {
// Functions introducing procedural macros reserve a slot
// in the macro namespace as well (see #52225).
self.define_macro(item);
self.define_macro(item, feed);
}
// These items live in the type namespace.
@@ -928,14 +930,13 @@ fn build_reduced_graph_for_item(&mut self, item: &'a Item) {
field_visibilities.push(field_vis.to_def_id());
}
// If this is a unit or tuple-like struct, register the constructor.
self.create_def(
let feed = self.create_def(
ctor_node_id,
None,
DefKind::Ctor(CtorOf::Struct, ctor_kind),
item.span,
);
let feed = self.r.feed(ctor_node_id);
let ctor_def_id = feed.key();
let ctor_res = self.res(ctor_def_id);
self.r.define_local(parent, ident, ValueNS, ctor_res, ctor_vis, sp, expansion);
@@ -1070,8 +1071,8 @@ pub(crate) fn build_reduced_graph_for_foreign_item(
&mut self,
item: &ForeignItem,
ident: Ident,
feed: TyCtxtFeed<'tcx, LocalDefId>,
) {
let feed = self.r.feed(item.id);
let local_def_id = feed.key();
let def_id = local_def_id.to_def_id();
let ns = match item.kind {
@@ -1267,10 +1268,13 @@ fn insert_unused_macro(&mut self, ident: Ident, def_id: LocalDefId, node_id: Nod
}
}
fn define_macro(&mut self, item: &ast::Item) -> MacroRulesScopeRef<'ra> {
fn define_macro(
&mut self,
item: &ast::Item,
feed: TyCtxtFeed<'tcx, LocalDefId>,
) -> MacroRulesScopeRef<'ra> {
let parent_scope = self.parent_scope;
let expansion = parent_scope.expansion;
let feed = self.r.feed(item.id);
let def_id = feed.key();
let (res, orig_ident, span, macro_rules) = match &item.kind {
ItemKind::MacroDef(ident, def) => {
@@ -1369,17 +1373,17 @@ fn define_macro(&mut self, item: &ast::Item) -> MacroRulesScopeRef<'ra> {
}
impl<'a, 'ra, 'tcx> DefCollector<'a, 'ra, 'tcx> {
pub(crate) fn brg_visit_item(&mut self, item: &'a Item) {
pub(crate) fn brg_visit_item(&mut self, item: &'a Item, feed: TyCtxtFeed<'tcx, LocalDefId>) {
let orig_module_scope = self.parent_scope.module;
self.parent_scope.macro_rules = match item.kind {
ItemKind::MacroDef(..) => {
let macro_rules_scope = self.define_macro(item);
let macro_rules_scope = self.define_macro(item, feed);
visit::walk_item(self, item);
macro_rules_scope
}
_ => {
let orig_macro_rules_scope = self.parent_scope.macro_rules;
self.build_reduced_graph_for_item(item);
self.build_reduced_graph_for_item(item, feed);
match item.kind {
ItemKind::Mod(..) => {
// Visit attributes after items for backward compatibility.
@@ -1422,9 +1426,9 @@ pub(crate) fn brg_visit_assoc_item(
ctxt: AssocCtxt,
ident: Ident,
ns: Namespace,
feed: TyCtxtFeed<'tcx, LocalDefId>,
) {
let vis = self.resolve_visibility(&item.vis);
let feed = self.r.feed(item.id);
let local_def_id = feed.key();
let def_id = local_def_id.to_def_id();
@@ -1476,21 +1480,28 @@ pub(crate) fn visit_assoc_item_mac_call(
}
}
pub(crate) fn brg_visit_field_def(&mut self, sf: &'a ast::FieldDef) {
pub(crate) fn brg_visit_field_def(
&mut self,
sf: &'a ast::FieldDef,
feed: TyCtxtFeed<'tcx, LocalDefId>,
) {
let vis = self.resolve_visibility(&sf.vis);
self.r.feed_visibility(self.r.feed(sf.id), vis);
self.r.feed_visibility(feed, vis);
visit::walk_field_def(self, sf);
}
// Constructs the reduced graph for one variant. Variants exist in the
// type and value namespaces.
pub(crate) fn brg_visit_variant(&mut self, variant: &'a ast::Variant) {
pub(crate) fn brg_visit_variant(
&mut self,
variant: &'a ast::Variant,
feed: TyCtxtFeed<'tcx, LocalDefId>,
) {
let parent = self.parent_scope.module.expect_local();
let expn_id = self.parent_scope.expansion;
let ident = variant.ident;
// Define a name in the type namespace.
let feed = self.r.feed(variant.id);
let def_id = feed.key();
let vis = self.resolve_visibility(&variant.vis);
self.r.define_local(parent, ident, TypeNS, self.res(def_id), vis, variant.span, expn_id);
@@ -1506,13 +1517,12 @@ pub(crate) fn brg_visit_variant(&mut self, variant: &'a ast::Variant) {
// Define a constructor name in the value namespace.
if let Some((ctor_kind, ctor_node_id)) = CtorKind::from_ast(&variant.data) {
self.create_def(
let feed = self.create_def(
ctor_node_id,
None,
DefKind::Ctor(CtorOf::Variant, ctor_kind),
variant.span,
);
let feed = self.r.feed(ctor_node_id);
let ctor_def_id = feed.key();
let ctor_res = self.res(ctor_def_id);
self.r.define_local(parent, ident, ValueNS, ctor_res, ctor_vis, variant.span, expn_id);
+49 -43
View File
@@ -11,6 +11,7 @@
use rustc_hir::def::Namespace::{TypeNS, ValueNS};
use rustc_hir::def_id::LocalDefId;
use rustc_middle::span_bug;
use rustc_middle::ty::TyCtxtFeed;
use rustc_span::{Span, Symbol, sym};
use tracing::{debug, instrument};
@@ -43,22 +44,20 @@ pub(super) fn create_def(
name: Option<Symbol>,
def_kind: DefKind,
span: Span,
) -> LocalDefId {
) -> TyCtxtFeed<'tcx, LocalDefId> {
let parent_def = self.invocation_parent.parent_def;
debug!(
"create_def(node_id={:?}, def_kind={:?}, parent_def={:?})",
node_id, def_kind, parent_def
);
self.r
.create_def(
parent_def,
node_id,
name,
def_kind,
self.parent_scope.expansion.to_expn_id(),
span.with_parent(None),
)
.def_id()
self.r.create_def(
parent_def,
node_id,
name,
def_kind,
self.parent_scope.expansion.to_expn_id(),
span.with_parent(None),
)
}
fn with_parent<F: FnOnce(&mut Self)>(&mut self, parent_def: LocalDefId, f: F) {
@@ -100,7 +99,7 @@ fn collect_field(&mut self, field: &'a FieldDef, index: Option<usize>) {
} else {
let name = field.ident.map_or_else(|| sym::integer(index(self)), |ident| ident.name);
let def = self.create_def(field.id, Some(name), DefKind::Field, field.span);
self.with_parent(def, |this| this.brg_visit_field_def(field));
self.with_parent(def.def_id(), |this| this.brg_visit_field_def(field, def));
}
}
@@ -173,8 +172,8 @@ fn visit_item(&mut self, i: &'a Item) {
}
ItemKind::GlobalAsm(..) => DefKind::GlobalAsm,
ItemKind::Use(_) => {
self.create_def(i.id, None, DefKind::Use, i.span);
self.brg_visit_item(i);
let feed = self.create_def(i.id, None, DefKind::Use, i.span);
self.brg_visit_item(i, feed);
return;
}
ItemKind::MacCall(..) => {
@@ -184,15 +183,14 @@ fn visit_item(&mut self, i: &'a Item) {
}
ItemKind::DelegationMac(..) => unreachable!(),
};
let def_id =
self.create_def(i.id, i.kind.ident().map(|ident| ident.name), def_kind, i.span);
let feed = self.create_def(i.id, i.kind.ident().map(|ident| ident.name), def_kind, i.span);
if let Some(macro_data) = opt_macro_data {
self.r.new_local_macro(def_id, macro_data);
self.r.new_local_macro(feed.def_id(), macro_data);
}
self.with_parent(def_id, |this| {
this.with_impl_trait(ImplTraitContext::Existential, |this| this.brg_visit_item(i))
self.with_parent(feed.def_id(), |this| {
this.with_impl_trait(ImplTraitContext::Existential, |this| this.brg_visit_item(i, feed))
});
}
@@ -228,15 +226,17 @@ fn visit_fn(&mut self, fn_kind: FnKind<'a>, _: &AttrVec, span: Span, _: NodeId)
}
let (return_id, return_span) = coroutine_kind.return_id();
let return_def = self.create_def(return_id, None, DefKind::OpaqueTy, return_span);
let return_def =
self.create_def(return_id, None, DefKind::OpaqueTy, return_span).def_id();
self.with_parent(return_def, |this| this.visit_fn_ret_ty(output));
// If this async fn has no body (i.e. it's an async fn signature in a trait)
// then the closure_def will never be used, and we should avoid generating a
// def-id for it.
if let Some(body) = body {
let closure_def =
self.create_def(coroutine_kind.closure_id(), None, DefKind::Closure, span);
let closure_def = self
.create_def(coroutine_kind.closure_id(), None, DefKind::Closure, span)
.def_id();
self.with_parent(closure_def, |this| this.visit_block(body));
}
}
@@ -246,8 +246,9 @@ fn visit_fn(&mut self, fn_kind: FnKind<'a>, _: &AttrVec, span: Span, _: NodeId)
// Async closures desugar to closures inside of closures, so
// we must create two defs.
let coroutine_def =
self.create_def(coroutine_kind.closure_id(), None, DefKind::Closure, span);
let coroutine_def = self
.create_def(coroutine_kind.closure_id(), None, DefKind::Closure, span)
.def_id();
self.with_parent(coroutine_def, |this| this.visit_expr(body));
}
_ => visit::walk_fn(self, fn_kind),
@@ -283,8 +284,8 @@ fn visit_foreign_item(&mut self, fi: &'a ForeignItem) {
let def = self.create_def(fi.id, Some(ident.name), def_kind, fi.span);
self.with_parent(def, |this| {
this.build_reduced_graph_for_foreign_item(fi, ident);
self.with_parent(def.def_id(), |this| {
this.build_reduced_graph_for_foreign_item(fi, ident, def);
visit::walk_item(this, fi)
});
}
@@ -295,8 +296,8 @@ fn visit_variant(&mut self, v: &'a Variant) {
self.visit_invoc_in_module(v.id);
return;
}
let def = self.create_def(v.id, Some(v.ident.name), DefKind::Variant, v.span);
self.with_parent(def, |this| this.brg_visit_variant(v));
let feed = self.create_def(v.id, Some(v.ident.name), DefKind::Variant, v.span);
self.with_parent(feed.def_id(), |this| this.brg_visit_variant(v, feed));
}
fn visit_where_predicate(&mut self, pred: &'a WherePredicate) {
@@ -365,8 +366,8 @@ fn visit_assoc_item(&mut self, i: &'a AssocItem, ctxt: visit::AssocCtxt) {
}
};
let def = self.create_def(i.id, Some(ident.name), def_kind, i.span);
self.with_parent(def, |this| this.brg_visit_assoc_item(i, ctxt, ident, ns));
let feed = self.create_def(i.id, Some(ident.name), def_kind, i.span);
self.with_parent(feed.def_id(), |this| this.brg_visit_assoc_item(i, ctxt, ident, ns, feed));
}
fn visit_pat(&mut self, pat: &'a Pat) {
@@ -384,8 +385,9 @@ fn visit_anon_const(&mut self, constant: &'a AnonConst) {
// to avoid affecting stable we have to feature gate the not creating
// anon consts
if !self.r.tcx.features().min_generic_const_args() {
let parent =
self.create_def(constant.id, None, DefKind::AnonConst, constant.value.span);
let parent = self
.create_def(constant.id, None, DefKind::AnonConst, constant.value.span)
.def_id();
return self.with_parent(parent, |this| visit::walk_anon_const(this, constant));
}
@@ -395,8 +397,9 @@ fn visit_anon_const(&mut self, constant: &'a AnonConst) {
}),
MgcaDisambiguation::AnonConst => {
self.with_const_arg(ConstArgContext::NonDirect, |this| {
let parent =
this.create_def(constant.id, None, DefKind::AnonConst, constant.value.span);
let parent = this
.create_def(constant.id, None, DefKind::AnonConst, constant.value.span)
.def_id();
this.with_parent(parent, |this| visit::walk_anon_const(this, constant));
})
}
@@ -414,7 +417,7 @@ fn visit_expr(&mut self, expr: &'a Expr) {
return;
}
ExprKind::Closure(..) | ExprKind::Gen(..) => {
self.create_def(expr.id, None, DefKind::Closure, expr.span)
self.create_def(expr.id, None, DefKind::Closure, expr.span).def_id()
}
ExprKind::ConstBlock(constant) => {
// Under `min_generic_const_args` a `const { }` block sometimes
@@ -429,7 +432,8 @@ fn visit_expr(&mut self, expr: &'a Expr) {
visit::walk_attribute(this, attr);
}
let def = this.create_def(constant.id, None, def_kind, constant.value.span);
let def =
this.create_def(constant.id, None, def_kind, constant.value.span).def_id();
this.with_parent(def, |this| visit::walk_anon_const(this, constant));
});
}
@@ -479,7 +483,7 @@ fn visit_ty(&mut self, ty: &'a Ty) {
ImplTraitContext::Existential => DefKind::OpaqueTy,
ImplTraitContext::InBinding => return visit::walk_ty(self, ty),
};
let id = self.create_def(opaque_id, Some(name), kind, ty.span);
let id = self.create_def(opaque_id, Some(name), kind, ty.span).def_id();
match self.invocation_parent.impl_trait_context {
// Do not nest APIT, as we desugar them as `impl_trait: bounds`,
// so the `impl_trait` node is not a parent to `bounds`.
@@ -602,12 +606,14 @@ fn visit_inline_asm(&mut self, asm: &'a InlineAsm) {
}
}
InlineAsmOperand::Const { anon_const } => {
let def = self.create_def(
anon_const.id,
None,
DefKind::InlineConst,
anon_const.value.span,
);
let def = self
.create_def(
anon_const.id,
None,
DefKind::InlineConst,
anon_const.value.span,
)
.def_id();
self.with_parent(def, |this| visit::walk_anon_const(this, anon_const));
}
InlineAsmOperand::Sym { sym } => self.visit_inline_asm_sym(sym),
+4 -1
View File
@@ -3765,7 +3765,10 @@ fn check_trait_item<F>(
);
Visibility::Public
};
this.r.feed_visibility(this.r.feed(id), vis);
// HACK: because we don't want to track the `TyCtxtFeed` through the resolver to here
// in a hash-map, we instead conjure a `TyCtxtFeed` for any `DefId` here, but prevent
// it from being used generally.
this.r.tcx.feed_visibility_for_trait_impl_item(this.r.local_def_id(id), vis);
};
let Some(decl) = decl else {
+12 -27
View File
@@ -66,8 +66,8 @@
use rustc_middle::middle::privacy::EffectiveVisibilities;
use rustc_middle::query::Providers;
use rustc_middle::ty::{
self, DelegationInfo, Feed, MainDefinition, RegisteredTools, ResolverAstLowering,
ResolverGlobalCtxt, TyCtxt, TyCtxtFeed, Visibility,
self, DelegationInfo, MainDefinition, RegisteredTools, ResolverAstLowering, ResolverGlobalCtxt,
TyCtxt, TyCtxtFeed, Visibility,
};
use rustc_session::config::CrateType;
use rustc_session::lint::builtin::PRIVATE_MACRO_USE;
@@ -1415,7 +1415,7 @@ pub struct Resolver<'ra, 'tcx> {
next_node_id: NodeId = CRATE_NODE_ID,
node_id_to_def_id: NodeMap<Feed<'tcx, LocalDefId>>,
node_id_to_def_id: NodeMap<LocalDefId>,
per_parent_disambiguators: LocalDefIdMap<PerParentDisambiguatorState>,
@@ -1582,19 +1582,11 @@ fn as_ref(&self) -> &Resolver<'ra, 'tcx> {
impl<'tcx> Resolver<'_, 'tcx> {
fn opt_local_def_id(&self, node: NodeId) -> Option<LocalDefId> {
self.opt_feed(node).map(|f| f.key())
}
fn local_def_id(&self, node: NodeId) -> LocalDefId {
self.feed(node).key()
}
fn opt_feed(&self, node: NodeId) -> Option<Feed<'tcx, LocalDefId>> {
self.node_id_to_def_id.get(&node).copied()
}
fn feed(&self, node: NodeId) -> Feed<'tcx, LocalDefId> {
self.opt_feed(node).unwrap_or_else(|| panic!("no entry for node id: `{node:?}`"))
fn local_def_id(&self, node: NodeId) -> LocalDefId {
self.opt_local_def_id(node).unwrap_or_else(|| panic!("no entry for node id: `{node:?}`"))
}
fn local_def_kind(&self, node: NodeId) -> DefKind {
@@ -1617,7 +1609,7 @@ fn create_def(
node_id,
name,
def_kind,
self.tcx.definitions_untracked().def_key(self.node_id_to_def_id[&node_id].key()),
self.tcx.definitions_untracked().def_key(self.node_id_to_def_id[&node_id]),
);
// FIXME: remove `def_span` body, pass in the right spans here and call `tcx.at().create_def()`
@@ -1645,7 +1637,7 @@ fn create_def(
// we don't need a mapping from `NodeId` to `LocalDefId`.
if node_id != ast::DUMMY_NODE_ID {
debug!("create_def: def_id_to_node_id[{:?}] <-> {:?}", def_id, node_id);
self.node_id_to_def_id.insert(node_id, feed.downgrade());
self.node_id_to_def_id.insert(node_id, def_id);
}
feed
@@ -1696,7 +1688,7 @@ pub fn tcx(&self) -> TyCtxt<'tcx> {
fn def_id_to_node_id(&self, def_id: LocalDefId) -> NodeId {
self.node_id_to_def_id
.items()
.filter(|(_, v)| v.key() == def_id)
.filter(|(_, v)| **v == def_id)
.map(|(k, _)| *k)
.get_only()
.unwrap()
@@ -1737,8 +1729,7 @@ pub fn new(
let crate_feed = tcx.create_local_crate_def_id(crate_span);
crate_feed.def_kind(DefKind::Mod);
let crate_feed = crate_feed.downgrade();
node_id_to_def_id.insert(CRATE_NODE_ID, crate_feed);
node_id_to_def_id.insert(CRATE_NODE_ID, CRATE_DEF_ID);
let mut invocation_parents = FxHashMap::default();
invocation_parents.insert(LocalExpnId::ROOT, InvocationParent::ROOT);
@@ -1891,8 +1882,7 @@ pub fn arenas() -> ResolverArenas<'ra> {
Default::default()
}
fn feed_visibility(&mut self, feed: Feed<'tcx, LocalDefId>, vis: Visibility) {
let feed = feed.upgrade(self.tcx);
fn feed_visibility(&mut self, feed: TyCtxtFeed<'tcx, LocalDefId>, vis: Visibility) {
feed.visibility(vis.to_def_id());
self.visibilities_for_hashing.push((feed.def_id(), vis));
}
@@ -1911,8 +1901,7 @@ pub fn into_outputs(self) -> ResolverOutputs<'tcx> {
.stripped_cfg_items
.into_iter()
.filter_map(|item| {
let parent_scope =
self.node_id_to_def_id.get(&item.parent_scope)?.key().to_def_id();
let parent_scope = self.node_id_to_def_id.get(&item.parent_scope)?.to_def_id();
Some(StrippedCfgItem { parent_scope, ident: item.ident, cfg: item.cfg })
})
.collect();
@@ -1942,11 +1931,7 @@ pub fn into_outputs(self) -> ResolverOutputs<'tcx> {
lifetimes_res_map: self.lifetimes_res_map,
extra_lifetime_params_map: self.extra_lifetime_params_map,
next_node_id: self.next_node_id,
node_id_to_def_id: self
.node_id_to_def_id
.into_items()
.map(|(k, f)| (k, f.key()))
.collect(),
node_id_to_def_id: self.node_id_to_def_id,
trait_map: self.trait_map,
lifetime_elision_allowed: self.lifetime_elision_allowed,
lint_buffer: Steal::new(self.lint_buffer),