Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Specify the kind of the item for E0121 #86223

Merged
merged 3 commits into from
Jun 23, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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