Skip to content

Commit

Permalink
Rollup merge of rust-lang#79185 - petrochenkov:derattr2, r=Aaron1011
Browse files Browse the repository at this point in the history
expand/resolve: Pre-requisites to "Turn `#[derive]` into a regular macro attribute"

Miscellaneous refactorings and error reporting changes extracted from rust-lang#79078.

Unlike rust-lang#79078 this PR doesn't make any observable changes to the language or library.
r? ```@Aaron1011```
  • Loading branch information
Dylan-DPC authored Nov 19, 2020
2 parents d5ee4ed + d575aa4 commit 8216b35
Show file tree
Hide file tree
Showing 33 changed files with 481 additions and 654 deletions.
11 changes: 7 additions & 4 deletions compiler/rustc_builtin_macros/src/cfg_accessible.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//! Implementation of the `#[cfg_accessible(path)]` attribute macro.

use rustc_ast as ast;
use rustc_expand::base::{Annotatable, ExpandResult, ExtCtxt, MultiItemModifier};
use rustc_expand::base::{Annotatable, ExpandResult, ExtCtxt, Indeterminate, MultiItemModifier};
use rustc_feature::AttributeTemplate;
use rustc_parse::validate_attr;
use rustc_span::symbol::sym;
Expand Down Expand Up @@ -31,7 +31,7 @@ impl MultiItemModifier for Expander {
fn expand(
&self,
ecx: &mut ExtCtxt<'_>,
_span: Span,
span: Span,
meta_item: &ast::MetaItem,
item: Annotatable,
) -> ExpandResult<Vec<Annotatable>, Annotatable> {
Expand All @@ -49,11 +49,14 @@ impl MultiItemModifier for Expander {
None => return ExpandResult::Ready(Vec::new()),
};

let failure_msg = "cannot determine whether the path is accessible or not";
match ecx.resolver.cfg_accessible(ecx.current_expansion.id, path) {
Ok(true) => ExpandResult::Ready(vec![item]),
Ok(false) => ExpandResult::Ready(Vec::new()),
Err(_) => ExpandResult::Retry(item, failure_msg.into()),
Err(Indeterminate) if ecx.force_mode => {
ecx.span_err(span, "cannot determine whether the path is accessible or not");
ExpandResult::Ready(vec![item])
}
Err(Indeterminate) => ExpandResult::Retry(item),
}
}
}
15 changes: 2 additions & 13 deletions compiler/rustc_builtin_macros/src/deriving/generic/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -407,13 +407,7 @@ impl<'a> TraitDef<'a> {
_ => false,
})
}
_ => {
// Non-ADT derive is an error, but it should have been
// set earlier; see
// librustc_expand/expand.rs:MacroExpander::fully_expand_fragment()
// librustc_expand/base.rs:Annotatable::derive_allowed()
return;
}
_ => unreachable!(),
};
let container_id = cx.current_expansion.id.expn_data().parent;
let always_copy = has_no_type_params && cx.resolver.has_derive_copy(container_id);
Expand Down Expand Up @@ -475,12 +469,7 @@ impl<'a> TraitDef<'a> {
);
push(Annotatable::Item(P(ast::Item { attrs, ..(*newitem).clone() })))
}
_ => {
// Non-Item derive is an error, but it should have been
// set earlier; see
// librustc_expand/expand.rs:MacroExpander::fully_expand_fragment()
// librustc_expand/base.rs:Annotatable::derive_allowed()
}
_ => unreachable!(),
}
}

