Add the #[derive_const]
attribute
This commit is contained in:
parent
4af79ccd5e
commit
a052f2cce1
30 changed files with 163 additions and 30 deletions
|
@ -34,6 +34,7 @@ impl MultiItemModifier for Expander {
|
|||
span: Span,
|
||||
meta_item: &ast::MetaItem,
|
||||
item: Annotatable,
|
||||
_is_derive_const: bool,
|
||||
) -> ExpandResult<Vec<Annotatable>, Annotatable> {
|
||||
let template = AttributeTemplate { list: Some("path"), ..Default::default() };
|
||||
let attr = &ecx.attribute(meta_item.clone());
|
||||
|
|
|
@ -10,7 +10,7 @@ use rustc_session::Session;
|
|||
use rustc_span::symbol::{sym, Ident};
|
||||
use rustc_span::Span;
|
||||
|
||||
pub(crate) struct Expander;
|
||||
pub(crate) struct Expander(pub bool);
|
||||
|
||||
impl MultiItemModifier for Expander {
|
||||
fn expand(
|
||||
|
@ -19,6 +19,7 @@ impl MultiItemModifier for Expander {
|
|||
span: Span,
|
||||
meta_item: &ast::MetaItem,
|
||||
item: Annotatable,
|
||||
_: bool,
|
||||
) -> ExpandResult<Vec<Annotatable>, Annotatable> {
|
||||
let sess = ecx.sess;
|
||||
if report_bad_target(sess, &item, span) {
|
||||
|
@ -58,20 +59,20 @@ impl MultiItemModifier for Expander {
|
|||
report_path_args(sess, &meta);
|
||||
meta.path
|
||||
})
|
||||
.map(|path| (path, dummy_annotatable(), None))
|
||||
.map(|path| (path, dummy_annotatable(), None, self.0))
|
||||
.collect();
|
||||
|
||||
// Do not configure or clone items unless necessary.
|
||||
match &mut resolutions[..] {
|
||||
[] => {}
|
||||
[(_, first_item, _), others @ ..] => {
|
||||
[(_, first_item, ..), others @ ..] => {
|
||||
*first_item = cfg_eval(
|
||||
sess,
|
||||
features,
|
||||
item.clone(),
|
||||
ecx.current_expansion.lint_node_id,
|
||||
);
|
||||
for (_, item, _) in others {
|
||||
for (_, item, _, _) in others {
|
||||
*item = first_item.clone();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@ pub fn expand_deriving_copy(
|
|||
mitem: &MetaItem,
|
||||
item: &Annotatable,
|
||||
push: &mut dyn FnMut(Annotatable),
|
||||
is_const: bool,
|
||||
) {
|
||||
let trait_def = TraitDef {
|
||||
span,
|
||||
|
@ -21,6 +22,7 @@ pub fn expand_deriving_copy(
|
|||
supports_unions: true,
|
||||
methods: Vec::new(),
|
||||
associated_types: Vec::new(),
|
||||
is_const,
|
||||
};
|
||||
|
||||
trait_def.expand(cx, mitem, item, push);
|
||||
|
|
|
@ -14,6 +14,7 @@ pub fn expand_deriving_clone(
|
|||
mitem: &MetaItem,
|
||||
item: &Annotatable,
|
||||
push: &mut dyn FnMut(Annotatable),
|
||||
is_const: bool,
|
||||
) {
|
||||
// The simple form is `fn clone(&self) -> Self { *self }`, possibly with
|
||||
// some additional `AssertParamIsClone` assertions.
|
||||
|
@ -86,6 +87,7 @@ pub fn expand_deriving_clone(
|
|||
combine_substructure: substructure,
|
||||
}],
|
||||
associated_types: Vec::new(),
|
||||
is_const,
|
||||
};
|
||||
|
||||
trait_def.expand_ext(cx, mitem, item, push, is_simple)
|
||||
|
|
|
@ -15,6 +15,7 @@ pub fn expand_deriving_eq(
|
|||
mitem: &MetaItem,
|
||||
item: &Annotatable,
|
||||
push: &mut dyn FnMut(Annotatable),
|
||||
is_const: bool,
|
||||
) {
|
||||
let span = cx.with_def_site_ctxt(span);
|
||||
let inline = cx.meta_word(span, sym::inline);
|
||||
|
@ -41,6 +42,7 @@ pub fn expand_deriving_eq(
|
|||
})),
|
||||
}],
|
||||
associated_types: Vec::new(),
|
||||
is_const,
|
||||
};
|
||||
|
||||
super::inject_impl_of_structural_trait(cx, span, item, path_std!(marker::StructuralEq), push);
|
||||
|
|
|
@ -13,6 +13,7 @@ pub fn expand_deriving_ord(
|
|||
mitem: &MetaItem,
|
||||
item: &Annotatable,
|
||||
push: &mut dyn FnMut(Annotatable),
|
||||
is_const: bool,
|
||||
) {
|
||||
let inline = cx.meta_word(span, sym::inline);
|
||||
let attrs = thin_vec![cx.attribute(inline)];
|
||||
|
@ -33,6 +34,7 @@ pub fn expand_deriving_ord(
|
|||
combine_substructure: combine_substructure(Box::new(|a, b, c| cs_cmp(a, b, c))),
|
||||
}],
|
||||
associated_types: Vec::new(),
|
||||
is_const,
|
||||
};
|
||||
|
||||
trait_def.expand(cx, mitem, item, push)
|
||||
|
|
|
@ -14,6 +14,7 @@ pub fn expand_deriving_partial_eq(
|
|||
mitem: &MetaItem,
|
||||
item: &Annotatable,
|
||||
push: &mut dyn FnMut(Annotatable),
|
||||
is_const: bool,
|
||||
) {
|
||||
fn cs_eq(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>) -> BlockOrExpr {
|
||||
let base = true;
|
||||
|
@ -88,6 +89,7 @@ pub fn expand_deriving_partial_eq(
|
|||
supports_unions: false,
|
||||
methods,
|
||||
associated_types: Vec::new(),
|
||||
is_const,
|
||||
};
|
||||
trait_def.expand(cx, mitem, item, push)
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@ pub fn expand_deriving_partial_ord(
|
|||
mitem: &MetaItem,
|
||||
item: &Annotatable,
|
||||
push: &mut dyn FnMut(Annotatable),
|
||||
is_const: bool,
|
||||
) {
|
||||
let ordering_ty = Path(path_std!(cmp::Ordering));
|
||||
let ret_ty =
|
||||
|
@ -42,6 +43,7 @@ pub fn expand_deriving_partial_ord(
|
|||
supports_unions: false,
|
||||
methods: vec![partial_cmp_def],
|
||||
associated_types: Vec::new(),
|
||||
is_const,
|
||||
};
|
||||
trait_def.expand(cx, mitem, item, push)
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@ pub fn expand_deriving_debug(
|
|||
mitem: &MetaItem,
|
||||
item: &Annotatable,
|
||||
push: &mut dyn FnMut(Annotatable),
|
||||
is_const: bool,
|
||||
) {
|
||||
// &mut ::std::fmt::Formatter
|
||||
let fmtr = Ref(Box::new(Path(path_std!(fmt::Formatter))), ast::Mutability::Mut);
|
||||
|
@ -36,6 +37,7 @@ pub fn expand_deriving_debug(
|
|||
})),
|
||||
}],
|
||||
associated_types: Vec::new(),
|
||||
is_const,
|
||||
};
|
||||
trait_def.expand(cx, mitem, item, push)
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@ pub fn expand_deriving_rustc_decodable(
|
|||
mitem: &MetaItem,
|
||||
item: &Annotatable,
|
||||
push: &mut dyn FnMut(Annotatable),
|
||||
is_const: bool,
|
||||
) {
|
||||
let krate = sym::rustc_serialize;
|
||||
let typaram = sym::__D;
|
||||
|
@ -54,6 +55,7 @@ pub fn expand_deriving_rustc_decodable(
|
|||
})),
|
||||
}],
|
||||
associated_types: Vec::new(),
|
||||
is_const,
|
||||
};
|
||||
|
||||
trait_def.expand(cx, mitem, item, push)
|
||||
|
|
|
@ -16,6 +16,7 @@ pub fn expand_deriving_default(
|
|||
mitem: &ast::MetaItem,
|
||||
item: &Annotatable,
|
||||
push: &mut dyn FnMut(Annotatable),
|
||||
is_const: bool,
|
||||
) {
|
||||
item.visit_with(&mut DetectNonVariantDefaultAttr { cx });
|
||||
|
||||
|
@ -46,6 +47,7 @@ pub fn expand_deriving_default(
|
|||
})),
|
||||
}],
|
||||
associated_types: Vec::new(),
|
||||
is_const,
|
||||
};
|
||||
trait_def.expand(cx, mitem, item, push)
|
||||
}
|
||||
|
|
|
@ -100,6 +100,7 @@ pub fn expand_deriving_rustc_encodable(
|
|||
mitem: &MetaItem,
|
||||
item: &Annotatable,
|
||||
push: &mut dyn FnMut(Annotatable),
|
||||
is_const: bool,
|
||||
) {
|
||||
let krate = sym::rustc_serialize;
|
||||
let typaram = sym::__S;
|
||||
|
@ -138,6 +139,7 @@ pub fn expand_deriving_rustc_encodable(
|
|||
})),
|
||||
}],
|
||||
associated_types: Vec::new(),
|
||||
is_const,
|
||||
};
|
||||
|
||||
trait_def.expand(cx, mitem, item, push)
|
||||
|
|
|
@ -171,7 +171,7 @@ use rustc_ast::{GenericArg, GenericParamKind, VariantData};
|
|||
use rustc_attr as attr;
|
||||
use rustc_expand::base::{Annotatable, ExtCtxt};
|
||||
use rustc_span::symbol::{kw, sym, Ident, Symbol};
|
||||
use rustc_span::Span;
|
||||
use rustc_span::{Span, DUMMY_SP};
|
||||
use std::cell::RefCell;
|
||||
use std::iter;
|
||||
use std::vec;
|
||||
|
@ -200,6 +200,8 @@ pub struct TraitDef<'a> {
|
|||
pub methods: Vec<MethodDef<'a>>,
|
||||
|
||||
pub associated_types: Vec<(Ident, Ty)>,
|
||||
|
||||
pub is_const: bool,
|
||||
}
|
||||
|
||||
pub struct MethodDef<'a> {
|
||||
|
@ -726,7 +728,7 @@ impl<'a> TraitDef<'a> {
|
|||
unsafety: ast::Unsafe::No,
|
||||
polarity: ast::ImplPolarity::Positive,
|
||||
defaultness: ast::Defaultness::Final,
|
||||
constness: ast::Const::No,
|
||||
constness: if self.is_const { ast::Const::Yes(DUMMY_SP) } else { ast::Const::No },
|
||||
generics: trait_generics,
|
||||
of_trait: opt_trait_ref,
|
||||
self_ty: self_type,
|
||||
|
|
|
@ -13,6 +13,7 @@ pub fn expand_deriving_hash(
|
|||
mitem: &MetaItem,
|
||||
item: &Annotatable,
|
||||
push: &mut dyn FnMut(Annotatable),
|
||||
is_const: bool,
|
||||
) {
|
||||
let path = Path::new_(pathvec_std!(hash::Hash), vec![], PathKind::Std);
|
||||
|
||||
|
@ -38,6 +39,7 @@ pub fn expand_deriving_hash(
|
|||
})),
|
||||
}],
|
||||
associated_types: Vec::new(),
|
||||
is_const,
|
||||
};
|
||||
|
||||
hash_trait_def.expand(cx, mitem, item, push);
|
||||
|
|
|
@ -38,9 +38,10 @@ pub mod partial_ord;
|
|||
|
||||
pub mod generic;
|
||||
|
||||
pub(crate) struct BuiltinDerive(
|
||||
pub(crate) fn(&mut ExtCtxt<'_>, Span, &MetaItem, &Annotatable, &mut dyn FnMut(Annotatable)),
|
||||
);
|
||||
pub(crate) type BuiltinDeriveFn =
|
||||
fn(&mut ExtCtxt<'_>, Span, &MetaItem, &Annotatable, &mut dyn FnMut(Annotatable), bool);
|
||||
|
||||
pub(crate) struct BuiltinDerive(pub(crate) BuiltinDeriveFn);
|
||||
|
||||
impl MultiItemModifier for BuiltinDerive {
|
||||
fn expand(
|
||||
|
@ -49,6 +50,7 @@ impl MultiItemModifier for BuiltinDerive {
|
|||
span: Span,
|
||||
meta_item: &MetaItem,
|
||||
item: Annotatable,
|
||||
is_derive_const: bool,
|
||||
) -> ExpandResult<Vec<Annotatable>, Annotatable> {
|
||||
// FIXME: Built-in derives often forget to give spans contexts,
|
||||
// so we are doing it here in a centralized way.
|
||||
|
@ -57,21 +59,28 @@ impl MultiItemModifier for BuiltinDerive {
|
|||
match item {
|
||||
Annotatable::Stmt(stmt) => {
|
||||
if let ast::StmtKind::Item(item) = stmt.into_inner().kind {
|
||||
(self.0)(ecx, span, meta_item, &Annotatable::Item(item), &mut |a| {
|
||||
// Cannot use 'ecx.stmt_item' here, because we need to pass 'ecx'
|
||||
// to the function
|
||||
items.push(Annotatable::Stmt(P(ast::Stmt {
|
||||
id: ast::DUMMY_NODE_ID,
|
||||
kind: ast::StmtKind::Item(a.expect_item()),
|
||||
span,
|
||||
})));
|
||||
});
|
||||
(self.0)(
|
||||
ecx,
|
||||
span,
|
||||
meta_item,
|
||||
&Annotatable::Item(item),
|
||||
&mut |a| {
|
||||
// Cannot use 'ecx.stmt_item' here, because we need to pass 'ecx'
|
||||
// to the function
|
||||
items.push(Annotatable::Stmt(P(ast::Stmt {
|
||||
id: ast::DUMMY_NODE_ID,
|
||||
kind: ast::StmtKind::Item(a.expect_item()),
|
||||
span,
|
||||
})));
|
||||
},
|
||||
is_derive_const,
|
||||
);
|
||||
} else {
|
||||
unreachable!("should have already errored on non-item statement")
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
(self.0)(ecx, span, meta_item, &item, &mut |a| items.push(a));
|
||||
(self.0)(ecx, span, meta_item, &item, &mut |a| items.push(a), is_derive_const);
|
||||
}
|
||||
}
|
||||
ExpandResult::Ready(items)
|
||||
|
|
|
@ -97,7 +97,8 @@ pub fn register_builtin_macros(resolver: &mut dyn ResolverExpand) {
|
|||
bench: test::expand_bench,
|
||||
cfg_accessible: cfg_accessible::Expander,
|
||||
cfg_eval: cfg_eval::expand,
|
||||
derive: derive::Expander,
|
||||
derive: derive::Expander(false),
|
||||
derive_const: derive::Expander(true),
|
||||
global_allocator: global_allocator::expand,
|
||||
test: test::expand_test,
|
||||
test_case: test::expand_test_case,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue