| %empty { $$ = mk_none(); }
;
-maybe_default_impl
-: IMPL { $$ = mk_none(); }
-| DEFAULT IMPL { $$ = $1 }
-;
+maybe_default_maybe_unsafe
+: DEFAULT UNSAFE { $$ = mk_atom("DefaultUnsafe"); }
+| DEFAULT { $$ = mk_atom("Default"); }
+| UNSAFE { $$ = mk_atom("Unsafe"); }
+| %empty { $$ = mk_none(); }
trait_method
: type_method { $$ = mk_node("Required", 1, $1); }
// they are ambiguous with traits. We do the same here, regrettably,
// by splitting ty into ty and ty_prim.
item_impl
-: maybe_unsafe maybe_default_impl generic_params ty_prim_sum maybe_where_clause '{' maybe_inner_attrs maybe_impl_items '}'
+: maybe_default_maybe_unsafe IMPL generic_params ty_prim_sum maybe_where_clause '{' maybe_inner_attrs maybe_impl_items '}'
{
- $$ = mk_node("ItemImpl", 6, $1, $3, $4, $5, $7, $8, $2);
+ $$ = mk_node("ItemImpl", 6, $1, $3, $4, $5, $7, $8);
}
-| maybe_unsafe maybe_default_impl generic_params '(' ty ')' maybe_where_clause '{' maybe_inner_attrs maybe_impl_items '}'
+| maybe_default_maybe_unsafe IMPL generic_params '(' ty ')' maybe_where_clause '{' maybe_inner_attrs maybe_impl_items '}'
{
- $$ = mk_node("ItemImpl", 6, $1, $3, 5, $6, $9, $10, $2);
+ $$ = mk_node("ItemImpl", 6, $1, $3, 5, $6, $9, $10);
}
-| maybe_unsafe maybe_default_impl generic_params trait_ref FOR ty_sum maybe_where_clause '{' maybe_inner_attrs maybe_impl_items '}'
+| maybe_default_maybe_unsafe IMPL generic_params trait_ref FOR ty_sum maybe_where_clause '{' maybe_inner_attrs maybe_impl_items '}'
{
- $$ = mk_node("ItemImpl", 6, $3, $4, $6, $7, $9, $10, $2);
+ $$ = mk_node("ItemImpl", 6, $3, $4, $6, $7, $9, $10);
}
-| maybe_unsafe maybe_default_impl generic_params '!' trait_ref FOR ty_sum maybe_where_clause '{' maybe_inner_attrs maybe_impl_items '}'
+| maybe_default_maybe_unsafe IMPL generic_params '!' trait_ref FOR ty_sum maybe_where_clause '{' maybe_inner_attrs maybe_impl_items '}'
{
- $$ = mk_node("ItemImplNeg", 7, $1, $3, $5, $7, $8, $10, $11, $2);
+ $$ = mk_node("ItemImplNeg", 7, $1, $3, $5, $7, $8, $10, $11);
}
-| maybe_unsafe maybe_default_impl generic_params trait_ref FOR DOTDOT '{' '}'
+| maybe_default_maybe_unsafe IMPL generic_params trait_ref FOR DOTDOT '{' '}'
{
$$ = mk_node("ItemImplDefault", 3, $1, $3, $4);
}
-| maybe_unsafe maybe_default_impl generic_params '!' trait_ref FOR DOTDOT '{' '}'
+| maybe_default_maybe_unsafe IMPL generic_params '!' trait_ref FOR DOTDOT '{' '}'
{
$$ = mk_node("ItemImplDefaultNeg", 3, $1, $3, $4);
}
ItemKind::MacroDef(..) | ItemKind::Mac(..) => panic!("Shouldn't still be around"),
}
- // [1] `defaultness.has_value()` is necer called for an `impl`, always `true` in order to
+ // [1] `defaultness.has_value()` is never called for an `impl`, always `true` in order to
// not cause an assertion failure inside the `lower_defaultness` function
}
use ty::outlives::Component;
use util::nodemap::FxHashSet;
use hir::{self};
+use traits::specialize::specialization_graph::NodeItem;
use super::{Obligation, ObligationCause, PredicateObligation, SelectionContext, Normalized};
}
}
}
+
+ pub fn impl_item_is_final(self, node_item: &NodeItem<hir::Defaultness>) -> bool {
+ node_item.item.is_final() && !self.impl_is_default(node_item.node.def_id())
+ }
}
pub enum TupleArgumentsFlag { Yes, No }
.map(|node_item| node_item.map(|parent| parent.defaultness));
if let Some(parent) = parent {
- if parent.item.is_final() {
- if !tcx.impl_is_default(parent.node.def_id()) {
- report_forbidden_specialization(tcx, impl_item, parent.node.def_id());
- }
+ if tcx.impl_item_is_final(&parent) {
+ report_forbidden_specialization(tcx, impl_item, parent.node.def_id());
}
}
_ => {}
}
- match defaultness {
- ast::Defaultness::Default => {
- gate_feature_post!(&self, specialization,
- i.span,
- "specialization is unstable");
- }
- _ => {}
+ if let ast::Defaultness::Default = defaultness {
+ gate_feature_post!(&self, specialization,
+ i.span,
+ "specialization is unstable");
}
}
allowed to have generics");
}
- match defaultness {
- ast::Defaultness::Default => {
- self.span_err(impl_span, "`default impl` is not allowed for \
- default trait implementations");
- }
- _ => {}
+ if let ast::Defaultness::Default = defaultness {
+ self.span_err(impl_span, "`default impl` is not allowed for \
+ default trait implementations");
}
self.expect(&token::OpenDelim(token::Brace))?;
}
if (self.check_keyword(keywords::Unsafe) &&
self.look_ahead(1, |t| t.is_keyword(keywords::Impl))) ||
- (self.check_keyword(keywords::Unsafe) &&
- self.look_ahead(1, |t| t.is_keyword(keywords::Default)) &&
+ (self.check_keyword(keywords::Default) &&
+ self.look_ahead(1, |t| t.is_keyword(keywords::Unsafe)) &&
self.look_ahead(2, |t| t.is_keyword(keywords::Impl)))
{
// IMPL ITEM
- self.expect_keyword(keywords::Unsafe)?;
let defaultness = self.parse_defaultness()?;
+ self.expect_keyword(keywords::Unsafe)?;
self.expect_keyword(keywords::Impl)?;
let (ident,
item_,
fn foo(&self) -> &'static str;
}
-unsafe default impl<T> Foo for T {
+default unsafe impl<T> Foo for T {
fn foo(&self) -> &'static str {
"generic"
}
}
-unsafe default impl<T: Clone> Foo for T {
+default unsafe impl<T: Clone> Foo for T {
fn foo(&self) -> &'static str {
"generic Clone"
}
}
-unsafe default impl<T, U> Foo for (T, U) where T: Clone, U: Clone {
+default unsafe impl<T, U> Foo for (T, U) where T: Clone, U: Clone {
fn foo(&self) -> &'static str {
"generic pair"
}
}
-unsafe default impl<T: Clone> Foo for (T, T) {
+default unsafe impl<T: Clone> Foo for (T, T) {
fn foo(&self) -> &'static str {
"generic uniform pair"
}
}
-unsafe default impl Foo for (u8, u32) {
+default unsafe impl Foo for (u8, u32) {
fn foo(&self) -> &'static str {
"(u8, u32)"
}
}
-unsafe default impl Foo for (u8, u8) {
+default unsafe impl Foo for (u8, u8) {
fn foo(&self) -> &'static str {
"(u8, u8)"
}
}
-unsafe default impl<T: Clone> Foo for Vec<T> {
+default unsafe impl<T: Clone> Foo for Vec<T> {
fn foo(&self) -> &'static str {
"generic Vec"
}
}
-unsafe impl Foo for Vec<i32> {
+default unsafe impl Foo for Vec<i32> {
fn foo(&self) -> &'static str {
"Vec<i32>"
}
}
-unsafe impl Foo for String {
+default unsafe impl Foo for String {
fn foo(&self) -> &'static str {
"String"
}
}
-unsafe impl Foo for i32 {
+default unsafe impl Foo for i32 {
fn foo(&self) -> &'static str {
"i32"
}
struct NotClone;
unsafe trait MyMarker {}
-unsafe default impl<T: Clone + MyMarker> Foo for T {
+default unsafe impl<T: Clone + MyMarker> Foo for T {
fn foo(&self) -> &'static str {
"generic Clone + MyMarker"
}