Skip to content

Commit

Permalink
generic_arg_infer: placeholder in signature err
Browse files Browse the repository at this point in the history
  • Loading branch information
lcnr committed Jan 5, 2022
1 parent a3e3787 commit c0aa0fa
Show file tree
Hide file tree
Showing 38 changed files with 402 additions and 235 deletions.
4 changes: 2 additions & 2 deletions compiler/rustc_typeck/src/astconv/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -2469,7 +2469,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);
}
Expand Down
40 changes: 24 additions & 16 deletions compiler/rustc_typeck/src/collect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -114,9 +114,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 {
type Map = intravisit::ErasedMap<'v>;

fn nested_visit_map(&mut self) -> NestedVisitorMap<Self::Map> {
Expand All @@ -138,6 +138,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> {
Expand Down Expand Up @@ -182,7 +188,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 {
Expand Down Expand Up @@ -240,7 +246,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(
Expand Down Expand Up @@ -316,7 +322,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> {
Expand All @@ -327,8 +332,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 {
Expand Down Expand Up @@ -743,7 +747,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,
Expand Down Expand Up @@ -826,7 +830,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,
Expand Down Expand Up @@ -862,7 +866,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");
}
Expand All @@ -871,7 +875,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");
}
Expand All @@ -880,7 +884,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");
Expand All @@ -902,7 +906,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");
Expand Down Expand Up @@ -1735,10 +1739,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),
Expand Down Expand Up @@ -1790,9 +1798,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() {
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_typeck/src/collect/type_of.rs
Original file line number Diff line number Diff line change
Expand Up @@ -785,7 +785,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);
Expand Down
12 changes: 0 additions & 12 deletions src/test/ui/const-generics/generic_arg_infer/array-in-sig.rs

This file was deleted.

This file was deleted.

61 changes: 61 additions & 0 deletions src/test/ui/const-generics/generic_arg_infer/in-signature.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
#![crate_type = "rlib"]
#![feature(generic_arg_infer)]

struct Foo<const N: usize>;
struct Bar<T, const N: usize>(T);

fn arr_fn() -> [u8; _] {
//~^ ERROR the placeholder `_` is not allowed within types on item signatures for return types
[0; 3]
}

fn ty_fn() -> Bar<i32, _> {
//~^ ERROR the placeholder `_` is not allowed within types on item signatures for return types
Bar::<i32, 3>(0)
}

fn ty_fn_mixed() -> Bar<_, _> {
//~^ ERROR the placeholder `_` is not allowed within types on item signatures for return types
Bar::<i32, 3>(0)
}

const ARR_CT: [u8; _] = [0; 3];
//~^ ERROR the placeholder `_` is not allowed within types on item signatures for constants
static ARR_STATIC: [u8; _] = [0; 3];
//~^ ERROR the placeholder `_` is not allowed within types on item signatures for static variables
const TY_CT: Bar<i32, _> = Bar::<i32, 3>(0);
//~^ ERROR the placeholder `_` is not allowed within types on item signatures for constants
static TY_STATIC: Bar<i32, _> = Bar::<i32, 3>(0);
//~^ ERROR the placeholder `_` is not allowed within types on item signatures for static variables
const TY_CT_MIXED: Bar<_, _> = Bar::<i32, 3>(0);
//~^ ERROR the placeholder `_` is not allowed within types on item signatures for constants
static TY_STATIC_MIXED: Bar<_, _> = Bar::<i32, 3>(0);
//~^ ERROR the placeholder `_` is not allowed within types on item signatures for static variables
trait ArrAssocConst {
const ARR: [u8; _];
//~^ ERROR the placeholder `_` is not allowed within types on item signatures for constants
}
trait TyAssocConst {
const ARR: Bar<i32, _>;
//~^ ERROR the placeholder `_` is not allowed within types on item signatures for constants
}
trait TyAssocConstMixed {
const ARR: Bar<_, _>;
//~^ ERROR the placeholder `_` is not allowed within types on item signatures for constants
}

trait AssocTy {
type Assoc;
}
impl AssocTy for i8 {
type Assoc = [u8; _];
//~^ ERROR the placeholder `_` is not allowed within types on item signatures for associated types
}
impl AssocTy for i16 {
type Assoc = Bar<i32, _>;
//~^ ERROR the placeholder `_` is not allowed within types on item signatures for associated types
}
impl AssocTy for i32 {
type Assoc = Bar<_, _>;
//~^ ERROR the placeholder `_` is not allowed within types on item signatures for associated types
}
119 changes: 119 additions & 0 deletions src/test/ui/const-generics/generic_arg_infer/in-signature.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types
--> $DIR/in-signature.rs:7:21
|
LL | fn arr_fn() -> [u8; _] {
| -----^-
| | |
| | not allowed in type signatures
| help: replace with the correct return type: `[u8; 3]`

error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types
--> $DIR/in-signature.rs:12:24
|
LL | fn ty_fn() -> Bar<i32, _> {
| ---------^-
| | |
| | not allowed in type signatures
| help: replace with the correct return type: `Bar<i32, 3_usize>`

error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types
--> $DIR/in-signature.rs:17:25
|
LL | fn ty_fn_mixed() -> Bar<_, _> {
| ----^--^-
| | | |
| | | not allowed in type signatures
| | not allowed in type signatures
| help: replace with the correct return type: `Bar<i32, 3_usize>`

error[E0121]: the placeholder `_` is not allowed within types on item signatures for constants
--> $DIR/in-signature.rs:22:15
|
LL | const ARR_CT: [u8; _] = [0; 3];
| ^^^^^^^ not allowed in type signatures

error[E0121]: the placeholder `_` is not allowed within types on item signatures for static variables
--> $DIR/in-signature.rs:24:20
|
LL | static ARR_STATIC: [u8; _] = [0; 3];
| ^^^^^^^ not allowed in type signatures

error[E0121]: the placeholder `_` is not allowed within types on item signatures for constants
--> $DIR/in-signature.rs:26:14
|
LL | const TY_CT: Bar<i32, _> = Bar::<i32, 3>(0);
| ^^^^^^^^^^^
| |
| not allowed in type signatures
| help: replace with the correct type: `Bar<i32, 3_usize>`

error[E0121]: the placeholder `_` is not allowed within types on item signatures for static variables
--> $DIR/in-signature.rs:28:19
|
LL | static TY_STATIC: Bar<i32, _> = Bar::<i32, 3>(0);
| ^^^^^^^^^^^
| |
| not allowed in type signatures
| help: replace with the correct type: `Bar<i32, 3_usize>`

error[E0121]: the placeholder `_` is not allowed within types on item signatures for constants
--> $DIR/in-signature.rs:30:20
|
LL | const TY_CT_MIXED: Bar<_, _> = Bar::<i32, 3>(0);
| ^^^^^^^^^
| |
| not allowed in type signatures
| help: replace with the correct type: `Bar<i32, 3_usize>`

error[E0121]: the placeholder `_` is not allowed within types on item signatures for static variables
--> $DIR/in-signature.rs:32:25
|
LL | static TY_STATIC_MIXED: Bar<_, _> = Bar::<i32, 3>(0);
| ^^^^^^^^^
| |
| not allowed in type signatures
| help: replace with the correct type: `Bar<i32, 3_usize>`

error[E0121]: the placeholder `_` is not allowed within types on item signatures for constants
--> $DIR/in-signature.rs:35:21
|
LL | const ARR: [u8; _];
| ^ not allowed in type signatures

error[E0121]: the placeholder `_` is not allowed within types on item signatures for constants
--> $DIR/in-signature.rs:39:25
|
LL | const ARR: Bar<i32, _>;
| ^ not allowed in type signatures

error[E0121]: the placeholder `_` is not allowed within types on item signatures for constants
--> $DIR/in-signature.rs:43:20
|
LL | const ARR: Bar<_, _>;
| ^ ^ not allowed in type signatures
| |
| not allowed in type signatures

error[E0121]: the placeholder `_` is not allowed within types on item signatures for associated types
--> $DIR/in-signature.rs:51:23
|
LL | type Assoc = [u8; _];
| ^ not allowed in type signatures

error[E0121]: the placeholder `_` is not allowed within types on item signatures for associated types
--> $DIR/in-signature.rs:55:27
|
LL | type Assoc = Bar<i32, _>;
| ^ not allowed in type signatures

error[E0121]: the placeholder `_` is not allowed within types on item signatures for associated types
--> $DIR/in-signature.rs:59:22
|
LL | type Assoc = Bar<_, _>;
| ^ ^ not allowed in type signatures
| |
| not allowed in type signatures

error: aborting due to 15 previous errors

For more information about this error, try `rustc --explain E0121`.
Loading

0 comments on commit c0aa0fa

Please sign in to comment.