Skip to content

Commit

Permalink
Rollup merge of rust-lang#86223 - fee1-dead:better-E0121, r=petrochenkov
Browse files Browse the repository at this point in the history
Specify the kind of the item for E0121

Fixes rust-lang#86005
  • Loading branch information
Dylan-DPC authored Jun 22, 2021
2 parents b8be316 + e66f241 commit af9e5d1
Show file tree
Hide file tree
Showing 34 changed files with 455 additions and 388 deletions.
21 changes: 21 additions & 0 deletions compiler/rustc_hir/src/hir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2815,6 +2815,27 @@ impl ItemKind<'_> {
_ => return None,
})
}

pub fn descr(&self) -> &'static str {
match self {
ItemKind::ExternCrate(..) => "extern crate",
ItemKind::Use(..) => "`use` import",
ItemKind::Static(..) => "static item",
ItemKind::Const(..) => "constant item",
ItemKind::Fn(..) => "function",
ItemKind::Mod(..) => "module",
ItemKind::ForeignMod { .. } => "extern block",
ItemKind::GlobalAsm(..) => "global asm item",
ItemKind::TyAlias(..) => "type alias",
ItemKind::OpaqueTy(..) => "opaque type",
ItemKind::Enum(..) => "enum",
ItemKind::Struct(..) => "struct",
ItemKind::Union(..) => "union",
ItemKind::Trait(..) => "trait",
ItemKind::TraitAlias(..) => "trait alias",
ItemKind::Impl(..) => "implementation",
}
}
}

/// A reference from an trait to one of its associated items. This
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_typeck/src/astconv/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2418,6 +2418,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
visitor.0,
true,
hir_ty,
"function",
);
}

Expand Down
51 changes: 40 additions & 11 deletions compiler/rustc_typeck/src/collect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ crate fn placeholder_type_error(
placeholder_types: Vec<Span>,
suggest: bool,
hir_ty: Option<&hir::Ty<'_>>,
kind: &'static str,
) {
if placeholder_types.is_empty() {
return;
Expand Down Expand Up @@ -174,7 +175,7 @@ crate fn placeholder_type_error(
));
}

let mut err = bad_placeholder_type(tcx, placeholder_types);
let mut err = bad_placeholder_type(tcx, placeholder_types, kind);

