summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEduard-Mihai Burtescu <edy.burt@gmail.com>2020-03-22 12:16:51 +0200
committerEduard-Mihai Burtescu <edy.burt@gmail.com>2020-04-04 08:20:58 +0300
commit8e9a5d928a035a13fea5d134eaa7c1657407692d (patch)
tree6c235d36eab9d2e682b81ff7a534b34b4aedec37
parenta98b5340d1768e631e2afbe9d00f2f2813ec1cfb (diff)
downloadrust-8e9a5d928a035a13fea5d134eaa7c1657407692d.tar.gz
typeck/type_of: let wfcheck handle concrete types in opaque types' substs.
-rw-r--r--src/librustc_typeck/check/wfcheck.rs33
-rw-r--r--src/librustc_typeck/collect/type_of.rs2
-rw-r--r--src/test/ui/type-alias-impl-trait/bound_reduction2.rs2
-rw-r--r--src/test/ui/type-alias-impl-trait/bound_reduction2.stderr10
-rw-r--r--src/test/ui/type-alias-impl-trait/generic_nondefining_use.rs2
-rw-r--r--src/test/ui/type-alias-impl-trait/generic_nondefining_use.stderr16
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-60564.rs3
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-60564.stderr35
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-68368-non-defining-use.rs2
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-68368-non-defining-use.stderr12
-rw-r--r--src/test/ui/type-alias-impl-trait/not_a_defining_use.rs1
-rw-r--r--src/test/ui/type-alias-impl-trait/not_a_defining_use.stderr14
12 files changed, 71 insertions, 61 deletions
diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs
index 30a53cbc397..43bf7660ac2 100644
--- a/src/librustc_typeck/check/wfcheck.rs
+++ b/src/librustc_typeck/check/wfcheck.rs
@@ -864,13 +864,15 @@ fn check_opaque_types<'fcx, 'tcx>(
trace!("check_opaque_types: opaque_ty, {:?}, {:?}", def_id, substs);
let generics = tcx.generics_of(def_id);
// Only check named `impl Trait` types defined in this crate.
+ // FIXME(eddyb) is `generics.parent.is_none()` correct? It seems
+ // potentially risky wrt associated types in `impl`s.
if generics.parent.is_none() && def_id.is_local() {
let opaque_hir_id = tcx.hir().as_local_hir_id(def_id).unwrap();
if may_define_opaque_type(tcx, fn_def_id, opaque_hir_id) {
trace!("check_opaque_types: may define, generics={:#?}", generics);
let mut seen: FxHashMap<_, Vec<_>> = FxHashMap::default();
- for (subst, param) in substs.iter().zip(&generics.params) {
- match subst.unpack() {
+ for (i, &arg) in substs.iter().enumerate() {
+ match arg.unpack() {
ty::subst::GenericArgKind::Type(ty) => match ty.kind {
ty::Param(..) => {}
// Prevent `fn foo() -> Foo<u32>` from being defining.
@@ -882,9 +884,9 @@ fn check_opaque_types<'fcx, 'tcx>(
in defining scope",
)
.span_note(
- tcx.def_span(param.def_id),
+ tcx.def_span(generics.param_at(i, tcx).def_id),
&format!(
- "used non-generic type {} for \
+ "used non-generic type `{}` for \
generic parameter",
ty,
),
@@ -894,7 +896,6 @@ fn check_opaque_types<'fcx, 'tcx>(
},
ty::subst::GenericArgKind::Lifetime(region) => {
- let param_span = tcx.def_span(param.def_id);
if let ty::ReStatic = region {
tcx.sess
.struct_span_err(
@@ -903,14 +904,14 @@ fn check_opaque_types<'fcx, 'tcx>(
in defining scope",
)
.span_label(
- param_span,
+ tcx.def_span(generics.param_at(i, tcx).def_id),
"cannot use static lifetime; use a bound lifetime \
instead or remove the lifetime parameter from the \
opaque type",
)
.emit();
} else {
- seen.entry(region).or_default().push(param_span);
+ seen.entry(region).or_default().push(i);
}
}
@@ -924,20 +925,24 @@ fn check_opaque_types<'fcx, 'tcx>(
in defining scope",
)
.span_note(
- tcx.def_span(param.def_id),
+ tcx.def_span(generics.param_at(i, tcx).def_id),
&format!(
- "used non-generic const {} for \
+ "used non-generic const `{}` for \
generic parameter",
- ty,
+ ct,
),
)
.emit();
}
},
- } // match subst
- } // for (subst, param)
- for (_, spans) in seen {
- if spans.len() > 1 {
+ } // match arg
+ } // for (arg, param)
+ for (_, indices) in seen {
+ if indices.len() > 1 {
+ let spans: Vec<_> = indices
+ .into_iter()
+ .map(|i| tcx.def_span(generics.param_at(i, tcx).def_id))
+ .collect();
tcx.sess
.struct_span_err(
span,
diff --git a/src/librustc_typeck/collect/type_of.rs b/src/librustc_typeck/collect/type_of.rs
index 79782c28253..43fd8ae0fff 100644
--- a/src/librustc_typeck/collect/type_of.rs
+++ b/src/librustc_typeck/collect/type_of.rs
@@ -424,7 +424,7 @@ fn find_opaque_ty_constraints(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
}
} else {
let param = opaque_generics.param_at(i, self.tcx);
- self.tcx.sess.span_err(
+ self.tcx.sess.delay_span_bug(
span,
&format!(
"defining opaque type use does not fully define opaque type: \
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 3bc40c43d77..0a4cc9b7fe8 100644
--- a/src/test/ui/type-alias-impl-trait/bound_reduction2.rs
+++ b/src/test/ui/type-alias-impl-trait/bound_reduction2.rs
@@ -14,6 +14,6 @@ trait Trait<U> {}
impl<W> Trait<W> for () {}
-fn foo_desugared<T: TraitWithAssoc>(_: T) -> Foo<T::Assoc> { //~ ERROR does not fully define
+fn foo_desugared<T: TraitWithAssoc>(_: T) -> Foo<T::Assoc> {
()
}
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 316ea97efb5..b871f79aa1d 100644
--- a/src/test/ui/type-alias-impl-trait/bound_reduction2.stderr
+++ b/src/test/ui/type-alias-impl-trait/bound_reduction2.stderr
@@ -9,14 +9,6 @@ help: consider further restricting this bound
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:17:1
- |
-LL | / fn foo_desugared<T: TraitWithAssoc>(_: T) -> Foo<T::Assoc> {
-LL | | ()
-LL | | }
- | |_^
-
-error: aborting due to 2 previous errors
+error: aborting due to previous error
For more information about this error, try `rustc --explain E0277`.
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 bb68975cd30..6e922a6911f 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
@@ -7,6 +7,6 @@ type Cmp<T> = impl 'static;
// not a defining use, because it doesn't define *all* possible generics
-fn cmp() -> Cmp<u32> { //~ ERROR defining opaque type use does not fully define
+fn cmp() -> Cmp<u32> { //~ ERROR non-defining opaque type use in defining scope
5u32
}
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 553b8381b0e..2e3de7d8c6e 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
@@ -4,13 +4,17 @@ error: at least one trait must be specified
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:10:1
+error: non-defining opaque type use in defining scope
+ --> $DIR/generic_nondefining_use.rs:10:13
|
-LL | / fn cmp() -> Cmp<u32> {
-LL | | 5u32
-LL | | }
- | |_^
+LL | fn cmp() -> Cmp<u32> {
+ | ^^^^^^^^
+ |
+note: used non-generic type `u32` for generic parameter
+ --> $DIR/generic_nondefining_use.rs:5:10
+ |
+LL | type Cmp<T> = impl 'static;
+ | ^
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 06f1f3430b2..4eb7f7836d8 100644
--- a/src/test/ui/type-alias-impl-trait/issue-60564.rs
+++ b/src/test/ui/type-alias-impl-trait/issue-60564.rs
@@ -17,7 +17,8 @@ where
{
type BitsIter = IterBitsIter<T, E, u8>;
fn iter_bits(self, n: u8) -> Self::BitsIter {
- //~^ ERROR defining opaque type use does not fully define opaque type
+ //~^ ERROR non-defining opaque type use in defining scope
+ //~| ERROR non-defining opaque type use in defining scope
(0u8..n)
.rev()
.map(move |shift| ((self >> T::from(shift)) & T::from(1)).try_into().unwrap())
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 2ed7e1376c1..55984609437 100644
--- a/src/test/ui/type-alias-impl-trait/issue-60564.stderr
+++ b/src/test/ui/type-alias-impl-trait/issue-60564.stderr
@@ -1,13 +1,26 @@
-error: defining opaque type use does not fully define opaque type: generic parameter `I` is specified as concrete type `u8`
- --> $DIR/issue-60564.rs:19:5
- |
-LL | / fn iter_bits(self, n: u8) -> Self::BitsIter {
-LL | |
-LL | | (0u8..n)
-LL | | .rev()
-LL | | .map(move |shift| ((self >> T::from(shift)) & T::from(1)).try_into().unwrap())
-LL | | }
- | |_____^
+error: non-defining opaque type use in defining scope
+ --> $DIR/issue-60564.rs:19:34
+ |
+LL | fn iter_bits(self, n: u8) -> Self::BitsIter {
+ | ^^^^^^^^^^^^^^
+ |
+note: used non-generic type `_` for generic parameter
+ --> $DIR/issue-60564.rs:8:22
+ |
+LL | type IterBitsIter<T, E, I> = impl std::iter::Iterator<Item = I>;
+ | ^
+
+error: non-defining opaque type use in defining scope
+ --> $DIR/issue-60564.rs:19:34
+ |
+LL | fn iter_bits(self, n: u8) -> Self::BitsIter {
+ | ^^^^^^^^^^^^^^
+ |
+note: used non-generic type `u8` for generic parameter
+ --> $DIR/issue-60564.rs:8:25
+ |
+LL | type IterBitsIter<T, E, I> = impl std::iter::Iterator<Item = I>;
+ | ^
-error: aborting due to previous error
+error: aborting due to 2 previous errors
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 060336b9661..3b6decbe9c6 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
@@ -6,7 +6,7 @@
trait Trait<T> {}
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`
+//~^ ERROR non-defining opaque type use in defining scope
fn main() {}
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 f8ad443f721..c2fa54f50f8 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
@@ -1,8 +1,14 @@
-error: defining opaque type use does not fully define opaque type: generic parameter `U` is specified as concrete type `()`
- --> $DIR/issue-68368-non-defining-use.rs:8:1
+error: non-defining opaque type use in defining scope
+ --> $DIR/issue-68368-non-defining-use.rs:8:15
|
LL | fn f<'a>() -> Alias<'a, ()> {}
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^
+ |
+note: used non-generic type `()` for generic parameter
+ --> $DIR/issue-68368-non-defining-use.rs:7:16
+ |
+LL | type Alias<'a, U> = impl Trait<U>;
+ | ^
error: aborting due to previous error
diff --git a/src/test/ui/type-alias-impl-trait/not_a_defining_use.rs b/src/test/ui/type-alias-impl-trait/not_a_defining_use.rs
index ca00e582d34..02485b24e7b 100644
--- a/src/test/ui/type-alias-impl-trait/not_a_defining_use.rs
+++ b/src/test/ui/type-alias-impl-trait/not_a_defining_use.rs
@@ -7,7 +7,6 @@ fn main() {}
type Two<T, U> = impl Debug;
fn two<T: Debug>(t: T) -> Two<T, u32> {
- //~^ ERROR defining opaque type use does not fully define opaque type
(t, 4i8)
}
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 a5deeb3b7a3..cce861b76c9 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
@@ -1,14 +1,5 @@
-error: defining opaque type use does not fully define opaque type: generic parameter `U` is specified as concrete type `u32`
- --> $DIR/not_a_defining_use.rs:9:1
- |
-LL | / fn two<T: Debug>(t: T) -> Two<T, u32> {
-LL | |
-LL | | (t, 4i8)
-LL | | }
- | |_^
-
error: concrete type differs from previous defining opaque type use
- --> $DIR/not_a_defining_use.rs:30:1
+ --> $DIR/not_a_defining_use.rs:29:1
|
LL | / fn four<T: Debug, U: Bar>(t: T) -> Two<T, U> {
LL | | (t, <U as Bar>::FOO)
@@ -19,10 +10,9 @@ note: previous use here
--> $DIR/not_a_defining_use.rs:9:1
|
LL | / fn two<T: Debug>(t: T) -> Two<T, u32> {
-LL | |
LL | | (t, 4i8)
LL | | }
| |_^
-error: aborting due to 2 previous errors
+error: aborting due to previous error