Allow defaultness on trait items syntactically.
id: DUMMY_NODE_ID,
span: lo.to(self.prev_span),
ident: name,
+ attrs,
vis,
defaultness,
- attrs,
generics,
kind,
tokens: None,
) -> PResult<'a, TraitItem> {
let lo = self.token.span;
let vis = self.parse_visibility(FollowedByType::No)?;
+ let defaultness = self.parse_defaultness();
let (name, kind, generics) = if self.eat_keyword(kw::Type) {
self.parse_trait_item_assoc_ty()?
} else if self.is_const_item() {
Ok(TraitItem {
id: DUMMY_NODE_ID,
+ span: lo.to(self.prev_span),
ident: name,
attrs,
vis,
+ defaultness,
generics,
kind,
- span: lo.to(self.prev_span),
tokens: None,
})
}
forbid, and warn are the only allowed built-in attributes in function parameters")
});
}
+
+ fn check_defaultness(&self, span: Span, defaultness: Defaultness) {
+ if let Defaultness::Default = defaultness {
+ self.err_handler()
+ .struct_span_err(span, "`default` is only allowed on items in `impl` definitions")
+ .emit();
+ }
+ }
}
enum GenericPosition {
fn visit_trait_item(&mut self, ti: &'a TraitItem) {
self.invalid_visibility(&ti.vis, None);
+ self.check_defaultness(ti.span, ti.defaultness);
visit::walk_trait_item(self, ti);
}
}
pub decl: P<FnDecl>,
}
-/// Represents an item declaration within a trait declaration,
+pub type TraitItem = ImplItem<TraitItemKind>;
+
+/// Represents the kind of an item declaration within a trait declaration,
/// possibly including a default implementation. A trait item is
/// either required (meaning it doesn't have an implementation, just a
/// signature) or provided (meaning it has a default implementation).
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
-pub struct TraitItem {
- pub attrs: Vec<Attribute>,
- pub id: NodeId,
- pub span: Span,
- pub vis: Visibility,
- pub ident: Ident,
-
- pub generics: Generics,
- pub kind: TraitItemKind,
- /// See `Item::tokens` for what this is.
- pub tokens: Option<TokenStream>,
-}
-
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
pub enum TraitItemKind {
Const(P<Ty>, Option<P<Expr>>),
/// Represents anything within an `impl` block.
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
-pub struct ImplItem {
+pub struct ImplItem<K = ImplItemKind> {
pub attrs: Vec<Attribute>,
pub id: NodeId,
pub span: Span,
pub defaultness: Defaultness,
pub generics: Generics,
- pub kind: ImplItemKind,
+ pub kind: K,
/// See `Item::tokens` for what this is.
pub tokens: Option<TokenStream>,
}
pub fn noop_flat_map_trait_item<T: MutVisitor>(mut item: TraitItem, visitor: &mut T)
-> SmallVec<[TraitItem; 1]>
{
- let TraitItem { id, ident, vis, attrs, generics, kind, span, tokens: _ } = &mut item;
+ let TraitItem { id, ident, vis, defaultness: _, attrs, generics, kind, span, tokens: _ } =
+ &mut item;
visitor.visit_id(id);
visitor.visit_ident(ident);
visitor.visit_vis(vis);
self.hardbreak_if_not_bol();
self.maybe_print_comment(ti.span.lo());
self.print_outer_attributes(&ti.attrs);
+ self.print_defaultness(ti.defaultness);
match ti.kind {
ast::TraitItemKind::Const(ref ty, ref default) => {
self.print_associated_const(
AstFragmentKind::TraitItems => AstFragment::TraitItems(smallvec![ast::TraitItem {
id, span, ident, vis, attrs, generics,
kind: ast::TraitItemKind::Macro(mac_placeholder()),
+ defaultness: ast::Defaultness::Final,
tokens: None,
}]),
AstFragmentKind::ImplItems => AstFragment::ImplItems(smallvec![ast::ImplItem {
LL | });
| ^ expected one of `.`, `;`, `?`, `else`, or an operator
-error: expected one of `async`, `const`, `crate`, `extern`, `fn`, `pub`, `type`, `unsafe`, or `}`, found `;`
+error: expected one of `async`, `const`, `crate`, `default`, `extern`, `fn`, `pub`, `type`, `unsafe`, or `}`, found `;`
--> $DIR/issue-60075.rs:6:11
|
LL | fn qux() -> Option<usize> {
-error: expected one of `async`, `const`, `crate`, `extern`, `fn`, `pub`, `type`, `unsafe`, or `}`, found `...`
+error: expected one of `async`, `const`, `crate`, `default`, `extern`, `fn`, `pub`, `type`, `unsafe`, or `}`, found `...`
--> $DIR/issue-32446.rs:4:11
|
LL | trait T { ... }
- | ^^^ expected one of 9 possible tokens
+ | ^^^ expected one of 10 possible tokens
error: aborting due to previous error
-error: expected one of `async`, `const`, `crate`, `extern`, `fn`, `pub`, `type`, or `unsafe`, found `2`
+error: expected one of `async`, `const`, `crate`, `default`, `extern`, `fn`, `pub`, `type`, or `unsafe`, found `2`
--> $DIR/trait-non-item-macros.rs:2:19
|
LL | ($a:expr) => ($a)
- | ^^ expected one of 8 possible tokens
+ | ^^ expected one of 9 possible tokens
...
LL | bah!(2);
| -------- in this macro invocation
LL | fn main() {}
| ^
-error: expected one of `async`, `const`, `extern`, `fn`, `type`, or `unsafe`, found keyword `struct`
+error: expected one of `async`, `const`, `default`, `extern`, `fn`, `type`, or `unsafe`, found keyword `struct`
--> $DIR/missing-close-brace-in-trait.rs:5:12
|
LL | pub(crate) struct Bar<T>();
- | ^^^^^^ expected one of `async`, `const`, `extern`, `fn`, `type`, or `unsafe`
+ | ^^^^^^ expected one of 7 possible tokens
error[E0601]: `main` function not found in crate `missing_close_brace_in_trait`
--> $DIR/missing-close-brace-in-trait.rs:1:1
--- /dev/null
+fn main() {}
+
+trait X {
+ default const A: u8; //~ ERROR `default` is only allowed on items in `impl` definitions
+ default const B: u8 = 0; //~ ERROR `default` is only allowed on items in `impl` definitions
+ default type D; //~ ERROR `default` is only allowed on items in `impl` definitions
+ default type C: Ord; //~ ERROR `default` is only allowed on items in `impl` definitions
+ default fn f1(); //~ ERROR `default` is only allowed on items in `impl` definitions
+ default fn f2() {} //~ ERROR `default` is only allowed on items in `impl` definitions
+}
--- /dev/null
+error: `default` is only allowed on items in `impl` definitions
+ --> $DIR/trait-item-with-defaultness-fail-semantic.rs:4:5
+ |
+LL | default const A: u8;
+ | ^^^^^^^^^^^^^^^^^^^^
+
+error: `default` is only allowed on items in `impl` definitions
+ --> $DIR/trait-item-with-defaultness-fail-semantic.rs:5:5
+ |
+LL | default const B: u8 = 0;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: `default` is only allowed on items in `impl` definitions
+ --> $DIR/trait-item-with-defaultness-fail-semantic.rs:6:5
+ |
+LL | default type D;
+ | ^^^^^^^^^^^^^^^
+
+error: `default` is only allowed on items in `impl` definitions
+ --> $DIR/trait-item-with-defaultness-fail-semantic.rs:7:5
+ |
+LL | default type C: Ord;
+ | ^^^^^^^^^^^^^^^^^^^^
+
+error: `default` is only allowed on items in `impl` definitions
+ --> $DIR/trait-item-with-defaultness-fail-semantic.rs:8:5
+ |
+LL | default fn f1();
+ | ^^^^^^^^^^^^^^^^
+
+error: `default` is only allowed on items in `impl` definitions
+ --> $DIR/trait-item-with-defaultness-fail-semantic.rs:9:5
+ |
+LL | default fn f2() {}
+ | ^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 6 previous errors
+
--- /dev/null
+// check-pass
+
+fn main() {}
+
+#[cfg(FALSE)]
+trait X {
+ default const A: u8;
+ default const B: u8 = 0;
+ default type D;
+ default type C: Ord;
+ default fn f1();
+ default fn f2() {}
+}