Skip to content

Commit c0aa0fa

Browse files
committed
generic_arg_infer: placeholder in signature err
1 parent a3e3787 commit c0aa0fa

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,
@@ -2469,7 +2469,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
24692469
debug!(?bound_vars);
24702470

24712471
// We proactively collect all the inferred type params to emit a single error per fn def.
2472-
let mut visitor = PlaceholderHirTyCollector::default();
2472+
let mut visitor = HirPlaceholderCollector::default();
24732473
for ty in decl.inputs {
24742474
visitor.visit_ty(ty);
24752475
}

compiler/rustc_typeck/src/collect.rs

+24-16
Original file line numberDiff line numberDiff line change
@@ -114,9 +114,9 @@ pub struct ItemCtxt<'tcx> {
114114
///////////////////////////////////////////////////////////////////////////
115115

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

119-
impl<'v> Visitor<'v> for PlaceholderHirTyCollector {
119+
impl<'v> Visitor<'v> for HirPlaceholderCollector {
120120
type Map = intravisit::ErasedMap<'v>;
121121

122122
fn nested_visit_map(&mut self) -> NestedVisitorMap<Self::Map> {
@@ -138,6 +138,12 @@ impl<'v> Visitor<'v> for PlaceholderHirTyCollector {
138138
_ => {}
139139
}
140140
}
141+
fn visit_array_length(&mut self, length: &'v hir::ArrayLen) {
142+
if let &hir::ArrayLen::Infer(_, span) = length {
143+
self.0.push(span);
144+
}
145+
intravisit::walk_array_len(self, length)
146+
}
141147
}
142148

143149
struct CollectItemTypesVisitor<'tcx> {
@@ -182,7 +188,7 @@ crate fn placeholder_type_error<'tcx>(
182188
sugg.push((span, format!(", {}", type_name)));
183189
}
184190

185-
let mut err = bad_placeholder(tcx, "type", placeholder_types, kind);
191+
let mut err = bad_placeholder(tcx, placeholder_types, kind);
186192

187193
// Suggest, but only if it is not a function in const or static
188194
if suggest {
@@ -240,7 +246,7 @@ fn reject_placeholder_type_signatures_in_item<'tcx>(
240246
_ => return,
241247
};
242248

243-
let mut visitor = PlaceholderHirTyCollector::default();
249+
let mut visitor = HirPlaceholderCollector::default();
244250
visitor.visit_item(item);
245251

