From: Oli Scherer Date: Thu, 16 Sep 2021 19:08:25 +0000 (+0000) Subject: Check that TAIT generics are fully generic in mir typeck instead of wf-check, as... X-Git-Url: https://git.lizzy.rs/?a=commitdiff_plain;h=6067eadb65fbc7ba13c32cd76d888d8868a450c5;p=rust.git Check that TAIT generics are fully generic in mir typeck instead of wf-check, as wf-check can by definition only check TAIT in return position and not account for TAITs defined in the body of the function --- diff --git a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs index d790e31105c..b35e76b96ad 100644 --- a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs +++ b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs @@ -1,5 +1,9 @@ +use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::vec_map::VecMap; +use rustc_hir::OpaqueTyOrigin; +use rustc_infer::infer::opaque_types::OpaqueTypeDecl; use rustc_infer::infer::InferCtxt; +use rustc_middle::ty::subst::GenericArgKind; use rustc_middle::ty::{self, OpaqueTypeKey, Ty, TyCtxt, TypeFoldable}; use rustc_span::Span; use rustc_trait_selection::opaque_types::InferCtxtExt; @@ -50,13 +54,14 @@ impl<'tcx> RegionInferenceContext<'tcx> { pub(crate) fn infer_opaque_types( &self, infcx: &InferCtxt<'_, 'tcx>, - opaque_ty_decls: VecMap, Ty<'tcx>>, + opaque_ty_decls: VecMap, OpaqueTypeDecl<'tcx>>, span: Span, ) -> VecMap, Ty<'tcx>> { opaque_ty_decls .into_iter() - .map(|(opaque_type_key, concrete_type)| { + .filter_map(|(opaque_type_key, decl)| { let substs = opaque_type_key.substs; + let concrete_type = decl.concrete_ty; debug!(?concrete_type, ?substs); let mut subst_regions = vec![self.universal_regions.fr_static]; @@ -94,7 +99,13 @@ pub(crate) fn infer_opaque_types( universal_concrete_type, span, ); - (opaque_type_key, remapped_type) + + check_opaque_type_parameter_valid( + infcx.tcx, + opaque_type_key, + OpaqueTypeDecl { concrete_ty: remapped_type, ..decl }, + ) + .then_some((opaque_type_key, remapped_type)) }) .collect() } @@ -119,3 +130,95 @@ pub(crate) fn name_regions(&self, tcx: TyCtxt<'tcx>, ty: T) -> T }) } } + +fn check_opaque_type_parameter_valid( + tcx: TyCtxt<'_>, + opaque_type_key: OpaqueTypeKey<'_>, + decl: OpaqueTypeDecl<'_>, +) -> bool { + match decl.origin { + // No need to check return position impl trait (RPIT) + // because for type and const parameters they are correct + // by construction: we convert + // + // fn foo() -> impl Trait + // + // into + // + // type Foo + // fn foo() -> Foo. + // + // For lifetime parameters we convert + // + // fn foo<'l0..'ln>() -> impl Trait<'l0..'lm> + // + // into + // + // type foo::<'p0..'pn>::Foo<'q0..'qm> + // fn foo() -> foo::<'static..'static>::Foo<'l0..'lm>. + // + // which would error here on all of the `'static` args. + OpaqueTyOrigin::FnReturn | OpaqueTyOrigin::AsyncFn => return true, + // Check these + OpaqueTyOrigin::TyAlias => {} + } + let span = decl.definition_span; + let opaque_generics = tcx.generics_of(opaque_type_key.def_id); + let mut seen_params: FxHashMap<_, Vec<_>> = FxHashMap::default(); + for (i, arg) in opaque_type_key.substs.iter().enumerate() { + let arg_is_param = match arg.unpack() { + GenericArgKind::Type(ty) => matches!(ty.kind(), ty::Param(_)), + GenericArgKind::Lifetime(ty::ReStatic) => { + tcx.sess + .struct_span_err(span, "non-defining opaque type use in defining scope") + .span_label( + tcx.def_span(opaque_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(); + return false; + } + GenericArgKind::Lifetime(lt) => { + matches!(lt, ty::ReEarlyBound(_) | ty::ReFree(_)) + } + 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 = opaque_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(); + return false; + } + } + + for (_, indices) in seen_params { + if indices.len() > 1 { + let descr = opaque_generics.param_at(indices[0], tcx).kind.descr(); + let spans: Vec<_> = indices + .into_iter() + .map(|i| tcx.def_span(opaque_generics.param_at(i, tcx).def_id)) + .collect(); + tcx.sess + .struct_span_err(span, "non-defining opaque type use in defining scope") + .span_note(spans, &format!("{} used multiple times", descr)) + .emit(); + return false; + } + } + true +} diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index 5ccf3806025..3e536eb845f 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -14,6 +14,7 @@ use rustc_hir::lang_items::LangItem; use rustc_index::vec::{Idx, IndexVec}; use rustc_infer::infer::canonical::QueryRegionConstraints; +use rustc_infer::infer::opaque_types::OpaqueTypeDecl; use rustc_infer::infer::outlives::env::RegionBoundPairs; use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; use rustc_infer::infer::{ @@ -193,16 +194,17 @@ pub(crate) fn type_check<'mir, 'tcx>( opaque_type_values .into_iter() - .filter_map(|(opaque_type_key, decl)| { - let mut revealed_ty = infcx.resolve_vars_if_possible(decl.concrete_ty); - if revealed_ty.has_infer_types_or_consts() { + .filter_map(|(opaque_type_key, mut decl)| { + decl.concrete_ty = infcx.resolve_vars_if_possible(decl.concrete_ty); + if decl.concrete_ty.has_infer_types_or_consts() { infcx.tcx.sess.delay_span_bug( body.span, - &format!("could not resolve {:#?}", revealed_ty.kind()), + &format!("could not resolve {:#?}", decl.concrete_ty.kind()), ); - revealed_ty = infcx.tcx.ty_error(); + decl.concrete_ty = infcx.tcx.ty_error(); } - let concrete_is_opaque = if let ty::Opaque(def_id, _) = revealed_ty.kind() { + let concrete_is_opaque = if let ty::Opaque(def_id, _) = decl.concrete_ty.kind() + { *def_id == opaque_type_key.def_id } else { false @@ -234,7 +236,7 @@ pub(crate) fn type_check<'mir, 'tcx>( ); None } else { - Some((opaque_type_key, revealed_ty)) + Some((opaque_type_key, decl)) } }) .collect() @@ -890,7 +892,7 @@ struct BorrowCheckContext<'a, 'tcx> { crate struct MirTypeckResults<'tcx> { crate constraints: MirTypeckRegionConstraints<'tcx>, crate universal_region_relations: Frozen>, - crate opaque_type_values: VecMap, Ty<'tcx>>, + crate opaque_type_values: VecMap, OpaqueTypeDecl<'tcx>>, } /// A collection of region constraints that must be satisfied for the diff --git a/compiler/rustc_trait_selection/src/opaque_types.rs b/compiler/rustc_trait_selection/src/opaque_types.rs index c01faae5d6a..028f6e89f18 100644 --- a/compiler/rustc_trait_selection/src/opaque_types.rs +++ b/compiler/rustc_trait_selection/src/opaque_types.rs @@ -1062,11 +1062,7 @@ fn fold_opaque_ty( /// Here, `def_id` is the `LocalDefId` of the defining use of the opaque type (e.g., `f1` or `f2`), /// and `opaque_hir_id` is the `HirId` of the definition of the opaque type `Baz`. /// For the above example, this function returns `true` for `f1` and `false` for `f2`. -pub fn may_define_opaque_type( - tcx: TyCtxt<'_>, - def_id: LocalDefId, - opaque_hir_id: hir::HirId, -) -> bool { +fn may_define_opaque_type(tcx: TyCtxt<'_>, def_id: LocalDefId, opaque_hir_id: hir::HirId) -> bool { let mut hir_id = tcx.hir().local_def_id_to_hir_id(def_id); // Named opaque types can be defined by any siblings or children of siblings. diff --git a/compiler/rustc_typeck/src/check/wfcheck.rs b/compiler/rustc_typeck/src/check/wfcheck.rs index cb07fcf5fef..01ec801228e 100644 --- a/compiler/rustc_typeck/src/check/wfcheck.rs +++ b/compiler/rustc_typeck/src/check/wfcheck.rs @@ -2,7 +2,7 @@ use crate::constrained_generic_params::{identify_constrained_generic_params, Parameter}; use rustc_ast as ast; -use rustc_data_structures::fx::{FxHashMap, FxHashSet}; +use rustc_data_structures::fx::FxHashSet; use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder}; use rustc_hir as hir; use rustc_hir::def_id::{DefId, LocalDefId}; @@ -12,7 +12,7 @@ use rustc_hir::lang_items::LangItem; use rustc_hir::ItemKind; use rustc_middle::hir::map as hir_map; -use rustc_middle::ty::subst::{GenericArgKind, InternalSubsts, Subst}; +use rustc_middle::ty::subst::{InternalSubsts, Subst}; use rustc_middle::ty::trait_def::TraitSpecializationKind; use rustc_middle::ty::{ self, AdtKind, GenericParamDefKind, ToPredicate, Ty, TyCtxt, TypeFoldable, WithConstness, @@ -20,7 +20,6 @@ use rustc_session::parse::feature_err; use rustc_span::symbol::{sym, Ident, Symbol}; use rustc_span::Span; -use rustc_trait_selection::opaque_types::may_define_opaque_type; use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt; use rustc_trait_selection::traits::{self, ObligationCause, ObligationCauseCode, WellFormedLoc}; @@ -77,14 +76,14 @@ fn with_fcx(&mut self, f: F) /// We do this check as a pre-pass before checking fn bodies because if these constraints are /// not included it frequently leads to confusing errors in fn bodies. So it's better to check /// the types first. +#[instrument(skip(tcx), level = "debug")] pub fn check_item_well_formed(tcx: TyCtxt<'_>, def_id: LocalDefId) { let hir_id = tcx.hir().local_def_id_to_hir_id(def_id); let item = tcx.hir().expect_item(hir_id); debug!( - "check_item_well_formed(it.def_id={:?}, it.name={})", - item.def_id, - tcx.def_path_str(def_id.to_def_id()) + ?item.def_id, + item.name = ? tcx.def_path_str(def_id.to_def_id()) ); match item.kind { @@ -557,8 +556,9 @@ fn check_type_defn<'tcx, F>( }); } +#[instrument(skip(tcx, item))] fn check_trait(tcx: TyCtxt<'_>, item: &hir::Item<'_>) { - debug!("check_trait: {:?}", item.def_id); + debug!(?item.def_id); let trait_def = tcx.trait_def(item.def_id); if trait_def.is_marker @@ -712,13 +712,13 @@ fn check_impl<'tcx>( } /// Checks where-clauses and inline bounds that are declared on `def_id`. +#[instrument(skip(fcx), level = "debug")] fn check_where_clauses<'tcx, 'fcx>( fcx: &FnCtxt<'fcx, 'tcx>, span: Span, def_id: DefId, return_ty: Option<(Ty<'tcx>, Span)>, ) { - debug!("check_where_clauses(def_id={:?}, return_ty={:?})", def_id, return_ty); let tcx = fcx.tcx; let predicates = tcx.predicates_of(def_id); @@ -888,17 +888,15 @@ fn visit_const(&mut self, c: &'tcx ty::Const<'tcx>) -> ControlFlow( check_where_clauses(fcx, span, def_id, Some((sig.output(), hir_decl.output.span()))); } -/// Checks "defining uses" of opaque `impl Trait` types to ensure that they meet the restrictions -/// laid for "higher-order pattern unification". -/// This ensures that inference is tractable. -/// In particular, definitions of opaque types can only use other generics as arguments, -/// and they cannot repeat an argument. Example: -/// -/// ```rust -/// type Foo = impl Bar; -/// -/// // Okay -- `Foo` is applied to two distinct, generic types. -/// fn a() -> Foo { .. } -/// -/// // Not okay -- `Foo` is applied to `T` twice. -/// fn b() -> Foo { .. } -/// -/// // Not okay -- `Foo` is applied to a non-generic type. -/// fn b() -> Foo { .. } -/// ``` -/// -fn check_opaque_types<'fcx, 'tcx>( - fcx: &FnCtxt<'fcx, 'tcx>, - fn_def_id: LocalDefId, - span: Span, - ty: Ty<'tcx>, -) { - trace!("check_opaque_types(fn_def_id={:?}, ty={:?})", fn_def_id, ty); - let tcx = fcx.tcx; - - ty.fold_with(&mut ty::fold::BottomUpFolder { - tcx, - ty_op: |ty| { - if let ty::Opaque(def_id, substs) = *ty.kind() { - trace!("check_opaque_types: opaque_ty, {:?}, {:?}", def_id, substs); - let generics = tcx.generics_of(def_id); - - let opaque_hir_id = if let Some(local_id) = def_id.as_local() { - tcx.hir().local_def_id_to_hir_id(local_id) - } else { - // Opaque types from other crates won't have defining uses in this crate. - return ty; - }; - if let hir::ItemKind::OpaqueTy(hir::OpaqueTy { impl_trait_fn: Some(_), .. }) = - tcx.hir().expect_item(opaque_hir_id).kind - { - // No need to check return position impl trait (RPIT) - // because for type and const parameters they are correct - // by construction: we convert - // - // fn foo() -> impl Trait - // - // into - // - // type Foo - // fn foo() -> Foo. - // - // For lifetime parameters we convert - // - // fn foo<'l0..'ln>() -> impl Trait<'l0..'lm> - // - // into - // - // type foo::<'p0..'pn>::Foo<'q0..'qm> - // fn foo() -> foo::<'static..'static>::Foo<'l0..'lm>. - // - // which would error here on all of the `'static` args. - return ty; - } - if !may_define_opaque_type(tcx, fn_def_id, opaque_hir_id) { - return ty; - } - trace!("check_opaque_types: may define, generics={:#?}", generics); - 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(_)), - - GenericArgKind::Lifetime(region) if let ty::ReStatic = region => { - tcx.sess - .struct_span_err( - span, - "non-defining opaque type use in defining scope", - ) - .span_label( - 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(); - continue; - } - - GenericArgKind::Lifetime(_) => true, - - 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") - .span_note(spans, &format!("{} used multiple times", descr)) - .emit(); - } - } - } // if let Opaque - ty - }, - lt_op: |lt| lt, - ct_op: |ct| ct, - }); -} - const HELP_FOR_SELF_TYPE: &str = "consider changing to `self`, `&self`, `&mut self`, `self: Box`, \ `self: Rc`, `self: Arc`, or `self: Pin