Expand Down
8 changes: 1 addition & 7 deletions compiler/rustc_builtin_macros/src/deriving/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,13 +98,7 @@ fn inject_impl_of_structural_trait(
) {
let item = match *item {
Annotatable::Item(ref item) => item,
_ => {
// Non-Item derive is an error, but it should have been
// set earlier; see
// librustc_expand/expand.rs:MacroExpander::fully_expand_fragment()
// librustc_expand/base.rs:Annotatable::derive_allowed()
return;
}
_ => unreachable!(),
};

let generics = match item.kind {
Expand Down
11 changes: 8 additions & 3 deletions compiler/rustc_expand/src/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -251,8 +251,7 @@ pub enum ExpandResult<T, U> {
/// Expansion produced a result (possibly dummy).
Ready(T),
/// Expansion could not produce a result and needs to be retried.
/// The string is an explanation that will be printed if we are stuck in an infinite retry loop.
Retry(U, String),
Retry(U),
}

// `meta_item` is the attribute, and `item` is the item being modified.
Expand Down Expand Up @@ -889,8 +888,10 @@ pub trait ResolverExpand {
/// Some parent node that is close enough to the given macro call.
fn lint_node_id(&mut self, expn_id: ExpnId) -> NodeId;

// Resolver interfaces for specific built-in macros.
/// Does `#[derive(...)]` attribute with the given `ExpnId` have built-in `Copy` inside it?
fn has_derive_copy(&self, expn_id: ExpnId) -> bool;
fn add_derive_copy(&mut self, expn_id: ExpnId);
/// Path resolution logic for `#[cfg_accessible(path)]`.
fn cfg_accessible(&mut self, expn_id: ExpnId, path: &ast::Path) -> Result<bool, Indeterminate>;
}

Expand Down Expand Up @@ -919,6 +920,9 @@ pub struct ExtCtxt<'a> {
pub root_path: PathBuf,
pub resolver: &'a mut dyn ResolverExpand,
pub current_expansion: ExpansionData,
/// Error recovery mode entered when expansion is stuck
/// (or during eager expansion, but that's a hack).
pub force_mode: bool,
pub expansions: FxHashMap<Span, Vec<String>>,
/// Called directly after having parsed an external `mod foo;` in expansion.
pub(super) extern_mod_loaded: Option<&'a dyn Fn(&ast::Crate)>,
Expand All @@ -945,6 +949,7 @@ impl<'a> ExtCtxt<'a> {
directory_ownership: DirectoryOwnership::Owned { relative: None },
prior_type_ascription: None,
},
force_mode: false,
expansions: FxHashMap::default(),
}
}
Expand Down
45 changes: 45 additions & 0 deletions compiler/rustc_expand/src/config.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
//! Conditional compilation stripping.

use crate::base::Annotatable;

use rustc_ast::attr::HasAttrs;
use rustc_ast::mut_visit::*;
use rustc_ast::ptr::P;
Expand Down Expand Up @@ -496,6 +498,49 @@ impl<'a> StripUnconfigured<'a> {
pub fn configure_fn_decl(&mut self, fn_decl: &mut ast::FnDecl) {
fn_decl.inputs.flat_map_in_place(|arg| self.configure(arg));
}

pub fn fully_configure(&mut self, item: Annotatable) -> Annotatable {
// Since the item itself has already been configured by the InvocationCollector,
// we know that fold result vector will contain exactly one element
match item {
Annotatable::Item(item) => Annotatable::Item(self.flat_map_item(item).pop().unwrap()),
Annotatable::TraitItem(item) => {
Annotatable::TraitItem(self.flat_map_trait_item(item).pop().unwrap())
}
Annotatable::ImplItem(item) => {
Annotatable::ImplItem(self.flat_map_impl_item(item).pop().unwrap())
}
Annotatable::ForeignItem(item) => {
Annotatable::ForeignItem(self.flat_map_foreign_item(item).pop().unwrap())
}
Annotatable::Stmt(stmt) => {
Annotatable::Stmt(stmt.map(|stmt| self.flat_map_stmt(stmt).pop().unwrap()))
}
Annotatable::Expr(mut expr) => Annotatable::Expr({
self.visit_expr(&mut expr);
expr
}),
Annotatable::Arm(arm) => Annotatable::Arm(self.flat_map_arm(arm).pop().unwrap()),
Annotatable::Field(field) => {
Annotatable::Field(self.flat_map_field(field).pop().unwrap())
}
Annotatable::FieldPat(fp) => {
Annotatable::FieldPat(self.flat_map_field_pattern(fp).pop().unwrap())
}
Annotatable::GenericParam(param) => {
Annotatable::GenericParam(self.flat_map_generic_param(param).pop().unwrap())
}
Annotatable::Param(param) => {
Annotatable::Param(self.flat_map_param(param).pop().unwrap())
}
Annotatable::StructField(sf) => {
Annotatable::StructField(self.flat_map_struct_field(sf).pop().unwrap())
}
Annotatable::Variant(v) => {
Annotatable::Variant(self.flat_map_variant(v).pop().unwrap())
}
}
}
}

impl<'a> MutVisitor for StripUnconfigured<'a> {
Expand Down
Loading

0 comments on commit 8216b35

Please sign in to comment.