246252
placeholder_type_error(
@@ -316,7 +322,6 @@ impl<'tcx> Visitor<'tcx> for CollectItemTypesVisitor<'tcx> {
316322

317323
fn bad_placeholder<'tcx>(
318324
tcx: TyCtxt<'tcx>,
319-
placeholder_kind: &'static str,
320325
mut spans: Vec<Span>,
321326
kind: &'static str,
322327
) -> rustc_errors::DiagnosticBuilder<'tcx> {
@@ -327,8 +332,7 @@ fn bad_placeholder<'tcx>(
327332
tcx.sess,
328333
spans.clone(),
329334
E0121,
330-
"the {} placeholder `_` is not allowed within types on item signatures for {}",
331-
placeholder_kind,
335+
"the placeholder `_` is not allowed within types on item signatures for {}",
332336
kind
333337
);
334338
for span in spans {
@@ -743,7 +747,7 @@ fn convert_item(tcx: TyCtxt<'_>, item_id: hir::ItemId) {
743747
match item.kind {
744748
hir::ForeignItemKind::Fn(..) => tcx.ensure().fn_sig(item.def_id),
745749
hir::ForeignItemKind::Static(..) => {
746-
let mut visitor = PlaceholderHirTyCollector::default();
750+
let mut visitor = HirPlaceholderCollector::default();
747751
visitor.visit_foreign_item(item);
748752
placeholder_type_error(
749753
tcx,
@@ -826,7 +830,7 @@ fn convert_item(tcx: TyCtxt<'_>, item_id: hir::ItemId) {
826830
hir::ItemKind::Const(ty, ..) | hir::ItemKind::Static(ty, ..) => {
827831
// (#75889): Account for `const C: dyn Fn() -> _ = "";`
828832
if let hir::TyKind::TraitObject(..) = ty.kind {
829-
let mut visitor = PlaceholderHirTyCollector::default();
833+
let mut visitor = HirPlaceholderCollector::default();
830834
visitor.visit_item(it);
831835
placeholder_type_error(
832836
tcx,
@@ -862,7 +866,7 @@ fn convert_trait_item(tcx: TyCtxt<'_>, trait_item_id: hir::TraitItemId) {
862866
hir::TraitItemKind::Const(..) => {
863867
tcx.ensure().type_of(trait_item_id.def_id);
864868
// Account for `const C: _;`.
865-
let mut visitor = PlaceholderHirTyCollector::default();
869+
let mut visitor = HirPlaceholderCollector::default();
866870
visitor.visit_trait_item(trait_item);
867871
placeholder_type_error(tcx, None, &[], visitor.0, false, None, "constant");
868872
}
@@ -871,7 +875,7 @@ fn convert_trait_item(tcx: TyCtxt<'_>, trait_item_id: hir::TraitItemId) {
871875
tcx.ensure().item_bounds(trait_item_id.def_id);
872876
tcx.ensure().type_of(trait_item_id.def_id);
873877
// Account for `type T = _;`.
874-
let mut visitor = PlaceholderHirTyCollector::default();
878+
let mut visitor = HirPlaceholderCollector::default();
875879
visitor.visit_trait_item(trait_item);
876880
placeholder_type_error(tcx, None, &[], visitor.0, false, None, "associated type");
877881
}
@@ -880,7 +884,7 @@ fn convert_trait_item(tcx: TyCtxt<'_>, trait_item_id: hir::TraitItemId) {
880884
tcx.ensure().item_bounds(trait_item_id.def_id);
881885
// #74612: Visit and try to find bad placeholders
882886
// even if there is no concrete type.
883-
let mut visitor = PlaceholderHirTyCollector::default();
887+
let mut visitor = HirPlaceholderCollector::default();
884888
visitor.visit_trait_item(trait_item);
885889

886890
placeholder_type_error(tcx, None, &[], visitor.0, false, None, "associated type");
@@ -902,7 +906,7 @@ fn convert_impl_item(tcx: TyCtxt<'_>, impl_item_id: hir::ImplItemId) {
902906
}
903907
hir::ImplItemKind::TyAlias(_) => {
904908
// Account for `type T = _;`
905-
let mut visitor = PlaceholderHirTyCollector::default();
909+
let mut visitor = HirPlaceholderCollector::default();
906910
visitor.visit_impl_item(impl_item);
907911

908912
placeholder_type_error(tcx, None, &[], visitor.0, false, None, "associated type");
@@ -1735,10 +1739,14 @@ fn are_suggestable_generic_args(generic_args: &[hir::GenericArg<'_>]) -> bool {
17351739
/// Whether `ty` is a type with `_` placeholders that can be inferred. Used in diagnostics only to
17361740
/// use inference to provide suggestions for the appropriate type if possible.
17371741
fn is_suggestable_infer_ty(ty: &hir::Ty<'_>) -> bool {
1742+
debug!(?ty);
17381743
use hir::TyKind::*;
17391744
match &ty.kind {
17401745
Infer => true,
1741-
Slice(ty) | Array(ty, _) => is_suggestable_infer_ty(ty),
1746+
Slice(ty) => is_suggestable_infer_ty(ty),
1747+
Array(ty, length) => {
1748+
is_suggestable_infer_ty(ty) || matches!(length, hir::ArrayLen::Infer(_, _))
1749+
}
17421750
Tup(tys) => tys.iter().any(is_suggestable_infer_ty),
17431751
Ptr(mut_ty) | Rptr(_, mut_ty) => is_suggestable_infer_ty(mut_ty.ty),
17441752
OpaqueDef(_, generic_args) => are_suggestable_generic_args(generic_args),
@@ -1790,9 +1798,9 @@ fn fn_sig(tcx: TyCtxt<'_>, def_id: DefId) -> ty::PolyFnSig<'_> {
17901798
});
17911799
let fn_sig = ty::Binder::dummy(fn_sig);
17921800

1793-
let mut visitor = PlaceholderHirTyCollector::default();
1801+
let mut visitor = HirPlaceholderCollector::default();
17941802
visitor.visit_ty(ty);
1795-
let mut diag = bad_placeholder(tcx, "type", visitor.0, "return type");
1803+
let mut diag = bad_placeholder(tcx, visitor.0, "return type");
17961804
let ret_ty = fn_sig.skip_binder().output();
17971805
if !ret_ty.references_error() {
17981806
if !ret_ty.is_closure() {

compiler/rustc_typeck/src/collect/type_of.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -785,7 +785,7 @@ fn infer_placeholder_type<'a>(
785785
err.emit();
786786
}
787787
None => {
788-
let mut diag = bad_placeholder(tcx, "type", vec![span], kind);
788+
let mut diag = bad_placeholder(tcx, vec![span], kind);
789789

790790
if !ty.references_error() {
791791
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)