Rollup merge of #81914 - kper:fixing-81885, r=estebank
Fixing bad suggestion for `_` in `const` type when a function #81885 Closes #81885 ``` error[E0121]: the type placeholder `_` is not allowed within types on item signatures --> $DIR/typeck_type_placeholder_item_help.rs:13:22 | LL | const TEST4: fn() -> _ = 42; | ^ | | | not allowed in type signatures | help: use type parameters instead: `T` ``` Do not show the suggestion `help: use type parameters instead: T` when `fn`
This commit is contained in:
commit
a6809d00ae
@ -2191,12 +2191,14 @@ fn ast_ty_to_ty_inner(&self, ast_ty: &hir::Ty<'_>, borrowed: bool) -> Ty<'tcx> {
|
||||
}
|
||||
hir::TyKind::BareFn(ref bf) => {
|
||||
require_c_abi_if_c_variadic(tcx, &bf.decl, bf.abi, ast_ty.span);
|
||||
|
||||
tcx.mk_fn_ptr(self.ty_of_fn(
|
||||
bf.unsafety,
|
||||
bf.abi,
|
||||
&bf.decl,
|
||||
&hir::Generics::empty(),
|
||||
None,
|
||||
Some(ast_ty),
|
||||
))
|
||||
}
|
||||
hir::TyKind::TraitObject(ref bounds, ref lifetime) => {
|
||||
@ -2336,6 +2338,7 @@ pub fn ty_of_fn(
|
||||
decl: &hir::FnDecl<'_>,
|
||||
generics: &hir::Generics<'_>,
|
||||
ident_span: Option<Span>,
|
||||
hir_ty: Option<&hir::Ty<'_>>,
|
||||
) -> ty::PolyFnSig<'tcx> {
|
||||
debug!("ty_of_fn");
|
||||
|
||||
@ -2367,12 +2370,14 @@ pub fn ty_of_fn(
|
||||
// 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.map(|sp| sp.shrink_to_hi()),
|
||||
&generics.params[..],
|
||||
visitor.0,
|
||||
true,
|
||||
hir_ty,
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -502,6 +502,7 @@ fn typeck_with_fallback<'tcx>(
|
||||
decl,
|
||||
&hir::Generics::empty(),
|
||||
None,
|
||||
None,
|
||||
)
|
||||
} else {
|
||||
tcx.fn_sig(def_id)
|
||||
|
@ -143,6 +143,7 @@ struct CollectItemTypesVisitor<'tcx> {
|
||||
generics: &[hir::GenericParam<'_>],
|
||||
placeholder_types: Vec<Span>,
|
||||
suggest: bool,
|
||||
hir_ty: Option<&hir::Ty<'_>>,
|
||||
) {
|
||||
if placeholder_types.is_empty() {
|
||||
return;
|
||||
@ -173,12 +174,40 @@ struct CollectItemTypesVisitor<'tcx> {
|
||||
}
|
||||
|
||||
let mut err = bad_placeholder_type(tcx, placeholder_types);
|
||||
|
||||
// Suggest, but only if it is not a function in const or static
|
||||
if suggest {
|
||||
err.multipart_suggestion(
|
||||
"use type parameters instead",
|
||||
sugg,
|
||||
Applicability::HasPlaceholders,
|
||||
);
|
||||
let mut is_fn = false;
|
||||
let mut is_const = false;
|
||||
let mut is_static = false;
|
||||
|
||||
if let Some(hir_ty) = hir_ty {
|
||||
if let hir::TyKind::BareFn(_) = hir_ty.kind {
|
||||
is_fn = true;
|
||||
|
||||
// Check if parent is const or static
|
||||
let parent_id = tcx.hir().get_parent_node(hir_ty.hir_id);
|
||||
let parent_node = tcx.hir().get(parent_id);
|
||||
|
||||
if let hir::Node::Item(item) = parent_node {
|
||||
if let hir::ItemKind::Const(_, _) = item.kind {
|
||||
is_const = true;
|
||||
} else if let hir::ItemKind::Static(_, _, _) = item.kind {
|
||||
is_static = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// if function is wrapped around a const or static,
|
||||
// then don't show the suggestion
|
||||
if !(is_fn && (is_const || is_static)) {
|
||||
err.multipart_suggestion(
|
||||
"use type parameters instead",
|
||||
sugg,
|
||||
Applicability::HasPlaceholders,
|
||||
);
|
||||
}
|
||||
}
|
||||
err.emit();
|
||||
}
|
||||
@ -200,7 +229,14 @@ 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);
|
||||
placeholder_type_error(
|
||||
tcx,
|
||||
Some(generics.span),
|
||||
&generics.params[..],
|
||||
visitor.0,
|
||||
suggest,
|
||||
None,
|
||||
);
|
||||
}
|
||||
|
||||
impl Visitor<'tcx> for CollectItemTypesVisitor<'tcx> {
|
||||
@ -682,6 +718,7 @@ fn convert_item(tcx: TyCtxt<'_>, item_id: hir::HirId) {
|
||||
let it = tcx.hir().expect_item(item_id);
|
||||
debug!("convert: item {} with id {}", it.ident, it.hir_id);
|
||||
let def_id = tcx.hir().local_def_id(item_id);
|
||||
|
||||
match it.kind {
|
||||
// These don't define types.
|
||||
hir::ItemKind::ExternCrate(_)
|
||||
@ -787,7 +824,7 @@ fn convert_trait_item(tcx: TyCtxt<'_>, trait_item_id: hir::HirId) {
|
||||
// Account for `const C: _;`.
|
||||
let mut visitor = PlaceholderHirTyCollector::default();
|
||||
visitor.visit_trait_item(trait_item);
|
||||
placeholder_type_error(tcx, None, &[], visitor.0, false);
|
||||
placeholder_type_error(tcx, None, &[], visitor.0, false, None);
|
||||
}
|
||||
|
||||
hir::TraitItemKind::Type(_, Some(_)) => {
|
||||
@ -796,7 +833,7 @@ fn convert_trait_item(tcx: TyCtxt<'_>, trait_item_id: hir::HirId) {
|
||||
// Account for `type T = _;`.
|
||||
let mut visitor = PlaceholderHirTyCollector::default();
|
||||
visitor.visit_trait_item(trait_item);
|
||||
placeholder_type_error(tcx, None, &[], visitor.0, false);
|
||||
placeholder_type_error(tcx, None, &[], visitor.0, false, None);
|
||||
}
|
||||
|
||||
hir::TraitItemKind::Type(_, None) => {
|
||||
@ -805,7 +842,8 @@ fn convert_trait_item(tcx: TyCtxt<'_>, trait_item_id: hir::HirId) {
|
||||
// even if there is no concrete type.
|
||||
let mut visitor = PlaceholderHirTyCollector::default();
|
||||
visitor.visit_trait_item(trait_item);
|
||||
placeholder_type_error(tcx, None, &[], visitor.0, false);
|
||||
|
||||
placeholder_type_error(tcx, None, &[], visitor.0, false, None);
|
||||
}
|
||||
};
|
||||
|
||||
@ -826,7 +864,8 @@ 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, None, &[], visitor.0, false);
|
||||
|
||||
placeholder_type_error(tcx, None, &[], visitor.0, false, None);
|
||||
}
|
||||
hir::ImplItemKind::Const(..) => {}
|
||||
}
|
||||
@ -1654,6 +1693,7 @@ fn fn_sig(tcx: TyCtxt<'_>, def_id: DefId) -> ty::PolyFnSig<'_> {
|
||||
&sig.decl,
|
||||
&generics,
|
||||
Some(ident.span),
|
||||
None,
|
||||
),
|
||||
}
|
||||
}
|
||||
@ -1663,9 +1703,15 @@ fn fn_sig(tcx: TyCtxt<'_>, def_id: DefId) -> ty::PolyFnSig<'_> {
|
||||
ident,
|
||||
generics,
|
||||
..
|
||||
}) => {
|
||||
AstConv::ty_of_fn(&icx, header.unsafety, header.abi, decl, &generics, Some(ident.span))
|
||||
}
|
||||
}) => AstConv::ty_of_fn(
|
||||
&icx,
|
||||
header.unsafety,
|
||||
header.abi,
|
||||
decl,
|
||||
&generics,
|
||||
Some(ident.span),
|
||||
None,
|
||||
),
|
||||
|
||||
ForeignItem(&hir::ForeignItem {
|
||||
kind: ForeignItemKind::Fn(ref fn_decl, _, _),
|
||||
@ -2335,6 +2381,7 @@ fn compute_sig_of_foreign_fn_decl<'tcx>(
|
||||
decl,
|
||||
&hir::Generics::empty(),
|
||||
Some(ident.span),
|
||||
None,
|
||||
);
|
||||
|
||||
// Feature gate SIMD types in FFI, since I am not sure that the
|
||||
|
@ -2,10 +2,7 @@ error[E0121]: the type placeholder `_` is not allowed within types on item signa
|
||||
--> $DIR/issue-74086.rs:2:20
|
||||
|
|
||||
LL | static BUG: fn(_) -> u8 = |_| 8;
|
||||
| ^
|
||||
| |
|
||||
| not allowed in type signatures
|
||||
| help: use type parameters instead: `T`
|
||||
| ^ not allowed in type signatures
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
10
src/test/ui/issues/issue-81885.rs
Normal file
10
src/test/ui/issues/issue-81885.rs
Normal file
@ -0,0 +1,10 @@
|
||||
const TEST4: fn() -> _ = 42;
|
||||
//~^ ERROR the type placeholder `_` is not allowed within types on item
|
||||
//signatures
|
||||
|
||||
fn main() {
|
||||
const TEST5: fn() -> _ = 42;
|
||||
//~^ ERROR the type placeholder `_` is not allowed within types on item
|
||||
//signatures
|
||||
|
||||
}
|
15
src/test/ui/issues/issue-81885.stderr
Normal file
15
src/test/ui/issues/issue-81885.stderr
Normal file
@ -0,0 +1,15 @@
|
||||
error[E0121]: the type placeholder `_` is not allowed within types on item signatures
|
||||
--> $DIR/issue-81885.rs:1:22
|
||||
|
|
||||
LL | const TEST4: fn() -> _ = 42;
|
||||
| ^ not allowed in type signatures
|
||||
|
||||
error[E0121]: the type placeholder `_` is not allowed within types on item signatures
|
||||
--> $DIR/issue-81885.rs:6:26
|
||||
|
|
||||
LL | const TEST5: fn() -> _ = 42;
|
||||
| ^ not allowed in type signatures
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0121`.
|
@ -29,10 +29,7 @@ error[E0121]: the type placeholder `_` is not allowed within types on item signa
|
||||
--> $DIR/typeck_type_placeholder_item_help.rs:13:22
|
||||
|
|
||||
LL | const TEST4: fn() -> _ = 42;
|
||||
| ^
|
||||
| |
|
||||
| not allowed in type signatures
|
||||
| help: use type parameters instead: `T`
|
||||
| ^ not allowed in type signatures
|
||||
|
||||
error[E0121]: the type placeholder `_` is not allowed within types on item signatures
|
||||
--> $DIR/typeck_type_placeholder_item_help.rs:17:18
|
||||
|
Loading…
Reference in New Issue
Block a user