` (where P is one \ of the previous types except `Self`)"; @@ -1439,20 +1300,23 @@ fn nested_visit_map(&mut self) -> hir_visit::NestedVisitorMap { hir_visit::NestedVisitorMap::OnlyBodies(self.tcx.hir()) } + #[instrument(skip(self, i), level = "debug")] fn visit_item(&mut self, i: &'tcx hir::Item<'tcx>) { - debug!("visit_item: {:?}", i); + trace!(?i); self.tcx.ensure().check_item_well_formed(i.def_id); hir_visit::walk_item(self, i); } + #[instrument(skip(self, trait_item), level = "debug")] fn visit_trait_item(&mut self, trait_item: &'tcx hir::TraitItem<'tcx>) { - debug!("visit_trait_item: {:?}", trait_item); + trace!(?trait_item); self.tcx.ensure().check_trait_item_well_formed(trait_item.def_id); hir_visit::walk_trait_item(self, trait_item); } + #[instrument(skip(self, impl_item), level = "debug")] fn visit_impl_item(&mut self, impl_item: &'tcx hir::ImplItem<'tcx>) { - debug!("visit_impl_item: {:?}", impl_item); + trace!(?impl_item); self.tcx.ensure().check_impl_item_well_formed(impl_item.def_id); hir_visit::walk_impl_item(self, impl_item); } diff --git a/compiler/rustc_typeck/src/collect/type_of.rs b/compiler/rustc_typeck/src/collect/type_of.rs index 7f9afaae0ea..7a14d7f3d28 100644 --- a/compiler/rustc_typeck/src/collect/type_of.rs +++ b/compiler/rustc_typeck/src/collect/type_of.rs @@ -1,4 +1,3 @@ -use rustc_data_structures::fx::FxHashSet; use rustc_errors::{Applicability, ErrorReported, StashKey}; use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; @@ -7,7 +6,7 @@ use rustc_hir::intravisit::Visitor; use rustc_hir::{HirId, Node}; use rustc_middle::hir::map::Map; -use rustc_middle::ty::subst::{GenericArgKind, InternalSubsts, SubstsRef}; +use rustc_middle::ty::subst::{InternalSubsts, SubstsRef}; use rustc_middle::ty::util::IntTypeExt; use rustc_middle::ty::{self, DefIdTree, Ty, TyCtxt, TypeFoldable, TypeFolder}; use rustc_span::symbol::Ident; @@ -539,6 +538,25 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> { } #[instrument(skip(tcx), level = "debug")] +/// Checks "defining uses" of opaque `impl Trait` types to ensure that they meet the restrictions +/// laid for "higher-order pattern unification". +/// This ensures that inference is tractable. +/// In particular, definitions of opaque types can only use other generics as arguments, +/// and they cannot repeat an argument. Example: +/// +/// ```rust +/// type Foo = impl Bar; +/// +/// // Okay -- `Foo` is applied to two distinct, generic types. +/// fn a() -> Foo { .. } +/// +/// // Not okay -- `Foo` is applied to `T` twice. +/// fn b() -> Foo { .. } +/// +/// // Not okay -- `Foo` is applied to a non-generic type. +/// fn b() -> Foo { .. } +/// ``` +/// fn find_opaque_ty_constraints(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Ty<'_> { use rustc_hir::{Expr, ImplItem, Item, TraitItem}; @@ -584,50 +602,8 @@ fn check(&mut self, def_id: LocalDefId) { // FIXME(oli-obk): trace the actual span from inference to improve errors. let span = self.tcx.def_span(def_id); - // 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 opaque_type_key.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!( - "defining opaque type use restricts opaque \ - type by using the generic parameter `{}` twice", - arg, - ), - ); - } - } 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 {} `{}`", - param.name, - param.kind.descr(), - arg, - ), - ); - } - } - if let Some((prev_span, prev_ty)) = self.found { - if *concrete_type != prev_ty { + if *concrete_type != prev_ty && !(*concrete_type, prev_ty).references_error() { debug!(?span); // Found different concrete types for the opaque type. let mut err = self.tcx.sess.struct_span_err( 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 a15074c3593..579067340e8 100644 --- a/src/test/ui/type-alias-impl-trait/bound_reduction2.rs +++ b/src/test/ui/type-alias-impl-trait/bound_reduction2.rs @@ -7,6 +7,7 @@ trait TraitWithAssoc { } type Foo = impl Trait; +//~^ ERROR could not find defining uses trait Trait {} @@ -14,5 +15,9 @@ impl Trait for () {} fn foo_desugared(_: T) -> Foo { //~^ ERROR non-defining opaque type use in defining scope + //~| ERROR non-defining opaque type use in defining scope + //~| ERROR non-defining opaque type use in defining scope + //~| ERROR `T` is part of concrete type but not used in parameter list + //~| ERROR `T` is part of concrete type but not used in parameter list () } 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 c9d6a43b909..a77c0000f12 100644 --- a/src/test/ui/type-alias-impl-trait/bound_reduction2.stderr +++ b/src/test/ui/type-alias-impl-trait/bound_reduction2.stderr @@ -1,8 +1,34 @@ +error: type parameter `T` is part of concrete type but not used in parameter list for the `impl Trait` type alias + --> $DIR/bound_reduction2.rs:16:60 + | +LL | fn foo_desugared(_: T) -> Foo { + | ____________________________________________________________^ +LL | | +LL | | +LL | | +... | +LL | | () +LL | | } + | |_^ + +error: type parameter `T` is part of concrete type but not used in parameter list for the `impl Trait` type alias + --> $DIR/bound_reduction2.rs:16:60 + | +LL | fn foo_desugared(_: T) -> Foo { + | ____________________________________________________________^ +LL | | +LL | | +LL | | +... | +LL | | () +LL | | } + | |_^ + error: non-defining opaque type use in defining scope - --> $DIR/bound_reduction2.rs:15:46 + --> $DIR/bound_reduction2.rs:16:1 | LL | fn foo_desugared(_: T) -> Foo { - | ^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: used non-generic type `::Assoc` for generic parameter --> $DIR/bound_reduction2.rs:9:10 @@ -10,5 +36,35 @@ note: used non-generic type `::Assoc` for generic parameter LL | type Foo = impl Trait; | ^ -error: aborting due to previous error +error: non-defining opaque type use in defining scope + --> $DIR/bound_reduction2.rs:16:1 + | +LL | fn foo_desugared(_: T) -> Foo { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: used non-generic type `_` for generic parameter + --> $DIR/bound_reduction2.rs:9:10 + | +LL | type Foo = impl Trait; + | ^ + +error: non-defining opaque type use in defining scope + --> $DIR/bound_reduction2.rs:16:1 + | +LL | fn foo_desugared(_: T) -> Foo { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: used non-generic type `_` for generic parameter + --> $DIR/bound_reduction2.rs:9:10 + | +LL | type Foo = impl Trait; + | ^ + +error: could not find defining uses + --> $DIR/bound_reduction2.rs:9:15 + | +LL | type Foo = impl Trait; + | ^^^^^^^^^^^^^ + +error: aborting due to 6 previous errors diff --git a/src/test/ui/type-alias-impl-trait/generic_duplicate_lifetime_param.rs b/src/test/ui/type-alias-impl-trait/generic_duplicate_lifetime_param.rs index 31f992976b1..885aae619d6 100644 --- a/src/test/ui/type-alias-impl-trait/generic_duplicate_lifetime_param.rs +++ b/src/test/ui/type-alias-impl-trait/generic_duplicate_lifetime_param.rs @@ -3,6 +3,7 @@ fn main() {} type Two<'a, 'b> = impl std::fmt::Debug; +//~^ ERROR could not find defining uses fn one<'a>(t: &'a ()) -> Two<'a, 'a> { //~^ ERROR non-defining opaque type use diff --git a/src/test/ui/type-alias-impl-trait/generic_duplicate_lifetime_param.stderr b/src/test/ui/type-alias-impl-trait/generic_duplicate_lifetime_param.stderr index 08b26b8fc13..b99c6a51f4b 100644 --- a/src/test/ui/type-alias-impl-trait/generic_duplicate_lifetime_param.stderr +++ b/src/test/ui/type-alias-impl-trait/generic_duplicate_lifetime_param.stderr @@ -1,5 +1,5 @@ error: non-defining opaque type use in defining scope - --> $DIR/generic_duplicate_lifetime_param.rs:7:26 + --> $DIR/generic_duplicate_lifetime_param.rs:8:26 | LL | fn one<'a>(t: &'a ()) -> Two<'a, 'a> { | ^^^^^^^^^^^ @@ -10,5 +10,11 @@ note: lifetime used multiple times LL | type Two<'a, 'b> = impl std::fmt::Debug; | ^^ ^^ -error: aborting due to previous error +error: could not find defining uses + --> $DIR/generic_duplicate_lifetime_param.rs:5:20 + | +LL | type Two<'a, 'b> = impl std::fmt::Debug; + | ^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors 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 a4e40f516dc..33cd2f6ba07 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,8 +6,11 @@ fn main() {} // test that unused generic parameters are ok type TwoTys = impl Debug; +//~^ ERROR could not find defining uses type TwoLifetimes<'a, 'b> = impl Debug; +//~^ ERROR could not find defining uses type TwoConsts = impl Debug; +//~^ ERROR could not find defining uses fn one_ty(t: T) -> TwoTys { //~^ ERROR non-defining opaque type use in defining scope 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 641cce26d99..52c60d1777e 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: non-defining opaque type use in defining scope - --> $DIR/generic_duplicate_param_use.rs:12:30 + --> $DIR/generic_duplicate_param_use.rs:15:30 | LL | fn one_ty(t: T) -> TwoTys { | ^^^^^^^^^^^^ @@ -10,29 +10,47 @@ note: type used multiple times LL | type TwoTys = impl Debug; | ^ ^ +error: could not find defining uses + --> $DIR/generic_duplicate_param_use.rs:8:21 + | +LL | type TwoTys = impl Debug; + | ^^^^^^^^^^ + error: non-defining opaque type use in defining scope - --> $DIR/generic_duplicate_param_use.rs:17:36 + --> $DIR/generic_duplicate_param_use.rs:20:36 | LL | fn one_lifetime<'a>(t: &'a u32) -> TwoLifetimes<'a, 'a> { | ^^^^^^^^^^^^^^^^^^^^ | note: lifetime used multiple times - --> $DIR/generic_duplicate_param_use.rs:9:19 + --> $DIR/generic_duplicate_param_use.rs:10:19 | LL | type TwoLifetimes<'a, 'b> = impl Debug; | ^^ ^^ +error: could not find defining uses + --> $DIR/generic_duplicate_param_use.rs:10:29 + | +LL | type TwoLifetimes<'a, 'b> = impl Debug; + | ^^^^^^^^^^ + error: non-defining opaque type use in defining scope - --> $DIR/generic_duplicate_param_use.rs:22:50 + --> $DIR/generic_duplicate_param_use.rs:25:50 | LL | fn one_const(t: *mut [u8; N]) -> TwoConsts { | ^^^^^^^^^^^^^^^ | note: constant used multiple times - --> $DIR/generic_duplicate_param_use.rs:10:22 + --> $DIR/generic_duplicate_param_use.rs:12:22 | LL | type TwoConsts = impl Debug; | ^ ^ -error: aborting due to 3 previous errors +error: could not find defining uses + --> $DIR/generic_duplicate_param_use.rs:12:50 + | +LL | type TwoConsts = impl Debug; + | ^^^^^^^^^^ + +error: aborting due to 6 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 a74731df695..04fb57b39c0 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 @@ -6,6 +6,7 @@ fn main() {} // test that unused generic parameters are ok type Two = impl Debug; +//~^ ERROR `T` doesn't implement `Debug` fn one(t: T) -> Two { //~^ ERROR non-defining opaque type use in defining scope 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 d87e8c5783b..fca9b70d184 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,5 +1,5 @@ error: non-defining opaque type use in defining scope - --> $DIR/generic_duplicate_param_use2.rs:10:27 + --> $DIR/generic_duplicate_param_use2.rs:11:27 | LL | fn one(t: T) -> Two { | ^^^^^^^^^ @@ -10,5 +10,17 @@ note: type used multiple times LL | type Two = impl Debug; | ^ ^ -error: aborting due to previous error +error[E0277]: `T` doesn't implement `Debug` + --> $DIR/generic_duplicate_param_use2.rs:8:18 + | +LL | type Two = impl Debug; + | ^^^^^^^^^^ `T` cannot be formatted using `{:?}` because it doesn't implement `Debug` + | +help: consider restricting type parameter `T` + | +LL | type Two = impl Debug; + | +++++++++++++++++ + +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_use3.rs b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use3.rs index 0597b8385d2..1a755d39026 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 @@ -6,6 +6,7 @@ fn main() {} // test that unused generic parameters are ok type Two = impl Debug; +//~^ ERROR `T` doesn't implement `Debug` fn one(t: T) -> Two { //~^ ERROR non-defining opaque type use in defining scope @@ -17,5 +18,6 @@ fn two(t: T, _: U) -> Two { } fn three(_: T, u: U) -> Two { + //~^ ERROR 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 711de855f0d..90b04c043a0 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,5 +1,5 @@ error: non-defining opaque type use in defining scope - --> $DIR/generic_duplicate_param_use3.rs:10:27 + --> $DIR/generic_duplicate_param_use3.rs:11:27 | LL | fn one(t: T) -> Two { | ^^^^^^^^^ @@ -10,5 +10,29 @@ note: type used multiple times LL | type Two = impl Debug; | ^ ^ -error: aborting due to previous error +error: concrete type differs from previous defining opaque type use + --> $DIR/generic_duplicate_param_use3.rs:20:1 + | +LL | fn three(_: T, u: U) -> Two { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `T`, got `U` + | +note: previous use here + --> $DIR/generic_duplicate_param_use3.rs:16:1 + | +LL | fn two(t: T, _: U) -> Two { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0277]: `T` doesn't implement `Debug` + --> $DIR/generic_duplicate_param_use3.rs:8:18 + | +LL | type Two = impl Debug; + | ^^^^^^^^^^ `T` cannot be formatted using `{:?}` because it doesn't implement `Debug` + | +help: consider restricting type parameter `T` + | +LL | type Two = impl Debug; + | +++++++++++++++++ + +error: aborting due to 3 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_use4.rs b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use4.rs index e77c94988f7..50d95c83d58 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 @@ -6,6 +6,7 @@ fn main() {} // test that unused generic parameters are ok type Two = impl Debug; +//~^ ERROR `U` doesn't implement `Debug` fn one(t: T) -> Two { //~^ ERROR non-defining opaque type use in defining scope 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 fcf01f5164a..c4be2fa83f1 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,5 +1,5 @@ error: non-defining opaque type use in defining scope - --> $DIR/generic_duplicate_param_use4.rs:10:27 + --> $DIR/generic_duplicate_param_use4.rs:11:27 | LL | fn one(t: T) -> Two { | ^^^^^^^^^ @@ -10,5 +10,17 @@ note: type used multiple times LL | type Two = impl Debug; | ^ ^ -error: aborting due to previous error +error[E0277]: `U` doesn't implement `Debug` + --> $DIR/generic_duplicate_param_use4.rs:8:18 + | +LL | type Two = impl Debug; + | ^^^^^^^^^^ `U` cannot be formatted using `{:?}` because it doesn't implement `Debug` + | +help: consider restricting type parameter `U` + | +LL | type Two = impl Debug; + | +++++++++++++++++ + +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_nondefining_use.rs b/src/test/ui/type-alias-impl-trait/generic_nondefining_use.rs index 7ee5f7b068f..cf43085877f 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 @@ -5,8 +5,11 @@ fn main() {} type OneTy = impl Debug; +//~^ ERROR could not find defining uses type OneLifetime<'a> = impl Debug; +//~^ ERROR could not find defining uses type OneConst = impl Debug; +//~^ ERROR could not find defining uses // Not defining uses, because they 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 5b42f10a6ee..3aa42a25484 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,5 +1,5 @@ error: non-defining opaque type use in defining scope - --> $DIR/generic_nondefining_use.rs:13:21 + --> $DIR/generic_nondefining_use.rs:16:21 | LL | fn concrete_ty() -> OneTy { | ^^^^^^^^^^ @@ -10,8 +10,14 @@ note: used non-generic type `u32` for generic parameter LL | type OneTy = impl Debug; | ^ +error: could not find defining uses + --> $DIR/generic_nondefining_use.rs:7:17 + | +LL | type OneTy = impl Debug; + | ^^^^^^^^^^ + error: non-defining opaque type use in defining scope - --> $DIR/generic_nondefining_use.rs:18:27 + --> $DIR/generic_nondefining_use.rs:21:27 | LL | type OneLifetime<'a> = impl Debug; | -- cannot use static lifetime; use a bound lifetime instead or remove the lifetime parameter from the opaque type @@ -19,17 +25,29 @@ LL | type OneLifetime<'a> = impl Debug; LL | fn concrete_lifetime() -> OneLifetime<'static> { | ^^^^^^^^^^^^^^^^^^^^ +error: could not find defining uses + --> $DIR/generic_nondefining_use.rs:9:24 + | +LL | type OneLifetime<'a> = impl Debug; + | ^^^^^^^^^^ + error: non-defining opaque type use in defining scope - --> $DIR/generic_nondefining_use.rs:23:24 + --> $DIR/generic_nondefining_use.rs:26:24 | LL | fn concrete_const() -> OneConst<{ 123 }> { | ^^^^^^^^^^^^^^^^^ | note: used non-generic constant `123_usize` for generic parameter - --> $DIR/generic_nondefining_use.rs:9:21 + --> $DIR/generic_nondefining_use.rs:11:21 | LL | type OneConst = impl Debug; | ^ -error: aborting due to 3 previous errors +error: could not find defining uses + --> $DIR/generic_nondefining_use.rs:11:33 + | +LL | type OneConst = impl Debug; + | ^^^^^^^^^^ + +error: aborting due to 6 previous errors diff --git a/src/test/ui/type-alias-impl-trait/incomplete-inference.rs b/src/test/ui/type-alias-impl-trait/incomplete-inference.rs index 955d1288a45..4c8bf2cfca1 100644 --- a/src/test/ui/type-alias-impl-trait/incomplete-inference.rs +++ b/src/test/ui/type-alias-impl-trait/incomplete-inference.rs @@ -8,7 +8,6 @@ fn bar() -> Foo { } fn baz() -> Foo { - //~^ ERROR: concrete type differs from previous defining opaque type use Some(()) } diff --git a/src/test/ui/type-alias-impl-trait/incomplete-inference.stderr b/src/test/ui/type-alias-impl-trait/incomplete-inference.stderr index 53cdf9e5b38..0cdd4cc8dc3 100644 --- a/src/test/ui/type-alias-impl-trait/incomplete-inference.stderr +++ b/src/test/ui/type-alias-impl-trait/incomplete-inference.stderr @@ -4,18 +4,6 @@ error[E0282]: type annotations needed LL | None | ^^^^ cannot infer type for type parameter `T` declared on the enum `Option` -error: concrete type differs from previous defining opaque type use - --> $DIR/incomplete-inference.rs:10:1 - | -LL | fn baz() -> Foo { - | ^^^^^^^^^^^^^^^ expected `[type error]`, got `Option<()>` - | -note: previous use here - --> $DIR/incomplete-inference.rs:5:1 - | -LL | fn bar() -> Foo { - | ^^^^^^^^^^^^^^^ - -error: aborting due to 2 previous errors +error: aborting due to previous error For more information about this error, try `rustc --explain E0282`. diff --git a/src/test/ui/type-alias-impl-trait/issue-60371.rs b/src/test/ui/type-alias-impl-trait/issue-60371.rs index 37a2f28ce07..9d2ba849c86 100644 --- a/src/test/ui/type-alias-impl-trait/issue-60371.rs +++ b/src/test/ui/type-alias-impl-trait/issue-60371.rs @@ -11,6 +11,7 @@ impl Bug for &() { const FUN: fn() -> Self::Item = || (); //~^ ERROR the trait bound `(): Bug` is not satisfied + //~| ERROR non-defining opaque type use in defining scope } fn main() {} diff --git a/src/test/ui/type-alias-impl-trait/issue-60371.stderr b/src/test/ui/type-alias-impl-trait/issue-60371.stderr index 1710e07644d..62ab7eb4560 100644 --- a/src/test/ui/type-alias-impl-trait/issue-60371.stderr +++ b/src/test/ui/type-alias-impl-trait/issue-60371.stderr @@ -16,7 +16,16 @@ LL | const FUN: fn() -> Self::Item = || (); = help: the following implementations were found: <&() as Bug> -error: aborting due to 2 previous errors +error: non-defining opaque type use in defining scope + --> $DIR/issue-60371.rs:12:37 + | +LL | impl Bug for &() { + | - cannot use static lifetime; use a bound lifetime instead or remove the lifetime parameter from the opaque type +... +LL | const FUN: fn() -> Self::Item = || (); + | ^^^^^ + +error: aborting due to 3 previous errors Some errors have detailed explanations: E0277, E0658. For more information about an error, try `rustc --explain E0277`. 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 78def0d1136..44dcec2c3da 100644 --- a/src/test/ui/type-alias-impl-trait/issue-60564.rs +++ b/src/test/ui/type-alias-impl-trait/issue-60564.rs @@ -6,6 +6,7 @@ trait IterBits { } type IterBitsIter = impl std::iter::Iterator; +//~^ ERROR could not find defining uses impl 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 66fa862ef9d..6b73fbef011 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: non-defining opaque type use in defining scope - --> $DIR/issue-60564.rs:19:34 + --> $DIR/issue-60564.rs:20:34 | LL | fn iter_bits(self, n: u8) -> Self::BitsIter { | ^^^^^^^^^^^^^^ @@ -10,5 +10,11 @@ note: used non-generic type `u8` for generic parameter LL | type IterBitsIter = impl std::iter::Iterator; | ^ -error: aborting due to previous error +error: could not find defining uses + --> $DIR/issue-60564.rs:8:30 + | +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-2.rs b/src/test/ui/type-alias-impl-trait/issue-68368-non-defining-use-2.rs new file mode 100644 index 00000000000..2e6354088ac --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-68368-non-defining-use-2.rs @@ -0,0 +1,14 @@ +// Regression test for issue #68368 +// Ensures that we don't ICE when emitting an error +// for a non-defining use when lifetimes are involved + +#![feature(type_alias_impl_trait)] +trait Trait {} +type Alias<'a, U> = impl Trait; +//~^ ERROR could not find defining uses +fn f<'a>() -> Alias<'a, ()> {} +//~^ ERROR non-defining opaque type use in defining scope + +fn main() {} + +impl Trait for () {} diff --git a/src/test/ui/type-alias-impl-trait/issue-68368-non-defining-use-2.stderr b/src/test/ui/type-alias-impl-trait/issue-68368-non-defining-use-2.stderr new file mode 100644 index 00000000000..721f99a3f0d --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-68368-non-defining-use-2.stderr @@ -0,0 +1,20 @@ +error: non-defining opaque type use in defining scope + --> $DIR/issue-68368-non-defining-use-2.rs:9:15 + | +LL | fn f<'a>() -> Alias<'a, ()> {} + | ^^^^^^^^^^^^^ + | +note: used non-generic type `()` for generic parameter + --> $DIR/issue-68368-non-defining-use-2.rs:7:16 + | +LL | type Alias<'a, U> = impl Trait; + | ^ + +error: could not find defining uses + --> $DIR/issue-68368-non-defining-use-2.rs:7:21 + | +LL | type Alias<'a, U> = impl Trait; + | ^^^^^^^^^^^^^ + +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 3b6decbe9c6..3addd8dcc4f 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 @@ -5,6 +5,7 @@ #![feature(type_alias_impl_trait)] trait Trait {} type Alias<'a, U> = impl Trait; +//~^ ERROR could not find defining uses fn f<'a>() -> Alias<'a, ()> {} //~^ ERROR non-defining opaque type use in defining scope 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 c2fa54f50f8..f5b8fccf65d 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,5 +1,5 @@ error: non-defining opaque type use in defining scope - --> $DIR/issue-68368-non-defining-use.rs:8:15 + --> $DIR/issue-68368-non-defining-use.rs:9:15 | LL | fn f<'a>() -> Alias<'a, ()> {} | ^^^^^^^^^^^^^ @@ -10,5 +10,11 @@ note: used non-generic type `()` for generic parameter LL | type Alias<'a, U> = impl Trait; | ^ -error: aborting due to previous error +error: could not find defining uses + --> $DIR/issue-68368-non-defining-use.rs:7:21 + | +LL | type Alias<'a, U> = impl Trait; + | ^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors diff --git a/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn3.rs b/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn3.rs index bcd9aeff6b4..11a922443e6 100644 --- a/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn3.rs +++ b/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn3.rs @@ -11,7 +11,6 @@ fn f(a: A, b: B) -> (X, X) } fn g(a: A, b: B) -> (X, X) { - //~^ ERROR concrete type differs from previous defining opaque type (a, b) //~^ ERROR mismatched types } diff --git a/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn3.stderr b/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn3.stderr index 3d943b77af5..bbe709dccab 100644 --- a/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn3.stderr +++ b/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn3.stderr @@ -1,11 +1,10 @@ error[E0308]: mismatched types - --> $DIR/multiple-def-uses-in-one-fn3.rs:15:9 + --> $DIR/multiple-def-uses-in-one-fn3.rs:14:9 | LL | fn g(a: A, b: B) -> (X, X) { | - - found type parameter | | | expected type parameter -LL | LL | (a, b) | ^ expected type parameter `A`, found type parameter `B` | @@ -14,18 +13,6 @@ LL | (a, b) = note: a type parameter was expected, but a different one was found; you might be missing a type parameter or trait bound = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters -error: concrete type differs from previous defining opaque type use - --> $DIR/multiple-def-uses-in-one-fn3.rs:13:1 - | -LL | fn g(a: A, b: B) -> (X, X) { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `A`, got `[type error]` - | -note: previous use here - --> $DIR/multiple-def-uses-in-one-fn3.rs:9:1 - | -LL | fn f(a: A, b: B) -> (X, X) { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: aborting due to 2 previous errors +error: aborting due to previous error For more information about this error, try `rustc --explain E0308`. 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 f29b980dfd0..107cd394579 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 @@ -5,6 +5,7 @@ fn main() {} type Two = impl Debug; +//~^ ERROR `T` doesn't implement `Debug` fn two(t: T) -> Two { //~^ ERROR non-defining opaque type use in defining scope @@ -26,6 +27,7 @@ impl Bar for u32 { } fn four(t: T) -> Two { + //~^ ERROR concrete type differs from previous (t, ::FOO) } 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 2fa236b373a..08e49845521 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,5 +1,5 @@ error: non-defining opaque type use in defining scope - --> $DIR/not_a_defining_use.rs:9:27 + --> $DIR/not_a_defining_use.rs:10:27 | LL | fn two(t: T) -> Two { | ^^^^^^^^^^^ @@ -10,5 +10,30 @@ note: used non-generic type `u32` for generic parameter LL | type Two = impl Debug; | ^ -error: aborting due to previous error +error: concrete type differs from previous defining opaque type use + --> $DIR/not_a_defining_use.rs:29:1 + | +LL | fn four(t: T) -> Two { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `(T, i8)`, got `(T, ::Blub)` + | +note: previous use here + --> $DIR/not_a_defining_use.rs:15:1 + | +LL | fn three(t: T) -> Two { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0277]: `T` doesn't implement `Debug` + --> $DIR/not_a_defining_use.rs:7:18 + | +LL | type Two = impl Debug; + | ^^^^^^^^^^ `T` cannot be formatted using `{:?}` because it doesn't implement `Debug` + | + = note: required because of the requirements on the impl of `Debug` for `(T, i8)` +help: consider restricting type parameter `T` + | +LL | type Two = impl Debug; + | +++++++++++++++++ + +error: aborting due to 3 previous errors +For more information about this error, try `rustc --explain E0277`.