diff options
| author | Eduard-Mihai Burtescu <edy.burt@gmail.com> | 2020-03-22 11:15:56 +0200 |
|---|---|---|
| committer | Eduard-Mihai Burtescu <edy.burt@gmail.com> | 2020-04-04 08:00:26 +0300 |
| commit | a98b5340d1768e631e2afbe9d00f2f2813ec1cfb (patch) | |
| tree | 1005c18fbf5fd8dbe439ae98ca2eb7d5024d21e3 | |
| parent | 64651138524b45a7e18bec7dcaf143c7fa4f2794 (diff) | |
| download | rust-a98b5340d1768e631e2afbe9d00f2f2813ec1cfb.tar.gz rust-a98b5340d1768e631e2afbe9d00f2f2813ec1cfb.zip | |
typeck/type_of: don't ignore incorrect defining uses of opaque types.
16 files changed, 48 insertions, 67 deletions
diff --git a/src/librustc_typeck/collect/type_of.rs b/src/librustc_typeck/collect/type_of.rs index acf593c2912..79782c28253 100644 --- a/src/librustc_typeck/collect/type_of.rs +++ b/src/librustc_typeck/collect/type_of.rs @@ -405,12 +405,12 @@ fn find_opaque_ty_constraints(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> { let opaque_generics = self.tcx.generics_of(self.def_id); let mut used_params: FxHashSet<ty::ParamTy> = FxHashSet::default(); - let mut has_errors = false; + let mut duplicate_params: FxHashSet<ty::ParamTy> = FxHashSet::default(); for (i, arg) in substs.iter().enumerate() { // FIXME(eddyb) enforce lifetime and const param 1:1 mapping. if let GenericArgKind::Type(ty) = arg.unpack() { if let ty::Param(p) = ty.kind { - if !used_params.insert(p) { + if !used_params.insert(p) && duplicate_params.insert(p) { // There was already an entry for `p`, meaning a generic parameter // was used twice. self.tcx.sess.span_err( @@ -421,7 +421,6 @@ fn find_opaque_ty_constraints(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> { p, ), ); - return; } } else { let param = opaque_generics.param_at(i, self.tcx); @@ -435,15 +434,10 @@ fn find_opaque_ty_constraints(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> { arg, ), ); - has_errors = true; } } } - if has_errors { - return; - } - if let Some((prev_span, prev_ty)) = self.found { if *concrete_type != prev_ty { debug!("find_opaque_ty_constraints: span={:?}", span); diff --git a/src/test/ui/type-alias-impl-trait/bound_reduction2.rs b/src/test/ui/type-alias-impl-trait/bound_reduction2.rs index 1becb1e83a5..3bc40c43d77 100644 --- a/src/test/ui/type-alias-impl-trait/bound_reduction2.rs +++ b/src/test/ui/type-alias-impl-trait/bound_reduction2.rs @@ -8,8 +8,7 @@ trait TraitWithAssoc { } type Foo<V> = impl Trait<V>; -//~^ ERROR could not find defining uses -//~| ERROR the trait bound `T: TraitWithAssoc` is not satisfied +//~^ ERROR the trait bound `T: TraitWithAssoc` is not satisfied trait Trait<U> {} diff --git a/src/test/ui/type-alias-impl-trait/bound_reduction2.stderr b/src/test/ui/type-alias-impl-trait/bound_reduction2.stderr index aff558569ea..316ea97efb5 100644 --- a/src/test/ui/type-alias-impl-trait/bound_reduction2.stderr +++ b/src/test/ui/type-alias-impl-trait/bound_reduction2.stderr @@ -10,19 +10,13 @@ LL | fn foo_desugared<T: TraitWithAssoc + TraitWithAssoc>(_: T) -> Foo<T::Assoc> | ^^^^^^^^^^^^^^^^ error: defining opaque type use does not fully define opaque type: generic parameter `V` is specified as concrete type `<T as TraitWithAssoc>::Assoc` - --> $DIR/bound_reduction2.rs:18:1 + --> $DIR/bound_reduction2.rs:17:1 | LL | / fn foo_desugared<T: TraitWithAssoc>(_: T) -> Foo<T::Assoc> { LL | | () LL | | } | |_^ -error: could not find defining uses - --> $DIR/bound_reduction2.rs:10:1 - | -LL | type Foo<V> = impl Trait<V>; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use.rs b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use.rs index 165e320be5e..3993cebeb44 100644 --- a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use.rs +++ b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use.rs @@ -6,7 +6,6 @@ fn main() {} // test that unused generic parameters are ok type Two<T, U> = impl Debug; -//~^ could not find defining uses fn one<T: Debug>(t: T) -> Two<T, T> { //~^ ERROR defining opaque type use restricts opaque type diff --git a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use.stderr b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use.stderr index e1794034e20..4a02e85faea 100644 --- a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use.stderr +++ b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use.stderr @@ -1,5 +1,5 @@ error: defining opaque type use restricts opaque type by using the generic parameter `T` twice - --> $DIR/generic_duplicate_param_use.rs:11:1 + --> $DIR/generic_duplicate_param_use.rs:10:1 | LL | / fn one<T: Debug>(t: T) -> Two<T, T> { LL | | @@ -7,11 +7,5 @@ LL | | t LL | | } | |_^ -error: could not find defining uses - --> $DIR/generic_duplicate_param_use.rs:8:1 - | -LL | type Two<T, U> = impl Debug; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: aborting due to 2 previous errors +error: aborting due to previous error diff --git a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use2.rs b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use2.rs index 0adce817c5c..b1d3260eba3 100644 --- a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use2.rs +++ b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use2.rs @@ -8,10 +8,11 @@ fn main() {} type Two<T, U> = impl Debug; fn one<T: Debug>(t: T) -> Two<T, T> { -//~^ defining opaque type use restricts opaque type +//~^ ERROR defining opaque type use restricts opaque type t } fn two<T: Debug, U>(t: T, _: U) -> Two<T, U> { +//~^ ERROR concrete type differs from previous defining opaque type use t } diff --git a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use2.stderr b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use2.stderr index a9a51fa0b4b..f8cc49ba99f 100644 --- a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use2.stderr +++ b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use2.stderr @@ -7,5 +7,23 @@ LL | | t LL | | } | |_^ -error: aborting due to previous error +error: concrete type differs from previous defining opaque type use + --> $DIR/generic_duplicate_param_use2.rs:15:1 + | +LL | / fn two<T: Debug, U>(t: T, _: U) -> Two<T, U> { +LL | | +LL | | t +LL | | } + | |_^ expected `U`, got `T` + | +note: previous use here + --> $DIR/generic_duplicate_param_use2.rs:10:1 + | +LL | / fn one<T: Debug>(t: T) -> Two<T, T> { +LL | | +LL | | t +LL | | } + | |_^ + +error: aborting due to 2 previous errors diff --git a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use3.rs b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use3.rs index ec9f40851c5..40f20af07b5 100644 --- a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use3.rs +++ b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use3.rs @@ -8,15 +8,15 @@ fn main() {} type Two<T, U> = impl Debug; fn one<T: Debug>(t: T) -> Two<T, T> { -//~^ defining opaque type use restricts opaque type +//~^ ERROR defining opaque type use restricts opaque type t } fn two<T: Debug, U>(t: T, _: U) -> Two<T, U> { +//~^ ERROR concrete type differs from previous defining opaque type use t } fn three<T, U: Debug>(_: T, u: U) -> Two<T, U> { -//~^ concrete type differs from previous defining opaque type use u } diff --git a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use3.stderr b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use3.stderr index 51bee41aba3..1171befd0b1 100644 --- a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use3.stderr +++ b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use3.stderr @@ -8,18 +8,19 @@ LL | | } | |_^ error: concrete type differs from previous defining opaque type use - --> $DIR/generic_duplicate_param_use3.rs:19:1 + --> $DIR/generic_duplicate_param_use3.rs:15:1 | -LL | / fn three<T, U: Debug>(_: T, u: U) -> Two<T, U> { +LL | / fn two<T: Debug, U>(t: T, _: U) -> Two<T, U> { LL | | -LL | | u +LL | | t LL | | } - | |_^ expected `T`, got `U` + | |_^ expected `U`, got `T` | note: previous use here - --> $DIR/generic_duplicate_param_use3.rs:15:1 + --> $DIR/generic_duplicate_param_use3.rs:10:1 | -LL | / fn two<T: Debug, U>(t: T, _: U) -> Two<T, U> { +LL | / fn one<T: Debug>(t: T) -> Two<T, T> { +LL | | LL | | t LL | | } | |_^ diff --git a/src/test/ui/type-alias-impl-trait/generic_nondefining_use.rs b/src/test/ui/type-alias-impl-trait/generic_nondefining_use.rs index 60106eba175..bb68975cd30 100644 --- a/src/test/ui/type-alias-impl-trait/generic_nondefining_use.rs +++ b/src/test/ui/type-alias-impl-trait/generic_nondefining_use.rs @@ -3,8 +3,7 @@ fn main() {} type Cmp<T> = impl 'static; -//~^ ERROR could not find defining uses -//~^^ ERROR: at least one trait must be specified +//~^ ERROR: at least one trait must be specified // not a defining use, because it doesn't define *all* possible generics diff --git a/src/test/ui/type-alias-impl-trait/generic_nondefining_use.stderr b/src/test/ui/type-alias-impl-trait/generic_nondefining_use.stderr index b952aaa79cc..553b8381b0e 100644 --- a/src/test/ui/type-alias-impl-trait/generic_nondefining_use.stderr +++ b/src/test/ui/type-alias-impl-trait/generic_nondefining_use.stderr @@ -5,18 +5,12 @@ LL | type Cmp<T> = impl 'static; | ^^^^^^^^^^^^ error: defining opaque type use does not fully define opaque type: generic parameter `T` is specified as concrete type `u32` - --> $DIR/generic_nondefining_use.rs:11:1 + --> $DIR/generic_nondefining_use.rs:10:1 | LL | / fn cmp() -> Cmp<u32> { LL | | 5u32 LL | | } | |_^ -error: could not find defining uses - --> $DIR/generic_nondefining_use.rs:5:1 - | -LL | type Cmp<T> = impl 'static; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors diff --git a/src/test/ui/type-alias-impl-trait/issue-60564.rs b/src/test/ui/type-alias-impl-trait/issue-60564.rs index 73acc92172b..06f1f3430b2 100644 --- a/src/test/ui/type-alias-impl-trait/issue-60564.rs +++ b/src/test/ui/type-alias-impl-trait/issue-60564.rs @@ -6,7 +6,6 @@ trait IterBits { } type IterBitsIter<T, E, I> = impl std::iter::Iterator<Item = I>; -//~^ ERROR could not find defining uses impl<T: Copy, E> IterBits for T where diff --git a/src/test/ui/type-alias-impl-trait/issue-60564.stderr b/src/test/ui/type-alias-impl-trait/issue-60564.stderr index 9de3e759e15..2ed7e1376c1 100644 --- a/src/test/ui/type-alias-impl-trait/issue-60564.stderr +++ b/src/test/ui/type-alias-impl-trait/issue-60564.stderr @@ -1,5 +1,5 @@ error: defining opaque type use does not fully define opaque type: generic parameter `I` is specified as concrete type `u8` - --> $DIR/issue-60564.rs:20:5 + --> $DIR/issue-60564.rs:19:5 | LL | / fn iter_bits(self, n: u8) -> Self::BitsIter { LL | | @@ -9,11 +9,5 @@ LL | | .map(move |shift| ((self >> T::from(shift)) & T::from(1)).try LL | | } | |_____^ -error: could not find defining uses - --> $DIR/issue-60564.rs:8:1 - | -LL | type IterBitsIter<T, E, I> = impl std::iter::Iterator<Item = I>; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: aborting due to 2 previous errors +error: aborting due to previous error diff --git a/src/test/ui/type-alias-impl-trait/issue-68368-non-defining-use.rs b/src/test/ui/type-alias-impl-trait/issue-68368-non-defining-use.rs index d00f8d7a901..060336b9661 100644 --- a/src/test/ui/type-alias-impl-trait/issue-68368-non-defining-use.rs +++ b/src/test/ui/type-alias-impl-trait/issue-68368-non-defining-use.rs @@ -4,7 +4,7 @@ #![feature(type_alias_impl_trait)] trait Trait<T> {} -type Alias<'a, U> = impl Trait<U>; //~ ERROR could not find defining uses +type Alias<'a, U> = impl Trait<U>; fn f<'a>() -> Alias<'a, ()> {} //~^ ERROR defining opaque type use does not fully define opaque type: generic parameter `U` diff --git a/src/test/ui/type-alias-impl-trait/issue-68368-non-defining-use.stderr b/src/test/ui/type-alias-impl-trait/issue-68368-non-defining-use.stderr index b585942406f..f8ad443f721 100644 --- a/src/test/ui/type-alias-impl-trait/issue-68368-non-defining-use.stderr +++ b/src/test/ui/type-alias-impl-trait/issue-68368-non-defining-use.stderr @@ -4,11 +4,5 @@ error: defining opaque type use does not fully define opaque type: generic param LL | fn f<'a>() -> Alias<'a, ()> {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: could not find defining uses - --> $DIR/issue-68368-non-defining-use.rs:7:1 - | -LL | type Alias<'a, U> = impl Trait<U>; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: aborting due to 2 previous errors +error: aborting due to previous error diff --git a/src/test/ui/type-alias-impl-trait/not_a_defining_use.stderr b/src/test/ui/type-alias-impl-trait/not_a_defining_use.stderr index d68f1bd30a0..a5deeb3b7a3 100644 --- a/src/test/ui/type-alias-impl-trait/not_a_defining_use.stderr +++ b/src/test/ui/type-alias-impl-trait/not_a_defining_use.stderr @@ -16,10 +16,11 @@ LL | | } | |_^ expected `(T, i8)`, got `(T, <U as Bar>::Blub)` | note: previous use here - --> $DIR/not_a_defining_use.rs:14:1 + --> $DIR/not_a_defining_use.rs:9:1 | -LL | / fn three<T: Debug, U>(t: T) -> Two<T, U> { -LL | | (t, 5i8) +LL | / fn two<T: Debug>(t: T) -> Two<T, u32> { +LL | | +LL | | (t, 4i8) LL | | } | |_^ |
