Skip to content

Commit 8e9a5d9

Browse files
committed
typeck/type_of: let wfcheck handle concrete types in opaque types' substs.
1 parent a98b534 commit 8e9a5d9

12 files changed

+71
-61
lines changed

src/librustc_typeck/check/wfcheck.rs

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -864,13 +864,15 @@ fn check_opaque_types<'fcx, 'tcx>(
864864
trace!("check_opaque_types: opaque_ty, {:?}, {:?}", def_id, substs);
865865
let generics = tcx.generics_of(def_id);
866866
// Only check named `impl Trait` types defined in this crate.
867+
// FIXME(eddyb) is `generics.parent.is_none()` correct? It seems
868+
// potentially risky wrt associated types in `impl`s.
867869
if generics.parent.is_none() && def_id.is_local() {
868870
let opaque_hir_id = tcx.hir().as_local_hir_id(def_id).unwrap();
869871
if may_define_opaque_type(tcx, fn_def_id, opaque_hir_id) {
870872
trace!("check_opaque_types: may define, generics={:#?}", generics);
871873
let mut seen: FxHashMap<_, Vec<_>> = FxHashMap::default();
872-
for (subst, param) in substs.iter().zip(&generics.params) {
873-
match subst.unpack() {
874+
for (i, &arg) in substs.iter().enumerate() {
875+
match arg.unpack() {
874876
ty::subst::GenericArgKind::Type(ty) => match ty.kind {
875877
ty::Param(..) => {}
876878
// Prevent `fn foo() -> Foo<u32>` from being defining.
@@ -882,9 +884,9 @@ fn check_opaque_types<'fcx, 'tcx>(
882884
in defining scope",
883885
)
884886
.span_note(
885-
tcx.def_span(param.def_id),
887+
tcx.def_span(generics.param_at(i, tcx).def_id),
886888
&format!(
887-
"used non-generic type {} for \
889+
"used non-generic type `{}` for \
888890
generic parameter",
889891
ty,
890892
),
@@ -894,7 +896,6 @@ fn check_opaque_types<'fcx, 'tcx>(
894896
},
895897

896898
ty::subst::GenericArgKind::Lifetime(region) => {
897-
let param_span = tcx.def_span(param.def_id);
898899
if let ty::ReStatic = region {
899900
tcx.sess
900901
.struct_span_err(
@@ -903,14 +904,14 @@ fn check_opaque_types<'fcx, 'tcx>(
903904
in defining scope",
904905
)
905906
.span_label(
906-
param_span,
907+
tcx.def_span(generics.param_at(i, tcx).def_id),
907908
"cannot use static lifetime; use a bound lifetime \
908909
instead or remove the lifetime parameter from the \
909910
opaque type",
910911
)
911912
.emit();
912913
} else {
913-
seen.entry(region).or_default().push(param_span);
914+
seen.entry(region).or_default().push(i);
914915
}
915916
}
916917

@@ -924,20 +925,24 @@ fn check_opaque_types<'fcx, 'tcx>(
924925
in defining scope",
925926
)
926927
.span_note(
927-
tcx.def_span(param.def_id),
928+
tcx.def_span(generics.param_at(i, tcx).def_id),
928929
&format!(
929-
"used non-generic const {} for \
930+
"used non-generic const `{}` for \
930931
generic parameter",
931-
ty,
932+
ct,
932933
),
933934
)
934935
.emit();
935936
}
936937
},
937-
} // match subst
938-
} // for (subst, param)
939-
for (_, spans) in seen {
940-
if spans.len() > 1 {
938+
} // match arg
939+
} // for (arg, param)
940+
for (_, indices) in seen {
941+
if indices.len() > 1 {
942+
let spans: Vec<_> = indices
943+
.into_iter()
944+
.map(|i| tcx.def_span(generics.param_at(i, tcx).def_id))
945+
.collect();
941946
tcx.sess
942947
.struct_span_err(
943948
span,

src/librustc_typeck/collect/type_of.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -424,7 +424,7 @@ fn find_opaque_ty_constraints(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
424424
}
425425
} else {
426426
let param = opaque_generics.param_at(i, self.tcx);
427-
self.tcx.sess.span_err(
427+
self.tcx.sess.delay_span_bug(
428428
span,
429429
&format!(
430430
"defining opaque type use does not fully define opaque type: \

src/test/ui/type-alias-impl-trait/bound_reduction2.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,6 @@ trait Trait<U> {}
1414

1515
impl<W> Trait<W> for () {}
1616

17-
fn foo_desugared<T: TraitWithAssoc>(_: T) -> Foo<T::Assoc> { //~ ERROR does not fully define
17+
fn foo_desugared<T: TraitWithAssoc>(_: T) -> Foo<T::Assoc> {
1818
()
1919
}

src/test/ui/type-alias-impl-trait/bound_reduction2.stderr

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,6 @@ help: consider further restricting this bound
99
LL | fn foo_desugared<T: TraitWithAssoc + TraitWithAssoc>(_: T) -> Foo<T::Assoc> {
1010
| ^^^^^^^^^^^^^^^^
1111

12-
error: defining opaque type use does not fully define opaque type: generic parameter `V` is specified as concrete type `<T as TraitWithAssoc>::Assoc`
13-
--> $DIR/bound_reduction2.rs:17:1
14-
|
15-
LL | / fn foo_desugared<T: TraitWithAssoc>(_: T) -> Foo<T::Assoc> {
16-
LL | | ()
17-
LL | | }
18-
| |_^
19-
20-
error: aborting due to 2 previous errors
12+
error: aborting due to previous error
2113

2214
For more information about this error, try `rustc --explain E0277`.

src/test/ui/type-alias-impl-trait/generic_nondefining_use.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,6 @@ type Cmp<T> = impl 'static;
77

88

99
// not a defining use, because it doesn't define *all* possible generics
10-
fn cmp() -> Cmp<u32> { //~ ERROR defining opaque type use does not fully define
10+
fn cmp() -> Cmp<u32> { //~ ERROR non-defining opaque type use in defining scope
1111
5u32
1212
}

src/test/ui/type-alias-impl-trait/generic_nondefining_use.stderr

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,17 @@ error: at least one trait must be specified
44
LL | type Cmp<T> = impl 'static;
55
| ^^^^^^^^^^^^
66

7-
error: defining opaque type use does not fully define opaque type: generic parameter `T` is specified as concrete type `u32`
8-
--> $DIR/generic_nondefining_use.rs:10:1
7+
error: non-defining opaque type use in defining scope
8+
--> $DIR/generic_nondefining_use.rs:10:13
99
|
10-
LL | / fn cmp() -> Cmp<u32> {
11-
LL | | 5u32
12-
LL | | }
13-
| |_^
10+
LL | fn cmp() -> Cmp<u32> {
11+
| ^^^^^^^^
12+
|
13+
note: used non-generic type `u32` for generic parameter
14+
--> $DIR/generic_nondefining_use.rs:5:10
15+
|
16+
LL | type Cmp<T> = impl 'static;
17+
| ^
1418

1519
error: aborting due to 2 previous errors
1620

src/test/ui/type-alias-impl-trait/issue-60564.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@ where
1717
{
1818
type BitsIter = IterBitsIter<T, E, u8>;
1919
fn iter_bits(self, n: u8) -> Self::BitsIter {
20-
//~^ ERROR defining opaque type use does not fully define opaque type
20+
//~^ ERROR non-defining opaque type use in defining scope
21+
//~| ERROR non-defining opaque type use in defining scope
2122
(0u8..n)
2223
.rev()
2324
.map(move |shift| ((self >> T::from(shift)) & T::from(1)).try_into().unwrap())
Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,26 @@
1-
error: defining opaque type use does not fully define opaque type: generic parameter `I` is specified as concrete type `u8`
2-
--> $DIR/issue-60564.rs:19:5
3-
|
4-
LL | / fn iter_bits(self, n: u8) -> Self::BitsIter {
5-
LL | |
6-
LL | | (0u8..n)
7-
LL | | .rev()
8-
LL | | .map(move |shift| ((self >> T::from(shift)) & T::from(1)).try_into().unwrap())
9-
LL | | }
10-
| |_____^
1+
error: non-defining opaque type use in defining scope
2+
--> $DIR/issue-60564.rs:19:34
3+
|
4+
LL | fn iter_bits(self, n: u8) -> Self::BitsIter {
5+
| ^^^^^^^^^^^^^^
6+
|
7+
note: used non-generic type `_` for generic parameter
8+
--> $DIR/issue-60564.rs:8:22
9+
|
10+
LL | type IterBitsIter<T, E, I> = impl std::iter::Iterator<Item = I>;
11+
| ^
12+
13+
error: non-defining opaque type use in defining scope
14+
--> $DIR/issue-60564.rs:19:34
15+
|
16+
LL | fn iter_bits(self, n: u8) -> Self::BitsIter {
17+
| ^^^^^^^^^^^^^^
18+
|
19+
note: used non-generic type `u8` for generic parameter
20+
--> $DIR/issue-60564.rs:8:25
21+
|
22+
LL | type IterBitsIter<T, E, I> = impl std::iter::Iterator<Item = I>;
23+
| ^
1124

12-
error: aborting due to previous error
25+
error: aborting due to 2 previous errors
1326

src/test/ui/type-alias-impl-trait/issue-68368-non-defining-use.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
trait Trait<T> {}
77
type Alias<'a, U> = impl Trait<U>;
88
fn f<'a>() -> Alias<'a, ()> {}
9-
//~^ ERROR defining opaque type use does not fully define opaque type: generic parameter `U`
9+
//~^ ERROR non-defining opaque type use in defining scope
1010

1111
fn main() {}
1212

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,14 @@
1-
error: defining opaque type use does not fully define opaque type: generic parameter `U` is specified as concrete type `()`
2-
--> $DIR/issue-68368-non-defining-use.rs:8:1
1+
error: non-defining opaque type use in defining scope
2+
--> $DIR/issue-68368-non-defining-use.rs:8:15
33
|
44
LL | fn f<'a>() -> Alias<'a, ()> {}
5-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
5+
| ^^^^^^^^^^^^^
6+
|
7+
note: used non-generic type `()` for generic parameter
8+
--> $DIR/issue-68368-non-defining-use.rs:7:16
9+
|
10+
LL | type Alias<'a, U> = impl Trait<U>;
11+
| ^
612

713
error: aborting due to previous error
814

src/test/ui/type-alias-impl-trait/not_a_defining_use.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ fn main() {}
77
type Two<T, U> = impl Debug;
88

99
fn two<T: Debug>(t: T) -> Two<T, u32> {
10-
//~^ ERROR defining opaque type use does not fully define opaque type
1110
(t, 4i8)
1211
}
1312

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,5 @@
1-
error: defining opaque type use does not fully define opaque type: generic parameter `U` is specified as concrete type `u32`
2-
--> $DIR/not_a_defining_use.rs:9:1
3-
|
4-
LL | / fn two<T: Debug>(t: T) -> Two<T, u32> {
5-
LL | |
6-
LL | | (t, 4i8)
7-
LL | | }
8-
| |_^
9-
101
error: concrete type differs from previous defining opaque type use
11-
--> $DIR/not_a_defining_use.rs:30:1
2+
--> $DIR/not_a_defining_use.rs:29:1
123
|
134
LL | / fn four<T: Debug, U: Bar>(t: T) -> Two<T, U> {
145
LL | | (t, <U as Bar>::FOO)
@@ -19,10 +10,9 @@ note: previous use here
1910
--> $DIR/not_a_defining_use.rs:9:1
2011
|
2112
LL | / fn two<T: Debug>(t: T) -> Two<T, u32> {
22-
LL | |
2313
LL | | (t, 4i8)
2414
LL | | }
2515
| |_^
2616

27-
error: aborting due to 2 previous errors
17+
error: aborting due to previous error
2818

0 commit comments

Comments
 (0)