diff options
Diffstat (limited to 'compiler/rustc_ast_lowering/src/lib.rs')
| -rw-r--r-- | compiler/rustc_ast_lowering/src/lib.rs | 140 |
1 files changed, 49 insertions, 91 deletions
diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 127b7e3684e..1c69937eed0 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -45,7 +45,7 @@ use std::sync::Arc; use rustc_ast::node_id::NodeMap; use rustc_ast::{self as ast, *}; -use rustc_data_structures::captures::Captures; +use rustc_attr_parsing::{AttributeParser, OmitDoc}; use rustc_data_structures::fingerprint::Fingerprint; use rustc_data_structures::sorted_map::SortedMap; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; @@ -61,7 +61,8 @@ use rustc_macros::extension; use rustc_middle::span_bug; use rustc_middle::ty::{ResolverAstLowering, TyCtxt}; use rustc_session::parse::{add_feature_diagnostics, feature_err}; -use rustc_span::{DUMMY_SP, DesugaringKind, Ident, Span, Symbol, kw, sym}; +use rustc_span::symbol::{Ident, Symbol, kw, sym}; +use rustc_span::{DUMMY_SP, DesugaringKind, Span}; use smallvec::{SmallVec, smallvec}; use thin_vec::ThinVec; use tracing::{debug, instrument, trace}; @@ -84,22 +85,10 @@ mod index; mod item; mod pat; mod path; +pub mod stability; rustc_fluent_macro::fluent_messages! { "../messages.ftl" } -#[derive(Debug, Clone)] -struct FnContractLoweringInfo<'hir> { - pub span: Span, - pub requires: Option<ast::ptr::P<ast::Expr>>, - pub ensures: Option<FnContractLoweringEnsures<'hir>>, -} - -#[derive(Debug, Clone)] -struct FnContractLoweringEnsures<'hir> { - expr: ast::ptr::P<ast::Expr>, - fresh_ident: (Ident, hir::Pat<'hir>, HirId), -} - struct LoweringContext<'a, 'hir> { tcx: TyCtxt<'hir>, resolver: &'a mut ResolverAstLowering, @@ -114,7 +103,7 @@ struct LoweringContext<'a, 'hir> { /// Collect items that were created by lowering the current owner. children: Vec<(LocalDefId, hir::MaybeOwner<'hir>)>, - contract: Option<FnContractLoweringInfo<'hir>>, + contract_ensures: Option<(Span, Ident, HirId)>, coroutine_kind: Option<hir::CoroutineKind>, @@ -150,10 +139,13 @@ struct LoweringContext<'a, 'hir> { allow_async_iterator: Arc<[Symbol]>, allow_for_await: Arc<[Symbol]>, allow_async_fn_traits: Arc<[Symbol]>, + + attribute_parser: AttributeParser<'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, @@ -164,7 +156,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { bodies: Vec::new(), attrs: SortedMap::default(), children: Vec::default(), - contract: None, + contract_ensures: None, current_hir_id_owner: hir::CRATE_OWNER_ID, item_local_id_counter: hir::ItemLocalId::ZERO, ident_and_label_to_local_id: Default::default(), @@ -194,6 +186,8 @@ 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_parser: AttributeParser::new(tcx.sess, tcx.features(), registered_tools), } } @@ -229,7 +223,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() } @@ -419,7 +412,7 @@ fn compute_hir_hash( .iter_enumerated() .filter_map(|(def_id, info)| { let info = info.as_owner()?; - let def_path_hash = tcx.hir().def_path_hash(def_id); + let def_path_hash = tcx.hir_def_path_hash(def_id); Some((def_path_hash, info)) }) .collect(); @@ -509,7 +502,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { "adding a def'n for node-id {:?} and def kind {:?} but a previous def'n exists: {:?}", node_id, def_kind, - self.tcx.hir().def_key(self.local_def_id(node_id)), + self.tcx.hir_def_key(self.local_def_id(node_id)), ); let def_id = self.tcx.at(span).create_def(parent, name, def_kind).def_id(); @@ -851,7 +844,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { let was_in_loop_condition = self.is_in_loop_condition; self.is_in_loop_condition = false; - let old_contract = self.contract.take(); + let old_contract = self.contract_ensures.take(); let catch_scope = self.catch_scope.take(); let loop_scope = self.loop_scope.take(); @@ -859,7 +852,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { self.catch_scope = catch_scope; self.loop_scope = loop_scope; - self.contract = old_contract; + self.contract_ensures = old_contract; self.is_in_loop_condition = was_in_loop_condition; @@ -868,45 +861,38 @@ 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, self.lower_span(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))); - debug_assert!(!ret.is_empty()); - self.attrs.insert(id.local_id, ret); - ret + let ret = self.arena.alloc_from_iter(lowered_attrs); + + // this is possible if an item contained syntactical attribute, + // but none of them parse succesfully or all of them were ignored + // for not being built-in attributes at all. They could be remaining + // unexpanded attributes used as markers in proc-macro derives for example. + // This will have emitted some diagnostics for the misparse, but will then + // not emit the attribute making the list empty. + if ret.is_empty() { + &[] + } else { + 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_parser + .parse_attribute_list(attrs, target_span, OmitDoc::Lower, |s| self.lower_span(s)) } fn alias_attrs(&mut self, id: HirId, target_id: HirId) { @@ -918,34 +904,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() } } @@ -1833,11 +1791,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { self.new_named_lifetime_with_res(new_id, ident, res) } - fn lower_generic_params_mut<'s>( - &'s mut self, - params: &'s [GenericParam], + fn lower_generic_params_mut( + &mut self, + params: &[GenericParam], source: hir::GenericParamSource, - ) -> impl Iterator<Item = hir::GenericParam<'hir>> + Captures<'a> + Captures<'s> { + ) -> impl Iterator<Item = hir::GenericParam<'hir>> { params.iter().map(move |param| self.lower_generic_param(param, source)) } @@ -1858,7 +1816,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, ¶m.attrs); + self.lower_attrs(hir_id, ¶m.attrs, param.span()); hir::GenericParam { hir_id, def_id: self.local_def_id(param.id), @@ -1998,11 +1956,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { self.arena.alloc_from_iter(self.lower_param_bounds_mut(bounds, itctx)) } - fn lower_param_bounds_mut<'s>( - &'s mut self, - bounds: &'s [GenericBound], + fn lower_param_bounds_mut( + &mut self, + bounds: &[GenericBound], itctx: ImplTraitContext, - ) -> impl Iterator<Item = hir::GenericBound<'hir>> + Captures<'s> + Captures<'a> { + ) -> impl Iterator<Item = hir::GenericBound<'hir>> { bounds.iter().map(move |bound| self.lower_param_bound(bound, itctx)) } |
