Skip to content

Commit

Permalink
New attribute parsing
Browse files Browse the repository at this point in the history
  • Loading branch information
jdonszelmann committed Dec 8, 2024
1 parent befae45 commit c73feca
Show file tree
Hide file tree
Showing 102 changed files with 3,378 additions and 1,676 deletions.
6 changes: 6 additions & 0 deletions Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3263,13 +3263,15 @@ version = "0.0.0"
dependencies = [
"rustc_ast",
"rustc_ast_pretty",
"rustc_attr_parsing",
"rustc_data_structures",
"rustc_errors",
"rustc_fluent_macro",
"rustc_hir",
"rustc_index",
"rustc_macros",
"rustc_middle",
"rustc_parse",
"rustc_session",
"rustc_span",
"rustc_target",
Expand Down Expand Up @@ -3320,6 +3322,7 @@ dependencies = [
"rustc_macros",
"rustc_serialize",
"rustc_span",
"thin-vec",
]

[[package]]
Expand All @@ -3340,6 +3343,7 @@ dependencies = [
"rustc_serialize",
"rustc_session",
"rustc_span",
"thin-vec",
]

[[package]]
Expand Down Expand Up @@ -4351,6 +4355,7 @@ version = "0.0.0"
dependencies = [
"bitflags 2.6.0",
"rustc_abi",
"rustc_ast",
"rustc_data_structures",
"rustc_hir",
"rustc_middle",
Expand Down Expand Up @@ -4444,6 +4449,7 @@ dependencies = [
"punycode",
"rustc-demangle",
"rustc_abi",
"rustc_ast",
"rustc_data_structures",
"rustc_errors",
"rustc_hir",
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_ast_lowering/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,15 @@ doctest = false
# tidy-alphabetical-start
rustc_ast = { path = "../rustc_ast" }
rustc_ast_pretty = { path = "../rustc_ast_pretty" }
rustc_attr_parsing = { path = "../rustc_attr_parsing" }
rustc_data_structures = { path = "../rustc_data_structures" }
rustc_errors = { path = "../rustc_errors" }
rustc_fluent_macro = { path = "../rustc_fluent_macro" }
rustc_hir = { path = "../rustc_hir" }
rustc_index = { path = "../rustc_index" }
rustc_macros = { path = "../rustc_macros" }
rustc_middle = { path = "../rustc_middle" }
rustc_parse = { path = "../rustc_parse" }
rustc_session = { path = "../rustc_session" }
rustc_span = { path = "../rustc_span" }
rustc_target = { path = "../rustc_target" }
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_ast_lowering/src/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
};
let span = self.lower_span(l.span);
let source = hir::LocalSource::Normal;
self.lower_attrs(hir_id, &l.attrs);
self.lower_attrs(hir_id, &l.attrs, l.span);
self.arena.alloc(hir::LetStmt { hir_id, ty, pat, init, els, span, source })
}

Expand Down
39 changes: 21 additions & 18 deletions compiler/rustc_ast_lowering/src/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,9 +78,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
self.attrs.insert(
ex.hir_id.local_id,
&*self.arena.alloc_from_iter(
e.attrs
.iter()
.map(|a| self.lower_attr(a))
self.lower_attrs_vec(&e.attrs, e.span)
.into_iter()
.chain(old_attrs.iter().cloned()),
),
);
Expand All @@ -99,7 +98,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
}

let expr_hir_id = self.lower_node_id(e.id);
self.lower_attrs(expr_hir_id, &e.attrs);
self.lower_attrs(expr_hir_id, &e.attrs, e.span);

let kind = match &e.kind {
ExprKind::Array(exprs) => hir::ExprKind::Array(self.lower_exprs(exprs)),
Expand Down Expand Up @@ -638,7 +637,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
let guard = arm.guard.as_ref().map(|cond| self.lower_expr(cond));
let hir_id = self.next_id();
let span = self.lower_span(arm.span);
self.lower_attrs(hir_id, &arm.attrs);
self.lower_attrs(hir_id, &arm.attrs, arm.span);
let is_never_pattern = pat.is_never_pattern();
let body = if let Some(body) = &arm.body
&& !is_never_pattern
Expand Down Expand Up @@ -796,15 +795,19 @@ impl<'hir> LoweringContext<'_, 'hir> {
span,
Some(Lrc::clone(&self.allow_gen_future)),
);
self.lower_attrs(inner_hir_id, &[Attribute {
kind: AttrKind::Normal(ptr::P(NormalAttr::from_ident(Ident::new(
sym::track_caller,
span,
)))),
id: self.tcx.sess.psess.attr_id_generator.mk_attr_id(),
style: AttrStyle::Outer,
span: unstable_span,
}]);
self.lower_attrs(
inner_hir_id,
&[Attribute {
kind: AttrKind::Normal(ptr::P(NormalAttr::from_ident(Ident::new(
sym::track_caller,
span,
)))),
id: self.tcx.sess.psess.attr_id_generator.mk_attr_id(),
style: AttrStyle::Outer,
span: unstable_span,
}],
span,
);
}
}

