Skip to content

Commit 8216b35

Browse files
authored
Rollup merge of #79185 - petrochenkov:derattr2, r=Aaron1011
expand/resolve: Pre-requisites to "Turn `#[derive]` into a regular macro attribute" Miscellaneous refactorings and error reporting changes extracted from #79078. Unlike #79078 this PR doesn't make any observable changes to the language or library. r? ```@Aaron1011```
2 parents d5ee4ed + d575aa4 commit 8216b35

33 files changed

+481
-654
lines changed

compiler/rustc_builtin_macros/src/cfg_accessible.rs

+7-4
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//! Implementation of the `#[cfg_accessible(path)]` attribute macro.
22
33
use rustc_ast as ast;
4-
use rustc_expand::base::{Annotatable, ExpandResult, ExtCtxt, MultiItemModifier};
4+
use rustc_expand::base::{Annotatable, ExpandResult, ExtCtxt, Indeterminate, MultiItemModifier};
55
use rustc_feature::AttributeTemplate;
66
use rustc_parse::validate_attr;
77
use rustc_span::symbol::sym;
@@ -31,7 +31,7 @@ impl MultiItemModifier for Expander {
3131
fn expand(
3232
&self,
3333
ecx: &mut ExtCtxt<'_>,
34-
_span: Span,
34+
span: Span,
3535
meta_item: &ast::MetaItem,
3636
item: Annotatable,
3737
) -> ExpandResult<Vec<Annotatable>, Annotatable> {
@@ -49,11 +49,14 @@ impl MultiItemModifier for Expander {
4949
None => return ExpandResult::Ready(Vec::new()),
5050
};
5151

52-
let failure_msg = "cannot determine whether the path is accessible or not";
5352
match ecx.resolver.cfg_accessible(ecx.current_expansion.id, path) {
5453
Ok(true) => ExpandResult::Ready(vec![item]),
5554
Ok(false) => ExpandResult::Ready(Vec::new()),
56-
Err(_) => ExpandResult::Retry(item, failure_msg.into()),
55+
Err(Indeterminate) if ecx.force_mode => {
56+
ecx.span_err(span, "cannot determine whether the path is accessible or not");
57+
ExpandResult::Ready(vec![item])
58+
}
59+
Err(Indeterminate) => ExpandResult::Retry(item),
5760
}
5861
}
5962
}

compiler/rustc_builtin_macros/src/deriving/generic/mod.rs

+2-13
Original file line numberDiff line numberDiff line change
@@ -407,13 +407,7 @@ impl<'a> TraitDef<'a> {
407407
_ => false,
408408
})
409409
}
410-
_ => {
411-
// Non-ADT derive is an error, but it should have been
412-
// set earlier; see
413-
// librustc_expand/expand.rs:MacroExpander::fully_expand_fragment()
414-
// librustc_expand/base.rs:Annotatable::derive_allowed()
415-
return;
416-
}
410+
_ => unreachable!(),
417411
};
418412
let container_id = cx.current_expansion.id.expn_data().parent;
419413
let always_copy = has_no_type_params && cx.resolver.has_derive_copy(container_id);
@@ -475,12 +469,7 @@ impl<'a> TraitDef<'a> {
475469
);
476470
push(Annotatable::Item(P(ast::Item { attrs, ..(*newitem).clone() })))
477471
}
478-
_ => {
479-
// Non-Item derive is an error, but it should have been
480-
// set earlier; see
481-
// librustc_expand/expand.rs:MacroExpander::fully_expand_fragment()
482-
// librustc_expand/base.rs:Annotatable::derive_allowed()
483-
}
472+
_ => unreachable!(),
484473
}
485474
}
486475

compiler/rustc_builtin_macros/src/deriving/mod.rs

