diff --git a/src/librustc_middle/ty/mod.rs b/src/librustc_middle/ty/mod.rs index 901365ef69170..9b18233390797 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 30a53cbc397e8..b0ff17ad56d7c 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` 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` 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 e6099b98dc82b..d45c82700689a 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)>, + // (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 = 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| { - 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 1becb1e83a5ac..0a4cc9b7fe8be 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 = impl Trait; -//~^ 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 {} impl Trait for () {} -fn foo_desugared(_: T) -> Foo { //~ ERROR does not fully define +fn foo_desugared(_: T) -> Foo { () } 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 aff558569eaca..b871f79aa1dc5 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) -> Foo { | ^^^^^^^^^^^^^^^^ -error: defining opaque type use does not fully define opaque type: generic parameter `V` is specified as concrete type `::Assoc` - --> $DIR/bound_reduction2.rs:18:1 - | -LL | / fn foo_desugared(_: T) -> Foo { -LL | | () -LL | | } - | |_^ - -error: could not find defining uses - --> $DIR/bound_reduction2.rs:10:1 - | -LL | type Foo = impl Trait; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -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 165e320be5e9a..4503607a83638 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 = impl Debug; -//~^ could not find defining uses +type TwoTys = impl Debug; +type TwoLifetimes<'a, 'b> = impl Debug; +type TwoConsts = impl Debug; -fn one(t: T) -> Two { -//~^ ERROR defining opaque type use restricts opaque type +fn one_ty(t: T) -> TwoTys { +//~^ 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(t: *mut [u8; N]) -> TwoConsts { +//~^ 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 e1794034e20dd..b4757e2763d06 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: T) -> Two { -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: T) -> TwoTys { + | ^^^^^^^^^^^^ + | +note: type used multiple times + --> $DIR/generic_duplicate_param_use.rs:9:13 + | +LL | type TwoTys = 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(t: *mut [u8; N]) -> TwoConsts { + | ^^^^^^^^^^^^^^^ + | +note: constant used multiple times + --> $DIR/generic_duplicate_param_use.rs:11:22 | -LL | type Two = impl Debug; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | type TwoConsts = 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 0adce817c5c37..2b98d8fc63a11 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 = impl Debug; fn one(t: T) -> Two { -//~^ defining opaque type use restricts opaque type t } fn two(t: T, _: U) -> Two { +//~^ 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 a9a51fa0b4bad..8170c671f68cd 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: T, _: U) -> Two { +LL | | +LL | | t +LL | | } + | |_^ expected `U`, got `T` + | +note: previous use here --> $DIR/generic_duplicate_param_use2.rs:10:1 | LL | / fn one(t: T) -> Two { -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 8d3e7f9f42497..d9133fd11f7cd 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 = impl Debug; fn one(t: T) -> Two { -//~^ defining opaque type use restricts opaque type t } fn two(t: T, _: U) -> Two { +//~^ ERROR concrete type differs from previous defining opaque type use t } fn three(_: T, u: U) -> Two { -//~^ 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 04dcdc295f9cb..86dd33684005b 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: T) -> Two { +LL | / fn two(t: T, _: U) -> Two { 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: U) -> Two { -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: T, _: U) -> Two { +LL | / fn one(t: T) -> Two { 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 65f7d7f485d49..40388c3b6c88a 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 = impl Debug; fn one(t: T) -> Two { -//~^ 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 082177b82128d..fcf01f5164ae4 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: T) -> Two { -LL | | -LL | | t -LL | | } - | |_^ +LL | fn one(t: T) -> Two { + | ^^^^^^^^^ + | +note: type used multiple times + --> $DIR/generic_duplicate_param_use4.rs:8:10 + | +LL | type Two = 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 60106eba1756e..b1782120f84cc 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 = impl 'static; -//~^ ERROR could not find defining uses -//~^^ ERROR: at least one trait must be specified +type OneTy = impl Debug; +type OneLifetime<'a> = impl Debug; +type OneConst = 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 { //~ ERROR defining opaque type use does not fully define +fn concrete_ty() -> OneTy { +//~^ 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 b952aaa79ccee..b0ffc4a5ef61d 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 = impl 'static; - | ^^^^^^^^^^^^ +LL | fn concrete_ty() -> OneTy { + | ^^^^^^^^^^ + | +note: used non-generic type `u32` for generic parameter + --> $DIR/generic_nondefining_use.rs:8:12 + | +LL | type OneTy = 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 { -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 = impl 'static; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | type OneConst = 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 73acc92172bad..4eb7f7836d869 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 = impl std::iter::Iterator; -//~^ ERROR could not find defining uses impl IterBits for T where @@ -18,7 +17,8 @@ where { type BitsIter = IterBitsIter; 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 9de3e759e1521..55984609437b0 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 = impl std::iter::Iterator; + | ^ -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 = impl std::iter::Iterator; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^ 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 d00f8d7a90119..3b6decbe9c65e 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 {} -type Alias<'a, U> = impl Trait; //~ ERROR could not find defining uses +type Alias<'a, U> = impl Trait; 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 b585942406fd4..c2fa54f50f881 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; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^ -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 ca00e582d3442..02485b24e7b8a 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 = impl Debug; fn two(t: T) -> Two { - //~^ 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 d68f1bd30a0da..cce861b76c95e 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: T) -> Two { -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: T) -> Two { LL | | (t, ::FOO) @@ -16,12 +7,12 @@ LL | | } | |_^ expected `(T, i8)`, got `(T, ::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: T) -> Two { -LL | | (t, 5i8) +LL | / fn two(t: T) -> Two { +LL | | (t, 4i8) LL | | } | |_^ -error: aborting due to 2 previous errors +error: aborting due to previous error