mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-22 14:55:26 +00:00
typeck/type_of: let wfcheck handle concrete types in opaque types' substs.
This commit is contained in:
parent
a98b5340d1
commit
8e9a5d928a
@ -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,
|
||||
|
@ -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: \
|
||||
|
@ -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> {
|
||||
()
|
||||
}
|
||||
|
@ -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`.
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
|
||||
|
@ -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())
|
||||
|
@ -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
|
||||
error: non-defining opaque type use in defining scope
|
||||
--> $DIR/issue-60564.rs:19:34
|
||||
|
|
||||
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 | | }
|
||||
| |_____^
|
||||
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: aborting due to previous error
|
||||
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 2 previous errors
|
||||
|
||||
|
@ -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() {}
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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)
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user