Skip to content

Commit eaa02f5

Browse files
committed
Auto merge of #69148 - estebank:cold-as-ice, r=oli-obk
Account for bounds and asociated items when denying `_` Fix #68801, #69204. Follow up to #67597 and #68071. Output for the original ICE report: ``` Checking vinoteca v5.0.0 (/Users/ekuber/workspace/vinoteca) error[E0121]: the type placeholder `_` is not allowed within types on item signatures --> src/producers.rs:43:70 | 43 | pub fn top<Table: diesel::Table + diesel::query_dsl::InternalJoinDsl<_, diesel::query_source::joins::Inner, _>>(table: Table, limit: usize, connection: DbConn) -> RestResult<Vec<TopWineType>> { | ^ not allowed in type signatures ^ not allowed in type signatures error: aborting due to previous error ```
2 parents e2223c9 + c6cfcf9 commit eaa02f5

8 files changed

+215
-314
lines changed

src/librustc_typeck/astconv.rs

+20-2
Original file line numberDiff line numberDiff line change
@@ -514,7 +514,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
514514
self_ty: Option<Ty<'tcx>>,
515515
arg_count_correct: bool,
516516
args_for_def_id: impl Fn(DefId) -> (Option<&'b GenericArgs<'b>>, bool),
517-
provided_kind: impl Fn(&GenericParamDef, &GenericArg<'_>) -> subst::GenericArg<'tcx>,
517+
mut provided_kind: impl FnMut(&GenericParamDef, &GenericArg<'_>) -> subst::GenericArg<'tcx>,
518518
mut inferred_kind: impl FnMut(
519519
Option<&[subst::GenericArg<'tcx>]>,
520520
&GenericParamDef,
@@ -751,6 +751,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
751751
};
752752

753753
let mut missing_type_params = vec![];
754+
let mut inferred_params = vec![];
754755
let substs = Self::create_substs_for_generic_args(
755756
tcx,
756757
def_id,
@@ -773,7 +774,12 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
773774
self.ast_region_to_region(&lt, Some(param)).into()
774775
}
775776
(GenericParamDefKind::Type { .. }, GenericArg::Type(ty)) => {
776-
self.ast_ty_to_ty(&ty).into()
777+
if let (hir::TyKind::Infer, false) = (&ty.kind, self.allow_ty_infer()) {
778+
inferred_params.push(ty.span);
779+
tcx.types.err.into()
780+
} else {
781+
self.ast_ty_to_ty(&ty).into()
782+
}
777783
}
778784
(GenericParamDefKind::Const, GenericArg::Const(ct)) => {
779785
self.ast_const_to_const(&ct.value, tcx.type_of(param.def_id)).into()
@@ -832,6 +838,18 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
832838
}
833839
},
834840
);
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+
}
835853

836854
self.complain_about_missing_type_params(
837855
missing_type_params,

src/librustc_typeck/collect.rs

+27-9
Original file line numberDiff line numberDiff line change
@@ -320,7 +320,7 @@ impl AstConv<'tcx> for ItemCtxt<'tcx> {
320320
}
321321

322322
fn ty_infer(&self, _: Option<&ty::GenericParamDef>, span: Span) -> Ty<'tcx> {
323-
placeholder_type_error(self.tcx(), span, &[], vec![span], false);
323+
self.tcx().sess.delay_span_bug(span, "bad placeholder type");
324324
self.tcx().types.err
325325
}
326326

