}
}
- fn check_foreign_ty_bodyless(&self, ident: Ident, body: Option<&Ty>) {
+ fn check_foreign_kind_bodyless(&self, ident: Ident, kind: &str, body: Option<Span>) {
let body = match body {
None => return,
Some(body) => body,
};
self.err_handler()
- .struct_span_err(ident.span, "incorrect `type` inside `extern` block")
+ .struct_span_err(ident.span, &format!("incorrect `{}` inside `extern` block", kind))
.span_label(ident.span, "cannot have a body")
- .span_label(body.span, "the invalid body")
+ .span_label(body, "the invalid body")
.span_label(
self.current_extern_span(),
- "`extern` blocks define existing foreign types and types \
- inside of them cannot have a body",
+ format!(
+ "`extern` blocks define existing foreign {0}s and {0}s \
+ inside of them cannot have a body",
+ kind
+ ),
)
.note(MORE_EXTERN)
.emit();
}
}
}
+
+ fn check_item_named(&self, ident: Ident, kind: &str) {
+ if ident.name != kw::Underscore {
+ return;
+ }
+ self.err_handler()
+ .struct_span_err(ident.span, &format!("`{}` items in this context need a name", kind))
+ .span_label(ident.span, format!("`_` is not a valid name for this `{}` item", kind))
+ .emit();
+ }
}
enum GenericPosition {
self.err_handler().span_err(item.span, "unions cannot have zero fields");
}
}
+ ItemKind::Const(.., None) => {
+ let msg = "free constant item without body";
+ self.error_item_without_body(item.span, "constant", msg, " = <expr>;");
+ }
+ ItemKind::Static(.., None) => {
+ let msg = "free static item without body";
+ self.error_item_without_body(item.span, "static", msg, " = <expr>;");
+ }
+ ItemKind::TyAlias(_, ref bounds, ref body) => {
+ if body.is_none() {
+ let msg = "free type alias without body";
+ self.error_item_without_body(item.span, "type", msg, " = <type>;");
+ }
+ self.check_type_no_bounds(bounds, "this context");
+ }
_ => {}
}
self.check_foreign_fn_headerless(fi.ident, fi.span, sig.header);
}
ForeignItemKind::TyAlias(generics, bounds, body) => {
- self.check_foreign_ty_bodyless(fi.ident, body.as_deref());
+ self.check_foreign_kind_bodyless(fi.ident, "type", body.as_ref().map(|b| b.span));
self.check_type_no_bounds(bounds, "`extern` blocks");
self.check_foreign_ty_genericless(generics);
}
- ForeignItemKind::Static(..) | ForeignItemKind::Macro(..) => {}
+ ForeignItemKind::Static(_, _, body) => {
+ self.check_foreign_kind_bodyless(fi.ident, "static", body.as_ref().map(|b| b.span));
+ }
+ ForeignItemKind::Const(..) | ForeignItemKind::Macro(..) => {}
}
visit::walk_foreign_item(self, fi)
}
GenericArgs::Parenthesized(ref data) => {
walk_list!(self, visit_ty, &data.inputs);
- if let FunctionRetTy::Ty(ty) = &data.output {
+ if let FnRetTy::Ty(ty) = &data.output {
// `-> Foo` syntax is essentially an associated type binding,
// so it is also allowed to contain nested `impl Trait`.
self.with_impl_trait(None, |this| this.visit_ty(ty));
}
}
+ if let AssocItemKind::Const(..) = item.kind {
+ self.check_item_named(item.ident, "const");
+ }
+
self.with_in_trait_impl(false, |this| visit::walk_assoc_item(this, item, ctxt));
}
}