Skip to content

Commit b2d8f0c

Browse files
committed
generic_arg_infer: placeholder in signature err
1 parent 621e60a commit b2d8f0c

38 files changed

+402
-235
lines changed

compiler/rustc_typeck/src/astconv/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ mod errors;
66
mod generics;
77

88
use crate::bounds::Bounds;
9-
use crate::collect::PlaceholderHirTyCollector;
9+
use crate::collect::HirPlaceholderCollector;
1010
use crate::errors::{
1111
AmbiguousLifetimeBound, MultipleRelaxedDefaultBounds, TraitObjectDeclaredWithNoTraits,
1212
TypeofReservedKeywordUsed, ValueOfAssociatedStructAlreadySpecified,
@@ -2478,7 +2478,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
24782478
debug!(?bound_vars);
24792479

24802480
// We proactively collect all the inferred type params to emit a single error per fn def.
2481-
let mut visitor = PlaceholderHirTyCollector::default();
2481+
let mut visitor = HirPlaceholderCollector::default();
24822482
for ty in decl.inputs {
24832483
visitor.visit_ty(ty);
24842484
}

compiler/rustc_typeck/src/collect.rs

+24-16
Original file line numberDiff line numberDiff line change
@@ -112,9 +112,9 @@ pub struct ItemCtxt<'tcx> {
112112
///////////////////////////////////////////////////////////////////////////
113113

114114
#[derive(Default)]
115-
crate struct PlaceholderHirTyCollector(crate Vec<Span>);
115+
crate struct HirPlaceholderCollector(crate Vec<Span>);
116116

117-
impl<'v> Visitor<'v> for PlaceholderHirTyCollector {
117+
impl<'v> Visitor<'v> for HirPlaceholderCollector {
118118
fn visit_ty(&mut self, t: &'v hir::Ty<'v>) {
119119
if let hir::TyKind::Infer = t.kind {
120120
self.0.push(t.span);
@@ -131,6 +131,12 @@ impl<'v> Visitor<'v> for PlaceholderHirTyCollector {
131131
_ => {}
132132
}
133133
}
134+
fn visit_array_length(&mut self, length: &'v hir::ArrayLen) {
135+
if let &hir::ArrayLen::Infer(_, span) = length {
136+
self.0.push(span);
137+
}
138+
intravisit::walk_array_len(self, length)
139+
}
134140
}
135141

136142
struct CollectItemTypesVisitor<'tcx> {
@@ -175,7 +181,7 @@ crate fn placeholder_type_error<'tcx>(
175181
sugg.push((span, format!(", {}", type_name)));
176182
}
177183

178-
let mut err = bad_placeholder(tcx, "type", placeholder_types, kind);
184+
let mut err = bad_placeholder(tcx, placeholder_types, kind);
179185

180186
// Suggest, but only if it is not a function in const or static
181187
if suggest {
@@ -233,7 +239,7 @@ fn reject_placeholder_type_signatures_in_item<'tcx>(
233239
_ => return,
234240
};
235241

236-
let mut visitor = PlaceholderHirTyCollector::default();
242+
let mut visitor = HirPlaceholderCollector::default();
237243
visitor.visit_item(item);
238244

239245
placeholder_type_error(
@@ -311,7 +317,6 @@ impl<'tcx> Visitor<'tcx> for CollectItemTypesVisitor<'tcx> {
311317

312318
fn bad_placeholder<'tcx>(
313319
tcx: TyCtxt<'tcx>,
314-
placeholder_kind: &'static str,
315320
mut spans: Vec<Span>,
316321
kind: &'static str,
317322
) -> rustc_errors::DiagnosticBuilder<'tcx> {
@@ -322,8 +327,7 @@ fn bad_placeholder<'tcx>(
322327
tcx.sess,
323328
spans.clone(),
324329
E0121,
325-
"the {} placeholder `_` is not allowed within types on item signatures for {}",
326-
placeholder_kind,
330+
"the placeholder `_` is not allowed within types on item signatures for {}",
327331
kind
328332
);
329333
for span in spans {
@@ -737,7 +741,7 @@ fn convert_item(tcx: TyCtxt<'_>, item_id: hir::ItemId) {
737741
match item.kind {
738742
hir::ForeignItemKind::Fn(..) => tcx.ensure().fn_sig(item.def_id),
739743
hir::ForeignItemKind::Static(..) => {
740-
let mut visitor = PlaceholderHirTyCollector::default();
744+
let mut visitor = HirPlaceholderCollector::default();
741745
visitor.visit_foreign_item(item);
742746
placeholder_type_error(
743747
tcx,
@@ -820,7 +824,7 @@ fn convert_item(tcx: TyCtxt<'_>, item_id: hir::ItemId) {
820824
hir::ItemKind::Const(ty, ..) | hir::ItemKind::Static(ty, ..) => {
821825
// (#75889): Account for `const C: dyn Fn() -> _ = "";`
822826
if let hir::TyKind::TraitObject(..) = ty.kind {
823-
let mut visitor = PlaceholderHirTyCollector::default();
827+
let mut visitor = HirPlaceholderCollector::default();
824828
visitor.visit_item(it);
825829
placeholder_type_error(
826830
tcx,
@@ -856,7 +860,7 @@ fn convert_trait_item(tcx: TyCtxt<'_>, trait_item_id: hir::TraitItemId) {
856860
hir::TraitItemKind::Const(..) => {
857861
tcx.ensure().type_of(trait_item_id.def_id);
858862
// Account for `const C: _;`.
859-
let mut visitor = PlaceholderHirTyCollector::default();
863+
let mut visitor = HirPlaceholderCollector::default();
860864
visitor.visit_trait_item(trait_item);
861865
placeholder_type_error(tcx, None, &[], visitor.0, false, None, "constant");
862866
}
@@ -865,7 +869,7 @@ fn convert_trait_item(tcx: TyCtxt<'_>, trait_item_id: hir::TraitItemId) {
865869
tcx.ensure().item_bounds(trait_item_id.def_id);
866870
tcx.ensure().type_of(trait_item_id.def_id);
867871
// Account for `type T = _;`.
868-
let mut visitor = PlaceholderHirTyCollector::default();
872+
let mut visitor = HirPlaceholderCollector::default();
869873
visitor.visit_trait_item(trait_item);
870874
placeholder_type_error(tcx, None, &[], visitor.0, false, None, "associated type");
871875
}
@@ -874,7 +878,7 @@ fn convert_trait_item(tcx: TyCtxt<'_>, trait_item_id: hir::TraitItemId) {
874878
tcx.ensure().item_bounds(trait_item_id.def_id);
875879
// #74612: Visit and try to find bad placeholders
876880
// even if there is no concrete type.
877-
let mut visitor = PlaceholderHirTyCollector::default();
881+
let mut visitor = HirPlaceholderCollector::default();
878882
visitor.visit_trait_item(trait_item);
879883

880884
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) {
896900
}
897901
hir::ImplItemKind::TyAlias(_) => {
898902
// Account for `type T = _;`
899-
let mut visitor = PlaceholderHirTyCollector::default();
903+
let mut visitor = HirPlaceholderCollector::default();
900904
visitor.visit_impl_item(impl_item);
901905

902906
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 {
18161820
/// Whether `ty` is a type with `_` placeholders that can be inferred. Used in diagnostics only to
18171821
/// use inference to provide suggestions for the appropriate type if possible.
18181822
fn is_suggestable_infer_ty(ty: &hir::Ty<'_>) -> bool {
1823+
debug!(?ty);
18191824
use hir::TyKind::*;
18201825
match &ty.kind {
18211826
Infer => true,
1822-
Slice(ty) | Array(ty, _) => is_suggestable_infer_ty(ty),
1827+
Slice(ty) => is_suggestable_infer_ty(ty),
1828+
Array(ty, length) => {
1829+
is_suggestable_infer_ty(ty) || matches!(length, hir::ArrayLen::Infer(_, _))
1830+
}
18231831
Tup(tys) => tys.iter().any(is_suggestable_infer_ty),
18241832
Ptr(mut_ty) | Rptr(_, mut_ty) => is_suggestable_infer_ty(mut_ty.ty),
18251833
OpaqueDef(_, generic_args) => are_suggestable_generic_args(generic_args),
@@ -1871,9 +1879,9 @@ fn fn_sig(tcx: TyCtxt<'_>, def_id: DefId) -> ty::PolyFnSig<'_> {
18711879
});
18721880
let fn_sig = ty::Binder::dummy(fn_sig);
18731881

1874-
let mut visitor = PlaceholderHirTyCollector::default();
1882+
let mut visitor = HirPlaceholderCollector::default();
18751883
visitor.visit_ty(ty);
1876-
let mut diag = bad_placeholder(tcx, "type", visitor.0, "return type");
1884+
let mut diag = bad_placeholder(tcx, visitor.0, "return type");
18771885
let ret_ty = fn_sig.skip_binder().output();
18781886
if !ret_ty.references_error() {
18791887
if !ret_ty.is_closure() {

compiler/rustc_typeck/src/collect/type_of.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -750,7 +750,7 @@ fn infer_placeholder_type<'a>(
750750
err.emit();
751751
}
752752
None => {
753-
let mut diag = bad_placeholder(tcx, "type", vec![span], kind);
753+
let mut diag = bad_placeholder(tcx, vec![span], kind);
754754

755755
if !ty.references_error() {
756756
let mut mk_nameable = MakeNameable::new(tcx);

src/test/ui/const-generics/generic_arg_infer/array-in-sig.rs

-12
This file was deleted.

src/test/ui/const-generics/generic_arg_infer/array-in-sig.stderr

-9
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
#![crate_type = "rlib"]
2+
#![feature(generic_arg_infer)]
3+
4+
struct Foo<const N: usize>;
5+
struct Bar<T, const N: usize>(T);
6+
7+
fn arr_fn() -> [u8; _] {
8+
//~^ ERROR the placeholder `_` is not allowed within types on item signatures for return types
9+
[0; 3]
10+
}
11+
12+
fn ty_fn() -> Bar<i32, _> {
13+
//~^ ERROR the placeholder `_` is not allowed within types on item signatures for return types
14+
Bar::<i32, 3>(0)
15+
}
16+
17+
fn ty_fn_mixed() -> Bar<_, _> {
18+
//~^ ERROR the placeholder `_` is not allowed within types on item signatures for return types
19+
Bar::<i32, 3>(0)
20+
}
21+
22+
const ARR_CT: [u8; _] = [0; 3];
23+
//~^ ERROR the placeholder `_` is not allowed within types on item signatures for constants
24+
static ARR_STATIC: [u8; _] = [0; 3];
25+
//~^ ERROR the placeholder `_` is not allowed within types on item signatures for static variables
26+
const TY_CT: Bar<i32, _> = Bar::<i32, 3>(0);
27+
//~^ ERROR the placeholder `_` is not allowed within types on item signatures for constants
28+
static TY_STATIC: Bar<i32, _> = Bar::<i32, 3>(0);
29+
//~^ ERROR the placeholder `_` is not allowed within types on item signatures for static variables
30+
const TY_CT_MIXED: Bar<_, _> = Bar::<i32, 3>(0);
31+
//~^ ERROR the placeholder `_` is not allowed within types on item signatures for constants
32+
static TY_STATIC_MIXED: Bar<_, _> = Bar::<i32, 3>(0);
33+
//~^ ERROR the placeholder `_` is not allowed within types on item signatures for static variables
34+
trait ArrAssocConst {
35+
const ARR: [u8; _];
36+
//~^ ERROR the placeholder `_` is not allowed within types on item signatures for constants
37+
}
38+
trait TyAssocConst {
39+
const ARR: Bar<i32, _>;
40+
//~^ ERROR the placeholder `_` is not allowed within types on item signatures for constants
41+
}
42+
trait TyAssocConstMixed {
43+
const ARR: Bar<_, _>;
44+
//~^ ERROR the placeholder `_` is not allowed within types on item signatures for constants
45+
}
46+
47+
trait AssocTy {
48+
type Assoc;
49+
}
50+
impl AssocTy for i8 {
51+
type Assoc = [u8; _];
52+
//~^ ERROR the placeholder `_` is not allowed within types on item signatures for associated types
53+
}
54+
impl AssocTy for i16 {
55+
type Assoc = Bar<i32, _>;
56+
//~^ ERROR the placeholder `_` is not allowed within types on item signatures for associated types
57+
}
58+
impl AssocTy for i32 {
59+
type Assoc = Bar<_, _>;
60+
//~^ ERROR the placeholder `_` is not allowed within types on item signatures for associated types
61+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types
2+
--> $DIR/in-signature.rs:7:21
3+
|
4+
LL | fn arr_fn() -> [u8; _] {
5+
| -----^-
6+
| | |
7+
| | not allowed in type signatures
8+
| help: replace with the correct return type: `[u8; 3]`
9+
10+
error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types
11+
--> $DIR/in-signature.rs:12:24
12+
|
13+
LL | fn ty_fn() -> Bar<i32, _> {
14+
| ---------^-
15+
| | |
16+
| | not allowed in type signatures
17+
| help: replace with the correct return type: `Bar<i32, 3_usize>`
18+
19+
error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types
20+
--> $DIR/in-signature.rs:17:25
21+
|
22+
LL | fn ty_fn_mixed() -> Bar<_, _> {
23+
| ----^--^-
24+
| | | |
25+
| | | not allowed in type signatures
26+
| | not allowed in type signatures
27+
| help: replace with the correct return type: `Bar<i32, 3_usize>`
28+
29+
error[E0121]: the placeholder `_` is not allowed within types on item signatures for constants
30+
--> $DIR/in-signature.rs:22:15
31+
|
32+
LL | const ARR_CT: [u8; _] = [0; 3];
33+
| ^^^^^^^ not allowed in type signatures
34+
35+
error[E0121]: the placeholder `_` is not allowed within types on item signatures for static variables
36+
--> $DIR/in-signature.rs:24:20
37+
|
38+
LL | static ARR_STATIC: [u8; _] = [0; 3];
39+
| ^^^^^^^ not allowed in type signatures
40+
41+
error[E0121]: the placeholder `_` is not allowed within types on item signatures for constants
42+
--> $DIR/in-signature.rs:26:14
43+
|
44+
LL | const TY_CT: Bar<i32, _> = Bar::<i32, 3>(0);
45+
| ^^^^^^^^^^^
46+
| |
47+
| not allowed in type signatures
48+
| help: replace with the correct type: `Bar<i32, 3_usize>`
49+
50+
error[E0121]: the placeholder `_` is not allowed within types on item signatures for static variables
51+
--> $DIR/in-signature.rs:28:19
52+
|
53+
LL | static TY_STATIC: Bar<i32, _> = Bar::<i32, 3>(0);
54+
| ^^^^^^^^^^^
55+
| |
56+
| not allowed in type signatures
57+
| help: replace with the correct type: `Bar<i32, 3_usize>`
58+
59+
error[E0121]: the placeholder `_` is not allowed within types on item signatures for constants
60+
--> $DIR/in-signature.rs:30:20
61+
|
62+
LL | const TY_CT_MIXED: Bar<_, _> = Bar::<i32, 3>(0);
63+
| ^^^^^^^^^
64+
| |
65+
| not allowed in type signatures
66+
| help: replace with the correct type: `Bar<i32, 3_usize>`
67+
68+
error[E0121]: the placeholder `_` is not allowed within types on item signatures for static variables
69+
--> $DIR/in-signature.rs:32:25
70+
|
71+
LL | static TY_STATIC_MIXED: Bar<_, _> = Bar::<i32, 3>(0);
72+
| ^^^^^^^^^
73+
| |
74+
| not allowed in type signatures
75+
| help: replace with the correct type: `Bar<i32, 3_usize>`
76+
77+
error[E0121]: the placeholder `_` is not allowed within types on item signatures for constants
78+
--> $DIR/in-signature.rs:35:21
79+
|
80+
LL | const ARR: [u8; _];
81+
| ^ not allowed in type signatures
82+
83+
error[E0121]: the placeholder `_` is not allowed within types on item signatures for constants
84+
--> $DIR/in-signature.rs:39:25
85+
|
86+
LL | const ARR: Bar<i32, _>;
87+
| ^ not allowed in type signatures
88+
89+
error[E0121]: the placeholder `_` is not allowed within types on item signatures for constants
90+
--> $DIR/in-signature.rs:43:20
91+
|
92+
LL | const ARR: Bar<_, _>;
93+
| ^ ^ not allowed in type signatures
94+
| |
95+
| not allowed in type signatures
96+
97+
error[E0121]: the placeholder `_` is not allowed within types on item signatures for associated types
98+
--> $DIR/in-signature.rs:51:23
99+
|
100+
LL | type Assoc = [u8; _];
101+
| ^ not allowed in type signatures
102+
103+
error[E0121]: the placeholder `_` is not allowed within types on item signatures for associated types
104+
--> $DIR/in-signature.rs:55:27
105+
|
106+
LL | type Assoc = Bar<i32, _>;
107+
| ^ not allowed in type signatures
108+
109+
error[E0121]: the placeholder `_` is not allowed within types on item signatures for associated types
110+
--> $DIR/in-signature.rs:59:22
111+
|
112+
LL | type Assoc = Bar<_, _>;
113+
| ^ ^ not allowed in type signatures
114+
| |
115+
| not allowed in type signatures
116+
117+
error: aborting due to 15 previous errors
118+
119+
For more information about this error, try `rustc --explain E0121`.

0 commit comments

Comments
 (0)