@@ -715,13 +715,21 @@ fn convert_trait_item(tcx: TyCtxt<'_>, trait_item_id: hir::HirId) {
715715
tcx.generics_of(def_id);
716716

717717
match trait_item.kind {
718-
hir::TraitItemKind::Const(..)
719-
| hir::TraitItemKind::Type(_, Some(_))
720-
| hir::TraitItemKind::Method(..) => {
718+
hir::TraitItemKind::Method(..) => {
721719
tcx.type_of(def_id);
722-
if let hir::TraitItemKind::Method(..) = trait_item.kind {
723-
tcx.fn_sig(def_id);
724-
}
720+
tcx.fn_sig(def_id);
721+
}
722+
723+
hir::TraitItemKind::Const(.., Some(_)) => {
724+
tcx.type_of(def_id);
725+
}
726+
727+
hir::TraitItemKind::Const(..) | hir::TraitItemKind::Type(_, Some(_)) => {
728+
tcx.type_of(def_id);
729+
// Account for `const C: _;` and `type T = _;`.
730+
let mut visitor = PlaceholderHirTyCollector::default();
731+
visitor.visit_trait_item(trait_item);
732+
placeholder_type_error(tcx, DUMMY_SP, &[], visitor.0, false);
725733
}
726734

727735
hir::TraitItemKind::Type(_, None) => {}
@@ -735,8 +743,18 @@ fn convert_impl_item(tcx: TyCtxt<'_>, impl_item_id: hir::HirId) {
735743
tcx.generics_of(def_id);
736744
tcx.type_of(def_id);
737745
tcx.predicates_of(def_id);
738-
if let hir::ImplItemKind::Method(..) = tcx.hir().expect_impl_item(impl_item_id).kind {
739-
tcx.fn_sig(def_id);
746+
let impl_item = tcx.hir().expect_impl_item(impl_item_id);
747+
match impl_item.kind {
748+
hir::ImplItemKind::Method(..) => {
749+
tcx.fn_sig(def_id);
750+
}
751+
hir::ImplItemKind::TyAlias(_) | hir::ImplItemKind::OpaqueTy(_) => {
752+
// Account for `type T = _;`
753+
let mut visitor = PlaceholderHirTyCollector::default();
754+
visitor.visit_impl_item(impl_item);
755+
placeholder_type_error(tcx, DUMMY_SP, &[], visitor.0, false);
756+
}
757+
hir::ImplItemKind::Const(..) => {}
740758
}
741759
}
742760

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

+4-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ type D = (u8, u8)::AssocTy;
1717
type E = _::AssocTy;
1818
//~^ ERROR missing angle brackets in associated item path
1919
//~| ERROR the type placeholder `_` is not allowed within types on item signatures
20-
//~| ERROR the type placeholder `_` is not allowed within types on item signatures
2120

2221
type F = &'static (u8)::AssocTy;
2322
//~^ ERROR missing angle brackets in associated item path
@@ -46,4 +45,8 @@ type I = ty!()::AssocTy;
4645
//~^ ERROR missing angle brackets in associated item path
4746
//~| ERROR ambiguous associated type
4847

48+
trait K<A, B> {}
49+
fn foo<X: K<_, _>>(x: X) {}
50+
//~^ ERROR the type placeholder `_` is not allowed within types on item signatures
51+
4952
fn main() {}

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

+17-15
Original file line numberDiff line numberDiff line change
@@ -29,25 +29,25 @@ LL | type E = _::AssocTy;
2929
| ^^^^^^^^^^ help: try: `<_>::AssocTy`
3030

3131
error: missing angle brackets in associated item path
32-
--> $DIR/bad-assoc-ty.rs:22:19
32+
--> $DIR/bad-assoc-ty.rs:21:19
3333
|
3434
LL | type F = &'static (u8)::AssocTy;
3535
| ^^^^^^^^^^^^^ help: try: `<(u8)>::AssocTy`
3636

3737
error: missing angle brackets in associated item path
38-
--> $DIR/bad-assoc-ty.rs:28:10
38+
--> $DIR/bad-assoc-ty.rs:27:10
3939
|
4040
LL | type G = dyn 'static + (Send)::AssocTy;
4141
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `<dyn 'static + (Send)>::AssocTy`
4242

4343
error: missing angle brackets in associated item path
44-
--> $DIR/bad-assoc-ty.rs:45:10
44+
--> $DIR/bad-assoc-ty.rs:44:10
4545
|
4646
LL | type I = ty!()::AssocTy;
4747
| ^^^^^^^^^^^^^^ help: try: `<ty!()>::AssocTy`
4848

4949
error: missing angle brackets in associated item path
50-
--> $DIR/bad-assoc-ty.rs:38:19
50+
--> $DIR/bad-assoc-ty.rs:37:19
5151
|
5252
LL | ($ty: ty) => ($ty::AssocTy);
5353
| ^^^^^^^^^^^^ help: try: `<$ty>::AssocTy`
@@ -87,32 +87,26 @@ error[E0121]: the type placeholder `_` is not allowed within types on item signa
8787
LL | type E = _::AssocTy;
8888
| ^ not allowed in type signatures
8989

90-
error[E0121]: the type placeholder `_` is not allowed within types on item signatures
91-
--> $DIR/bad-assoc-ty.rs:17:10
92-
|
93-
LL | type E = _::AssocTy;
94-
| ^ not allowed in type signatures
95-
9690
error[E0223]: ambiguous associated type
97-
--> $DIR/bad-assoc-ty.rs:22:19
91+
--> $DIR/bad-assoc-ty.rs:21:19
9892
|
9993
LL | type F = &'static (u8)::AssocTy;
10094
| ^^^^^^^^^^^^^ help: use fully-qualified syntax: `<u8 as Trait>::AssocTy`
10195

10296
error[E0223]: ambiguous associated type
103-
--> $DIR/bad-assoc-ty.rs:28:10
97+
--> $DIR/bad-assoc-ty.rs:27:10
10498
|
10599
LL | type G = dyn 'static + (Send)::AssocTy;
106100
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use fully-qualified syntax: `<(dyn std::marker::Send + 'static) as Trait>::AssocTy`
107101

108102
error[E0223]: ambiguous associated type
109-
--> $DIR/bad-assoc-ty.rs:34:10
103+
--> $DIR/bad-assoc-ty.rs:33:10
110104
|
111105
LL | type H = Fn(u8) -> (u8)::Output;
112106
| ^^^^^^^^^^^^^^^^^^^^^^ help: use fully-qualified syntax: `<(dyn std::ops::Fn(u8) -> u8 + 'static) as Trait>::Output`
113107

114108
error[E0223]: ambiguous associated type
115-
--> $DIR/bad-assoc-ty.rs:38:19
109+
--> $DIR/bad-assoc-ty.rs:37:19
116110
|
117111
LL | ($ty: ty) => ($ty::AssocTy);
118112
| ^^^^^^^^^^^^ help: use fully-qualified syntax: `<u8 as Trait>::AssocTy`
@@ -123,11 +117,19 @@ LL | type J = ty!(u8);
123117
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
124118

125119
error[E0223]: ambiguous associated type
126-
--> $DIR/bad-assoc-ty.rs:45:10
120+
--> $DIR/bad-assoc-ty.rs:44:10
127121
|
128122
LL | type I = ty!()::AssocTy;
129123
| ^^^^^^^^^^^^^^ help: use fully-qualified syntax: `<u8 as Trait>::AssocTy`
130124

125+
error[E0121]: the type placeholder `_` is not allowed within types on item signatures
126+
--> $DIR/bad-assoc-ty.rs:49:13
127+
|
128+
LL | fn foo<X: K<_, _>>(x: X) {}
129+
| ^ ^ not allowed in type signatures
130+
| |
131+
| not allowed in type signatures
132+
131133
error: aborting due to 20 previous errors
132134

133135
Some errors have detailed explanations: E0121, E0223.

src/test/ui/self/self-infer.rs

-2
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,7 @@ struct S;
22

33
impl S {
44
fn f(self: _) {} //~ERROR the type placeholder `_` is not allowed within types on item sig
5-
//~^ ERROR the type placeholder `_` is not allowed within types on item sig
65
fn g(self: &_) {} //~ERROR the type placeholder `_` is not allowed within types on item sig
7-
//~^ ERROR the type placeholder `_` is not allowed within types on item sig
86
}
97

108
fn main() {}

src/test/ui/self/self-infer.stderr

+2-14
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,3 @@
1-
error[E0121]: the type placeholder `_` is not allowed within types on item signatures
2-
--> $DIR/self-infer.rs:4:16
3-
|
4-
LL | fn f(self: _) {}
5-
| ^ not allowed in type signatures
6-
71
error[E0121]: the type placeholder `_` is not allowed within types on item signatures
82
--> $DIR/self-infer.rs:4:16
93
|
@@ -16,13 +10,7 @@ LL | fn f<T>(self: T) {}
1610
| ^^^ ^
1711

1812
error[E0121]: the type placeholder `_` is not allowed within types on item signatures
19-
--> $DIR/self-infer.rs:6:17
20-
|
21-
LL | fn g(self: &_) {}
22-
| ^ not allowed in type signatures
23-
24-
error[E0121]: the type placeholder `_` is not allowed within types on item signatures
25-
--> $DIR/self-infer.rs:6:17
13+
--> $DIR/self-infer.rs:5:17
2614
|
2715
LL | fn g(self: &_) {}
2816
| ^ not allowed in type signatures
@@ -32,6 +20,6 @@ help: use type parameters instead
3220
LL | fn g<T>(self: &T) {}
3321
| ^^^ ^
3422

35-
error: aborting due to 4 previous errors
23+
error: aborting due to 2 previous errors
3624

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

0 commit comments

Comments
 (0)