Skip to content

Commit cb17049

Browse files
authored
Rollup merge of #70369 - estebank:bad-placeholder-in-where, r=Centril
Fix smaller issues with invalid placeholder type errors Follow up to #70294. - Fix placement of suggested generic param when bounds are present. - Reduce error duplication for invalid placeholder types in `fn` types. r? @Centril
2 parents 3d0976a + 7534efa commit cb17049

File tree

5 files changed

+75
-81
lines changed

5 files changed

+75
-81
lines changed

src/librustc_typeck/astconv.rs

+5-4
Original file line numberDiff line numberDiff line change
@@ -2883,16 +2883,17 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
28832883
let bare_fn_ty =
28842884
ty::Binder::bind(tcx.mk_fn_sig(input_tys, output_ty, decl.c_variadic, unsafety, abi));
28852885

2886-
if !self.allow_ty_infer() {
2886+
if let (false, Some(ident_span)) = (self.allow_ty_infer(), ident_span) {
28872887
// We always collect the spans for placeholder types when evaluating `fn`s, but we
28882888
// only want to emit an error complaining about them if infer types (`_`) are not
2889-
// allowed. `allow_ty_infer` gates this behavior.
2889+
// allowed. `allow_ty_infer` gates this behavior. We check for the presence of
2890+
// `ident_span` to not emit an error twice when we have `fn foo(_: fn() -> _)`.
28902891
crate::collect::placeholder_type_error(
28912892
tcx,
2892-
ident_span.map(|sp| sp.shrink_to_hi()).unwrap_or(DUMMY_SP),
2893+
ident_span.shrink_to_hi(),
28932894
&generics.params[..],
28942895
visitor.0,
2895-
ident_span.is_some(),
2896+
true,
28962897
);
28972898
}
28982899

src/librustc_typeck/collect.rs

+11-4
Original file line numberDiff line numberDiff line change
@@ -162,8 +162,10 @@ crate fn placeholder_type_error(
162162
// `struct S<T>(T);` instead of `struct S<_, T>(T);`.
163163
sugg.push((arg.span, (*type_name).to_string()));
164164
} else {
165+
let last = generics.iter().last().unwrap();
165166
sugg.push((
166-
generics.iter().last().unwrap().span.shrink_to_hi(),
167+
// Account for bounds, we want `fn foo<T: E, K>(_: K)` not `fn foo<T, K: E>(_: K)`.
168+
last.bounds_span().unwrap_or(last.span).shrink_to_hi(),
167169
format!(", {}", type_name),
168170
));
169171
}
@@ -1501,9 +1503,13 @@ fn fn_sig(tcx: TyCtxt<'_>, def_id: DefId) -> ty::PolyFnSig<'_> {
15011503
AstConv::ty_of_fn(&icx, header.unsafety, header.abi, decl, &generics, Some(ident.span))
15021504
}
15031505

1504-
ForeignItem(&hir::ForeignItem { kind: ForeignItemKind::Fn(ref fn_decl, _, _), .. }) => {
1506+
ForeignItem(&hir::ForeignItem {
1507+
kind: ForeignItemKind::Fn(ref fn_decl, _, _),
1508+
ident,
1509+
..
1510+
}) => {
15051511
let abi = tcx.hir().get_foreign_abi(hir_id);
1506-
compute_sig_of_foreign_fn_decl(tcx, def_id, fn_decl, abi)
1512+
compute_sig_of_foreign_fn_decl(tcx, def_id, fn_decl, abi, ident)
15071513
}
15081514

15091515
Ctor(data) | Variant(hir::Variant { data, .. }) if data.ctor_hir_id().is_some() => {
@@ -2116,6 +2122,7 @@ fn compute_sig_of_foreign_fn_decl<'tcx>(
21162122
def_id: DefId,
21172123
decl: &'tcx hir::FnDecl<'tcx>,
21182124
abi: abi::Abi,
2125+
ident: Ident,
21192126
) -> ty::PolyFnSig<'tcx> {
21202127
let unsafety = if abi == abi::Abi::RustIntrinsic {
21212128
intrinsic_operation_unsafety(&tcx.item_name(def_id).as_str())
@@ -2128,7 +2135,7 @@ fn compute_sig_of_foreign_fn_decl<'tcx>(
21282135
abi,
21292136
decl,
21302137
&hir::Generics::empty(),
2131-
None,
2138+
Some(ident.span),
21322139
);
21332140

21342141
// Feature gate SIMD types in FFI, since I am not sure that the

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

+4-4
Original file line numberDiff line numberDiff line change
@@ -145,8 +145,8 @@ LL | fn foo<X: K<_, _>>(x: X) {}
145145
|
146146
help: use type parameters instead
147147
|
148-
LL | fn foo<X, T: K<T, T>>(x: X) {}
149-
| ^^^ ^ ^
148+
LL | fn foo<X: K<T, T>, T>(x: X) {}
149+
| ^ ^ ^^^
150150

151151
error[E0121]: the type placeholder `_` is not allowed within types on item signatures
152152
--> $DIR/bad-assoc-ty.rs:52:34
@@ -167,8 +167,8 @@ LL | fn baz<F: Fn() -> _>(_: F) {}
167167
|
168168
help: use type parameters instead
169169
|
170-
LL | fn baz<F, T: Fn() -> T>(_: F) {}
171-
| ^^^ ^
170+
LL | fn baz<F: Fn() -> T, T>(_: F) {}
171+
| ^^^^
172172

173173
error[E0121]: the type placeholder `_` is not allowed within types on item signatures
174174
--> $DIR/bad-assoc-ty.rs:58:33

src/test/ui/typeck/typeck_type_placeholder_item.rs

-2
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ fn test7(x: _) { let _x: usize = x; }
3232

3333
fn test8(_f: fn() -> _) { }
3434
//~^ ERROR the type placeholder `_` is not allowed within types on item signatures
35-
//~| ERROR the type placeholder `_` is not allowed within types on item signatures
3635

3736
struct Test9;
3837

@@ -99,7 +98,6 @@ pub fn main() {
9998

10099
fn fn_test8(_f: fn() -> _) { }
101100
//~^ ERROR the type placeholder `_` is not allowed within types on item signatures
102-
//~| ERROR the type placeholder `_` is not allowed within types on item signatures
103101

104102
struct FnTest9;
105103

0 commit comments

Comments
 (0)