Alias TraitItem
& ImplItem
.
Allow defaultness on trait items syntactically.
This commit is contained in:
parent
3eebe058e5
commit
c4bbe9cbbe
@ -714,9 +714,9 @@ impl<'a> Parser<'a> {
|
||||
id: DUMMY_NODE_ID,
|
||||
span: lo.to(self.prev_span),
|
||||
ident: name,
|
||||
attrs,
|
||||
vis,
|
||||
defaultness,
|
||||
attrs,
|
||||
generics,
|
||||
kind,
|
||||
tokens: None,
|
||||
@ -882,6 +882,7 @@ impl<'a> Parser<'a> {
|
||||
) -> 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() {
|
||||
@ -895,12 +896,13 @@ impl<'a> Parser<'a> {
|
||||
|
||||
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,
|
||||
})
|
||||
}
|
||||
|
@ -271,6 +271,14 @@ impl<'a> AstValidator<'a> {
|
||||
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 {
|
||||
@ -746,6 +754,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
@ -1603,24 +1603,12 @@ pub struct FnSig {
|
||||
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>>),
|
||||
@ -1631,7 +1619,7 @@ pub enum TraitItemKind {
|
||||
|
||||
/// 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,
|
||||
@ -1640,7 +1628,7 @@ pub struct ImplItem {
|
||||
|
||||
pub defaultness: Defaultness,
|
||||
pub generics: Generics,
|
||||
pub kind: ImplItemKind,
|
||||
pub kind: K,
|
||||
/// See `Item::tokens` for what this is.
|
||||
pub tokens: Option<TokenStream>,
|
||||
}
|
||||
|
@ -939,7 +939,8 @@ pub fn noop_visit_item_kind<T: MutVisitor>(kind: &mut ItemKind, vis: &mut T) {
|
||||
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);
|
||||
|
@ -1550,6 +1550,7 @@ impl<'a> State<'a> {
|
||||
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(
|
||||
|
@ -53,6 +53,7 @@ pub fn placeholder(kind: AstFragmentKind, id: ast::NodeId, vis: Option<ast::Visi
|
||||
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 {
|
||||
|
@ -4,7 +4,7 @@ error: expected one of `.`, `;`, `?`, `else`, or an operator, found `}`
|
||||
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> {
|
||||
|
@ -1,8 +1,8 @@
|
||||
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
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
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
|
||||
|
@ -7,11 +7,11 @@ LL | trait T {
|
||||
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
|
||||
|
@ -0,0 +1,10 @@
|
||||
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
|
||||
}
|
@ -0,0 +1,38 @@
|
||||
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
|
||||
|
13
src/test/ui/parser/trait-item-with-defaultness-pass.rs
Normal file
13
src/test/ui/parser/trait-item-with-defaultness-pass.rs
Normal file
@ -0,0 +1,13 @@
|
||||
// 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() {}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user