Expand Down Expand Up @@ -1609,7 +1612,7 @@ impl<'hir> LoweringContext<'_, 'hir> {

fn lower_expr_field(&mut self, f: &ExprField) -> hir::ExprField<'hir> {
let hir_id = self.lower_node_id(f.id);
self.lower_attrs(hir_id, &f.attrs);
self.lower_attrs(hir_id, &f.attrs, f.span);
hir::ExprField {
hir_id,
ident: self.lower_ident(f.ident),
Expand Down Expand Up @@ -1872,7 +1875,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
//
// Also, add the attributes to the outer returned expr node.
let expr = self.expr_drop_temps_mut(for_span, match_expr);
self.lower_attrs(expr.hir_id, &e.attrs);
self.lower_attrs(expr.hir_id, &e.attrs, e.span);
expr
}

Expand Down Expand Up @@ -1929,7 +1932,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
let val_ident = Ident::with_dummy_span(sym::val);
let (val_pat, val_pat_nid) = self.pat_ident(span, val_ident);
let val_expr = self.expr_ident(span, val_ident, val_pat_nid);
self.lower_attrs(val_expr.hir_id, &attrs);
self.lower_attrs(val_expr.hir_id, &attrs, span);
let continue_pat = self.pat_cf_continue(unstable_span, val_pat);
self.arm(continue_pat, val_expr)
};
Expand Down Expand Up @@ -1959,7 +1962,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
} else {
self.arena.alloc(self.expr(try_span, hir::ExprKind::Ret(Some(from_residual_expr))))
};
self.lower_attrs(ret_expr.hir_id, &attrs);
self.lower_attrs(ret_expr.hir_id, &attrs, ret_expr.span);

