generic_arg_infer: placeholder in signature err
This commit is contained in:
parent
621e60a54f
commit
b2d8f0c77d
38 changed files with 402 additions and 235 deletions
|
@ -6,7 +6,7 @@ mod errors;
|
|||
mod generics;
|
||||
|
||||
use crate::bounds::Bounds;
|
||||
use crate::collect::PlaceholderHirTyCollector;
|
||||
use crate::collect::HirPlaceholderCollector;
|
||||
use crate::errors::{
|
||||
AmbiguousLifetimeBound, MultipleRelaxedDefaultBounds, TraitObjectDeclaredWithNoTraits,
|
||||
TypeofReservedKeywordUsed, ValueOfAssociatedStructAlreadySpecified,
|
||||
|
@ -2478,7 +2478,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
debug!(?bound_vars);
|
||||
|
||||
// We proactively collect all the inferred type params to emit a single error per fn def.
|
||||
let mut visitor = PlaceholderHirTyCollector::default();
|
||||
let mut visitor = HirPlaceholderCollector::default();
|
||||
for ty in decl.inputs {
|
||||
visitor.visit_ty(ty);
|
||||
}
|
||||
|
|
|
@ -112,9 +112,9 @@ pub struct ItemCtxt<'tcx> {
|
|||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#[derive(Default)]
|
||||
crate struct PlaceholderHirTyCollector(crate Vec<Span>);
|
||||
crate struct HirPlaceholderCollector(crate Vec<Span>);
|
||||
|
||||
impl<'v> Visitor<'v> for PlaceholderHirTyCollector {
|
||||
impl<'v> Visitor<'v> for HirPlaceholderCollector {
|
||||
fn visit_ty(&mut self, t: &'v hir::Ty<'v>) {
|
||||
if let hir::TyKind::Infer = t.kind {
|
||||
self.0.push(t.span);
|
||||
|
@ -131,6 +131,12 @@ impl<'v> Visitor<'v> for PlaceholderHirTyCollector {
|
|||
_ => {}
|
||||
}
|
||||
}
|
||||
fn visit_array_length(&mut self, length: &'v hir::ArrayLen) {
|
||||
if let &hir::ArrayLen::Infer(_, span) = length {
|
||||
self.0.push(span);
|
||||
}
|
||||
intravisit::walk_array_len(self, length)
|
||||
}
|
||||
}
|
||||
|
||||
struct CollectItemTypesVisitor<'tcx> {
|
||||
|
@ -175,7 +181,7 @@ crate fn placeholder_type_error<'tcx>(
|
|||
sugg.push((span, format!(", {}", type_name)));
|
||||
}
|
||||
|
||||
let mut err = bad_placeholder(tcx, "type", placeholder_types, kind);
|
||||
let mut err = bad_placeholder(tcx, placeholder_types, kind);
|
||||
|
||||
// Suggest, but only if it is not a function in const or static
|
||||
if suggest {
|
||||
|
@ -233,7 +239,7 @@ fn reject_placeholder_type_signatures_in_item<'tcx>(
|
|||
_ => return,
|
||||
};
|
||||
|
||||
let mut visitor = PlaceholderHirTyCollector::default();
|
||||
let mut visitor = HirPlaceholderCollector::default();
|
||||
visitor.visit_item(item);
|
||||
|
||||
placeholder_type_error(
|
||||
|
@ -311,7 +317,6 @@ impl<'tcx> Visitor<'tcx> for CollectItemTypesVisitor<'tcx> {
|
|||
|
||||
fn bad_placeholder<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
placeholder_kind: &'static str,
|
||||
mut spans: Vec<Span>,
|
||||
kind: &'static str,
|
||||
) -> rustc_errors::DiagnosticBuilder<'tcx> {
|
||||
|
@ -322,8 +327,7 @@ fn bad_placeholder<'tcx>(
|
|||
tcx.sess,
|
||||
spans.clone(),
|
||||
E0121,
|
||||
"the {} placeholder `_` is not allowed within types on item signatures for {}",
|
||||
placeholder_kind,
|
||||
"the placeholder `_` is not allowed within types on item signatures for {}",
|
||||
kind
|
||||
);
|
||||
for span in spans {
|
||||
|
@ -737,7 +741,7 @@ fn convert_item(tcx: TyCtxt<'_>, item_id: hir::ItemId) {
|
|||
match item.kind {
|
||||
hir::ForeignItemKind::Fn(..) => tcx.ensure().fn_sig(item.def_id),
|
||||
hir::ForeignItemKind::Static(..) => {
|
||||
let mut visitor = PlaceholderHirTyCollector::default();
|
||||
let mut visitor = HirPlaceholderCollector::default();
|
||||
visitor.visit_foreign_item(item);
|
||||
placeholder_type_error(
|
||||
tcx,
|
||||
|
@ -820,7 +824,7 @@ fn convert_item(tcx: TyCtxt<'_>, item_id: hir::ItemId) {
|
|||
hir::ItemKind::Const(ty, ..) | hir::ItemKind::Static(ty, ..) => {
|
||||
// (#75889): Account for `const C: dyn Fn() -> _ = "";`
|
||||
if let hir::TyKind::TraitObject(..) = ty.kind {
|
||||
let mut visitor = PlaceholderHirTyCollector::default();
|
||||
let mut visitor = HirPlaceholderCollector::default();
|
||||
visitor.visit_item(it);
|
||||
placeholder_type_error(
|
||||
tcx,
|
||||
|
@ -856,7 +860,7 @@ fn convert_trait_item(tcx: TyCtxt<'_>, trait_item_id: hir::TraitItemId) {
|
|||
hir::TraitItemKind::Const(..) => {
|
||||
tcx.ensure().type_of(trait_item_id.def_id);
|
||||
// Account for `const C: _;`.
|
||||
let mut visitor = PlaceholderHirTyCollector::default();
|
||||
let mut visitor = HirPlaceholderCollector::default();
|
||||
visitor.visit_trait_item(trait_item);
|
||||
placeholder_type_error(tcx, None, &[], visitor.0, false, None, "constant");
|
||||
}
|
||||
|
@ -865,7 +869,7 @@ fn convert_trait_item(tcx: TyCtxt<'_>, trait_item_id: hir::TraitItemId) {
|
|||
tcx.ensure().item_bounds(trait_item_id.def_id);
|
||||
tcx.ensure().type_of(trait_item_id.def_id);
|
||||
// Account for `type T = _;`.
|
||||
let mut visitor = PlaceholderHirTyCollector::default();
|
||||
let mut visitor = HirPlaceholderCollector::default();
|
||||
visitor.visit_trait_item(trait_item);
|
||||
placeholder_type_error(tcx, None, &[], visitor.0, false, None, "associated type");
|
||||
}
|
||||
|
@ -874,7 +878,7 @@ fn convert_trait_item(tcx: TyCtxt<'_>, trait_item_id: hir::TraitItemId) {
|
|||
tcx.ensure().item_bounds(trait_item_id.def_id);
|
||||
// #74612: Visit and try to find bad placeholders
|
||||
// even if there is no concrete type.
|
||||
let mut visitor = PlaceholderHirTyCollector::default();
|
||||
let mut visitor = HirPlaceholderCollector::default();
|
||||
visitor.visit_trait_item(trait_item);
|
||||
|
||||
placeholder_type_error(tcx, None, &[], visitor.0, false, None, "associated type");
|
||||
|
@ -896,7 +900,7 @@ fn convert_impl_item(tcx: TyCtxt<'_>, impl_item_id: hir::ImplItemId) {
|
|||
}
|
||||
hir::ImplItemKind::TyAlias(_) => {
|
||||
// Account for `type T = _;`
|
||||
let mut visitor = PlaceholderHirTyCollector::default();
|
||||
let mut visitor = HirPlaceholderCollector::default();
|
||||
visitor.visit_impl_item(impl_item);
|
||||
|
||||
placeholder_type_error(tcx, None, &[], visitor.0, false, None, "associated type");
|
||||
|
@ -1816,10 +1820,14 @@ fn are_suggestable_generic_args(generic_args: &[hir::GenericArg<'_>]) -> bool {
|
|||
/// Whether `ty` is a type with `_` placeholders that can be inferred. Used in diagnostics only to
|
||||
/// use inference to provide suggestions for the appropriate type if possible.
|
||||
fn is_suggestable_infer_ty(ty: &hir::Ty<'_>) -> bool {
|
||||
debug!(?ty);
|
||||
use hir::TyKind::*;
|
||||
match &ty.kind {
|
||||
Infer => true,
|
||||
Slice(ty) | Array(ty, _) => is_suggestable_infer_ty(ty),
|
||||
Slice(ty) => is_suggestable_infer_ty(ty),
|
||||
Array(ty, length) => {
|
||||
is_suggestable_infer_ty(ty) || matches!(length, hir::ArrayLen::Infer(_, _))
|
||||
}
|
||||
Tup(tys) => tys.iter().any(is_suggestable_infer_ty),
|
||||
Ptr(mut_ty) | Rptr(_, mut_ty) => is_suggestable_infer_ty(mut_ty.ty),
|
||||
OpaqueDef(_, generic_args) => are_suggestable_generic_args(generic_args),
|
||||
|
@ -1871,9 +1879,9 @@ fn fn_sig(tcx: TyCtxt<'_>, def_id: DefId) -> ty::PolyFnSig<'_> {
|
|||
});
|
||||
let fn_sig = ty::Binder::dummy(fn_sig);
|
||||
|
||||
let mut visitor = PlaceholderHirTyCollector::default();
|
||||
let mut visitor = HirPlaceholderCollector::default();
|
||||
visitor.visit_ty(ty);
|
||||
let mut diag = bad_placeholder(tcx, "type", visitor.0, "return type");
|
||||
let mut diag = bad_placeholder(tcx, visitor.0, "return type");
|
||||
let ret_ty = fn_sig.skip_binder().output();
|
||||
if !ret_ty.references_error() {
|
||||
if !ret_ty.is_closure() {
|
||||
|
|
|
@ -750,7 +750,7 @@ fn infer_placeholder_type<'a>(
|
|||
err.emit();
|
||||
}
|
||||
None => {
|
||||
let mut diag = bad_placeholder(tcx, "type", vec![span], kind);
|
||||
let mut diag = bad_placeholder(tcx, vec![span], kind);
|
||||
|
||||
if !ty.references_error() {
|
||||
let mut mk_nameable = MakeNameable::new(tcx);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue