Skip to content

Commit fba2f88

Browse files
committed
Implementing more sophisticated filter for fn in const or static
1 parent 49fc41f commit fba2f88

File tree

3 files changed

+59
-17
lines changed

3 files changed

+59
-17
lines changed

compiler/rustc_typeck/src/astconv/mod.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -2145,12 +2145,14 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
21452145
}
21462146
hir::TyKind::BareFn(ref bf) => {
21472147
require_c_abi_if_c_variadic(tcx, &bf.decl, bf.abi, ast_ty.span);
2148+
21482149
tcx.mk_fn_ptr(self.ty_of_fn(
21492150
bf.unsafety,
21502151
bf.abi,
21512152
&bf.decl,
21522153
&hir::Generics::empty(),
21532154
None,
2155+
Some(ast_ty),
21542156
))
21552157
}
21562158
hir::TyKind::TraitObject(ref bounds, ref lifetime) => {
@@ -2290,6 +2292,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
22902292
decl: &hir::FnDecl<'_>,
22912293
generics: &hir::Generics<'_>,
22922294
ident_span: Option<Span>,
2295+
hir_ty: Option<&hir::Ty<'_>>,
22932296
) -> ty::PolyFnSig<'tcx> {
22942297
debug!("ty_of_fn");
22952298

@@ -2321,13 +2324,14 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
23212324
// only want to emit an error complaining about them if infer types (`_`) are not
23222325
// allowed. `allow_ty_infer` gates this behavior. We check for the presence of
23232326
// `ident_span` to not emit an error twice when we have `fn foo(_: fn() -> _)`.
2327+
23242328
crate::collect::placeholder_type_error(
23252329
tcx,
23262330
ident_span.map(|sp| sp.shrink_to_hi()),
23272331
&generics.params[..],
23282332
visitor.0,
23292333
true,
2330-
true,
2334+
hir_ty,
23312335
);
23322336
}
23332337

compiler/rustc_typeck/src/check/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -502,6 +502,7 @@ fn typeck_with_fallback<'tcx>(
502502
decl,
503503
&hir::Generics::empty(),
504504
None,
505+
None,
505506
)
506507
} else {
507508
tcx.fn_sig(def_id)

compiler/rustc_typeck/src/collect.rs

+53-16
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ crate fn placeholder_type_error(
141141
generics: &[hir::GenericParam<'_>],
142142
placeholder_types: Vec<Span>,
143143
suggest: bool,
144-
is_fn: bool,
144+
hir_ty: Option<&hir::Ty<'_>>,
145145
) {
146146
if placeholder_types.is_empty() {
147147
return;
@@ -173,13 +173,39 @@ crate fn placeholder_type_error(
173173

174174
let mut err = bad_placeholder_type(tcx, placeholder_types);
175175

176-
// Suggest, but only if it is not a function
177-
if suggest && !is_fn {
178-
err.multipart_suggestion(
179-
"use type parameters instead",
180-
sugg,
181-
Applicability::HasPlaceholders,
182-
);
176+
// Suggest, but only if it is not a function in const or static
177+
if suggest {
178+
let mut is_fn = false;
179+
let mut is_const = false;
180+
let mut is_static = false;
181+
182+
if let Some(hir_ty) = hir_ty {
183+
if let hir::TyKind::BareFn(_) = hir_ty.kind {
184+
is_fn = true;
185+
186+
// Check if parent is const or static
187+
let parent_id = tcx.hir().get_parent_node(hir_ty.hir_id);
188+
let parent_node = tcx.hir().get(parent_id);
189+
190+
if let hir::Node::Item(item) = parent_node {
191+
if let hir::ItemKind::Const(_, _) = item.kind {
192+
is_const = true;
193+
} else if let hir::ItemKind::Static(_, _, _) = item.kind {
194+
is_static = true;
195+
}
196+
}
197+
}
198+
}
199+
200+
// if function is wrapped around a const or static,
201+
// then don't show the suggestion
202+
if !(is_fn && (is_const || is_static)) {
203+
err.multipart_suggestion(
204+
"use type parameters instead",
205+
sugg,
206+
Applicability::HasPlaceholders,
207+
);
208+
}
183209
}
184210
err.emit();
185211
}
@@ -207,7 +233,7 @@ fn reject_placeholder_type_signatures_in_item(tcx: TyCtxt<'tcx>, item: &'tcx hir
207233
&generics.params[..],
208234
visitor.0,
209235
suggest,
210-
false,
236+
None,
211237
);
212238
}
213239

@@ -648,6 +674,7 @@ fn convert_item(tcx: TyCtxt<'_>, item_id: hir::HirId) {
648674
let it = tcx.hir().expect_item(item_id);
649675
debug!("convert: item {} with id {}", it.ident, it.hir_id);
650676
let def_id = tcx.hir().local_def_id(item_id);
677+
651678
match it.kind {
652679
// These don't define types.
653680
hir::ItemKind::ExternCrate(_)
@@ -753,7 +780,7 @@ fn convert_trait_item(tcx: TyCtxt<'_>, trait_item_id: hir::HirId) {
753780
// Account for `const C: _;`.
754781
let mut visitor = PlaceholderHirTyCollector::default();
755782
visitor.visit_trait_item(trait_item);
756-
placeholder_type_error(tcx, None, &[], visitor.0, false, false);
783+
placeholder_type_error(tcx, None, &[], visitor.0, false, None);
757784
}
758785

759786
hir::TraitItemKind::Type(_, Some(_)) => {
@@ -762,7 +789,7 @@ fn convert_trait_item(tcx: TyCtxt<'_>, trait_item_id: hir::HirId) {
762789
// Account for `type T = _;`.
763790
let mut visitor = PlaceholderHirTyCollector::default();
764791
visitor.visit_trait_item(trait_item);
765-
placeholder_type_error(tcx, None, &[], visitor.0, false, false);
792+
placeholder_type_error(tcx, None, &[], visitor.0, false, None);
766793
}
767794

768795
hir::TraitItemKind::Type(_, None) => {
@@ -771,7 +798,8 @@ fn convert_trait_item(tcx: TyCtxt<'_>, trait_item_id: hir::HirId) {
771798
// even if there is no concrete type.
772799
let mut visitor = PlaceholderHirTyCollector::default();
773800
visitor.visit_trait_item(trait_item);
774-
placeholder_type_error(tcx, None, &[], visitor.0, false, false);
801+
802+
placeholder_type_error(tcx, None, &[], visitor.0, false, None);
775803
}
776804
};
777805

@@ -792,7 +820,8 @@ fn convert_impl_item(tcx: TyCtxt<'_>, impl_item_id: hir::HirId) {
792820
// Account for `type T = _;`
793821
let mut visitor = PlaceholderHirTyCollector::default();
794822
visitor.visit_impl_item(impl_item);
795-
placeholder_type_error(tcx, None, &[], visitor.0, false, false);
823+
824+
placeholder_type_error(tcx, None, &[], visitor.0, false, None);
796825
}
797826
hir::ImplItemKind::Const(..) => {}
798827
}
@@ -1583,6 +1612,7 @@ fn fn_sig(tcx: TyCtxt<'_>, def_id: DefId) -> ty::PolyFnSig<'_> {
15831612
&sig.decl,
15841613
&generics,
15851614
Some(ident.span),
1615+
None,
15861616
),
15871617
}
15881618
}
@@ -1592,9 +1622,15 @@ fn fn_sig(tcx: TyCtxt<'_>, def_id: DefId) -> ty::PolyFnSig<'_> {
15921622
ident,
15931623
generics,
15941624
..
1595-
}) => {
1596-
AstConv::ty_of_fn(&icx, header.unsafety, header.abi, decl, &generics, Some(ident.span))
1597-
}
1625+
}) => AstConv::ty_of_fn(
1626+
&icx,
1627+
header.unsafety,
1628+
header.abi,
1629+
decl,
1630+
&generics,
1631+
Some(ident.span),
1632+
None,
1633+
),
15981634

15991635
ForeignItem(&hir::ForeignItem {
16001636
kind: ForeignItemKind::Fn(ref fn_decl, _, _),
@@ -2264,6 +2300,7 @@ fn compute_sig_of_foreign_fn_decl<'tcx>(
22642300
decl,
22652301
&hir::Generics::empty(),
22662302
Some(ident.span),
2303+
None,
22672304
);
22682305

22692306
// Feature gate SIMD types in FFI, since I am not sure that the

0 commit comments

Comments
 (0)