Skip to content

Commit 6b47cba

Browse files
committed
Improve error message when opaque type is not fully constrained
1 parent 4b57d22 commit 6b47cba

File tree

8 files changed

+21
-46
lines changed

8 files changed

+21
-46
lines changed

src/librustc_typeck/collect.rs

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1617,11 +1617,18 @@ fn find_opaque_ty_constraints(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
16171617
ty::Param(_) => true,
16181618
_ => false,
16191619
};
1620-
if !substs.types().all(is_param) {
1621-
self.tcx.sess.span_err(
1622-
span,
1623-
"defining opaque type use does not fully define opaque type",
1624-
);
1620+
let bad_substs: Vec<_> = substs.types().enumerate()
1621+
.filter(|(_, ty)| !is_param(ty)).collect();
1622+
if !bad_substs.is_empty() {
1623+
let identity_substs = InternalSubsts::identity_for_item(self.tcx, self.def_id);
1624+
for (i, bad_subst) in bad_substs {
1625+
self.tcx.sess.span_err(
1626+
span,
1627+
&format!("defining opaque type use does not fully define opaque type: \
1628+
generic parameter `{}` is specified as concrete type `{}`",
1629+
identity_substs.type_at(i), bad_subst)
1630+
);
1631+
}
16251632
} else if let Some((prev_span, prev_ty, ref prev_indices)) = self.found {
16261633
let mut ty = concrete_type.walk().fuse();
16271634
let mut p_ty = prev_ty.walk().fuse();

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
error: defining opaque type use does not fully define opaque type
1+
error: defining opaque type use does not fully define opaque type: generic parameter `V` is specified as concrete type `<T as TraitWithAssoc>::Assoc`
22
--> $DIR/bound_reduction2.rs:17:1
33
|
44
LL | / fn foo_desugared<T: TraitWithAssoc>(_: T) -> Foo<T::Assoc> {

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ 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
7+
error: defining opaque type use does not fully define opaque type: generic parameter `T` is specified as concrete type `u32`
88
--> $DIR/generic_nondefining_use.rs:11:1
99
|
1010
LL | / fn cmp() -> Cmp<u32> {

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

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
// run-pass
2+
13
#![feature(type_alias_impl_trait)]
24

35
trait UnwrapItemsExt {
@@ -11,11 +13,8 @@ where
1113
E: std::fmt::Debug,
1214
{
1315
type Iter = impl Iterator<Item = T>;
14-
//~^ ERROR: could not find defining uses
1516

1617
fn unwrap_items(self) -> Self::Iter {
17-
//~^ ERROR: type parameter `T` is part of concrete type
18-
//~| ERROR: type parameter `E` is part of concrete type
1918
self.map(|x| x.unwrap())
2019
}
2120
}

src/test/ui/type-alias-impl-trait/issue-58887.stderr

Lines changed: 0 additions & 30 deletions
This file was deleted.

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ where
1818
{
1919
type BitsIter = IterBitsIter<T, E, u8>;
2020
fn iter_bits(self, n: u8) -> Self::BitsIter {
21-
//~^ ERROR type parameter `E` is part of concrete type but not used
21+
//~^ ERROR defining opaque type use does not fully define opaque typ
2222
(0u8..n)
2323
.rev()
2424
.map(move |shift| ((self >> T::from(shift)) & T::from(1)).try_into().unwrap())

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

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
1-
error: type parameter `E` is part of concrete type but not used in parameter list for the `impl Trait` type alias
2-
--> $DIR/issue-60564.rs:20:49
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:20:5
33
|
4-
LL | fn iter_bits(self, n: u8) -> Self::BitsIter {
5-
| _________________________________________________^
4+
LL | / fn iter_bits(self, n: u8) -> Self::BitsIter {
65
LL | |
76
LL | | (0u8..n)
87
LL | | .rev()

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
error: defining opaque type use does not fully define opaque type
1+
error: defining opaque type use does not fully define opaque type: generic parameter `U` is specified as concrete type `u32`
22
--> $DIR/not_a_defining_use.rs:9:1
33
|
44
LL | / fn two<T: Debug>(t: T) -> Two<T, u32> {

0 commit comments

Comments
 (0)