summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2020-04-04 09:16:19 +0000
committerbors <bors@rust-lang.org>2020-04-04 09:16:19 +0000
commit49dc2f9f091748beb1a8a9d5b3eb3bbe7362c3bd (patch)
tree3c9f383370676a43b5e46b1e57785f62427b9889
parent1b521f57735663de9373679cf8c6502622036bf1 (diff)
parent8ad149a0e0810cb2ef17b2b0aef18c9a2a9062b0 (diff)
downloadrust-49dc2f9f091748beb1a8a9d5b3eb3bbe7362c3bd.tar.gz
Auto merge of #70272 - eddyb:type-of-impl-trait, r=nikomatsakis
typeck/type_of: let wfcheck handle generics in opaque types' substs. I was working on #70164, and `type_of`'s handling of opaque types seemed to be, by far, the trickiest use of `Ty::walk`, but I believe it wasn't doing anything (see https://github.com/rust-lang/rust/pull/57896#discussion_r396064431 - I suspect, based on glancing at the PR discussion, that an early attempt was kept in, despite becoming just an overcomplicated way to do exactly the same as the previous simple type equality check). I would've loved to remove `ResolvedOpaqueTy` (keep the `Ty` and lose the `Substs`), but it looks like the MIR borrowck part of the process needs that now, so it would've been added anyway since #57896, even if that PR hadn't happened. <hr/> In the process, I've moved the remaining substitution validation to `wfcheck`, which was already handling lifetimes, and kept only `delay_span_bug`s in `type_of`, as an insurance policy. I've added tests for lifetime and const cases, they seem to be checked correctly now. (and more uniform than they were in https://github.com/rust-lang/rust/issues/63063#issuecomment-602162804) However, the quality of the errors is maybe a bit worse, and they don't trigger when there are other errors (not sure if this is due to compilation stop points or something more specific to one opaque type). r? @nikomatsakis cc @matthewjasper @oli-obk @Aaron1011
-rw-r--r--src/librustc_middle/ty/mod.rs48
-rw-r--r--src/librustc_typeck/check/wfcheck.rs108
-rw-r--r--src/librustc_typeck/collect/type_of.rs140
-rw-r--r--src/test/ui/type-alias-impl-trait/bound_reduction2.rs5
-rw-r--r--src/test/ui/type-alias-impl-trait/bound_reduction2.stderr16
-rw-r--r--src/test/ui/type-alias-impl-trait/generic_duplicate_param_use.rs22
-rw-r--r--src/test/ui/type-alias-impl-trait/generic_duplicate_param_use.stderr47
-rw-r--r--src/test/ui/type-alias-impl-trait/generic_duplicate_param_use2.rs2
-rw-r--r--src/test/ui/type-alias-impl-trait/generic_duplicate_param_use2.stderr12
-rw-r--r--src/test/ui/type-alias-impl-trait/generic_duplicate_param_use3.rs3
-rw-r--r--src/test/ui/type-alias-impl-trait/generic_duplicate_param_use3.stderr23
-rw-r--r--src/test/ui/type-alias-impl-trait/generic_duplicate_param_use4.rs2
-rw-r--r--src/test/ui/type-alias-impl-trait/generic_duplicate_param_use4.stderr17
-rw-r--r--src/test/ui/type-alias-impl-trait/generic_nondefining_use.rs26
-rw-r--r--src/test/ui/type-alias-impl-trait/generic_nondefining_use.stderr41
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-60564.rs4
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-60564.stderr31
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-68368-non-defining-use.rs4
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-68368-non-defining-use.stderr16
-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.stderr19
21 files changed, 276 insertions, 311 deletions
diff --git a/src/librustc_middle/ty/mod.rs b/src/librustc_middle/ty/mod.rs
index 901365ef691..9b182333907 100644
--- a/src/librustc_middle/ty/mod.rs
+++ b/src/librustc_middle/ty/mod.rs
@@ -1077,48 +1077,42 @@ impl<'tcx> Generics {
false
}
+ pub fn param_at(&'tcx self, param_index: usize, tcx: TyCtxt<'tcx>) -> &'tcx GenericParamDef {
+ if let Some(index) = param_index.checked_sub(self.parent_count) {
+ &self.params[index]
+ } else {
+ tcx.generics_of(self.parent.expect("parent_count > 0 but no parent?"))
+ .param_at(param_index, tcx)
+ }
+ }
+
pub fn region_param(
&'tcx self,
param: &EarlyBoundRegion,
tcx: TyCtxt<'tcx>,
) -> &'tcx GenericParamDef {
- if let Some(index) = param.index.checked_sub(self.parent_count as u32) {
- let param = &self.params[index as usize];
- match param.kind {
- GenericParamDefKind::Lifetime => param,
- _ => bug!("expected lifetime parameter, but found another generic parameter"),
- }
- } else {
- tcx.generics_of(self.parent.expect("parent_count > 0 but no parent?"))
- .region_param(param, tcx)
+ let param = self.param_at(param.index as usize, tcx);
+ match param.kind {
+ GenericParamDefKind::Lifetime => param,
+ _ => bug!("expected lifetime parameter, but found another generic parameter"),
}
}
/// Returns the `GenericParamDef` associated with this `ParamTy`.
pub fn type_param(&'tcx self, param: &ParamTy, tcx: TyCtxt<'tcx>) -> &'tcx GenericParamDef {
- if let Some(index) = param.index.checked_sub(self.parent_count as u32) {
- let param = &self.params[index as usize];
- match param.kind {
- GenericParamDefKind::Type { .. } => param,
- _ => bug!("expected type parameter, but found another generic parameter"),
- }
- } else {
- tcx.generics_of(self.parent.expect("parent_count > 0 but no parent?"))
- .type_param(param, tcx)
+ let param = self.param_at(param.index as usize, tcx);
+ match param.kind {
+ GenericParamDefKind::Type { .. } => param,
+ _ => bug!("expected type parameter, but found another generic parameter"),
}
}
/// Returns the `ConstParameterDef` associated with this `ParamConst`.
pub fn const_param(&'tcx self, param: &ParamConst, tcx: TyCtxt<'tcx>) -> &GenericParamDef {
- if let Some(index) = param.index.checked_sub(self.parent_count as u32) {
- let param = &self.params[index as usize];
- match param.kind {
- GenericParamDefKind::Const => param,
- _ => bug!("expected const parameter, but found another generic parameter"),
- }
- } else {
- tcx.generics_of(self.parent.expect("parent_count>0 but no parent?"))
- .const_param(param, tcx)
+ let param = self.param_at(param.index as usize, tcx);
+ match param.kind {
+ GenericParamDefKind::Const => param,
+ _ => bug!("expected const parameter, but found another generic parameter"),
}
}
}
diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs
index 30a53cbc397..b0ff17ad56d 100644
--- a/src/librustc_typeck/check/wfcheck.rs
+++ b/src/librustc_typeck/check/wfcheck.rs
@@ -9,7 +9,7 @@ use rustc_hir::def_id::DefId;
use rustc_hir::itemlikevisit::ParItemLikeVisitor;
use rustc_hir::lang_items;
use rustc_hir::ItemKind;
-use rustc_middle::ty::subst::{InternalSubsts, Subst};
+use rustc_middle::ty::subst::{GenericArgKind, InternalSubsts, Subst};
use rustc_middle::ty::trait_def::TraitSpecializationKind;
use rustc_middle::ty::{
self, AdtKind, GenericParamDefKind, ToPredicate, Ty, TyCtxt, TypeFoldable, WithConstness,
@@ -864,87 +864,77 @@ 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() {
- ty::subst::GenericArgKind::Type(ty) => match ty.kind {
- ty::Param(..) => {}
- // Prevent `fn foo() -> Foo<u32>` from being defining.
- _ => {
- tcx.sess
- .struct_span_err(
- span,
- "non-defining opaque type use \
- in defining scope",
- )
- .span_note(
- tcx.def_span(param.def_id),
- &format!(
- "used non-generic type {} for \
- generic parameter",
- ty,
- ),
- )
- .emit();
- }
- },
+ let mut seen_params: FxHashMap<_, Vec<_>> = FxHashMap::default();
+ for (i, &arg) in substs.iter().enumerate() {
+ let arg_is_param = match arg.unpack() {
+ GenericArgKind::Type(ty) => matches!(ty.kind, ty::Param(_)),
- ty::subst::GenericArgKind::Lifetime(region) => {
- let param_span = tcx.def_span(param.def_id);
+ GenericArgKind::Lifetime(region) => {
if let ty::ReStatic = region {
tcx.sess
.struct_span_err(
span,
- "non-defining opaque type use \
- in defining scope",
+ "non-defining opaque type use 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);
+ continue;
}
+
+ true
}
- ty::subst::GenericArgKind::Const(ct) => match ct.val {
- ty::ConstKind::Param(_) => {}
- _ => {
- tcx.sess
- .struct_span_err(
- span,
- "non-defining opaque type use \
- in defining scope",
- )
- .span_note(
- tcx.def_span(param.def_id),
- &format!(
- "used non-generic const {} for \
- generic parameter",
- ty,
- ),
- )
- .emit();
- }
- },
- } // match subst
- } // for (subst, param)
- for (_, spans) in seen {
- if spans.len() > 1 {
+ GenericArgKind::Const(ct) => {
+ matches!(ct.val, ty::ConstKind::Param(_))
+ }
+ };
+
+ if arg_is_param {
+ seen_params.entry(arg).or_default().push(i);
+ } else {
+ // Prevent `fn foo() -> Foo<u32>` from being defining.
+ let opaque_param = generics.param_at(i, tcx);
+ tcx.sess
+ .struct_span_err(
+ span,
+ "non-defining opaque type use in defining scope",
+ )
+ .span_note(
+ tcx.def_span(opaque_param.def_id),
+ &format!(
+ "used non-generic {} `{}` for generic parameter",
+ opaque_param.kind.descr(),
+ arg,
+ ),
+ )
+ .emit();
+ }
+ } // for (arg, param)
+
+ for (_, indices) in seen_params {
+ if indices.len() > 1 {
+ let descr = generics.param_at(indices[0], tcx).kind.descr();
+ 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,
- "non-defining opaque type use \
- in defining scope",
+ "non-defining opaque type use in defining scope",
)
- .span_note(spans, "lifetime used multiple times")
+ .span_note(spans, &format!("{} used multiple times", descr))
.emit();
}
}
diff --git a/src/librustc_typeck/collect/type_of.rs b/src/librustc_typeck/collect/type_of.rs
index e6099b98dc8..d45c8270068 100644
--- a/src/librustc_typeck/collect/type_of.rs
+++ b/src/librustc_typeck/collect/type_of.rs
@@ -1,4 +1,4 @@
-use rustc_data_structures::fx::FxHashMap;
+use rustc_data_structures::fx::FxHashSet;
use rustc_errors::{struct_span_err, Applicability, StashKey};
use rustc_hir as hir;
use rustc_hir::def::{DefKind, Res};
@@ -7,7 +7,7 @@ use rustc_hir::intravisit;
use rustc_hir::intravisit::Visitor;
use rustc_hir::Node;
use rustc_middle::hir::map::Map;
-use rustc_middle::ty::subst::{GenericArgKind, InternalSubsts, Subst};
+use rustc_middle::ty::subst::{GenericArgKind, InternalSubsts};
use rustc_middle::ty::util::IntTypeExt;
use rustc_middle::ty::{self, DefIdTree, Ty, TyCtxt, TypeFoldable};
use rustc_session::parse::feature_err;
@@ -369,13 +369,8 @@ fn find_opaque_ty_constraints(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
struct ConstraintLocator<'tcx> {
tcx: TyCtxt<'tcx>,
def_id: DefId,
- // (first found type span, actual type, mapping from the opaque type's generic
- // parameters to the concrete type's generic parameters)
- //
- // The mapping is an index for each use site of a generic parameter in the concrete type
- //
- // The indices index into the generic parameters on the opaque type.
- found: Option<(Span, Ty<'tcx>, Vec<usize>)>,
+ // (first found type span, actual type)
+ found: Option<(Span, Ty<'tcx>)>,
}
impl ConstraintLocator<'_> {
@@ -407,83 +402,51 @@ fn find_opaque_ty_constraints(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
// FIXME(oli-obk): trace the actual span from inference to improve errors.
let span = self.tcx.def_span(def_id);
- // used to quickly look up the position of a generic parameter
- let mut index_map: FxHashMap<ty::ParamTy, usize> = FxHashMap::default();
- // Skipping binder is ok, since we only use this to find generic parameters and
- // their positions.
- for (idx, subst) in substs.iter().enumerate() {
- if let GenericArgKind::Type(ty) = subst.unpack() {
- if let ty::Param(p) = ty.kind {
- if index_map.insert(p, idx).is_some() {
- // There was already an entry for `p`, meaning a generic parameter
- // was used twice.
- self.tcx.sess.span_err(
- span,
- &format!(
- "defining opaque type use restricts opaque \
- type by using the generic parameter `{}` twice",
- p,
- ),
- );
- return;
- }
- } else {
+
+ // HACK(eddyb) this check shouldn't be needed, as `wfcheck`
+ // performs the same checks, in theory, but I've kept it here
+ // using `delay_span_bug`, just in case `wfcheck` slips up.
+ let opaque_generics = self.tcx.generics_of(self.def_id);
+ let mut used_params: FxHashSet<_> = FxHashSet::default();
+ for (i, arg) in substs.iter().enumerate() {
+ let arg_is_param = match arg.unpack() {
+ GenericArgKind::Type(ty) => matches!(ty.kind, ty::Param(_)),
+ GenericArgKind::Lifetime(lt) => {
+ matches!(lt, ty::ReEarlyBound(_) | ty::ReFree(_))
+ }
+ GenericArgKind::Const(ct) => matches!(ct.val, ty::ConstKind::Param(_)),
+ };
+
+ if arg_is_param {
+ if !used_params.insert(arg) {
+ // There was already an entry for `arg`, meaning a generic parameter
+ // was used twice.
self.tcx.sess.delay_span_bug(
span,
&format!(
- "non-defining opaque ty use in defining scope: {:?}, {:?}",
- concrete_type, substs,
+ "defining opaque type use restricts opaque \
+ type by using the generic parameter `{}` twice",
+ arg,
),
);
}
- }
- }
- // Compute the index within the opaque type for each generic parameter used in
- // the concrete type.
- let indices = concrete_type
- .subst(self.tcx, substs)
- .walk()
- .filter_map(|t| match &t.kind {
- ty::Param(p) => Some(*index_map.get(p).unwrap()),
- _ => None,
- })
- .collect();
- let is_param = |ty: Ty<'_>| match ty.kind {
- ty::Param(_) => true,
- _ => false,
- };
- let bad_substs: Vec<_> = substs
- .iter()
- .enumerate()
- .filter_map(|(i, k)| {
- if let GenericArgKind::Type(ty) = k.unpack() { Some((i, ty)) } else { None }
- })
- .filter(|(_, ty)| !is_param(ty))
- .collect();
- if !bad_substs.is_empty() {
- let identity_substs = InternalSubsts::identity_for_item(self.tcx, self.def_id);
- for (i, bad_subst) in bad_substs {
- self.tcx.sess.span_err(
+ } else {
+ let param = opaque_generics.param_at(i, self.tcx);
+ self.tcx.sess.delay_span_bug(
span,
&format!(
"defining opaque type use does not fully define opaque type: \
- generic parameter `{}` is specified as concrete type `{}`",
- identity_substs.type_at(i),
- bad_subst
+ generic parameter `{}` is specified as concrete {} `{}`",
+ param.name,
+ param.kind.descr(),
+ arg,
),
);
}
- } else if let Some((prev_span, prev_ty, ref prev_indices)) = self.found {
- let mut ty = concrete_type.walk().fuse();
- let mut p_ty = prev_ty.walk().fuse();
- let iter_eq = (&mut ty).zip(&mut p_ty).all(|(t, p)| match (&t.kind, &p.kind) {
- // Type parameters are equal to any other type parameter for the purpose of
- // concrete type equality, as it is possible to obtain the same type just
- // by passing matching parameters to a function.
- (ty::Param(_), ty::Param(_)) => true,
- _ => t == p,
- });
- if !iter_eq || ty.next().is_some() || p_ty.next().is_some() {
+ }
+
+ if let Some((prev_span, prev_ty)) = self.found {
+ if *concrete_type != prev_ty {
debug!("find_opaque_ty_constraints: span={:?}", span);
// Found different concrete types for the opaque type.
let mut err = self.tcx.sess.struct_span_err(
@@ -496,34 +459,9 @@ fn find_opaque_ty_constraints(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
);
err.span_note(prev_span, "previous use here");
err.emit();
- } else if indices != *prev_indices {
- // Found "same" concrete types, but the generic parameter order differs.
- let mut err = self.tcx.sess.struct_span_err(
- span,
- "concrete type's generic parameters differ from previous defining use",
- );
- use std::fmt::Write;
- let mut s = String::new();
- write!(s, "expected [").unwrap();
- let list = |s: &mut String, indices: &Vec<usize>| {
- let mut indices = indices.iter().cloned();
- if let Some(first) = indices.next() {
- write!(s, "`{}`", substs[first]).unwrap();
- for i in indices {
- write!(s, ", `{}`", substs[i]).unwrap();
- }
- }
- };
- list(&mut s, prev_indices);
- write!(s, "], got [").unwrap();
- list(&mut s, &indices);
- write!(s, "]").unwrap();
- err.span_label(span, s);
- err.span_note(prev_span, "previous use here");
- err.emit();
}
} else {
- self.found = Some((span, concrete_type, indices));
+ self.found = Some((span, concrete_type));
}
} else {
debug!(
@@ -606,7 +544,7 @@ fn find_opaque_ty_constraints(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
}
match locator.found {
- Some((_, ty, _)) => ty,
+ Some((_, ty)) => ty,
None => {
let span = tcx.def_span(def_id);
tcx.sess.span_err(span, "could not find defining uses");
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..0a4cc9b7fe8 100644
--- a/src/test/ui/type-alias-impl-trait/bound_reduction2.rs
+++ b/src/test/ui/type-alias-impl-trait/bound_reduction2.rs
@@ -8,13 +8,12 @@ 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> {}
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 aff558569ea..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,20 +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:18: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 previous error
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..4503607a836 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
@@ -1,14 +1,26 @@
-#![feature(type_alias_impl_trait)]
+#![feature(type_alias_impl_trait, const_generics)]
+#![allow(incomplete_features)]
use std::fmt::Debug;
fn main() {}
// test that unused generic parameters are ok
-type Two<T, U> = impl Debug;
-//~^ could not find defining uses
+type TwoTys<T, U> = impl Debug;
+type TwoLifetimes<'a, 'b> = impl Debug;
+type TwoConsts<const X: usize, const Y: usize> = impl Debug;
-fn one<T: Debug>(t: T) -> Two<T, T> {
-//~^ ERROR defining opaque type use restricts opaque type
+fn one_ty<T: Debug>(t: T) -> TwoTys<T, T> {
+//~^ ERROR non-defining opaque type use in defining scope
+ t
+}
+
+fn one_lifetime<'a>(t: &'a u32) -> TwoLifetimes<'a, 'a> {
+//~^ ERROR non-defining opaque type use in defining scope
+ t
+}
+
+fn one_const<const N: usize>(t: *mut [u8; N]) -> TwoConsts<N, N> {
+//~^ ERROR non-defining opaque type use in defining scope
t
}
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..b4757e2763d 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,17 +1,38 @@
-error: defining opaque type use restricts opaque type by using the generic parameter `T` twice
- --> $DIR/generic_duplicate_param_use.rs:11:1
- |
-LL | / fn one<T: Debug>(t: T) -> Two<T, T> {
-LL | |
-LL | | t
-LL | | }
- | |_^
+error: non-defining opaque type use in defining scope
+ --> $DIR/generic_duplicate_param_use.rs:13:30
+ |
+LL | fn one_ty<T: Debug>(t: T) -> TwoTys<T, T> {
+ | ^^^^^^^^^^^^
+ |
+note: type used multiple times
+ --> $DIR/generic_duplicate_param_use.rs:9:13
+ |
+LL | type TwoTys<T, U> = impl Debug;
+ | ^ ^
-error: could not find defining uses
- --> $DIR/generic_duplicate_param_use.rs:8:1
+error: non-defining opaque type use in defining scope
+ --> $DIR/generic_duplicate_param_use.rs:18:36
+ |
+LL | fn one_lifetime<'a>(t: &'a u32) -> TwoLifetimes<'a, 'a> {
+ | ^^^^^^^^^^^^^^^^^^^^
+ |
+note: lifetime used multiple times
+ --> $DIR/generic_duplicate_param_use.rs:10:19
+ |
+LL | type TwoLifetimes<'a, 'b> = impl Debug;
+ | ^^ ^^
+
+error: non-defining opaque type use in defining scope
+ --> $DIR/generic_duplicate_param_use.rs:23:50
+ |
+LL | fn one_const<const N: usize>(t: *mut [u8; N]) -> TwoConsts<N, N> {
+ | ^^^^^^^^^^^^^^^
+ |
+note: constant used multiple times
+ --> $DIR/generic_duplicate_param_use.rs:11:22
|
-LL | type Two<T, U> = impl Debug;
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | type TwoConsts<const X: usize, const Y: usize> = impl Debug;
+ | ^ ^
-error: aborting due to 2 previous errors
+error: aborting due to 3 previous errors
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..2b98d8fc63a 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,10 @@ fn main() {}
type Two<T, U> = impl Debug;
fn one<T: Debug>(t: T) -> Two<T, T> {
-//~^ 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..8170c671f68 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
@@ -1,8 +1,16 @@
-error: defining opaque type use restricts opaque type by using the generic parameter `T` twice
+error: concrete type differs from previous defining opaque type use
+ --> $DIR/generic_duplicate_param_use2.rs:14: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 | | }
| |_^
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 8d3e7f9f424..d9133fd11f7 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,14 @@ fn main() {}
type Two<T, U> = impl Debug;
fn one<T: Debug>(t: T) -> Two<T, T> {
-//~^ 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's generic parameters differ from previous defining 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 04dcdc295f9..86dd3368400 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
@@ -1,28 +1,19 @@
-error: defining opaque type use restricts opaque type by using the generic parameter `T` twice
- --> $DIR/generic_duplicate_param_use3.rs:10:1
+error: concrete type differs from previous defining opaque type use
+ --> $DIR/generic_duplicate_param_use3.rs:14:1
|
-LL | / fn one<T: Debug>(t: T) -> Two<T, T> {
+LL | / fn two<T: Debug, U>(t: T, _: U) -> Two<T, U> {
LL | |
LL | | t
LL | | }
- | |_^
-
-error: concrete type's generic parameters differ from previous defining use
- --> $DIR/generic_duplicate_param_use3.rs:19:1
- |
-LL | / fn three<T, U: Debug>(_: T, u: U) -> Two<T, U> {
-LL | |
-LL | | u
-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 | | t
LL | | }
| |_^
-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_use4.rs b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use4.rs
index 65f7d7f485d..40388c3b6c8 100644
--- a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use4.rs
+++ b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use4.rs
@@ -8,7 +8,7 @@ fn main() {}
type Two<T, U> = impl Debug;
fn one<T: Debug>(t: T) -> Two<T, T> {
-//~^ ERROR defining opaque type use restricts opaque type
+//~^ ERROR non-defining opaque type use in defining scope
t
}
diff --git a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use4.stderr b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use4.stderr
index 082177b8212..fcf01f5164a 100644
--- a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use4.stderr
+++ b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use4.stderr
@@ -1,11 +1,14 @@
-error: defining opaque type use restricts opaque type by using the generic parameter `T` twice
- --> $DIR/generic_duplicate_param_use4.rs:10:1
+error: non-defining opaque type use in defining scope
+ --> $DIR/generic_duplicate_param_use4.rs:10:27
|
-LL | / fn one<T: Debug>(t: T) -> Two<T, T> {
-LL | |
-LL | | t
-LL | | }
- | |_^
+LL | fn one<T: Debug>(t: T) -> Two<T, T> {
+ | ^^^^^^^^^
+ |
+note: type used multiple times
+ --> $DIR/generic_duplicate_param_use4.rs:8:10
+ |
+LL | type Two<T, U> = impl Debug;
+ | ^ ^
error: aborting due to previous error
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..b1782120f84 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
@@ -1,13 +1,27 @@
-#![feature(type_alias_impl_trait)]
+#![feature(type_alias_impl_trait, const_generics)]
+#![allow(incomplete_features)]
+
+use std::fmt::Debug;
fn main() {}
-type Cmp<T> = impl 'static;
-//~^ ERROR could not find defining uses
-//~^^ ERROR: at least one trait must be specified
+type OneTy<T> = impl Debug;
+type OneLifetime<'a> = impl Debug;
+type OneConst<const X: usize> = impl Debug;
+// Not defining uses, because they doesn't define *all* possible generics.
-// 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 concrete_ty() -> OneTy<u32> {
+//~^ ERROR non-defining opaque type use in defining scope
5u32
}
+
+fn concrete_lifetime() -> OneLifetime<'static> {
+//~^ ERROR non-defining opaque type use in defining scope
+ 6u32
+}
+
+fn concrete_const() -> OneConst<{123}> {
+//~^ ERROR non-defining opaque type use in defining scope
+ 7u32
+}
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..b0ffc4a5ef6 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
@@ -1,22 +1,35 @@
-error: at least one trait must be specified
- --> $DIR/generic_nondefining_use.rs:5:15
+error: non-defining opaque type use in defining scope
+ --> $DIR/generic_nondefining_use.rs:14:21
|
-LL | type Cmp<T> = impl 'static;
- | ^^^^^^^^^^^^
+LL | fn concrete_ty() -> OneTy<u32> {
+ | ^^^^^^^^^^
+ |
+note: used non-generic type `u32` for generic parameter
+ --> $DIR/generic_nondefining_use.rs:8:12
+ |
+LL | type OneTy<T> = impl Debug;
+ | ^
-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
+error: non-defining opaque type use in defining scope
+ --> $DIR/generic_nondefining_use.rs:19:27
|
-LL | / fn cmp() -> Cmp<u32> {
-LL | | 5u32
-LL | | }
- | |_^
+LL | type OneLifetime<'a> = impl Debug;
+ | -- cannot use static lifetime; use a bound lifetime instead or remove the lifetime parameter from the opaque type
+...
+LL | fn concrete_lifetime() -> OneLifetime<'static> {
+ | ^^^^^^^^^^^^^^^^^^^^
-error: could not find defining uses
- --> $DIR/generic_nondefining_use.rs:5:1
+error: non-defining opaque type use in defining scope
+ --> $DIR/generic_nondefining_use.rs:24:24
+ |
+LL | fn concrete_const() -> OneConst<{123}> {
+ | ^^^^^^^^^^^^^^^
+ |
+note: used non-generic constant `123usize` for generic parameter
+ --> $DIR/generic_nondefining_use.rs:10:21
|
-LL | type Cmp<T> = impl 'static;
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | type OneConst<const X: usize> = impl Debug;
+ | ^
error: aborting due to 3 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..4eb7f7836d8 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
@@ -18,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 9de3e759e15..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,19 +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:20: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: could not find defining uses
- --> $DIR/issue-60564.rs:8:1
+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
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..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
@@ -4,9 +4,9 @@
#![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`
+//~^ 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 b585942406f..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,14 +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, ()> {}
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error: could not find defining uses
- --> $DIR/issue-68368-non-defining-use.rs:7:1
+ | ^^^^^^^^^^^^^
+ |
+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 2 previous errors
+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 d68f1bd30a0..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)
@@ -16,12 +7,12 @@ 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 | | (t, 4i8)
LL | | }
| |_^
-error: aborting due to 2 previous errors
+error: aborting due to previous error