Skip to content

typeck: report placeholder type error w/out span #74270

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

Merged
Merged
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
4 changes: 2 additions & 2 deletions src/librustc_typeck/astconv.rs
Original file line number Diff line number Diff line change
@@ -3049,14 +3049,14 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
let bare_fn_ty =
ty::Binder::bind(tcx.mk_fn_sig(input_tys, output_ty, decl.c_variadic, unsafety, abi));

if let (false, Some(ident_span)) = (self.allow_ty_infer(), ident_span) {
if !self.allow_ty_infer() {
// We always collect the spans for placeholder types when evaluating `fn`s, but we
// only want to emit an error complaining about them if infer types (`_`) are not
// allowed. `allow_ty_infer` gates this behavior. We check for the presence of
// `ident_span` to not emit an error twice when we have `fn foo(_: fn() -> _)`.
crate::collect::placeholder_type_error(
tcx,
ident_span.shrink_to_hi(),
ident_span.map(|sp| sp.shrink_to_hi()),
&generics.params[..],
visitor.0,
true,
16 changes: 10 additions & 6 deletions src/librustc_typeck/collect.rs
Original file line number Diff line number Diff line change
@@ -129,20 +129,23 @@ struct CollectItemTypesVisitor<'tcx> {
/// all already existing generic type parameters to avoid suggesting a name that is already in use.
crate fn placeholder_type_error(
tcx: TyCtxt<'tcx>,
span: Span,
span: Option<Span>,
generics: &[hir::GenericParam<'_>],
placeholder_types: Vec<Span>,
suggest: bool,
) {
if placeholder_types.is_empty() {
return;
}
let type_name = generics.next_type_param_name(None);

let type_name = generics.next_type_param_name(None);
let mut sugg: Vec<_> =
placeholder_types.iter().map(|sp| (*sp, (*type_name).to_string())).collect();

if generics.is_empty() {
sugg.push((span, format!("<{}>", type_name)));
if let Some(span) = span {
sugg.push((span, format!("<{}>", type_name)));
}
} else if let Some(arg) = generics.iter().find(|arg| match arg.name {
hir::ParamName::Plain(Ident { name: kw::Underscore, .. }) => true,
_ => false,
@@ -158,6 +161,7 @@ crate fn placeholder_type_error(
format!(", {}", type_name),
));
}

let mut err = bad_placeholder_type(tcx, placeholder_types);
if suggest {
err.multipart_suggestion(
@@ -186,7 +190,7 @@ 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, generics.span, &generics.params[..], visitor.0, suggest);
placeholder_type_error(tcx, Some(generics.span), &generics.params[..], visitor.0, suggest);
}

impl Visitor<'tcx> for CollectItemTypesVisitor<'tcx> {
@@ -722,7 +726,7 @@ fn convert_trait_item(tcx: TyCtxt<'_>, trait_item_id: hir::HirId) {
// Account for `const C: _;` and `type T = _;`.
let mut visitor = PlaceholderHirTyCollector::default();
visitor.visit_trait_item(trait_item);
placeholder_type_error(tcx, DUMMY_SP, &[], visitor.0, false);
placeholder_type_error(tcx, None, &[], visitor.0, false);
}

hir::TraitItemKind::Type(_, None) => {}
@@ -745,7 +749,7 @@ fn convert_impl_item(tcx: TyCtxt<'_>, impl_item_id: hir::HirId) {
// Account for `type T = _;`
let mut visitor = PlaceholderHirTyCollector::default();
visitor.visit_impl_item(impl_item);
placeholder_type_error(tcx, DUMMY_SP, &[], visitor.0, false);
placeholder_type_error(tcx, None, &[], visitor.0, false);
}
hir::ImplItemKind::Const(..) => {}
}
4 changes: 4 additions & 0 deletions src/test/ui/issues/issue-74086.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
fn main() {
static BUG: fn(_) -> u8 = |_| 8;
//~^ ERROR the type placeholder `_` is not allowed within types on item signatures [E0121]
}
12 changes: 12 additions & 0 deletions src/test/ui/issues/issue-74086.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
error[E0121]: the type placeholder `_` is not allowed within types on item signatures
--> $DIR/issue-74086.rs:2:20
|
LL | static BUG: fn(_) -> u8 = |_| 8;
| ^
| |
| not allowed in type signatures
| help: use type parameters instead: `T`

error: aborting due to previous error

For more information about this error, try `rustc --explain E0121`.
2 changes: 2 additions & 0 deletions src/test/ui/typeck/typeck_type_placeholder_item.rs
Original file line number Diff line number Diff line change
@@ -32,6 +32,7 @@ fn test7(x: _) { let _x: usize = x; }

fn test8(_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
Comment on lines 33 to +35
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunate.


struct Test9;

@@ -98,6 +99,7 @@ pub fn main() {

fn fn_test8(_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

struct FnTest9;

128 changes: 73 additions & 55 deletions src/test/ui/typeck/typeck_type_placeholder_item.stderr

Large diffs are not rendered by default.