Skip to content

Commit b07333c

Browse files
authored
Rollup merge of rust-lang#70294 - estebank:bad-placeholder-in-where, r=Centril
Account for bad placeholder types in where clauses Fix rust-lang#70291. Follow up to rust-lang#69148.
2 parents 9327c9d + e75158d commit b07333c

File tree

7 files changed

+192
-86
lines changed

7 files changed

+192
-86
lines changed

src/librustc_typeck/astconv.rs

+14-20
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticId};
2020
use rustc_hir as hir;
2121
use rustc_hir::def::{CtorOf, DefKind, Namespace, Res};
2222
use rustc_hir::def_id::DefId;
23-
use rustc_hir::intravisit::Visitor;
23+
use rustc_hir::intravisit::{walk_generics, Visitor};
2424
use rustc_hir::print;
2525
use rustc_hir::{Constness, ExprKind, GenericArg, GenericArgs};
2626
use rustc_session::lint::builtin::{AMBIGUOUS_ASSOCIATED_ITEMS, LATE_BOUND_LIFETIME_ARGUMENTS};
@@ -838,18 +838,6 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
838838
}
839839
},
840840
);
841-
if !inferred_params.is_empty() {
842-
// We always collect the spans for placeholder types when evaluating `fn`s, but we
843-
// only want to emit an error complaining about them if infer types (`_`) are not
844-
// allowed. `allow_ty_infer` gates this behavior.
845-
crate::collect::placeholder_type_error(
846-
tcx,
847-
inferred_params[0],
848-
&[],
849-
inferred_params,
850-
false,
851-
);
852-
}
853841