// Suggest, but only if it is not a function in const or static
if suggest {
Expand Down Expand Up @@ -236,7 +237,15 @@ fn reject_placeholder_type_signatures_in_item(tcx: TyCtxt<'tcx>, item: &'tcx hir
let mut visitor = PlaceholderHirTyCollector::default();
visitor.visit_item(item);

placeholder_type_error(tcx, Some(generics.span), generics.params, visitor.0, suggest, None);
placeholder_type_error(
tcx,
Some(generics.span),
generics.params,
visitor.0,
suggest,
None,
item.kind.descr(),
);
}

impl Visitor<'tcx> for CollectItemTypesVisitor<'tcx> {
Expand Down Expand Up @@ -302,13 +311,17 @@ impl Visitor<'tcx> for CollectItemTypesVisitor<'tcx> {
fn bad_placeholder_type(
tcx: TyCtxt<'tcx>,
mut spans: Vec<Span>,
kind: &'static str,
) -> rustc_errors::DiagnosticBuilder<'tcx> {
let kind = if kind.ends_with('s') { format!("{}es", kind) } else { format!("{}s", kind) };

spans.sort();
let mut err = struct_span_err!(
tcx.sess,
spans.clone(),
E0121,
"the type placeholder `_` is not allowed within types on item signatures",
"the type placeholder `_` is not allowed within types on item signatures for {}",
kind
);
for span in spans {
err.span_label(span, "not allowed in type signatures");
Expand Down Expand Up @@ -382,7 +395,7 @@ impl AstConv<'tcx> for ItemCtxt<'tcx> {
_: Option<&ty::GenericParamDef>,
span: Span,
) -> &'tcx Const<'tcx> {
bad_placeholder_type(self.tcx(), vec![span]).emit();
bad_placeholder_type(self.tcx(), vec![span], "generic").emit();
// Typeck doesn't expect erased regions to be returned from `type_of`.
let ty = self.tcx.fold_regions(ty, &mut false, |r, _| match r {
ty::ReErased => self.tcx.lifetimes.re_static,
Expand Down Expand Up @@ -746,7 +759,15 @@ fn convert_item(tcx: TyCtxt<'_>, item_id: hir::ItemId) {
hir::ForeignItemKind::Static(..) => {
let mut visitor = PlaceholderHirTyCollector::default();
visitor.visit_foreign_item(item);
placeholder_type_error(tcx, None, &[], visitor.0, false, None);
placeholder_type_error(
tcx,
None,
&[],
visitor.0,
false,
None,
"static variable",
);
}
_ => (),
}
Expand Down Expand Up @@ -818,7 +839,15 @@ fn convert_item(tcx: TyCtxt<'_>, item_id: hir::ItemId) {
if let hir::TyKind::TraitObject(..) = ty.kind {
let mut visitor = PlaceholderHirTyCollector::default();
visitor.visit_item(it);
placeholder_type_error(tcx, None, &[], visitor.0, false, None);
placeholder_type_error(
tcx,
None,
&[],
visitor.0,
false,
None,
it.kind.descr(),
);
}
}
_ => (),
Expand Down Expand Up @@ -846,7 +875,7 @@ fn convert_trait_item(tcx: TyCtxt<'_>, trait_item_id: hir::TraitItemId) {
// Account for `const C: _;`.
let mut visitor = PlaceholderHirTyCollector::default();
visitor.visit_trait_item(trait_item);
placeholder_type_error(tcx, None, &[], visitor.0, false, None);
placeholder_type_error(tcx, None, &[], visitor.0, false, None, "constant");
}

hir::TraitItemKind::Type(_, Some(_)) => {
Expand All @@ -855,7 +884,7 @@ fn convert_trait_item(tcx: TyCtxt<'_>, trait_item_id: hir::TraitItemId) {
// Account for `type T = _;`.
let mut visitor = PlaceholderHirTyCollector::default();
visitor.visit_trait_item(trait_item);
placeholder_type_error(tcx, None, &[], visitor.0, false, None);
placeholder_type_error(tcx, None, &[], visitor.0, false, None, "associated type");
}

hir::TraitItemKind::Type(_, None) => {
Expand All @@ -865,7 +894,7 @@ fn convert_trait_item(tcx: TyCtxt<'_>, trait_item_id: hir::TraitItemId) {
let mut visitor = PlaceholderHirTyCollector::default();
visitor.visit_trait_item(trait_item);

placeholder_type_error(tcx, None, &[], visitor.0, false, None);
placeholder_type_error(tcx, None, &[], visitor.0, false, None, "associated type");
}
};

Expand All @@ -887,7 +916,7 @@ fn convert_impl_item(tcx: TyCtxt<'_>, impl_item_id: hir::ImplItemId) {
let mut visitor = PlaceholderHirTyCollector::default();
visitor.visit_impl_item(impl_item);

placeholder_type_error(tcx, None, &[], visitor.0, false, None);
placeholder_type_error(tcx, None, &[], visitor.0, false, None, "associated type");
}
hir::ImplItemKind::Const(..) => {}
}
Expand Down Expand Up @@ -1711,7 +1740,7 @@ fn fn_sig(tcx: TyCtxt<'_>, def_id: DefId) -> ty::PolyFnSig<'_> {

let mut visitor = PlaceholderHirTyCollector::default();
visitor.visit_ty(ty);
let mut diag = bad_placeholder_type(tcx, visitor.0);
let mut diag = bad_placeholder_type(tcx, visitor.0, "return type");
let ret_ty = fn_sig.output();
if ret_ty != tcx.ty_error() {
if !ret_ty.is_closure() {
Expand Down
37 changes: 28 additions & 9 deletions compiler/rustc_typeck/src/collect/type_of.rs
Original file line number Diff line number Diff line change
Expand Up @@ -285,7 +285,9 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
TraitItemKind::Const(ref ty, body_id) => body_id
.and_then(|body_id| {
if is_suggestable_infer_ty(ty) {
Some(infer_placeholder_type(tcx, def_id, body_id, ty.span, item.ident))
Some(infer_placeholder_type(
tcx, def_id, body_id, ty.span, item.ident, "constant",
))
} else {
None
}
Expand All @@ -304,7 +306,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
}
ImplItemKind::Const(ref ty, body_id) => {
if is_suggestable_infer_ty(ty) {
infer_placeholder_type(tcx, def_id, body_id, ty.span, item.ident)
infer_placeholder_type(tcx, def_id, body_id, ty.span, item.ident, "constant")
} else {
icx.to_ty(ty)
}
Expand All @@ -320,9 +322,25 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {

Node::Item(item) => {
match item.kind {
ItemKind::Static(ref ty, .., body_id) | ItemKind::Const(ref ty, body_id) => {
ItemKind::Static(ref ty, .., body_id) => {
if is_suggestable_infer_ty(ty) {
infer_placeholder_type(tcx, def_id, body_id, ty.span, item.ident)
infer_placeholder_type(
tcx,
def_id,
body_id,
ty.span,
item.ident,
"static variable",
)
} else {
icx.to_ty(ty)
}
}
ItemKind::Const(ref ty, body_id) => {
if is_suggestable_infer_ty(ty) {
infer_placeholder_type(
tcx, def_id, body_id, ty.span, item.ident, "constant",
)
} else {
icx.to_ty(ty)
}
Expand Down Expand Up @@ -742,13 +760,14 @@ fn let_position_impl_trait_type(tcx: TyCtxt<'_>, opaque_ty_id: LocalDefId) -> Ty
concrete_ty
}

fn infer_placeholder_type(
tcx: TyCtxt<'_>,
fn infer_placeholder_type<'a>(
tcx: TyCtxt<'a>,
def_id: LocalDefId,
body_id: hir::BodyId,
span: Span,
item_ident: Ident,
) -> Ty<'_> {
kind: &'static str,
) -> Ty<'a> {
// Attempts to make the type nameable by turning FnDefs into FnPtrs.
struct MakeNameable<'tcx> {
success: bool,
Expand Down Expand Up @@ -802,7 +821,7 @@ fn infer_placeholder_type(
if let Some(sugg_ty) = sugg_ty {
err.span_suggestion(
span,
"provide a type for the item",
&format!("provide a type for the {item}", item = kind),
format!("{}: {}", item_ident, sugg_ty),
Applicability::MachineApplicable,
);
Expand All @@ -816,7 +835,7 @@ fn infer_placeholder_type(
err.emit_unless(ty.references_error());
}
None => {
let mut diag = bad_placeholder_type(tcx, vec![span]);
let mut diag = bad_placeholder_type(tcx, vec![span], kind);

if !ty.references_error() {
let mut mk_nameable = MakeNameable::new(tcx);
Expand Down
20 changes: 10 additions & 10 deletions src/test/ui/did_you_mean/bad-assoc-ty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ type D = (u8, u8)::AssocTy;

type E = _::AssocTy;
//~^ ERROR missing angle brackets in associated item path
//~| ERROR the type placeholder `_` is not allowed within types on item signatures
//~| ERROR the type placeholder `_` is not allowed within types on item signatures for type aliases

type F = &'static (u8)::AssocTy;
//~^ ERROR missing angle brackets in associated item path
Expand Down Expand Up @@ -47,37 +47,37 @@ type I = ty!()::AssocTy;

trait K<A, B> {}
fn foo<X: K<_, _>>(x: X) {}
//~^ ERROR the type placeholder `_` is not allowed within types on item signatures
//~^ ERROR the type placeholder `_` is not allowed within types on item signatures for functions

fn bar<F>(_: F) where F: Fn() -> _ {}
//~^ ERROR the type placeholder `_` is not allowed within types on item signatures
//~^ ERROR the type placeholder `_` is not allowed within types on item signatures for functions

fn baz<F: Fn() -> _>(_: F) {}
//~^ ERROR the type placeholder `_` is not allowed within types on item signatures
//~^ ERROR the type placeholder `_` is not allowed within types on item signatures for functions

struct L<F>(F) where F: Fn() -> _;
//~^ ERROR the type placeholder `_` is not allowed within types on item signatures
//~^ ERROR the type placeholder `_` is not allowed within types on item signatures for structs
struct M<F> where F: Fn() -> _ {
//~^ ERROR the type placeholder `_` is not allowed within types on item signatures
//~^ ERROR the type placeholder `_` is not allowed within types on item signatures for structs
a: F,
}
enum N<F> where F: Fn() -> _ {
//~^ ERROR the type placeholder `_` is not allowed within types on item signatures
//~^ ERROR the type placeholder `_` is not allowed within types on item signatures for enums
Foo(F),
}

union O<F> where F: Fn() -> _ {
//~^ ERROR the type placeholder `_` is not allowed within types on item signatures
//~^ ERROR the type placeholder `_` is not allowed within types on item signatures for unions
foo: F,
}

trait P<F> where F: Fn() -> _ {
//~^ ERROR the type placeholder `_` is not allowed within types on item signatures
//~^ ERROR the type placeholder `_` is not allowed within types on item signatures for traits
}

trait Q {
fn foo<F>(_: F) where F: Fn() -> _ {}
//~^ ERROR the type placeholder `_` is not allowed within types on item signatures
//~^ ERROR the type placeholder `_` is not allowed within types on item signatures for functions
}

fn main() {}
Loading

0 comments on commit af9e5d1

Please sign in to comment.