let break_pat = self.pat_cf_break(try_span, residual_local);
self.arm(break_pat, ret_expr)
Expand Down
19 changes: 10 additions & 9 deletions compiler/rustc_ast_lowering/src/item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use rustc_middle::span_bug;
use rustc_middle::ty::{ResolverAstLowering, TyCtxt};
use rustc_span::edit_distance::find_best_match_for_name;
use rustc_span::symbol::{Ident, kw, sym};
use rustc_span::{DesugaringKind, Span, Symbol};
use rustc_span::{DUMMY_SP, DesugaringKind, Span, Symbol};
use rustc_target::spec::abi;
use smallvec::{SmallVec, smallvec};
use thin_vec::ThinVec;
Expand Down Expand Up @@ -91,7 +91,8 @@ impl<'a, 'hir> ItemLowerer<'a, 'hir> {
debug_assert_eq!(self.resolver.node_id_to_def_id[&CRATE_NODE_ID], CRATE_DEF_ID);
self.with_lctx(CRATE_NODE_ID, |lctx| {
let module = lctx.lower_mod(&c.items, &c.spans);
lctx.lower_attrs(hir::CRATE_HIR_ID, &c.attrs);
// FIXME(jdonszelman): is dummy span ever a problem here?
lctx.lower_attrs(hir::CRATE_HIR_ID, &c.attrs, DUMMY_SP);
hir::OwnerNode::Crate(module)
})
}
Expand Down Expand Up @@ -155,7 +156,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
let mut ident = i.ident;
let vis_span = self.lower_span(i.vis.span);
let hir_id = hir::HirId::make_owner(self.current_hir_id_owner.def_id);
let attrs = self.lower_attrs(hir_id, &i.attrs);
let attrs = self.lower_attrs(hir_id, &i.attrs, i.span);
let kind = self.lower_item_kind(i.span, i.id, hir_id, &mut ident, attrs, vis_span, &i.kind);
let item = hir::Item {
owner_id: hir_id.expect_owner(),
Expand Down Expand Up @@ -606,7 +607,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
fn lower_foreign_item(&mut self, i: &ForeignItem) -> &'hir hir::ForeignItem<'hir> {
let hir_id = hir::HirId::make_owner(self.current_hir_id_owner.def_id);
let owner_id = hir_id.expect_owner();
self.lower_attrs(hir_id, &i.attrs);
self.lower_attrs(hir_id, &i.attrs, i.span);
let item = hir::ForeignItem {
owner_id,
ident: self.lower_ident(i.ident),
Expand Down Expand Up @@ -664,7 +665,7 @@ impl<'hir> LoweringContext<'_, 'hir> {

fn lower_variant(&mut self, v: &Variant) -> hir::Variant<'hir> {
let hir_id = self.lower_node_id(v.id);
self.lower_attrs(hir_id, &v.attrs);
self.lower_attrs(hir_id, &v.attrs, v.span);
hir::Variant {
hir_id,
def_id: self.local_def_id(v.id),
Expand Down Expand Up @@ -712,7 +713,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
) -> hir::FieldDef<'hir> {
let ty = self.lower_ty(&f.ty, ImplTraitContext::Disallowed(ImplTraitPosition::FieldTy));
let hir_id = self.lower_node_id(f.id);
self.lower_attrs(hir_id, &f.attrs);
self.lower_attrs(hir_id, &f.attrs, f.span);
hir::FieldDef {
span: self.lower_span(f.span),
hir_id,
Expand All @@ -730,7 +731,7 @@ impl<'hir> LoweringContext<'_, 'hir> {

fn lower_trait_item(&mut self, i: &AssocItem) -> &'hir hir::TraitItem<'hir> {
let hir_id = hir::HirId::make_owner(self.current_hir_id_owner.def_id);
self.lower_attrs(hir_id, &i.attrs);
self.lower_attrs(hir_id, &i.attrs, i.span);
let trait_item_def_id = hir_id.expect_owner();

let (generics, kind, has_default) = match &i.kind {
Expand Down Expand Up @@ -860,7 +861,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
let has_value = true;
let (defaultness, _) = self.lower_defaultness(i.kind.defaultness(), has_value);
let hir_id = hir::HirId::make_owner(self.current_hir_id_owner.def_id);
self.lower_attrs(hir_id, &i.attrs);
self.lower_attrs(hir_id, &i.attrs, i.span);

let (generics, kind) = match &i.kind {
AssocItemKind::Const(box ConstItem { generics, ty, expr, .. }) => self.lower_generics(
Expand Down Expand Up @@ -1015,7 +1016,7 @@ impl<'hir> LoweringContext<'_, 'hir> {

fn lower_param(&mut self, param: &Param) -> hir::Param<'hir> {
let hir_id = self.lower_node_id(param.id);
self.lower_attrs(hir_id, &param.attrs);
self.lower_attrs(hir_id, &param.attrs, param.span);
hir::Param {
hir_id,
pat: self.lower_pat(&param.pat),
Expand Down
81 changes: 22 additions & 59 deletions compiler/rustc_ast_lowering/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@

use rustc_ast::node_id::NodeMap;
use rustc_ast::{self as ast, *};
use rustc_attr_parsing::{AttributeParseContext, OmitDoc};
use rustc_data_structures::captures::Captures;
use rustc_data_structures::fingerprint::Fingerprint;
use rustc_data_structures::sorted_map::SortedMap;
Expand Down Expand Up @@ -133,10 +134,13 @@ struct LoweringContext<'a, 'hir> {
allow_async_iterator: Lrc<[Symbol]>,
allow_for_await: Lrc<[Symbol]>,
allow_async_fn_traits: Lrc<[Symbol]>,

attribute_parse_context: AttributeParseContext<'hir>,
}

impl<'a, 'hir> LoweringContext<'a, 'hir> {
fn new(tcx: TyCtxt<'hir>, resolver: &'a mut ResolverAstLowering) -> Self {
let registered_tools = tcx.registered_tools(()).iter().map(|x| x.name).collect();
Self {
// Pseudo-globals.
tcx,
Expand Down Expand Up @@ -176,6 +180,12 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
// FIXME(gen_blocks): how does `closure_track_caller`/`async_fn_track_caller`
// interact with `gen`/`async gen` blocks
allow_async_iterator: [sym::gen_future, sym::async_iterator].into(),

attribute_parse_context: AttributeParseContext::new(
tcx.sess,
tcx.features(),
registered_tools,
),
}
}

Expand Down Expand Up @@ -211,7 +221,6 @@ impl ResolverAstLowering {
None
}

/// Obtains resolution for a `NodeId` with a single resolution.
fn get_partial_res(&self, id: NodeId) -> Option<PartialRes> {
self.partial_res_map.get(&id).copied()
}
Expand Down Expand Up @@ -839,45 +848,27 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
ret
}

fn lower_attrs(&mut self, id: HirId, attrs: &[Attribute]) -> &'hir [hir::Attribute] {
fn lower_attrs(
&mut self,
id: HirId,
attrs: &[Attribute],
target_span: Span,
) -> &'hir [hir::Attribute] {
if attrs.is_empty() {
&[]
} else {
let lowered_attrs = self.lower_attrs_vec(attrs, target_span);

debug_assert_eq!(id.owner, self.current_hir_id_owner);
let ret = self.arena.alloc_from_iter(attrs.iter().map(|a| self.lower_attr(a)));
let ret = self.arena.alloc_from_iter(lowered_attrs);
debug_assert!(!ret.is_empty());
self.attrs.insert(id.local_id, ret);
ret
}
}

fn lower_attr(&self, attr: &Attribute) -> hir::Attribute {
// Note that we explicitly do not walk the path. Since we don't really
// lower attributes (we use the AST version) there is nowhere to keep
// the `HirId`s. We don't actually need HIR version of attributes anyway.
// Tokens are also not needed after macro expansion and parsing.
let kind = match attr.kind {
AttrKind::Normal(ref normal) => hir::AttrKind::Normal(Box::new(hir::AttrItem {
unsafety: self.lower_safety(normal.item.unsafety, hir::Safety::Safe),
path: hir::AttrPath {
segments: normal
.item
.path
.segments
.iter()
.map(|i| i.ident)
.collect::<Vec<_>>()
.into_boxed_slice(),
span: normal.item.path.span,
},
args: self.lower_attr_args(&normal.item.args),
})),
AttrKind::DocComment(comment_kind, data) => {
hir::AttrKind::DocComment(comment_kind, data)
}
};

hir::Attribute { kind, id: attr.id, style: attr.style, span: self.lower_span(attr.span) }
fn lower_attrs_vec(&self, attrs: &[Attribute], target_span: Span) -> Vec<hir::Attribute> {
self.attribute_parse_context.parse_attribute_list(attrs, target_span, OmitDoc::Lower)
}

fn alias_attrs(&mut self, id: HirId, target_id: HirId) {
Expand All @@ -889,34 +880,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
}
}

fn lower_attr_args(&self, args: &AttrArgs) -> hir::AttrArgs {
match args {
AttrArgs::Empty => hir::AttrArgs::Empty,
AttrArgs::Delimited(args) => hir::AttrArgs::Delimited(self.lower_delim_args(args)),
// This is an inert key-value attribute - it will never be visible to macros
// after it gets lowered to HIR. Therefore, we can extract literals to handle
// nonterminals in `#[doc]` (e.g. `#[doc = $e]`).
&AttrArgs::Eq { eq_span, ref expr } => {
// In valid code the value always ends up as a single literal. Otherwise, a dummy
// literal suffices because the error is handled elsewhere.
let lit = if let ExprKind::Lit(token_lit) = expr.kind
&& let Ok(lit) = MetaItemLit::from_token_lit(token_lit, expr.span)
{
lit
} else {
let guar = self.dcx().has_errors().unwrap();
MetaItemLit {
symbol: kw::Empty,
suffix: None,
kind: LitKind::Err(guar),
span: DUMMY_SP,
}
};
hir::AttrArgs::Eq { eq_span, expr: lit }
}
}
}

fn lower_delim_args(&self, args: &DelimArgs) -> DelimArgs {
DelimArgs { dspan: args.dspan, delim: args.delim, tokens: args.tokens.flattened() }
}
Expand Down Expand Up @@ -1807,7 +1770,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
let (name, kind) = self.lower_generic_param_kind(param, source);

let hir_id = self.lower_node_id(param.id);
self.lower_attrs(hir_id, &param.attrs);
self.lower_attrs(hir_id, &param.attrs, param.span());
hir::GenericParam {
hir_id,
def_id: self.local_def_id(param.id),
Expand Down
Loading

0 comments on commit c73feca

Please sign in to comment.