854842
self.complain_about_missing_type_params(
855843
missing_type_params,
@@ -2747,7 +2735,13 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
27472735
}
27482736
hir::TyKind::BareFn(ref bf) => {
27492737
require_c_abi_if_c_variadic(tcx, &bf.decl, bf.abi, ast_ty.span);
2750-
tcx.mk_fn_ptr(self.ty_of_fn(bf.unsafety, bf.abi, &bf.decl, &[], None))
2738+
tcx.mk_fn_ptr(self.ty_of_fn(
2739+
bf.unsafety,
2740+
bf.abi,
2741+
&bf.decl,
2742+
&hir::Generics::empty(),
2743+
None,
2744+
))
27512745
}
27522746
hir::TyKind::TraitObject(ref bounds, ref lifetime) => {
27532747
self.conv_object_ty_poly_trait_ref(ast_ty.span, bounds, lifetime)
@@ -2930,7 +2924,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
29302924
unsafety: hir::Unsafety,
29312925
abi: abi::Abi,
29322926
decl: &hir::FnDecl<'_>,
2933-
generic_params: &[hir::GenericParam<'_>],
2927+
generics: &hir::Generics<'_>,
29342928
ident_span: Option<Span>,
29352929
) -> ty::PolyFnSig<'tcx> {
29362930
debug!("ty_of_fn");
@@ -2942,6 +2936,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
29422936
for ty in decl.inputs {
29432937
visitor.visit_ty(ty);
29442938
}
2939+
walk_generics(&mut visitor, generics);
2940+
29452941
let input_tys = decl.inputs.iter().map(|a| self.ty_of_arg(a, None));
29462942
let output_ty = match decl.output {
29472943
hir::FnRetTy::Return(ref output) => {
@@ -2963,7 +2959,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
29632959
crate::collect::placeholder_type_error(
29642960
tcx,
29652961
ident_span.map(|sp| sp.shrink_to_hi()).unwrap_or(DUMMY_SP),
2966-
generic_params,
2962+
&generics.params[..],
29672963
visitor.0,
29682964
ident_span.is_some(),
29692965
);
@@ -2989,8 +2985,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
29892985
tcx.sess,
29902986
decl.output.span(),
29912987
E0581,
2992-
"return type references {} \
2993-
which is not constrained by the fn input types",
2988+
"return type references {} which is not constrained by the fn input types",
29942989
lifetime_name
29952990
);
29962991
if let ty::BrAnon(_) = *br {
@@ -3001,8 +2996,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
30012996
// though we can easily give a hint that ought to be
30022997
// relevant.
30032998
err.note(
3004-
"lifetimes appearing in an associated type \
3005-
are not considered constrained",
2999+
"lifetimes appearing in an associated type are not considered constrained",
30063000
);
30073001
}
30083002
err.emit();

src/librustc_typeck/check/mod.rs

+8-1
Original file line numberDiff line numberDiff line change
@@ -1003,7 +1003,14 @@ fn typeck_tables_of_with_fallback<'tcx>(
10031003
let fcx = if let (Some(header), Some(decl)) = (fn_header, fn_decl) {
10041004
let fn_sig = if crate::collect::get_infer_ret_ty(&decl.output).is_some() {
10051005
let fcx = FnCtxt::new(&inh, param_env, body.value.hir_id);
1006-
AstConv::ty_of_fn(&fcx, header.unsafety, header.abi, decl, &[], None)
1006+
AstConv::ty_of_fn(
1007+
&fcx,
1008+
header.unsafety,
1009+
header.abi,
1010+
decl,
1011+
&hir::Generics::empty(),
1012+
None,
1013+
)
10071014
} else {
10081015
tcx.fn_sig(def_id)
10091016
};

src/librustc_typeck/collect.rs

+12-10
Original file line numberDiff line numberDiff line change
@@ -1486,7 +1486,7 @@ fn fn_sig(tcx: TyCtxt<'_>, def_id: DefId) -> ty::PolyFnSig<'_> {
14861486
sig.header.unsafety,
14871487
sig.header.abi,
14881488
&sig.decl,
1489-
&generics.params[..],
1489+
&generics,
14901490
Some(ident.span),
14911491
),
14921492
}
@@ -1497,14 +1497,9 @@ fn fn_sig(tcx: TyCtxt<'_>, def_id: DefId) -> ty::PolyFnSig<'_> {
14971497
ident,
14981498
generics,
14991499
..
1500-
}) => AstConv::ty_of_fn(
1501-
&icx,
1502-
header.unsafety,
1503-
header.abi,
1504-
decl,
1505-
&generics.params[..],
1506-
Some(ident.span),
1507-
),
1500+
}) => {
1501+
AstConv::ty_of_fn(&icx, header.unsafety, header.abi, decl, &generics, Some(ident.span))
1502+
}
15081503

15091504
ForeignItem(&hir::ForeignItem { kind: ForeignItemKind::Fn(ref fn_decl, _, _), .. }) => {
15101505
let abi = tcx.hir().get_foreign_abi(hir_id);
@@ -2127,7 +2122,14 @@ fn compute_sig_of_foreign_fn_decl<'tcx>(
21272122
} else {
21282123
hir::Unsafety::Unsafe
21292124
};
2130-
let fty = AstConv::ty_of_fn(&ItemCtxt::new(tcx, def_id), unsafety, abi, decl, &[], None);
2125+
let fty = AstConv::ty_of_fn(
2126+
&ItemCtxt::new(tcx, def_id),
2127+
unsafety,
2128+
abi,
2129+
decl,
2130+
&hir::Generics::empty(),
2131+
None,
2132+
);
21312133

21322134
// Feature gate SIMD types in FFI, since I am not sure that the
21332135
// ABIs are handled at all correctly. -huonw

src/test/ui/did_you_mean/bad-assoc-ty.rs

+32
Original file line numberDiff line numberDiff line change
@@ -49,4 +49,36 @@ trait K<A, B> {}
4949
fn foo<X: K<_, _>>(x: X) {}
5050
//~^ ERROR the type placeholder `_` is not allowed within types on item signatures
5151

52+
fn bar<F>(_: F) where F: Fn() -> _ {}
53+
//~^ ERROR the type placeholder `_` is not allowed within types on item signatures
54+
55+
fn baz<F: Fn() -> _>(_: F) {}
56+
//~^ ERROR the type placeholder `_` is not allowed within types on item signatures
57+
58+
struct L<F>(F) where F: Fn() -> _;
59+
//~^ ERROR the type placeholder `_` is not allowed within types on item signatures
60+
struct M<F> where F: Fn() -> _ {
61+
//~^ ERROR the type placeholder `_` is not allowed within types on item signatures
62+
a: F,
63+
}
64+
enum N<F> where F: Fn() -> _ {
65+
//~^ ERROR the type placeholder `_` is not allowed within types on item signatures
66+
Foo(F),
67+
}
68+
69+
union O<F> where F: Fn() -> _ {
70+
//~^ ERROR the type placeholder `_` is not allowed within types on item signatures
71+
//~| ERROR unions with non-`Copy` fields are unstable
72+
foo: F,
73+
}
74+
75+
trait P<F> where F: Fn() -> _ {
76+
//~^ ERROR the type placeholder `_` is not allowed within types on item signatures
77+
}
78+
79+
trait Q {
80+
fn foo<F>(_: F) where F: Fn() -> _ {}
81+
//~^ ERROR the type placeholder `_` is not allowed within types on item signatures
82+
}
83+
5284
fn main() {}

src/test/ui/did_you_mean/bad-assoc-ty.stderr

+108-2
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,19 @@ LL | type J = ty!(u8);
5757
|
5858
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
5959

60+
error[E0658]: unions with non-`Copy` fields are unstable
61+
--> $DIR/bad-assoc-ty.rs:69:1
62+
|
63+
LL | / union O<F> where F: Fn() -> _ {
64+
LL | |
65+
LL | |
66+
LL | | foo: F,
67+
LL | | }
68+
| |_^
69+
|
70+
= note: see issue #55149 <https://github.com/rust-lang/rust/issues/55149> for more information
71+
= help: add `#![feature(untagged_unions)]` to the crate attributes to enable
72+
6073
error[E0223]: ambiguous associated type
6174
--> $DIR/bad-assoc-ty.rs:1:10
6275
|
@@ -129,8 +142,101 @@ LL | fn foo<X: K<_, _>>(x: X) {}
129142
| ^ ^ not allowed in type signatures
130143
| |
131144
| not allowed in type signatures
145+
|
146+
help: use type parameters instead
147+
|
148+
LL | fn foo<X, T: K<T, T>>(x: X) {}
149+
| ^^^ ^ ^
150+
151+
error[E0121]: the type placeholder `_` is not allowed within types on item signatures
152+
--> $DIR/bad-assoc-ty.rs:52:34
153+
|
154+
LL | fn bar<F>(_: F) where F: Fn() -> _ {}
155+
| ^ not allowed in type signatures
156+
|
157+
help: use type parameters instead
158+
|
159+
LL | fn bar<F, T>(_: F) where F: Fn() -> T {}
160+
| ^^^ ^
161+
162+
error[E0121]: the type placeholder `_` is not allowed within types on item signatures
163+
--> $DIR/bad-assoc-ty.rs:55:19
164+
|
165+
LL | fn baz<F: Fn() -> _>(_: F) {}
166+
| ^ not allowed in type signatures
167+
|
168+
help: use type parameters instead
169+
|
170+
LL | fn baz<F, T: Fn() -> T>(_: F) {}
171+
| ^^^ ^
172+
173+
error[E0121]: the type placeholder `_` is not allowed within types on item signatures
174+
--> $DIR/bad-assoc-ty.rs:58:33
175+
|
176+
LL | struct L<F>(F) where F: Fn() -> _;
177+
| ^ not allowed in type signatures
178+
|
179+
help: use type parameters instead
180+
|
181+
LL | struct L<F, T>(F) where F: Fn() -> T;
182+
| ^^^ ^
183+
184+
error[E0121]: the type placeholder `_` is not allowed within types on item signatures
185+
--> $DIR/bad-assoc-ty.rs:60:30
186+
|
187+
LL | struct M<F> where F: Fn() -> _ {
188+
| ^ not allowed in type signatures
189+
|
190+
help: use type parameters instead
191+
|
192+
LL | struct M<F, T> where F: Fn() -> T {
193+
| ^^^ ^
194+
195+
error[E0121]: the type placeholder `_` is not allowed within types on item signatures
196+
--> $DIR/bad-assoc-ty.rs:64:28
197+
|
198+
LL | enum N<F> where F: Fn() -> _ {
199+
| ^ not allowed in type signatures
200+
|
201+
help: use type parameters instead
202+
|
203+
LL | enum N<F, T> where F: Fn() -> T {
204+
| ^^^ ^
205+
206+
error[E0121]: the type placeholder `_` is not allowed within types on item signatures
207+
--> $DIR/bad-assoc-ty.rs:69:29
208+
|
209+
LL | union O<F> where F: Fn() -> _ {
210+
| ^ not allowed in type signatures
211+
|
212+
help: use type parameters instead
213+
|
214+
LL | union O<F, T> where F: Fn() -> T {
215+
| ^^^ ^
216+
217+
error[E0121]: the type placeholder `_` is not allowed within types on item signatures
218+
--> $DIR/bad-assoc-ty.rs:75:29
219+
|
220+
LL | trait P<F> where F: Fn() -> _ {
221+
| ^ not allowed in type signatures
222+
|
223+
help: use type parameters instead
224+
|
225+
LL | trait P<F, T> where F: Fn() -> T {
226+
| ^^^ ^
227+
228+
error[E0121]: the type placeholder `_` is not allowed within types on item signatures
229+
--> $DIR/bad-assoc-ty.rs:80:38
230+
|
231+
LL | fn foo<F>(_: F) where F: Fn() -> _ {}
232+
| ^ not allowed in type signatures
233+
|
234+
help: use type parameters instead
235+
|
236+
LL | fn foo<F, T>(_: F) where F: Fn() -> T {}
237+
| ^^^ ^
132238

133-
error: aborting due to 20 previous errors
239+
error: aborting due to 29 previous errors
134240

135-
Some errors have detailed explanations: E0121, E0223.
241+
Some errors have detailed explanations: E0121, E0223, E0658.
136242
For more information about an error, try `rustc --explain E0121`.

src/test/ui/typeck/typeck_type_placeholder_item.rs

-5
Original file line numberDiff line numberDiff line change
@@ -158,12 +158,9 @@ trait BadTrait<_> {}
158158
//~^ ERROR expected identifier, found reserved identifier `_`
159159
impl BadTrait<_> for BadStruct<_> {}
160160
//~^ ERROR the type placeholder `_` is not allowed within types on item signatures
161-
//~| ERROR the type placeholder `_` is not allowed within types on item signatures
162-
//~| ERROR the type placeholder `_` is not allowed within types on item signatures
163161

164162
fn impl_trait() -> impl BadTrait<_> {
165163
//~^ ERROR the type placeholder `_` is not allowed within types on item signatures
166-
//~| ERROR the type placeholder `_` is not allowed within types on item signatures
167164
unimplemented!()
168165
}
169166

@@ -178,14 +175,12 @@ struct BadStruct2<_, T>(_, T);
178175

179176
type X = Box<_>;
180177
//~^ ERROR the type placeholder `_` is not allowed within types on item signatures
181-
//~| ERROR the type placeholder `_` is not allowed within types on item signatures
182178

183179
struct Struct;
184180
trait Trait<T> {}
185181
impl Trait<usize> for Struct {}
186182
type Y = impl Trait<_>;
187183
//~^ ERROR the type placeholder `_` is not allowed within types on item signatures
188-
//~| ERROR the type placeholder `_` is not allowed within types on item signatures
189184
fn foo() -> Y {
190185
Struct
191186
}

0 commit comments

Comments
 (0)