+1-7
Original file line numberDiff line numberDiff line change
@@ -98,13 +98,7 @@ fn inject_impl_of_structural_trait(
9898
) {
9999
let item = match *item {
100100
Annotatable::Item(ref item) => item,
101-
_ => {
102-
// Non-Item derive is an error, but it should have been
103-
// set earlier; see
104-
// librustc_expand/expand.rs:MacroExpander::fully_expand_fragment()
105-
// librustc_expand/base.rs:Annotatable::derive_allowed()
106-
return;
107-
}
101+
_ => unreachable!(),
108102
};
109103

110104
let generics = match item.kind {

compiler/rustc_expand/src/base.rs

+8-3
Original file line numberDiff line numberDiff line change
@@ -251,8 +251,7 @@ pub enum ExpandResult<T, U> {
251251
/// Expansion produced a result (possibly dummy).
252252
Ready(T),
253253
/// Expansion could not produce a result and needs to be retried.
254-
/// The string is an explanation that will be printed if we are stuck in an infinite retry loop.
255-
Retry(U, String),
254+
Retry(U),
256255
}
257256

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

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

@@ -919,6 +920,9 @@ pub struct ExtCtxt<'a> {
919920
pub root_path: PathBuf,
920921
pub resolver: &'a mut dyn ResolverExpand,
921922
pub current_expansion: ExpansionData,
923+
/// Error recovery mode entered when expansion is stuck
924+
/// (or during eager expansion, but that's a hack).
925+
pub force_mode: bool,
922926
pub expansions: FxHashMap<Span, Vec<String>>,
923927
/// Called directly after having parsed an external `mod foo;` in expansion.
924928
pub(super) extern_mod_loaded: Option<&'a dyn Fn(&ast::Crate)>,
@@ -945,6 +949,7 @@ impl<'a> ExtCtxt<'a> {
945949
directory_ownership: DirectoryOwnership::Owned { relative: None },
946950
prior_type_ascription: None,
947951
},
952+
force_mode: false,
948953
expansions: FxHashMap::default(),
949954
}
950955
}

compiler/rustc_expand/src/config.rs

+45
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
//! Conditional compilation stripping.
22
3+
use crate::base::Annotatable;
4+
35
use rustc_ast::attr::HasAttrs;
46
use rustc_ast::mut_visit::*;
57
use rustc_ast::ptr::P;
@@ -496,6 +498,49 @@ impl<'a> StripUnconfigured<'a> {
496498
pub fn configure_fn_decl(&mut self, fn_decl: &mut ast::FnDecl) {
497499
fn_decl.inputs.flat_map_in_place(|arg| self.configure(arg));
498500
}
501+
502+
pub fn fully_configure(&mut self, item: Annotatable) -> Annotatable {
503+
// Since the item itself has already been configured by the InvocationCollector,
504+
// we know that fold result vector will contain exactly one element
505+
match item {
506+
Annotatable::Item(item) => Annotatable::Item(self.flat_map_item(item).pop().unwrap()),
507+
Annotatable::TraitItem(item) => {
508+
Annotatable::TraitItem(self.flat_map_trait_item(item).pop().unwrap())
509+
}
510+
Annotatable::ImplItem(item) => {
511+
Annotatable::ImplItem(self.flat_map_impl_item(item).pop().unwrap())
512+
}
513+
Annotatable::ForeignItem(item) => {
514+
Annotatable::ForeignItem(self.flat_map_foreign_item(item).pop().unwrap())
515+
}
516+
Annotatable::Stmt(stmt) => {
517+
Annotatable::Stmt(stmt.map(|stmt| self.flat_map_stmt(stmt).pop().unwrap()))
518+
}
519+
Annotatable::Expr(mut expr) => Annotatable::Expr({
520+
self.visit_expr(&mut expr);
521+
expr
522+
}),
523+
Annotatable::Arm(arm) => Annotatable::Arm(self.flat_map_arm(arm).pop().unwrap()),
524+
Annotatable::Field(field) => {
525+
Annotatable::Field(self.flat_map_field(field).pop().unwrap())
526+
}
527+
Annotatable::FieldPat(fp) => {
528+
Annotatable::FieldPat(self.flat_map_field_pattern(fp).pop().unwrap())
529+
}
530+
Annotatable::GenericParam(param) => {
531+
Annotatable::GenericParam(self.flat_map_generic_param(param).pop().unwrap())
532+
}
533+
Annotatable::Param(param) => {
534+
Annotatable::Param(self.flat_map_param(param).pop().unwrap())
535+
}
536+
Annotatable::StructField(sf) => {
537+
Annotatable::StructField(self.flat_map_struct_field(sf).pop().unwrap())
538+
}
539+
Annotatable::Variant(v) => {
540+
Annotatable::Variant(self.flat_map_variant(v).pop().unwrap())
541+
}
542+
}
543+
}
499544
}
500545

501546
impl<'a> MutVisitor for StripUnconfigured<'a> {

0 commit comments

Comments
 (0)