Implement #[rustc_default_body_unstable]
This attribute allows to mark default body of a trait function as unstable. This means that implementing the trait without implementing the function will require enabling unstable feature. This is useful in conjunction with `#[rustc_must_implement_one_of]`, we may want to relax requirements for a trait, for example allowing implementing either of `PartialEq::{eq, ne}`, but do so in a safe way -- making implementation of only `PartialEq::ne` unstable.
This commit is contained in:
parent
96b9bb4620
commit
177af47104
14 changed files with 206 additions and 17 deletions
|
@ -131,6 +131,14 @@ impl ConstStability {
|
|||
}
|
||||
}
|
||||
|
||||
/// Represents the `#[rustc_default_body_unstable]` attribute.
|
||||
#[derive(Encodable, Decodable, Copy, Clone, Debug, PartialEq, Eq, Hash)]
|
||||
#[derive(HashStable_Generic)]
|
||||
pub struct DefaultBodyStability {
|
||||
pub level: StabilityLevel,
|
||||
pub feature: Symbol,
|
||||
}
|
||||
|
||||
/// The available stability levels.
|
||||
#[derive(Encodable, Decodable, PartialEq, Copy, Clone, Debug, Eq, Hash)]
|
||||
#[derive(HashStable_Generic)]
|
||||
|
@ -214,7 +222,8 @@ pub fn find_stability(
|
|||
sess: &Session,
|
||||
attrs: &[Attribute],
|
||||
item_sp: Span,
|
||||
) -> (Option<(Stability, Span)>, Option<(ConstStability, Span)>) {
|
||||
) -> (Option<(Stability, Span)>, Option<(ConstStability, Span)>, Option<(DefaultBodyStability, Span)>)
|
||||
{
|
||||
find_stability_generic(sess, attrs.iter(), item_sp)
|
||||
}
|
||||
|
||||
|
@ -222,7 +231,7 @@ fn find_stability_generic<'a, I>(
|
|||
sess: &Session,
|
||||
attrs_iter: I,
|
||||
item_sp: Span,
|
||||
) -> (Option<(Stability, Span)>, Option<(ConstStability, Span)>)
|
||||
) -> (Option<(Stability, Span)>, Option<(ConstStability, Span)>, Option<(DefaultBodyStability, Span)>)
|
||||
where
|
||||
I: Iterator<Item = &'a Attribute>,
|
||||
{
|
||||
|
@ -230,6 +239,7 @@ where
|
|||
|
||||
let mut stab: Option<(Stability, Span)> = None;
|
||||
let mut const_stab: Option<(ConstStability, Span)> = None;
|
||||
let mut body_stab: Option<(DefaultBodyStability, Span)> = None;
|
||||
let mut promotable = false;
|
||||
let mut allowed_through_unstable_modules = false;
|
||||
|
||||
|
@ -243,6 +253,7 @@ where
|
|||
sym::stable,
|
||||
sym::rustc_promotable,
|
||||
sym::rustc_allowed_through_unstable_modules,
|
||||
sym::rustc_default_body_unstable,
|
||||
]
|
||||
.iter()
|
||||
.any(|&s| attr.has_name(s))
|
||||
|
@ -280,7 +291,7 @@ where
|
|||
|
||||
let meta_name = meta.name_or_empty();
|
||||
match meta_name {
|
||||
sym::rustc_const_unstable | sym::unstable => {
|
||||
sym::rustc_const_unstable | sym::rustc_default_body_unstable | sym::unstable => {
|
||||
if meta_name == sym::unstable && stab.is_some() {
|
||||
handle_errors(
|
||||
&sess.parse_sess,
|
||||
|
@ -295,6 +306,13 @@ where
|
|||
AttrError::MultipleStabilityLevels,
|
||||
);
|
||||
break;
|
||||
} else if meta_name == sym::rustc_default_body_unstable && body_stab.is_some() {
|
||||
handle_errors(
|
||||
&sess.parse_sess,
|
||||
attr.span,
|
||||
AttrError::MultipleStabilityLevels,
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
||||
let mut feature = None;
|
||||
|
@ -405,11 +423,14 @@ where
|
|||
};
|
||||
if sym::unstable == meta_name {
|
||||
stab = Some((Stability { level, feature }, attr.span));
|
||||
} else {
|
||||
} else if sym::rustc_const_unstable == meta_name {
|
||||
const_stab = Some((
|
||||
ConstStability { level, feature, promotable: false },
|
||||
attr.span,
|
||||
));
|
||||
} else {
|
||||
body_stab =
|
||||
Some((DefaultBodyStability { level, feature }, attr.span));
|
||||
}
|
||||
}
|
||||
(None, _, _) => {
|
||||
|
@ -542,7 +563,7 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
(stab, const_stab)
|
||||
(stab, const_stab, body_stab)
|
||||
}
|
||||
|
||||
pub fn find_crate_name(sess: &Session, attrs: &[Attribute]) -> Option<Symbol> {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue