Implementing more sophisticated filter for fn in const or static
This commit is contained in:
parent
49fc41f047
commit
fba2f883f3
3 changed files with 59 additions and 17 deletions
|
@ -2145,12 +2145,14 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
}
|
}
|
||||||
hir::TyKind::BareFn(ref bf) => {
|
hir::TyKind::BareFn(ref bf) => {
|
||||||
require_c_abi_if_c_variadic(tcx, &bf.decl, bf.abi, ast_ty.span);
|
require_c_abi_if_c_variadic(tcx, &bf.decl, bf.abi, ast_ty.span);
|
||||||
|
|
||||||
tcx.mk_fn_ptr(self.ty_of_fn(
|
tcx.mk_fn_ptr(self.ty_of_fn(
|
||||||
bf.unsafety,
|
bf.unsafety,
|
||||||
bf.abi,
|
bf.abi,
|
||||||
&bf.decl,
|
&bf.decl,
|
||||||
&hir::Generics::empty(),
|
&hir::Generics::empty(),
|
||||||
None,
|
None,
|
||||||
|
Some(ast_ty),
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
hir::TyKind::TraitObject(ref bounds, ref lifetime) => {
|
hir::TyKind::TraitObject(ref bounds, ref lifetime) => {
|
||||||
|
@ -2290,6 +2292,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
decl: &hir::FnDecl<'_>,
|
decl: &hir::FnDecl<'_>,
|
||||||
generics: &hir::Generics<'_>,
|
generics: &hir::Generics<'_>,
|
||||||
ident_span: Option<Span>,
|
ident_span: Option<Span>,
|
||||||
|
hir_ty: Option<&hir::Ty<'_>>,
|
||||||
) -> ty::PolyFnSig<'tcx> {
|
) -> ty::PolyFnSig<'tcx> {
|
||||||
debug!("ty_of_fn");
|
debug!("ty_of_fn");
|
||||||
|
|
||||||
|
@ -2321,13 +2324,14 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
// only want to emit an error complaining about them if infer types (`_`) are not
|
// 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
|
// 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() -> _)`.
|
// `ident_span` to not emit an error twice when we have `fn foo(_: fn() -> _)`.
|
||||||
|
|
||||||
crate::collect::placeholder_type_error(
|
crate::collect::placeholder_type_error(
|
||||||
tcx,
|
tcx,
|
||||||
ident_span.map(|sp| sp.shrink_to_hi()),
|
ident_span.map(|sp| sp.shrink_to_hi()),
|
||||||
&generics.params[..],
|
&generics.params[..],
|
||||||
visitor.0,
|
visitor.0,
|
||||||
true,
|
true,
|
||||||
true,
|
hir_ty,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -502,6 +502,7 @@ fn typeck_with_fallback<'tcx>(
|
||||||
decl,
|
decl,
|
||||||
&hir::Generics::empty(),
|
&hir::Generics::empty(),
|
||||||
None,
|
None,
|
||||||
|
None,
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
tcx.fn_sig(def_id)
|
tcx.fn_sig(def_id)
|
||||||
|
|
|
@ -141,7 +141,7 @@ crate fn placeholder_type_error(
|
||||||
generics: &[hir::GenericParam<'_>],
|
generics: &[hir::GenericParam<'_>],
|
||||||
placeholder_types: Vec<Span>,
|
placeholder_types: Vec<Span>,
|
||||||
suggest: bool,
|
suggest: bool,
|
||||||
is_fn: bool,
|
hir_ty: Option<&hir::Ty<'_>>,
|
||||||
) {
|
) {
|
||||||
if placeholder_types.is_empty() {
|
if placeholder_types.is_empty() {
|
||||||
return;
|
return;
|
||||||
|
@ -173,14 +173,40 @@ crate fn placeholder_type_error(
|
||||||
|
|
||||||
let mut err = bad_placeholder_type(tcx, placeholder_types);
|
let mut err = bad_placeholder_type(tcx, placeholder_types);
|
||||||
|
|
||||||
// Suggest, but only if it is not a function
|
// Suggest, but only if it is not a function in const or static
|
||||||
if suggest && !is_fn {
|
if suggest {
|
||||||
|
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(
|
err.multipart_suggestion(
|
||||||
"use type parameters instead",
|
"use type parameters instead",
|
||||||
sugg,
|
sugg,
|
||||||
Applicability::HasPlaceholders,
|
Applicability::HasPlaceholders,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
err.emit();
|
err.emit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -207,7 +233,7 @@ fn reject_placeholder_type_signatures_in_item(tcx: TyCtxt<'tcx>, item: &'tcx hir
|
||||||
&generics.params[..],
|
&generics.params[..],
|
||||||
visitor.0,
|
visitor.0,
|
||||||
suggest,
|
suggest,
|
||||||
false,
|
None,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -648,6 +674,7 @@ fn convert_item(tcx: TyCtxt<'_>, item_id: hir::HirId) {
|
||||||
let it = tcx.hir().expect_item(item_id);
|
let it = tcx.hir().expect_item(item_id);
|
||||||
debug!("convert: item {} with id {}", it.ident, it.hir_id);
|
debug!("convert: item {} with id {}", it.ident, it.hir_id);
|
||||||
let def_id = tcx.hir().local_def_id(item_id);
|
let def_id = tcx.hir().local_def_id(item_id);
|
||||||
|
|
||||||
match it.kind {
|
match it.kind {
|
||||||
// These don't define types.
|
// These don't define types.
|
||||||
hir::ItemKind::ExternCrate(_)
|
hir::ItemKind::ExternCrate(_)
|
||||||
|
@ -753,7 +780,7 @@ fn convert_trait_item(tcx: TyCtxt<'_>, trait_item_id: hir::HirId) {
|
||||||
// Account for `const C: _;`.
|
// Account for `const C: _;`.
|
||||||
let mut visitor = PlaceholderHirTyCollector::default();
|
let mut visitor = PlaceholderHirTyCollector::default();
|
||||||
visitor.visit_trait_item(trait_item);
|
visitor.visit_trait_item(trait_item);
|
||||||
placeholder_type_error(tcx, None, &[], visitor.0, false, false);
|
placeholder_type_error(tcx, None, &[], visitor.0, false, None);
|
||||||
}
|
}
|
||||||
|
|
||||||
hir::TraitItemKind::Type(_, Some(_)) => {
|
hir::TraitItemKind::Type(_, Some(_)) => {
|
||||||
|
@ -762,7 +789,7 @@ fn convert_trait_item(tcx: TyCtxt<'_>, trait_item_id: hir::HirId) {
|
||||||
// Account for `type T = _;`.
|
// Account for `type T = _;`.
|
||||||
let mut visitor = PlaceholderHirTyCollector::default();
|
let mut visitor = PlaceholderHirTyCollector::default();
|
||||||
visitor.visit_trait_item(trait_item);
|
visitor.visit_trait_item(trait_item);
|
||||||
placeholder_type_error(tcx, None, &[], visitor.0, false, false);
|
placeholder_type_error(tcx, None, &[], visitor.0, false, None);
|
||||||
}
|
}
|
||||||
|
|
||||||
hir::TraitItemKind::Type(_, None) => {
|
hir::TraitItemKind::Type(_, None) => {
|
||||||
|
@ -771,7 +798,8 @@ fn convert_trait_item(tcx: TyCtxt<'_>, trait_item_id: hir::HirId) {
|
||||||
// even if there is no concrete type.
|
// even if there is no concrete type.
|
||||||
let mut visitor = PlaceholderHirTyCollector::default();
|
let mut visitor = PlaceholderHirTyCollector::default();
|
||||||
visitor.visit_trait_item(trait_item);
|
visitor.visit_trait_item(trait_item);
|
||||||
placeholder_type_error(tcx, None, &[], visitor.0, false, false);
|
|
||||||
|
placeholder_type_error(tcx, None, &[], visitor.0, false, None);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -792,7 +820,8 @@ fn convert_impl_item(tcx: TyCtxt<'_>, impl_item_id: hir::HirId) {
|
||||||
// Account for `type T = _;`
|
// Account for `type T = _;`
|
||||||
let mut visitor = PlaceholderHirTyCollector::default();
|
let mut visitor = PlaceholderHirTyCollector::default();
|
||||||
visitor.visit_impl_item(impl_item);
|
visitor.visit_impl_item(impl_item);
|
||||||
placeholder_type_error(tcx, None, &[], visitor.0, false, false);
|
|
||||||
|
placeholder_type_error(tcx, None, &[], visitor.0, false, None);
|
||||||
}
|
}
|
||||||
hir::ImplItemKind::Const(..) => {}
|
hir::ImplItemKind::Const(..) => {}
|
||||||
}
|
}
|
||||||
|
@ -1583,6 +1612,7 @@ fn fn_sig(tcx: TyCtxt<'_>, def_id: DefId) -> ty::PolyFnSig<'_> {
|
||||||
&sig.decl,
|
&sig.decl,
|
||||||
&generics,
|
&generics,
|
||||||
Some(ident.span),
|
Some(ident.span),
|
||||||
|
None,
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1592,9 +1622,15 @@ fn fn_sig(tcx: TyCtxt<'_>, def_id: DefId) -> ty::PolyFnSig<'_> {
|
||||||
ident,
|
ident,
|
||||||
generics,
|
generics,
|
||||||
..
|
..
|
||||||
}) => {
|
}) => AstConv::ty_of_fn(
|
||||||
AstConv::ty_of_fn(&icx, header.unsafety, header.abi, decl, &generics, Some(ident.span))
|
&icx,
|
||||||
}
|
header.unsafety,
|
||||||
|
header.abi,
|
||||||
|
decl,
|
||||||
|
&generics,
|
||||||
|
Some(ident.span),
|
||||||
|
None,
|
||||||
|
),
|
||||||
|
|
||||||
ForeignItem(&hir::ForeignItem {
|
ForeignItem(&hir::ForeignItem {
|
||||||
kind: ForeignItemKind::Fn(ref fn_decl, _, _),
|
kind: ForeignItemKind::Fn(ref fn_decl, _, _),
|
||||||
|
@ -2264,6 +2300,7 @@ fn compute_sig_of_foreign_fn_decl<'tcx>(
|
||||||
decl,
|
decl,
|
||||||
&hir::Generics::empty(),
|
&hir::Generics::empty(),
|
||||||
Some(ident.span),
|
Some(ident.span),
|
||||||
|
None,
|
||||||
);
|
);
|
||||||
|
|
||||||
// Feature gate SIMD types in FFI, since I am not sure that the
|
// Feature gate SIMD types in FFI, since I am not sure that the
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue