diff --git a/src/librustc_ast/ast.rs b/src/librustc_ast/ast.rs index d3e3546cf31e4..62406552e318f 100644 --- a/src/librustc_ast/ast.rs +++ b/src/librustc_ast/ast.rs @@ -1860,15 +1860,6 @@ impl TyKind { pub fn is_unit(&self) -> bool { if let TyKind::Tup(ref tys) = *self { tys.is_empty() } else { false } } - - /// HACK(type_alias_impl_trait, Centril): A temporary crutch used - /// in lowering to avoid making larger changes there and beyond. - pub fn opaque_top_hack(&self) -> Option<&GenericBounds> { - match self { - Self::ImplTrait(_, bounds) => Some(bounds), - _ => None, - } - } } /// Syntax used to declare a trait object. diff --git a/src/librustc_ast_lowering/item.rs b/src/librustc_ast_lowering/item.rs index 47d10f86d03e2..8cfbd408e22b3 100644 --- a/src/librustc_ast_lowering/item.rs +++ b/src/librustc_ast_lowering/item.rs @@ -1,5 +1,5 @@ use super::{AnonymousLifetimeMode, LoweringContext, ParamMode}; -use super::{ImplTraitContext, ImplTraitPosition, ImplTraitTypeIdVisitor}; +use super::{ImplTraitContext, ImplTraitPosition}; use crate::Arena; use rustc_ast::ast::*; @@ -7,6 +7,7 @@ use rustc_ast::attr; use rustc_ast::node_id::NodeMap; use rustc_ast::ptr::P; use rustc_ast::visit::{self, AssocCtxt, Visitor}; +use rustc_data_structures::fx::FxHashSet; use rustc_errors::struct_span_err; use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; @@ -165,13 +166,6 @@ impl<'hir> LoweringContext<'_, 'hir> { } ItemKind::MacroDef(..) => SmallVec::new(), ItemKind::Fn(..) | ItemKind::Impl { of_trait: None, .. } => smallvec![i.id], - ItemKind::Static(ref ty, ..) | ItemKind::Const(_, ref ty, ..) => { - let mut ids = smallvec![i.id]; - if self.sess.features_untracked().impl_trait_in_bindings { - ImplTraitTypeIdVisitor { ids: &mut ids }.visit_ty(ty); - } - ids - } _ => smallvec![i.id], }; @@ -292,23 +286,25 @@ impl<'hir> LoweringContext<'_, 'hir> { ItemKind::Mod(ref m) => hir::ItemKind::Mod(self.lower_mod(m)), ItemKind::ForeignMod(ref nm) => hir::ItemKind::ForeignMod(self.lower_foreign_mod(nm)), ItemKind::GlobalAsm(ref ga) => hir::ItemKind::GlobalAsm(self.lower_global_asm(ga)), - ItemKind::TyAlias(_, ref gen, _, Some(ref ty)) => match ty.kind.opaque_top_hack() { - None => { - let ty = self.lower_ty(ty, ImplTraitContext::disallowed()); - let generics = self.lower_generics(gen, ImplTraitContext::disallowed()); - hir::ItemKind::TyAlias(ty, generics) - } - Some(bounds) => { - let ctx = || ImplTraitContext::OpaqueTy(None, hir::OpaqueTyOrigin::Misc); - let ty = hir::OpaqueTy { - generics: self.lower_generics(gen, ctx()), - bounds: self.lower_param_bounds(bounds, ctx()), - impl_trait_fn: None, - origin: hir::OpaqueTyOrigin::TypeAlias, - }; - hir::ItemKind::OpaqueTy(ty) - } - }, + ItemKind::TyAlias(_, ref gen, _, Some(ref ty)) => { + // We lower + // + // type Foo = impl Trait + // + // to + // + // type Foo = Foo1 + // opaque type Foo1: Trait + let ty = self.lower_ty( + ty, + ImplTraitContext::OtherOpaqueTy { + capturable_lifetimes: &mut FxHashSet::default(), + origin: hir::OpaqueTyOrigin::Misc, + }, + ); + let generics = self.lower_generics(gen, ImplTraitContext::disallowed()); + hir::ItemKind::TyAlias(ty, generics) + } ItemKind::TyAlias(_, ref generics, _, None) => { let ty = self.arena.alloc(self.ty(span, hir::TyKind::Err)); let generics = self.lower_generics(generics, ImplTraitContext::disallowed()); @@ -438,8 +434,13 @@ impl<'hir> LoweringContext<'_, 'hir> { span: Span, body: Option<&Expr>, ) -> (&'hir hir::Ty<'hir>, hir::BodyId) { + let mut capturable_lifetimes; let itctx = if self.sess.features_untracked().impl_trait_in_bindings { - ImplTraitContext::OpaqueTy(None, hir::OpaqueTyOrigin::Misc) + capturable_lifetimes = FxHashSet::default(); + ImplTraitContext::OtherOpaqueTy { + capturable_lifetimes: &mut capturable_lifetimes, + origin: hir::OpaqueTyOrigin::Misc, + } } else { ImplTraitContext::Disallowed(ImplTraitPosition::Binding) }; @@ -844,16 +845,16 @@ impl<'hir> LoweringContext<'_, 'hir> { let ty = self.arena.alloc(self.ty(i.span, hir::TyKind::Err)); hir::ImplItemKind::TyAlias(ty) } - Some(ty) => match ty.kind.opaque_top_hack() { - None => { - let ty = self.lower_ty(ty, ImplTraitContext::disallowed()); - hir::ImplItemKind::TyAlias(ty) - } - Some(bs) => { - let bs = self.lower_param_bounds(bs, ImplTraitContext::disallowed()); - hir::ImplItemKind::OpaqueTy(bs) - } - }, + Some(ty) => { + let ty = self.lower_ty( + ty, + ImplTraitContext::OtherOpaqueTy { + capturable_lifetimes: &mut FxHashSet::default(), + origin: hir::OpaqueTyOrigin::Misc, + }, + ); + hir::ImplItemKind::TyAlias(ty) + } }; (generics, kind) } @@ -887,12 +888,7 @@ impl<'hir> LoweringContext<'_, 'hir> { defaultness, kind: match &i.kind { AssocItemKind::Const(..) => hir::AssocItemKind::Const, - AssocItemKind::TyAlias(.., ty) => { - match ty.as_deref().and_then(|ty| ty.kind.opaque_top_hack()) { - None => hir::AssocItemKind::Type, - Some(_) => hir::AssocItemKind::OpaqueTy, - } - } + AssocItemKind::TyAlias(..) => hir::AssocItemKind::Type, AssocItemKind::Fn(_, sig, ..) => { hir::AssocItemKind::Fn { has_self: sig.decl.has_self() } } diff --git a/src/librustc_ast_lowering/lib.rs b/src/librustc_ast_lowering/lib.rs index 1f8c68f75e943..d7946ad009415 100644 --- a/src/librustc_ast_lowering/lib.rs +++ b/src/librustc_ast_lowering/lib.rs @@ -224,11 +224,30 @@ enum ImplTraitContext<'b, 'a> { /// Example: `fn foo() -> impl Debug`, where `impl Debug` is conceptually /// equivalent to a new opaque type like `type T = impl Debug; fn foo() -> T`. /// - /// We optionally store a `DefId` for the parent item here so we can look up necessary - /// information later. It is `None` when no information about the context should be stored - /// (e.g., for consts and statics). - OpaqueTy(Option /* fn def-ID */, hir::OpaqueTyOrigin), - + ReturnPositionOpaqueTy { + /// `DefId` for the parent function, used to look up necessary + /// information later. + fn_def_id: DefId, + /// Origin: Either OpaqueTyOrigin::FnReturn or OpaqueTyOrigin::AsyncFn, + origin: hir::OpaqueTyOrigin, + }, + /// Impl trait in type aliases, consts and statics. + OtherOpaqueTy { + /// Set of lifetimes that this opaque type can capture, if it uses + /// them. This includes lifetimes bound since we entered this context. + /// For example, in + /// + /// type A<'b> = impl for<'a> Trait<'a, Out = impl Sized + 'a>; + /// + /// the inner opaque type captures `'a` because it uses it. It doesn't + /// need to capture `'b` because it already inherits the lifetime + /// parameter from `A`. + // FIXME(impl_trait): but `required_region_bounds` will ICE later + // anyway. + capturable_lifetimes: &'b mut FxHashSet, + /// Origin: Either OpaqueTyOrigin::Misc or OpaqueTyOrigin::Binding, + origin: hir::OpaqueTyOrigin, + }, /// `impl Trait` is not accepted in this position. Disallowed(ImplTraitPosition), } @@ -253,7 +272,12 @@ impl<'a> ImplTraitContext<'_, 'a> { use self::ImplTraitContext::*; match self { Universal(params) => Universal(params), - OpaqueTy(fn_def_id, origin) => OpaqueTy(*fn_def_id, *origin), + ReturnPositionOpaqueTy { fn_def_id, origin } => { + ReturnPositionOpaqueTy { fn_def_id: *fn_def_id, origin: *origin } + } + OtherOpaqueTy { capturable_lifetimes, origin } => { + OtherOpaqueTy { capturable_lifetimes, origin: *origin } + } Disallowed(pos) => Disallowed(*pos), } } @@ -1001,6 +1025,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { hir::TypeBindingKind::Equality { ty: self.lower_ty(ty, itctx) } } AssocTyConstraintKind::Bound { ref bounds } => { + let mut capturable_lifetimes; // Piggy-back on the `impl Trait` context to figure out the correct behavior. let (desugar_to_impl_trait, itctx) = match itctx { // We are in the return position: @@ -1010,7 +1035,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { // so desugar to // // fn foo() -> impl Iterator - ImplTraitContext::OpaqueTy(..) => (true, itctx), + ImplTraitContext::ReturnPositionOpaqueTy { .. } + | ImplTraitContext::OtherOpaqueTy { .. } => (true, itctx), // We are in the argument position, but within a dyn type: // @@ -1028,7 +1054,14 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { // // FIXME: this is only needed until `impl Trait` is allowed in type aliases. ImplTraitContext::Disallowed(_) if self.is_in_dyn_type => { - (true, ImplTraitContext::OpaqueTy(None, hir::OpaqueTyOrigin::Misc)) + capturable_lifetimes = FxHashSet::default(); + ( + true, + ImplTraitContext::OtherOpaqueTy { + capturable_lifetimes: &mut capturable_lifetimes, + origin: hir::OpaqueTyOrigin::Misc, + }, + ) } // We are in the parameter position, but not within a dyn type: @@ -1270,10 +1303,31 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { TyKind::ImplTrait(def_node_id, ref bounds) => { let span = t.span; match itctx { - ImplTraitContext::OpaqueTy(fn_def_id, origin) => { - self.lower_opaque_impl_trait(span, fn_def_id, origin, def_node_id, |this| { - this.lower_param_bounds(bounds, itctx) - }) + ImplTraitContext::ReturnPositionOpaqueTy { fn_def_id, origin } => self + .lower_opaque_impl_trait( + span, + Some(fn_def_id), + origin, + def_node_id, + None, + |this| this.lower_param_bounds(bounds, itctx), + ), + ImplTraitContext::OtherOpaqueTy { ref capturable_lifetimes, origin } => { + // Reset capturable lifetimes, any nested impl trait + // types will inherit lifetimes from this opaque type, + // so don't need to capture them again. + let nested_itctx = ImplTraitContext::OtherOpaqueTy { + capturable_lifetimes: &mut FxHashSet::default(), + origin, + }; + self.lower_opaque_impl_trait( + span, + None, + origin, + def_node_id, + Some(capturable_lifetimes), + |this| this.lower_param_bounds(bounds, nested_itctx), + ) } ImplTraitContext::Universal(in_band_ty_params) => { // Add a definition for the in-band `Param`. @@ -1351,6 +1405,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { fn_def_id: Option, origin: hir::OpaqueTyOrigin, opaque_ty_node_id: NodeId, + capturable_lifetimes: Option<&FxHashSet>, lower_bounds: impl FnOnce(&mut Self) -> hir::GenericBounds<'hir>, ) -> hir::TyKind<'hir> { debug!( @@ -1371,12 +1426,16 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { let hir_bounds = self.with_hir_id_owner(opaque_ty_node_id, lower_bounds); - let (lifetimes, lifetime_defs) = - self.lifetimes_from_impl_trait_bounds(opaque_ty_node_id, opaque_ty_def_id, &hir_bounds); + let (lifetimes, lifetime_defs) = self.lifetimes_from_impl_trait_bounds( + opaque_ty_node_id, + opaque_ty_def_id, + &hir_bounds, + capturable_lifetimes, + ); - debug!("lower_opaque_impl_trait: lifetimes={:#?}", lifetimes,); + debug!("lower_opaque_impl_trait: lifetimes={:#?}", lifetimes); - debug!("lower_opaque_impl_trait: lifetime_defs={:#?}", lifetime_defs,); + debug!("lower_opaque_impl_trait: lifetime_defs={:#?}", lifetime_defs); self.with_hir_id_owner(opaque_ty_node_id, move |lctx| { let opaque_ty_item = hir::OpaqueTy { @@ -1395,7 +1454,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { lctx.generate_opaque_type(opaque_ty_node_id, opaque_ty_item, span, opaque_ty_span); // `impl Trait` now just becomes `Foo<'a, 'b, ..>`. - hir::TyKind::Def(hir::ItemId { id: opaque_ty_id }, lifetimes) + hir::TyKind::OpaqueDef(hir::ItemId { id: opaque_ty_id }, lifetimes) }) } @@ -1433,6 +1492,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { opaque_ty_id: NodeId, parent_def_id: LocalDefId, bounds: hir::GenericBounds<'hir>, + lifetimes_to_include: Option<&FxHashSet>, ) -> (&'hir [hir::GenericArg<'hir>], &'hir [hir::GenericParam<'hir>]) { debug!( "lifetimes_from_impl_trait_bounds(opaque_ty_id={:?}, \ @@ -1453,6 +1513,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { already_defined_lifetimes: FxHashSet, output_lifetimes: Vec>, output_lifetime_params: Vec>, + lifetimes_to_include: Option<&'r FxHashSet>, } impl<'r, 'a, 'v, 'hir> intravisit::Visitor<'v> for ImplTraitLifetimeCollector<'r, 'a, 'hir> { @@ -1538,6 +1599,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { if !self.currently_bound_lifetimes.contains(&name) && !self.already_defined_lifetimes.contains(&name) + && self.lifetimes_to_include.map_or(true, |lifetimes| lifetimes.contains(&name)) { self.already_defined_lifetimes.insert(name); @@ -1591,6 +1653,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { already_defined_lifetimes: FxHashSet::default(), output_lifetimes: Vec::new(), output_lifetime_params: Vec::new(), + lifetimes_to_include, }; for bound in bounds { @@ -1614,15 +1677,16 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { visitor.visit_ty(ty); } } - let parent_def_id = self.current_hir_id_owner.last().unwrap().0; let ty = l.ty.as_ref().map(|t| { + let mut capturable_lifetimes; self.lower_ty( t, if self.sess.features_untracked().impl_trait_in_bindings { - ImplTraitContext::OpaqueTy( - Some(parent_def_id.to_def_id()), - hir::OpaqueTyOrigin::Misc, - ) + capturable_lifetimes = FxHashSet::default(); + ImplTraitContext::OtherOpaqueTy { + capturable_lifetimes: &mut capturable_lifetimes, + origin: hir::OpaqueTyOrigin::Binding, + } } else { ImplTraitContext::Disallowed(ImplTraitPosition::Binding) }, @@ -1725,7 +1789,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { FnRetTy::Ty(ref ty) => { let context = match in_band_ty_params { Some((def_id, _)) if impl_trait_return_allow => { - ImplTraitContext::OpaqueTy(Some(def_id), hir::OpaqueTyOrigin::FnReturn) + ImplTraitContext::ReturnPositionOpaqueTy { + fn_def_id: def_id, + origin: hir::OpaqueTyOrigin::FnReturn, + } } _ => ImplTraitContext::disallowed(), }; @@ -1944,7 +2011,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { // Foo = impl Trait` is, internally, created as a child of the // async fn, so the *type parameters* are inherited. It's // only the lifetime parameters that we must supply. - let opaque_ty_ref = hir::TyKind::Def(hir::ItemId { id: opaque_ty_id }, generic_args); + let opaque_ty_ref = hir::TyKind::OpaqueDef(hir::ItemId { id: opaque_ty_id }, generic_args); let opaque_ty = self.ty(opaque_ty_span, opaque_ty_ref); hir::FnRetTy::Return(self.arena.alloc(opaque_ty)) } @@ -1962,8 +2029,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { // Not `OpaqueTyOrigin::AsyncFn`: that's only used for the // `impl Future` opaque type that `async fn` implicitly // generates. - let context = - ImplTraitContext::OpaqueTy(Some(fn_def_id), hir::OpaqueTyOrigin::FnReturn); + let context = ImplTraitContext::ReturnPositionOpaqueTy { + fn_def_id, + origin: hir::OpaqueTyOrigin::FnReturn, + }; self.lower_ty(ty, context) } FnRetTy::Default(ret_ty_span) => self.arena.alloc(self.ty_tup(*ret_ty_span, &[])), @@ -2113,7 +2182,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { default: default.as_ref().map(|x| { self.lower_ty( x, - ImplTraitContext::OpaqueTy(None, hir::OpaqueTyOrigin::Misc), + ImplTraitContext::OtherOpaqueTy { + capturable_lifetimes: &mut FxHashSet::default(), + origin: hir::OpaqueTyOrigin::Misc, + }, ) }), synthetic: param @@ -2169,8 +2241,28 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { &NodeMap::default(), itctx.reborrow(), ); + let trait_ref = self.with_in_scope_lifetime_defs(&p.bound_generic_params, |this| { - this.lower_trait_ref(&p.trait_ref, itctx) + // Any impl Trait types defined within this scope can capture + // lifetimes bound on this predicate. + let lt_def_names = p.bound_generic_params.iter().filter_map(|param| match param.kind { + GenericParamKind::Lifetime { .. } => Some(hir::LifetimeName::Param( + ParamName::Plain(param.ident.normalize_to_macros_2_0()), + )), + _ => None, + }); + if let ImplTraitContext::OtherOpaqueTy { ref mut capturable_lifetimes, .. } = itctx { + capturable_lifetimes.extend(lt_def_names.clone()); + } + + let res = this.lower_trait_ref(&p.trait_ref, itctx.reborrow()); + + if let ImplTraitContext::OtherOpaqueTy { ref mut capturable_lifetimes, .. } = itctx { + for param in lt_def_names { + capturable_lifetimes.remove(¶m); + } + } + res }); hir::PolyTraitRef { bound_generic_params, trait_ref, span: p.span } diff --git a/src/librustc_hir/def.rs b/src/librustc_hir/def.rs index 88049f85f45e4..af1860ca6bfea 100644 --- a/src/librustc_hir/def.rs +++ b/src/librustc_hir/def.rs @@ -54,15 +54,11 @@ pub enum DefKind { /// Refers to the variant itself, `DefKind::Ctor` refers to its constructor if it exists. Variant, Trait, - /// `type Foo = impl Bar;` - OpaqueTy, /// `type Foo = Bar;` TyAlias, ForeignTy, TraitAlias, AssocTy, - /// `type Foo = impl Bar;` - AssocOpaqueTy, TyParam, // Value namespace @@ -83,6 +79,7 @@ pub enum DefKind { Use, ForeignMod, AnonConst, + OpaqueTy, Field, LifetimeParam, GlobalAsm, @@ -115,7 +112,6 @@ impl DefKind { DefKind::TyAlias => "type alias", DefKind::TraitAlias => "trait alias", DefKind::AssocTy => "associated type", - DefKind::AssocOpaqueTy => "associated opaque type", DefKind::Union => "union", DefKind::Trait => "trait", DefKind::ForeignTy => "foreign type", @@ -143,7 +139,6 @@ impl DefKind { match *self { DefKind::AssocTy | DefKind::AssocConst - | DefKind::AssocOpaqueTy | DefKind::AssocFn | DefKind::Enum | DefKind::OpaqueTy @@ -168,7 +163,6 @@ impl DefKind { | DefKind::ForeignTy | DefKind::TraitAlias | DefKind::AssocTy - | DefKind::AssocOpaqueTy | DefKind::TyParam => ns == Namespace::TypeNS, DefKind::Fn diff --git a/src/librustc_hir/hir.rs b/src/librustc_hir/hir.rs index 6b751456618e9..634ab32a28542 100644 --- a/src/librustc_hir/hir.rs +++ b/src/librustc_hir/hir.rs @@ -1921,14 +1921,12 @@ pub enum ImplItemKind<'hir> { Fn(FnSig<'hir>, BodyId), /// An associated type. TyAlias(&'hir Ty<'hir>), - /// An associated `type = impl Trait`. - OpaqueTy(GenericBounds<'hir>), } impl ImplItemKind<'_> { pub fn namespace(&self) -> Namespace { match self { - ImplItemKind::OpaqueTy(..) | ImplItemKind::TyAlias(..) => Namespace::TypeNS, + ImplItemKind::TyAlias(..) => Namespace::TypeNS, ImplItemKind::Const(..) | ImplItemKind::Fn(..) => Namespace::ValueNS, } } @@ -2018,13 +2016,13 @@ pub struct OpaqueTy<'hir> { /// From whence the opaque type came. #[derive(Copy, Clone, RustcEncodable, RustcDecodable, Debug, HashStable_Generic)] pub enum OpaqueTyOrigin { - /// `type Foo = impl Trait;` - TypeAlias, /// `-> impl Trait` FnReturn, /// `async fn` AsyncFn, - /// Impl trait in bindings, consts, statics, bounds. + /// `let _: impl Trait = ...` + Binding, + /// Impl trait in type aliases, consts, statics, bounds. Misc, } @@ -2050,12 +2048,12 @@ pub enum TyKind<'hir> { /// /// Type parameters may be stored in each `PathSegment`. Path(QPath<'hir>), - /// A type definition itself. This is currently only used for the `type Foo = impl Trait` - /// item that `impl Trait` in return position desugars to. + /// A opaque type definition itself. This is currently only used for the + /// `opaque type Foo: Trait` item that `impl Trait` in desugars to. /// - /// The generic argument list contains the lifetimes (and in the future possibly parameters) - /// that are actually bound on the `impl Trait`. - Def(ItemId, &'hir [GenericArg<'hir>]), + /// The generic argument list contains the lifetimes (and in the future + /// possibly parameters) that are actually bound on the `impl Trait`. + OpaqueDef(ItemId, &'hir [GenericArg<'hir>]), /// A trait object type `Bound1 + Bound2 + Bound3` /// where `Bound` is a trait or a lifetime. TraitObject(&'hir [PolyTraitRef<'hir>], Lifetime), @@ -2616,7 +2614,6 @@ pub enum AssocItemKind { Const, Fn { has_self: bool }, Type, - OpaqueTy, } #[derive(RustcEncodable, RustcDecodable, Debug, HashStable_Generic)] diff --git a/src/librustc_hir/intravisit.rs b/src/librustc_hir/intravisit.rs index 6bc899622a363..23d642731da4d 100644 --- a/src/librustc_hir/intravisit.rs +++ b/src/librustc_hir/intravisit.rs @@ -690,7 +690,7 @@ pub fn walk_ty<'v, V: Visitor<'v>>(visitor: &mut V, typ: &'v Ty<'v>) { TyKind::Path(ref qpath) => { visitor.visit_qpath(qpath, typ.hir_id, typ.span); } - TyKind::Def(item_id, lifetimes) => { + TyKind::OpaqueDef(item_id, lifetimes) => { visitor.visit_nested_item(item_id); walk_list!(visitor, visit_generic_arg, lifetimes); } @@ -1007,10 +1007,6 @@ pub fn walk_impl_item<'v, V: Visitor<'v>>(visitor: &mut V, impl_item: &'v ImplIt visitor.visit_id(impl_item.hir_id); visitor.visit_ty(ty); } - ImplItemKind::OpaqueTy(bounds) => { - visitor.visit_id(impl_item.hir_id); - walk_list!(visitor, visit_param_bound, bounds); - } } } diff --git a/src/librustc_hir_pretty/lib.rs b/src/librustc_hir_pretty/lib.rs index bf5b7152f0ea9..c16b7c63e3147 100644 --- a/src/librustc_hir_pretty/lib.rs +++ b/src/librustc_hir_pretty/lib.rs @@ -407,7 +407,7 @@ impl<'a> State<'a> { &f.param_names[..], ); } - hir::TyKind::Def(..) => {} + hir::TyKind::OpaqueDef(..) => self.s.word("/*impl Trait*/"), hir::TyKind::Path(ref qpath) => self.print_qpath(qpath, false), hir::TyKind::TraitObject(bounds, ref lifetime) => { let mut first = true; @@ -1003,12 +1003,6 @@ impl<'a> State<'a> { hir::ImplItemKind::TyAlias(ref ty) => { self.print_associated_type(ii.ident, &ii.generics, None, Some(ty)); } - hir::ImplItemKind::OpaqueTy(bounds) => { - self.word_space("type"); - self.print_ident(ii.ident); - self.print_bounds("= impl", bounds); - self.s.word(";"); - } } self.ann.post(self, AnnNode::SubItem(ii.hir_id)) } diff --git a/src/librustc_incremental/persist/dirty_clean.rs b/src/librustc_incremental/persist/dirty_clean.rs index 9bf992537dfaf..2ee95174dffe6 100644 --- a/src/librustc_incremental/persist/dirty_clean.rs +++ b/src/librustc_incremental/persist/dirty_clean.rs @@ -336,7 +336,6 @@ impl DirtyCleanVisitor<'tcx> { ImplItemKind::Fn(..) => ("Node::ImplItem", LABELS_FN_IN_IMPL), ImplItemKind::Const(..) => ("NodeImplConst", LABELS_CONST_IN_IMPL), ImplItemKind::TyAlias(..) => ("NodeImplType", LABELS_CONST_IN_IMPL), - ImplItemKind::OpaqueTy(..) => ("NodeImplType", LABELS_CONST_IN_IMPL), }, _ => self.tcx.sess.span_fatal( attr.span, diff --git a/src/librustc_infer/infer/error_reporting/mod.rs b/src/librustc_infer/infer/error_reporting/mod.rs index a59a91e3005aa..12f7a9c0ca502 100644 --- a/src/librustc_infer/infer/error_reporting/mod.rs +++ b/src/librustc_infer/infer/error_reporting/mod.rs @@ -224,9 +224,7 @@ fn trait_item_scope_tag(item: &hir::TraitItem<'_>) -> &'static str { fn impl_item_scope_tag(item: &hir::ImplItem<'_>) -> &'static str { match item.kind { hir::ImplItemKind::Fn(..) => "method body", - hir::ImplItemKind::Const(..) - | hir::ImplItemKind::OpaqueTy(..) - | hir::ImplItemKind::TyAlias(..) => "associated item", + hir::ImplItemKind::Const(..) | hir::ImplItemKind::TyAlias(..) => "associated item", } } diff --git a/src/librustc_infer/infer/error_reporting/nice_region_error/named_anon_conflict.rs b/src/librustc_infer/infer/error_reporting/nice_region_error/named_anon_conflict.rs index acaf474699276..a56401ebb90f0 100644 --- a/src/librustc_infer/infer/error_reporting/nice_region_error/named_anon_conflict.rs +++ b/src/librustc_infer/infer/error_reporting/nice_region_error/named_anon_conflict.rs @@ -84,7 +84,8 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { rustc_hir::intravisit::walk_ty(&mut v, ty); debug!("try_report_named_anon_conflict: ret ty {:?}", ty); - if sub == &ty::ReStatic && (matches!(ty.kind, TyKind::Def(_, _)) || v.0.len() == 1) + if sub == &ty::ReStatic + && (matches!(ty.kind, TyKind::OpaqueDef(_, _)) || v.0.len() == 1) { debug!("try_report_named_anon_conflict: impl Trait + 'static"); // This is an `impl Trait` or `dyn Trait` return that evaluates de need of diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index aa0dd9c83113b..efe60ce1b8889 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -1102,6 +1102,10 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TypeAliasBounds { hir::ItemKind::TyAlias(ref ty, ref generics) => (&*ty, generics), _ => return, }; + if let hir::TyKind::OpaqueDef(..) = ty.kind { + // Bounds are respected for `type X = impl Trait` + return; + } let mut suggested_changing_assoc_types = false; // There must not be a where clause if !type_alias_generics.where_clause.predicates.is_empty() { diff --git a/src/librustc_metadata/rmeta/decoder.rs b/src/librustc_metadata/rmeta/decoder.rs index f5a9dceb78295..44944a9fb265a 100644 --- a/src/librustc_metadata/rmeta/decoder.rs +++ b/src/librustc_metadata/rmeta/decoder.rs @@ -579,7 +579,6 @@ impl EntryKind { EntryKind::ConstParam => DefKind::ConstParam, EntryKind::OpaqueTy => DefKind::OpaqueTy, EntryKind::AssocType(_) => DefKind::AssocTy, - EntryKind::AssocOpaqueTy(_) => DefKind::AssocOpaqueTy, EntryKind::Mod(_) => DefKind::Mod, EntryKind::Variant(_) => DefKind::Variant, EntryKind::Trait(_) => DefKind::Trait, @@ -1145,7 +1144,6 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { (ty::AssocKind::Fn, data.container, data.has_self) } EntryKind::AssocType(container) => (ty::AssocKind::Type, container, false), - EntryKind::AssocOpaqueTy(container) => (ty::AssocKind::OpaqueTy, container, false), _ => bug!("cannot get associated-item of `{:?}`", def_key), }; diff --git a/src/librustc_metadata/rmeta/encoder.rs b/src/librustc_metadata/rmeta/encoder.rs index 64ccd46a744f5..1dc22c10c8e7a 100644 --- a/src/librustc_metadata/rmeta/encoder.rs +++ b/src/librustc_metadata/rmeta/encoder.rs @@ -874,7 +874,6 @@ impl EncodeContext<'tcx> { })) } ty::AssocKind::Type => EntryKind::AssocType(container), - ty::AssocKind::OpaqueTy => span_bug!(ast_item.span, "opaque type in trait"), }); record!(self.tables.visibility[def_id] <- trait_item.vis); record!(self.tables.span[def_id] <- ast_item.span); @@ -892,7 +891,6 @@ impl EncodeContext<'tcx> { self.encode_item_type(def_id); } } - ty::AssocKind::OpaqueTy => unreachable!(), } if trait_item.kind == ty::AssocKind::Fn { record!(self.tables.fn_sig[def_id] <- tcx.fn_sig(def_id)); @@ -957,7 +955,6 @@ impl EncodeContext<'tcx> { has_self: impl_item.fn_has_self_parameter, })) } - ty::AssocKind::OpaqueTy => EntryKind::AssocOpaqueTy(container), ty::AssocKind::Type => EntryKind::AssocType(container) }); record!(self.tables.visibility[def_id] <- impl_item.vis); @@ -989,7 +986,7 @@ impl EncodeContext<'tcx> { let always_encode_mir = self.tcx.sess.opts.debugging_opts.always_encode_mir; needs_inline || is_const_fn || always_encode_mir } - hir::ImplItemKind::OpaqueTy(..) | hir::ImplItemKind::TyAlias(..) => false, + hir::ImplItemKind::TyAlias(..) => false, }; if mir { self.encode_optimized_mir(def_id.expect_local()); @@ -1786,7 +1783,7 @@ impl<'tcx, 'v> ParItemLikeVisitor<'v> for PrefetchVisitor<'tcx> { self.prefetch_mir(def_id) } } - hir::ImplItemKind::OpaqueTy(..) | hir::ImplItemKind::TyAlias(..) => (), + hir::ImplItemKind::TyAlias(..) => (), } } } diff --git a/src/librustc_metadata/rmeta/mod.rs b/src/librustc_metadata/rmeta/mod.rs index 89d525eb80b8c..626a436b40060 100644 --- a/src/librustc_metadata/rmeta/mod.rs +++ b/src/librustc_metadata/rmeta/mod.rs @@ -308,7 +308,6 @@ enum EntryKind { Impl(Lazy), AssocFn(Lazy), AssocType(AssocContainer), - AssocOpaqueTy(AssocContainer), AssocConst(AssocContainer, mir::ConstQualifs, Lazy), TraitAlias, } diff --git a/src/librustc_middle/hir/map/mod.rs b/src/librustc_middle/hir/map/mod.rs index b1dafb3c88585..d1cfc4867a2fe 100644 --- a/src/librustc_middle/hir/map/mod.rs +++ b/src/librustc_middle/hir/map/mod.rs @@ -228,7 +228,6 @@ impl<'hir> Map<'hir> { ImplItemKind::Const(..) => DefKind::AssocConst, ImplItemKind::Fn(..) => DefKind::AssocFn, ImplItemKind::TyAlias(..) => DefKind::AssocTy, - ImplItemKind::OpaqueTy(..) => DefKind::AssocOpaqueTy, }, Node::Variant(_) => DefKind::Variant, Node::Ctor(variant_data) => { @@ -672,6 +671,8 @@ impl<'hir> Map<'hir> { if let Node::Item(Item { kind: ItemKind::Fn(..) + | ItemKind::Const(..) + | ItemKind::Static(..) | ItemKind::Mod(..) | ItemKind::Enum(..) | ItemKind::Struct(..) @@ -700,11 +701,7 @@ impl<'hir> Map<'hir> { return CRATE_HIR_ID; } match self.get(scope) { - Node::Item(Item { - kind: ItemKind::OpaqueTy(OpaqueTy { impl_trait_fn: None, .. }), - .. - }) - | Node::Block(_) => {} + Node::Block(_) => {} _ => break, } } @@ -1025,9 +1022,6 @@ fn hir_id_to_string(map: &Map<'_>, id: HirId) -> String { ImplItemKind::TyAlias(_) => { format!("assoc type {} in {}{}", ii.ident, path_str(), id_str) } - ImplItemKind::OpaqueTy(_) => { - format!("assoc opaque type {} in {}{}", ii.ident, path_str(), id_str) - } }, Some(Node::TraitItem(ti)) => { let kind = match ti.kind { diff --git a/src/librustc_middle/traits/specialization_graph.rs b/src/librustc_middle/traits/specialization_graph.rs index 4f02aaa96acd3..f4961617b81c6 100644 --- a/src/librustc_middle/traits/specialization_graph.rs +++ b/src/librustc_middle/traits/specialization_graph.rs @@ -100,24 +100,11 @@ impl<'tcx> Node { trait_item_kind: ty::AssocKind, trait_def_id: DefId, ) -> Option { - use crate::ty::AssocKind::*; - tcx.associated_items(self.def_id()) .filter_by_name_unhygienic(trait_item_name.name) .find(move |impl_item| { - match (trait_item_kind, impl_item.kind) { - | (Const, Const) - | (Fn, Fn) - | (Type, Type) - | (Type, OpaqueTy) // assoc. types can be made opaque in impls - => tcx.hygienic_eq(impl_item.ident, trait_item_name, trait_def_id), - - | (Const, _) - | (Fn, _) - | (Type, _) - | (OpaqueTy, _) - => false, - } + trait_item_kind == impl_item.kind + && tcx.hygienic_eq(impl_item.ident, trait_item_name, trait_def_id) }) .copied() } diff --git a/src/librustc_middle/ty/error.rs b/src/librustc_middle/ty/error.rs index 480420dfdcf5e..be3bf748225b9 100644 --- a/src/librustc_middle/ty/error.rs +++ b/src/librustc_middle/ty/error.rs @@ -814,7 +814,7 @@ fn foo(&self) -> Self::T { String::new() } // FIXME: account for `#![feature(specialization)]` for item in &items[..] { match item.kind { - hir::AssocItemKind::Type | hir::AssocItemKind::OpaqueTy => { + hir::AssocItemKind::Type => { // FIXME: account for returning some type in a trait fn impl that has // an assoc type as a return type (#72076). if let hir::Defaultness::Default { has_value: true } = item.defaultness @@ -838,7 +838,7 @@ fn foo(&self) -> Self::T { String::new() } })) => { for item in &items[..] { match item.kind { - hir::AssocItemKind::Type | hir::AssocItemKind::OpaqueTy => { + hir::AssocItemKind::Type => { if self.type_of(self.hir().local_def_id(item.id.hir_id)) == found { db.span_label(item.span, "expected this associated type"); return true; diff --git a/src/librustc_middle/ty/mod.rs b/src/librustc_middle/ty/mod.rs index caa1b4cb375fe..93ef73171993c 100644 --- a/src/librustc_middle/ty/mod.rs +++ b/src/librustc_middle/ty/mod.rs @@ -198,14 +198,13 @@ pub struct AssocItem { pub enum AssocKind { Const, Fn, - OpaqueTy, Type, } impl AssocKind { pub fn namespace(&self) -> Namespace { match *self { - ty::AssocKind::OpaqueTy | ty::AssocKind::Type => Namespace::TypeNS, + ty::AssocKind::Type => Namespace::TypeNS, ty::AssocKind::Const | ty::AssocKind::Fn => Namespace::ValueNS, } } @@ -215,22 +214,11 @@ impl AssocKind { AssocKind::Const => DefKind::AssocConst, AssocKind::Fn => DefKind::AssocFn, AssocKind::Type => DefKind::AssocTy, - AssocKind::OpaqueTy => DefKind::AssocOpaqueTy, } } } impl AssocItem { - /// Tests whether the associated item admits a non-trivial implementation - /// for ! - pub fn relevant_for_never(&self) -> bool { - match self.kind { - AssocKind::OpaqueTy | AssocKind::Const | AssocKind::Type => true, - // FIXME(canndrew): Be more thorough here, check if any argument is uninhabited. - AssocKind::Fn => !self.fn_has_self_parameter, - } - } - pub fn signature(&self, tcx: TyCtxt<'_>) -> String { match self.kind { ty::AssocKind::Fn => { @@ -241,8 +229,6 @@ impl AssocItem { tcx.fn_sig(self.def_id).skip_binder().to_string() } ty::AssocKind::Type => format!("type {};", self.ident), - // FIXME(type_alias_impl_trait): we should print bounds here too. - ty::AssocKind::OpaqueTy => format!("type {};", self.ident), ty::AssocKind::Const => { format!("const {}: {:?};", self.ident, tcx.type_of(self.def_id)) } @@ -2581,10 +2567,6 @@ impl<'tcx> TyCtxt<'tcx> { .filter(|item| item.kind == AssocKind::Fn && item.defaultness.has_value()) } - pub fn trait_relevant_for_never(self, did: DefId) -> bool { - self.associated_items(did).in_definition_order().any(|item| item.relevant_for_never()) - } - pub fn opt_item_name(self, def_id: DefId) -> Option { def_id .as_local() diff --git a/src/librustc_mir/borrow_check/type_check/free_region_relations.rs b/src/librustc_mir/borrow_check/type_check/free_region_relations.rs index f97dff146450c..5707127340d87 100644 --- a/src/librustc_mir/borrow_check/type_check/free_region_relations.rs +++ b/src/librustc_mir/borrow_check/type_check/free_region_relations.rs @@ -259,7 +259,13 @@ impl UniversalRegionRelationsBuilder<'cx, 'tcx> { .param_env .and(type_op::normalize::Normalize::new(ty)) .fully_perform(self.infcx) - .unwrap_or_else(|_| bug!("failed to normalize {:?}", ty)); + .unwrap_or_else(|_| { + self.infcx + .tcx + .sess + .delay_span_bug(DUMMY_SP, &format!("failed to normalize {:?}", ty)); + (self.infcx.tcx.types.err, None) + }); let constraints2 = self.add_implied_bounds(ty); normalized_inputs_and_output.push(ty); constraints1.into_iter().chain(constraints2) diff --git a/src/librustc_passes/check_attr.rs b/src/librustc_passes/check_attr.rs index b54731d8881d1..80681c143750f 100644 --- a/src/librustc_passes/check_attr.rs +++ b/src/librustc_passes/check_attr.rs @@ -37,7 +37,7 @@ fn target_from_impl_item<'tcx>(tcx: TyCtxt<'tcx>, impl_item: &hir::ImplItem<'_>) Target::Method(MethodKind::Inherent) } } - hir::ImplItemKind::TyAlias(..) | hir::ImplItemKind::OpaqueTy(..) => Target::AssocTy, + hir::ImplItemKind::TyAlias(..) => Target::AssocTy, } } diff --git a/src/librustc_passes/dead.rs b/src/librustc_passes/dead.rs index 1dcf0e7c7a98a..503fbb64db83d 100644 --- a/src/librustc_passes/dead.rs +++ b/src/librustc_passes/dead.rs @@ -304,7 +304,7 @@ impl<'a, 'tcx> Visitor<'tcx> for MarkSymbolVisitor<'a, 'tcx> { } fn visit_ty(&mut self, ty: &'tcx hir::Ty<'tcx>) { - if let TyKind::Def(item_id, _) = ty.kind { + if let TyKind::OpaqueDef(item_id, _) = ty.kind { let item = self.tcx.hir().expect_item(item_id.id); intravisit::walk_item(self, item); } @@ -668,7 +668,7 @@ impl Visitor<'tcx> for DeadVisitor<'tcx> { } self.visit_nested_body(body_id) } - hir::ImplItemKind::OpaqueTy(..) | hir::ImplItemKind::TyAlias(..) => {} + hir::ImplItemKind::TyAlias(..) => {} } } diff --git a/src/librustc_passes/layout_test.rs b/src/librustc_passes/layout_test.rs index c0826f8cc605f..2419e6965968e 100644 --- a/src/librustc_passes/layout_test.rs +++ b/src/librustc_passes/layout_test.rs @@ -27,8 +27,7 @@ impl ItemLikeVisitor<'tcx> for LayoutTest<'tcx> { ItemKind::TyAlias(..) | ItemKind::Enum(..) | ItemKind::Struct(..) - | ItemKind::Union(..) - | ItemKind::OpaqueTy(..) => { + | ItemKind::Union(..) => { for attr in self.tcx.get_attrs(item_def_id.to_def_id()).iter() { if attr.check_name(sym::rustc_layout) { self.dump_layout_of(item_def_id, item, attr); @@ -83,9 +82,11 @@ impl LayoutTest<'tcx> { } sym::debug => { + let normalized_ty = + self.tcx.normalize_erasing_regions(param_env.with_reveal_all(), ty); self.tcx.sess.span_err( item.span, - &format!("layout_of({:?}) = {:#?}", ty, *ty_layout), + &format!("layout_of({:?}) = {:#?}", normalized_ty, *ty_layout), ); } diff --git a/src/librustc_passes/reachable.rs b/src/librustc_passes/reachable.rs index cac71b3836c54..c9a4428c007aa 100644 --- a/src/librustc_passes/reachable.rs +++ b/src/librustc_passes/reachable.rs @@ -180,7 +180,7 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> { } } } - hir::ImplItemKind::OpaqueTy(..) | hir::ImplItemKind::TyAlias(_) => false, + hir::ImplItemKind::TyAlias(_) => false, } } Some(_) => false, @@ -289,7 +289,7 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> { self.visit_nested_body(body) } } - hir::ImplItemKind::OpaqueTy(..) | hir::ImplItemKind::TyAlias(_) => {} + hir::ImplItemKind::TyAlias(_) => {} }, Node::Expr(&hir::Expr { kind: hir::ExprKind::Closure(.., body, _, _), .. }) => { self.visit_nested_body(body); diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs index d54ec2eca8c97..3c1b56a9ef40a 100644 --- a/src/librustc_privacy/lib.rs +++ b/src/librustc_privacy/lib.rs @@ -615,7 +615,6 @@ impl EmbargoVisitor<'tcx> { // public, or are not namespaced at all. DefKind::AssocConst | DefKind::AssocTy - | DefKind::AssocOpaqueTy | DefKind::ConstParam | DefKind::Ctor(_, _) | DefKind::Enum @@ -1333,11 +1332,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypePrivacyVisitor<'a, 'tcx> { _ => None, }; let def = def.filter(|(kind, _)| match kind { - DefKind::AssocFn - | DefKind::AssocConst - | DefKind::AssocTy - | DefKind::AssocOpaqueTy - | DefKind::Static => true, + DefKind::AssocFn | DefKind::AssocConst | DefKind::AssocTy | DefKind::Static => true, _ => false, }); if let Some((kind, def_id)) = def { @@ -1602,9 +1597,7 @@ impl<'a, 'tcx> Visitor<'tcx> for ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> { hir::ImplItemKind::Const(..) | hir::ImplItemKind::Fn(..) => { self.access_levels.is_reachable(impl_item_ref.id.hir_id) } - hir::ImplItemKind::OpaqueTy(..) | hir::ImplItemKind::TyAlias(_) => { - false - } + hir::ImplItemKind::TyAlias(_) => false, } }); @@ -1952,9 +1945,6 @@ impl<'a, 'tcx> PrivateItemsInPublicInterfacesVisitor<'a, 'tcx> { let (check_ty, is_assoc_ty) = match assoc_item_kind { AssocItemKind::Const | AssocItemKind::Fn { .. } => (true, false), AssocItemKind::Type => (defaultness.has_value(), true), - // `ty()` for opaque types is the underlying type, - // it's not a part of interface, so we skip it. - AssocItemKind::OpaqueTy => (false, true), }; check.in_assoc_ty = is_assoc_ty; check.generics().predicates(); diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs index 2ae063660e38d..e633bd1843e85 100644 --- a/src/librustc_resolve/build_reduced_graph.rs +++ b/src/librustc_resolve/build_reduced_graph.rs @@ -746,12 +746,11 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> { } // These items live in the type namespace. - ItemKind::TyAlias(_, _, _, ref ty) => { - let def_kind = match ty.as_deref().and_then(|ty| ty.kind.opaque_top_hack()) { - None => DefKind::TyAlias, - Some(_) => DefKind::OpaqueTy, - }; - let res = Res::Def(def_kind, self.r.definitions.local_def_id(item.id).to_def_id()); + ItemKind::TyAlias(..) => { + let res = Res::Def( + DefKind::TyAlias, + self.r.definitions.local_def_id(item.id).to_def_id(), + ); self.r.define(parent, ident, TypeNS, (res, vis, sp, expansion)); } @@ -917,8 +916,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> { | DefKind::ForeignTy | DefKind::OpaqueTy | DefKind::TraitAlias - | DefKind::AssocTy - | DefKind::AssocOpaqueTy, + | DefKind::AssocTy, _, ) | Res::PrimTy(..) diff --git a/src/librustc_resolve/late/lifetimes.rs b/src/librustc_resolve/late/lifetimes.rs index a3fbb28f22a56..5bbf8703f0b60 100644 --- a/src/librustc_resolve/late/lifetimes.rs +++ b/src/librustc_resolve/late/lifetimes.rs @@ -258,6 +258,9 @@ enum Elide { Exact(Region), /// Less or more than one lifetime were found, error on unspecified. Error(Vec), + /// Forbid lifetime elision inside of a larger scope where it would be + /// permitted. For example, in let position impl trait. + Forbid, } #[derive(Clone, Debug)] @@ -396,15 +399,12 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { let scope = Scope::Elision { elide: Elide::Exact(Region::Static), s: ROOT_SCOPE }; self.with(scope, |_, this| intravisit::walk_item(this, item)); } - hir::ItemKind::OpaqueTy(hir::OpaqueTy { impl_trait_fn: Some(_), .. }) => { - // Currently opaque type declarations are just generated from `impl Trait` - // items. Doing anything on this node is irrelevant, as we currently don't need - // it. + hir::ItemKind::OpaqueTy(hir::OpaqueTy { .. }) => { + // Opaque types are visited when we visit the + // `TyKind::OpaqueDef`, so that they have the lifetimes from + // their parent opaque_ty in scope. } hir::ItemKind::TyAlias(_, ref generics) - | hir::ItemKind::OpaqueTy(hir::OpaqueTy { - impl_trait_fn: None, ref generics, .. - }) | hir::ItemKind::Enum(_, ref generics) | hir::ItemKind::Struct(_, ref generics) | hir::ItemKind::Union(_, ref generics) @@ -557,23 +557,35 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { }; self.with(scope, |_, this| this.visit_ty(&mt.ty)); } - hir::TyKind::Def(item_id, lifetimes) => { + hir::TyKind::OpaqueDef(item_id, lifetimes) => { // Resolve the lifetimes in the bounds to the lifetime defs in the generics. // `fn foo<'a>() -> impl MyTrait<'a> { ... }` desugars to // `type MyAnonTy<'b> = impl MyTrait<'b>;` // ^ ^ this gets resolved in the scope of // the opaque_ty generics - let (generics, bounds) = match self.tcx.hir().expect_item(item_id.id).kind { + let opaque_ty = self.tcx.hir().expect_item(item_id.id); + let (generics, bounds) = match opaque_ty.kind { // Named opaque `impl Trait` types are reached via `TyKind::Path`. // This arm is for `impl Trait` in the types of statics, constants and locals. hir::ItemKind::OpaqueTy(hir::OpaqueTy { impl_trait_fn: None, .. }) => { intravisit::walk_ty(self, ty); + + // Elided lifetimes are not allowed in non-return + // position impl Trait + let scope = Scope::Elision { elide: Elide::Forbid, s: self.scope }; + self.with(scope, |_, this| { + intravisit::walk_item(this, opaque_ty); + }); + return; } // RPIT (return position impl trait) - hir::ItemKind::OpaqueTy(hir::OpaqueTy { ref generics, bounds, .. }) => { - (generics, bounds) - } + hir::ItemKind::OpaqueTy(hir::OpaqueTy { + impl_trait_fn: Some(_), + ref generics, + bounds, + .. + }) => (generics, bounds), ref i => bug!("`impl Trait` pointed to non-opaque type?? {:#?}", i), }; @@ -797,43 +809,6 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { this.visit_ty(ty); }); } - OpaqueTy(bounds) => { - let generics = &impl_item.generics; - let mut index = self.next_early_index(); - let mut next_early_index = index; - debug!("visit_ty: index = {}", index); - let lifetimes = generics - .params - .iter() - .filter_map(|param| match param.kind { - GenericParamKind::Lifetime { .. } => { - Some(Region::early(&self.tcx.hir(), &mut index, param)) - } - GenericParamKind::Type { .. } => { - next_early_index += 1; - None - } - GenericParamKind::Const { .. } => { - next_early_index += 1; - None - } - }) - .collect(); - - let scope = Scope::Binder { - lifetimes, - next_early_index, - s: self.scope, - track_lifetime_uses: true, - opaque_type_parent: true, - }; - self.with(scope, |_old_scope, this| { - this.visit_generics(generics); - for bound in bounds { - this.visit_param_bound(bound); - } - }); - } Const(_, _) => { // Only methods and types support generics. assert!(impl_item.generics.params.is_empty()); @@ -2367,6 +2342,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { } break Some(e); } + Elide::Forbid => break None, }; for lifetime_ref in lifetime_refs { self.insert_lifetime(lifetime_ref, lifetime); @@ -2667,8 +2643,9 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { // going to make a fresh name, so we cannot // necessarily replace a single-use lifetime with // `'_`. - Scope::Elision { elide: Elide::Exact(_), .. } => break false, - Scope::Elision { elide: Elide::Error(_), .. } => break false, + Scope::Elision { + elide: Elide::Exact(_) | Elide::Error(_) | Elide::Forbid, .. + } => break false, Scope::ObjectLifetimeDefault { s, .. } => scope = s, } diff --git a/src/librustc_save_analysis/dump_visitor.rs b/src/librustc_save_analysis/dump_visitor.rs index 9b08f709f342f..e63e31e03c9f0 100644 --- a/src/librustc_save_analysis/dump_visitor.rs +++ b/src/librustc_save_analysis/dump_visitor.rs @@ -1102,7 +1102,6 @@ impl<'l, 'tcx> DumpVisitor<'l, 'tcx> { impl_item.span, ); } - hir::ImplItemKind::OpaqueTy(..) => {} hir::ImplItemKind::TyAlias(ref ty) => { // FIXME: uses of the assoc type should ideally point to this // 'def' and the name here should be a ref to the def in the @@ -1380,7 +1379,7 @@ impl<'l, 'tcx> Visitor<'tcx> for DumpVisitor<'l, 'tcx> { v.visit_expr(&map.body(anon_const.body).value) }); } - hir::TyKind::Def(item_id, _) => { + hir::TyKind::OpaqueDef(item_id, _) => { let item = self.tcx.hir().item(item_id.id); self.nest_tables(self.tcx.hir().local_def_id(item_id.id), |v| v.visit_item(item)); } diff --git a/src/librustc_save_analysis/lib.rs b/src/librustc_save_analysis/lib.rs index eb35d74729a05..12d2c8c7eb9a4 100644 --- a/src/librustc_save_analysis/lib.rs +++ b/src/librustc_save_analysis/lib.rs @@ -698,7 +698,6 @@ impl<'l, 'tcx> SaveContext<'l, 'tcx> { | HirDefKind::TyAlias | HirDefKind::ForeignTy | HirDefKind::TraitAlias - | HirDefKind::AssocOpaqueTy | HirDefKind::AssocTy | HirDefKind::Trait | HirDefKind::OpaqueTy diff --git a/src/librustc_save_analysis/sig.rs b/src/librustc_save_analysis/sig.rs index 5f337f5f77033..cd2a5deeb2d72 100644 --- a/src/librustc_save_analysis/sig.rs +++ b/src/librustc_save_analysis/sig.rs @@ -324,7 +324,7 @@ impl<'hir> Sig for hir::Ty<'hir> { let text = format!("[{}; {}]", nested_ty.text, expr); Ok(replace_text(nested_ty, text)) } - hir::TyKind::Def(item_id, _) => { + hir::TyKind::OpaqueDef(item_id, _) => { let item = scx.tcx.hir().item(item_id.id); item.make(offset, Some(item_id.id), scx) } diff --git a/src/librustc_trait_selection/opaque_types.rs b/src/librustc_trait_selection/opaque_types.rs index 19caf64c63f1e..d53a0ec9ef884 100644 --- a/src/librustc_trait_selection/opaque_types.rs +++ b/src/librustc_trait_selection/opaque_types.rs @@ -11,7 +11,7 @@ use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKi use rustc_infer::infer::{self, InferCtxt, InferOk}; use rustc_middle::ty::fold::{BottomUpFolder, TypeFoldable, TypeFolder, TypeVisitor}; use rustc_middle::ty::subst::{GenericArg, GenericArgKind, InternalSubsts, SubstsRef}; -use rustc_middle::ty::{self, GenericParamDefKind, Ty, TyCtxt}; +use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_session::config::nightly_options; use rustc_span::Span; @@ -133,9 +133,9 @@ pub trait InferCtxtExt<'tcx> { fn generate_member_constraint( &self, concrete_ty: Ty<'tcx>, - opaque_type_generics: &ty::Generics, opaque_defn: &OpaqueTypeDecl<'tcx>, opaque_type_def_id: DefId, + first_own_region_index: usize, ); /*private*/ @@ -405,7 +405,24 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { debug!("constrain_opaque_type: concrete_ty={:?}", concrete_ty); - let opaque_type_generics = tcx.generics_of(def_id); + let first_own_region = match opaque_defn.origin { + hir::OpaqueTyOrigin::FnReturn | hir::OpaqueTyOrigin::AsyncFn => { + // We lower + // + // fn foo<'l0..'ln>() -> impl Trait<'l0..'lm> + // + // into + // + // type foo::<'p0..'pn>::Foo<'q0..'qm> + // fn foo() -> foo::<'static..'static>::Foo<'l0..'lm>. + // + // For these types we onlt iterate over `'l0..lm` below. + tcx.generics_of(def_id).parent_count + } + // These opaque type inherit all lifetime parameters from their + // parent, so we have to check them all. + hir::OpaqueTyOrigin::Binding | hir::OpaqueTyOrigin::Misc => 0, + }; let span = tcx.def_span(def_id); @@ -427,12 +444,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { }); } if let GenerateMemberConstraints::IfNoStaticBound = mode { - self.generate_member_constraint( - concrete_ty, - opaque_type_generics, - opaque_defn, - def_id, - ); + self.generate_member_constraint(concrete_ty, opaque_defn, def_id, first_own_region); } return; } @@ -445,29 +457,27 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { // `['a]` for the first impl trait and `'b` for the // second. let mut least_region = None; - for param in &opaque_type_generics.params { - match param.kind { - GenericParamDefKind::Lifetime => {} - _ => continue, - } - // Get the value supplied for this region from the substs. - let subst_arg = opaque_defn.substs.region_at(param.index as usize); + for subst_arg in &opaque_defn.substs[first_own_region..] { + let subst_region = match subst_arg.unpack() { + GenericArgKind::Lifetime(r) => r, + GenericArgKind::Type(_) | GenericArgKind::Const(_) => continue, + }; // Compute the least upper bound of it with the other regions. debug!("constrain_opaque_types: least_region={:?}", least_region); - debug!("constrain_opaque_types: subst_arg={:?}", subst_arg); + debug!("constrain_opaque_types: subst_region={:?}", subst_region); match least_region { - None => least_region = Some(subst_arg), + None => least_region = Some(subst_region), Some(lr) => { - if free_region_relations.sub_free_regions(self.tcx, lr, subst_arg) { + if free_region_relations.sub_free_regions(self.tcx, lr, subst_region) { // keep the current least region - } else if free_region_relations.sub_free_regions(self.tcx, subst_arg, lr) { - // switch to `subst_arg` - least_region = Some(subst_arg); + } else if free_region_relations.sub_free_regions(self.tcx, subst_region, lr) { + // switch to `subst_region` + least_region = Some(subst_region); } else { // There are two regions (`lr` and - // `subst_arg`) which are not relatable. We + // `subst_region`) which are not relatable. We // can't find a best choice. Therefore, // instead of creating a single bound like // `'r: 'a` (which is our preferred choice), @@ -476,13 +486,13 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { // regions that appear in the impl trait. // For now, enforce a feature gate outside of async functions. - self.member_constraint_feature_gate(opaque_defn, def_id, lr, subst_arg); + self.member_constraint_feature_gate(opaque_defn, def_id, lr, subst_region); return self.generate_member_constraint( concrete_ty, - opaque_type_generics, opaque_defn, def_id, + first_own_region, ); } } @@ -494,12 +504,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { if let GenerateMemberConstraints::IfNoStaticBound = mode { if least_region != tcx.lifetimes.re_static { - self.generate_member_constraint( - concrete_ty, - opaque_type_generics, - opaque_defn, - def_id, - ); + self.generate_member_constraint(concrete_ty, opaque_defn, def_id, first_own_region); } } concrete_ty.visit_with(&mut ConstrainOpaqueTypeRegionVisitor { @@ -518,22 +523,20 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { fn generate_member_constraint( &self, concrete_ty: Ty<'tcx>, - opaque_type_generics: &ty::Generics, opaque_defn: &OpaqueTypeDecl<'tcx>, opaque_type_def_id: DefId, + first_own_region: usize, ) { // Create the set of choice regions: each region in the hidden // type can be equal to any of the region parameters of the // opaque type definition. let choice_regions: Lrc>> = Lrc::new( - opaque_type_generics - .params + opaque_defn.substs[first_own_region..] .iter() - .filter(|param| match param.kind { - GenericParamDefKind::Lifetime => true, - GenericParamDefKind::Type { .. } | GenericParamDefKind::Const => false, + .filter_map(|arg| match arg.unpack() { + GenericArgKind::Lifetime(r) => Some(r), + GenericArgKind::Type(_) | GenericArgKind::Const(_) => None, }) - .map(|param| opaque_defn.substs.region_at(param.index as usize)) .chain(std::iter::once(self.tcx.lifetimes.re_static)) .collect(), ); @@ -574,7 +577,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { hir::OpaqueTyOrigin::AsyncFn => return false, // Otherwise, generate the label we'll use in the error message. - hir::OpaqueTyOrigin::TypeAlias + hir::OpaqueTyOrigin::Binding | hir::OpaqueTyOrigin::FnReturn | hir::OpaqueTyOrigin::Misc => "impl Trait", }; @@ -1064,21 +1067,10 @@ impl<'a, 'tcx> Instantiator<'a, 'tcx> { ), origin, ), - _ => (def_scope_default(), hir::OpaqueTyOrigin::TypeAlias), - }, - Some(Node::ImplItem(item)) => match item.kind { - hir::ImplItemKind::OpaqueTy(_) => ( - may_define_opaque_type( - tcx, - self.parent_def_id.expect_local(), - opaque_hir_id, - ), - hir::OpaqueTyOrigin::TypeAlias, - ), - _ => (def_scope_default(), hir::OpaqueTyOrigin::TypeAlias), + _ => (def_scope_default(), hir::OpaqueTyOrigin::Misc), }, _ => bug!( - "expected (impl) item, found {}", + "expected item, found {}", tcx.hir().node_to_string(opaque_hir_id), ), }; diff --git a/src/librustc_trait_selection/traits/project.rs b/src/librustc_trait_selection/traits/project.rs index d6c79d1973a71..9492c3c340995 100644 --- a/src/librustc_trait_selection/traits/project.rs +++ b/src/librustc_trait_selection/traits/project.rs @@ -25,7 +25,7 @@ use rustc_errors::ErrorReported; use rustc_hir::def_id::DefId; use rustc_hir::lang_items::{FnOnceTraitLangItem, GeneratorTraitLangItem}; use rustc_middle::ty::fold::{TypeFoldable, TypeFolder}; -use rustc_middle::ty::subst::{InternalSubsts, Subst}; +use rustc_middle::ty::subst::Subst; use rustc_middle::ty::util::IntTypeExt; use rustc_middle::ty::{self, ToPolyTraitRef, ToPredicate, Ty, TyCtxt, WithConstness}; use rustc_span::symbol::{sym, Ident}; @@ -1477,12 +1477,7 @@ fn confirm_impl_candidate<'cx, 'tcx>( let substs = obligation.predicate.substs.rebase_onto(tcx, trait_def_id, substs); let substs = translate_substs(selcx.infcx(), param_env, impl_def_id, substs, assoc_ty.defining_node); - let ty = if let ty::AssocKind::OpaqueTy = assoc_ty.item.kind { - let item_substs = InternalSubsts::identity_for_item(tcx, assoc_ty.item.def_id); - tcx.mk_opaque(assoc_ty.item.def_id, item_substs) - } else { - tcx.type_of(assoc_ty.item.def_id) - }; + let ty = tcx.type_of(assoc_ty.item.def_id); if substs.len() != tcx.generics_of(assoc_ty.item.def_id).count() { tcx.sess .delay_span_bug(DUMMY_SP, "impl item and trait item have different parameter counts"); @@ -1515,7 +1510,7 @@ fn assoc_ty_def( // cycle error if the specialization graph is currently being built. let impl_node = specialization_graph::Node::Impl(impl_def_id); for item in impl_node.items(tcx) { - if matches!(item.kind, ty::AssocKind::Type | ty::AssocKind::OpaqueTy) + if matches!(item.kind, ty::AssocKind::Type) && tcx.hygienic_eq(item.ident, assoc_ty_name, trait_def_id) { return Ok(specialization_graph::LeafDef { diff --git a/src/librustc_ty/ty.rs b/src/librustc_ty/ty.rs index 3da5da2d9efb8..99094246a6378 100644 --- a/src/librustc_ty/ty.rs +++ b/src/librustc_ty/ty.rs @@ -85,7 +85,6 @@ fn associated_item_from_trait_item_ref( hir::AssocItemKind::Const => (ty::AssocKind::Const, false), hir::AssocItemKind::Fn { has_self } => (ty::AssocKind::Fn, has_self), hir::AssocItemKind::Type => (ty::AssocKind::Type, false), - hir::AssocItemKind::OpaqueTy => bug!("only impls can have opaque types"), }; ty::AssocItem { @@ -110,7 +109,6 @@ fn associated_item_from_impl_item_ref( hir::AssocItemKind::Const => (ty::AssocKind::Const, false), hir::AssocItemKind::Fn { has_self } => (ty::AssocKind::Fn, has_self), hir::AssocItemKind::Type => (ty::AssocKind::Type, false), - hir::AssocItemKind::OpaqueTy => (ty::AssocKind::OpaqueTy, false), }; ty::AssocItem { diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index f1dc7e5390629..267f3d9f3ef6e 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -2838,9 +2838,16 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { let opt_self_ty = maybe_qself.as_ref().map(|qself| self.ast_ty_to_ty(qself)); self.res_to_ty(opt_self_ty, path, false) } - hir::TyKind::Def(item_id, ref lifetimes) => { - let did = tcx.hir().local_def_id(item_id.id); - self.impl_trait_ty_to_ty(did.to_def_id(), lifetimes) + hir::TyKind::OpaqueDef(item_id, ref lifetimes) => { + let opaque_ty = tcx.hir().expect_item(item_id.id); + let def_id = tcx.hir().local_def_id(item_id.id).to_def_id(); + + match opaque_ty.kind { + hir::ItemKind::OpaqueTy(hir::OpaqueTy { impl_trait_fn, .. }) => { + self.impl_trait_ty_to_ty(def_id, lifetimes, impl_trait_fn.is_some()) + } + ref i => bug!("`impl Trait` pointed to non-opaque type?? {:#?}", i), + } } hir::TyKind::Path(hir::QPath::TypeRelative(ref qself, ref segment)) => { debug!("ast_ty_to_ty: qself={:?} segment={:?}", qself, segment); @@ -2893,6 +2900,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { &self, def_id: DefId, lifetimes: &[hir::GenericArg<'_>], + replace_parent_lifetimes: bool, ) -> Ty<'tcx> { debug!("impl_trait_ty_to_ty(def_id={:?}, lifetimes={:?})", def_id, lifetimes); let tcx = self.tcx(); @@ -2914,9 +2922,18 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { _ => bug!(), } } else { - // Replace all parent lifetimes with `'static`. match param.kind { - GenericParamDefKind::Lifetime => tcx.lifetimes.re_static.into(), + // For RPIT (return position impl trait), only lifetimes + // mentioned in the impl Trait predicate are captured by + // the opaque type, so the lifetime parameters from the + // parent item need to be replaced with `'static`. + // + // For `impl Trait` in the types of statics, constants, + // locals and type aliases. These capture all parent + // lifetimes, so they can use their identity subst. + GenericParamDefKind::Lifetime if replace_parent_lifetimes => { + tcx.lifetimes.re_static.into() + } _ => tcx.mk_param_from_def(param), } } diff --git a/src/librustc_typeck/check/coercion.rs b/src/librustc_typeck/check/coercion.rs index 96c0d98ab0618..15ec92568fb4d 100644 --- a/src/librustc_typeck/check/coercion.rs +++ b/src/librustc_typeck/check/coercion.rs @@ -1494,7 +1494,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> { let mut is_object_safe = false; if let hir::FnRetTy::Return(ty) = fn_output { // Get the return type. - if let hir::TyKind::Def(..) = ty.kind { + if let hir::TyKind::OpaqueDef(..) = ty.kind { let ty = AstConv::ast_ty_to_ty(fcx, ty); // Get the `impl Trait`'s `DefId`. if let ty::Opaque(def_id, _) = ty.kind { diff --git a/src/librustc_typeck/check/compare_method.rs b/src/librustc_typeck/check/compare_method.rs index 29cd9681295be..5f8fcaadfdb0b 100644 --- a/src/librustc_typeck/check/compare_method.rs +++ b/src/librustc_typeck/check/compare_method.rs @@ -1165,6 +1165,6 @@ fn assoc_item_kind_str(impl_item: &ty::AssocItem) -> &'static str { match impl_item.kind { ty::AssocKind::Const => "const", ty::AssocKind::Fn => "method", - ty::AssocKind::Type | ty::AssocKind::OpaqueTy => "type", + ty::AssocKind::Type => "type", } } diff --git a/src/librustc_typeck/check/method/probe.rs b/src/librustc_typeck/check/method/probe.rs index 4095ab5e10fa5..a2e6c8793cbdd 100644 --- a/src/librustc_typeck/check/method/probe.rs +++ b/src/librustc_typeck/check/method/probe.rs @@ -1556,7 +1556,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { match self.mode { Mode::MethodCall => item.fn_has_self_parameter, Mode::Path => match item.kind { - ty::AssocKind::OpaqueTy | ty::AssocKind::Type => false, + ty::AssocKind::Type => false, ty::AssocKind::Fn | ty::AssocKind::Const => true, }, } diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs index 7ca3eb884d88f..67bdd04d3715c 100644 --- a/src/librustc_typeck/check/method/suggest.rs +++ b/src/librustc_typeck/check/method/suggest.rs @@ -158,9 +158,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let path = self.tcx.def_path_str(trait_ref.def_id); let ty = match item.kind { - ty::AssocKind::Const - | ty::AssocKind::Type - | ty::AssocKind::OpaqueTy => rcvr_ty, + ty::AssocKind::Const | ty::AssocKind::Type => rcvr_ty, ty::AssocKind::Fn => self .tcx .fn_sig(item.def_id) diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index fabedc3800ae4..7b8f180219688 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -1943,7 +1943,6 @@ fn check_specialization_validity<'tcx>( let kind = match impl_item.kind { hir::ImplItemKind::Const(..) => ty::AssocKind::Const, hir::ImplItemKind::Fn(..) => ty::AssocKind::Fn, - hir::ImplItemKind::OpaqueTy(..) => ty::AssocKind::OpaqueTy, hir::ImplItemKind::TyAlias(_) => ty::AssocKind::Type, }; @@ -2114,7 +2113,7 @@ fn check_impl_items_against_trait<'tcx>( err.emit() } } - hir::ImplItemKind::OpaqueTy(..) | hir::ImplItemKind::TyAlias(_) => { + hir::ImplItemKind::TyAlias(_) => { let opt_trait_span = tcx.hir().span_if_local(ty_trait_item.def_id); if ty_trait_item.kind == ty::AssocKind::Type { compare_ty_impl( @@ -2367,8 +2366,6 @@ fn suggestion_signature(assoc: &ty::AssocItem, tcx: TyCtxt<'_>) -> String { ) } ty::AssocKind::Type => format!("type {} = Type;", assoc.ident), - // FIXME(type_alias_impl_trait): we should print bounds here too. - ty::AssocKind::OpaqueTy => format!("type {} = Type;", assoc.ident), ty::AssocKind::Const => { let ty = tcx.type_of(assoc.def_id); let val = expr::ty_kind_suggestion(ty).unwrap_or("value"); diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs index 7d9bf975c6913..f3297ed674347 100644 --- a/src/librustc_typeck/check/wfcheck.rs +++ b/src/librustc_typeck/check/wfcheck.rs @@ -316,9 +316,6 @@ fn check_associated_item( fcx.register_wf_obligation(ty.into(), span, code.clone()); } } - ty::AssocKind::OpaqueTy => { - // Do nothing: opaque types check themselves. - } } implied_bounds @@ -804,14 +801,14 @@ fn check_where_clauses<'tcx, 'fcx>( traits::Obligation::new(cause, fcx.param_env, pred) }); - let mut predicates = predicates.instantiate_identity(fcx.tcx); + let predicates = predicates.instantiate_identity(fcx.tcx); - if let Some((return_ty, span)) = return_ty { - let opaque_types = check_opaque_types(tcx, fcx, def_id.expect_local(), span, return_ty); - for _ in 0..opaque_types.len() { - predicates.spans.push(span); + if let Some((mut return_ty, span)) = return_ty { + if return_ty.has_infer_types_or_consts() { + fcx.select_obligations_where_possible(false, |_| {}); + return_ty = fcx.resolve_vars_if_possible(&return_ty); } - predicates.predicates.extend(opaque_types); + check_opaque_types(tcx, fcx, def_id.expect_local(), span, return_ty); } let predicates = fcx.normalize_associated_types_in(span, &predicates); @@ -883,119 +880,117 @@ fn check_opaque_types<'fcx, 'tcx>( fn_def_id: LocalDefId, span: Span, ty: Ty<'tcx>, -) -> Vec> { +) { trace!("check_opaque_types(ty={:?})", ty); - let mut substituted_predicates = Vec::new(); ty.fold_with(&mut ty::fold::BottomUpFolder { tcx: fcx.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); - // 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.expect_local()); - if may_define_opaque_type(tcx, fn_def_id, opaque_hir_id) { - 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; - } - - 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); + + let opaque_hir_id = if let Some(local_id) = def_id.as_local() { + tcx.hir().as_local_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_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_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", ) - .span_note(spans, &format!("{} used multiple times", descr)) .emit(); + continue; } - } - } // if may_define_opaque_type - // Now register the bounds on the parameters of the opaque type - // so the parameters given by the function need to fulfill them. - // - // type Foo = impl Baz + 'static; - // fn foo() -> Foo { .. *} - // - // becomes - // - // type Foo = impl Baz + 'static; - // fn foo() -> Foo { .. *} - let predicates = tcx.predicates_of(def_id); - trace!("check_opaque_types: may define, predicates={:#?}", predicates,); - for &(pred, _) in predicates.predicates { - let substituted_pred = pred.subst(fcx.tcx, substs); - // Avoid duplication of predicates that contain no parameters, for example. - if !predicates.predicates.iter().any(|&(p, _)| p == substituted_pred) { - substituted_predicates.push(substituted_pred); + 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(); } - } // if is_named_opaque_type + } // 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, }); - substituted_predicates } const HELP_FOR_SELF_TYPE: &str = "consider changing to `self`, `&self`, `&mut self`, `self: Box`, \ diff --git a/src/librustc_typeck/check/writeback.rs b/src/librustc_typeck/check/writeback.rs index 3473dc7a58d04..159d3d7a538a6 100644 --- a/src/librustc_typeck/check/writeback.rs +++ b/src/librustc_typeck/check/writeback.rs @@ -460,7 +460,7 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { let mut skip_add = false; if let ty::Opaque(defin_ty_def_id, _substs) = definition_ty.kind { - if let hir::OpaqueTyOrigin::TypeAlias = opaque_defn.origin { + if let hir::OpaqueTyOrigin::Misc = opaque_defn.origin { if def_id == defin_ty_def_id { debug!( "skipping adding concrete definition for opaque type {:?} {:?}", diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 355b4fc413f42..1d59d749634ee 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -742,7 +742,7 @@ fn convert_impl_item(tcx: TyCtxt<'_>, impl_item_id: hir::HirId) { hir::ImplItemKind::Fn(..) => { tcx.ensure().fn_sig(def_id); } - hir::ImplItemKind::TyAlias(_) | hir::ImplItemKind::OpaqueTy(_) => { + hir::ImplItemKind::TyAlias(_) => { // Account for `type T = _;` let mut visitor = PlaceholderHirTyCollector::default(); visitor.visit_impl_item(impl_item); @@ -1202,22 +1202,11 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics { ItemKind::OpaqueTy(hir::OpaqueTy { impl_trait_fn, .. }) => { impl_trait_fn.or_else(|| { let parent_id = tcx.hir().get_parent_item(hir_id); - if parent_id != hir_id && parent_id != CRATE_HIR_ID { - debug!("generics_of: parent of opaque ty {:?} is {:?}", def_id, parent_id); - // If this 'impl Trait' is nested inside another 'impl Trait' - // (e.g. `impl Foo>`), we need to use the 'parent' - // 'impl Trait' for its generic parameters, since we can reference them - // from the 'child' 'impl Trait' - if let Node::Item(hir::Item { kind: ItemKind::OpaqueTy(..), .. }) = - tcx.hir().get(parent_id) - { - Some(tcx.hir().local_def_id(parent_id).to_def_id()) - } else { - None - } - } else { - None - } + assert!(parent_id != hir_id && parent_id != CRATE_HIR_ID); + debug!("generics_of: parent of opaque ty {:?} is {:?}", def_id, parent_id); + // Opaque types are always nested within another item, and + // inherit the generics of the item. + Some(tcx.hir().local_def_id(parent_id).to_def_id()) }) } _ => None, @@ -1428,7 +1417,7 @@ fn is_suggestable_infer_ty(ty: &hir::Ty<'_>) -> bool { Slice(ty) | Array(ty, _) => is_suggestable_infer_ty(ty), Tup(tys) => tys.iter().any(is_suggestable_infer_ty), Ptr(mut_ty) | Rptr(_, mut_ty) => is_suggestable_infer_ty(mut_ty.ty), - Def(_, generic_args) => are_suggestable_generic_args(generic_args), + OpaqueDef(_, generic_args) => are_suggestable_generic_args(generic_args), Path(hir::QPath::TypeRelative(ty, segment)) => { is_suggestable_infer_ty(ty) || are_suggestable_generic_args(segment.generic_args().args) } @@ -1715,31 +1704,7 @@ fn explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericPredicat let ast_generics = match node { Node::TraitItem(item) => &item.generics, - Node::ImplItem(item) => match item.kind { - ImplItemKind::OpaqueTy(ref bounds) => { - ty::print::with_no_queries(|| { - let substs = InternalSubsts::identity_for_item(tcx, def_id); - let opaque_ty = tcx.mk_opaque(def_id, substs); - debug!( - "explicit_predicates_of({:?}): created opaque type {:?}", - def_id, opaque_ty - ); - - // Collect the bounds, i.e., the `A + B + 'c` in `impl A + B + 'c`. - let bounds = AstConv::compute_bounds( - &icx, - opaque_ty, - bounds, - SizedByDefault::Yes, - tcx.def_span(def_id), - ); - - predicates.extend(bounds.predicates(tcx, opaque_ty)); - &item.generics - }) - } - _ => &item.generics, - }, + Node::ImplItem(item) => &item.generics, Node::Item(item) => { match item.kind { diff --git a/src/librustc_typeck/collect/type_of.rs b/src/librustc_typeck/collect/type_of.rs index cf0e3f9cdf592..549a20531e299 100644 --- a/src/librustc_typeck/collect/type_of.rs +++ b/src/librustc_typeck/collect/type_of.rs @@ -64,13 +64,6 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> { icx.to_ty(ty) } } - ImplItemKind::OpaqueTy(_) => { - if tcx.impl_trait_ref(tcx.hir().get_parent_did(hir_id).to_def_id()).is_none() { - report_assoc_ty_on_inherent_impl(tcx, item.span); - } - - find_opaque_ty_constraints(tcx, def_id.expect_local()) - } ImplItemKind::TyAlias(ref ty) => { if tcx.impl_trait_ref(tcx.hir().get_parent_did(hir_id).to_def_id()).is_none() { report_assoc_ty_on_inherent_impl(tcx, item.span); @@ -107,26 +100,17 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> { let substs = InternalSubsts::identity_for_item(tcx, def_id); tcx.mk_adt(def, substs) } + ItemKind::OpaqueTy(OpaqueTy { origin: hir::OpaqueTyOrigin::Binding, .. }) => { + let_position_impl_trait_type(tcx, def_id.expect_local()) + } ItemKind::OpaqueTy(OpaqueTy { impl_trait_fn: None, .. }) => { find_opaque_ty_constraints(tcx, def_id.expect_local()) } // Opaque types desugared from `impl Trait`. - ItemKind::OpaqueTy(OpaqueTy { impl_trait_fn: Some(owner), origin, .. }) => { - let concrete_types = match origin { - OpaqueTyOrigin::FnReturn | OpaqueTyOrigin::AsyncFn => { - &tcx.mir_borrowck(owner.expect_local()).concrete_opaque_types - } - OpaqueTyOrigin::Misc => { - // We shouldn't leak borrowck results through impl trait in bindings. - // For example, we shouldn't be able to tell if `x` in - // `let x: impl Sized + 'a = &()` has type `&'static ()` or `&'a ()`. - &tcx.typeck_tables_of(owner.expect_local()).concrete_opaque_types - } - OpaqueTyOrigin::TypeAlias => { - span_bug!(item.span, "Type alias impl trait shouldn't have an owner") - } - }; - let concrete_ty = concrete_types + ItemKind::OpaqueTy(OpaqueTy { impl_trait_fn: Some(owner), .. }) => { + let concrete_ty = tcx + .mir_borrowck(owner.expect_local()) + .concrete_opaque_types .get(&def_id) .map(|opaque| opaque.concrete_type) .unwrap_or_else(|| { @@ -155,13 +139,6 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> { } }); debug!("concrete_ty = {:?}", concrete_ty); - if concrete_ty.has_erased_regions() { - // FIXME(impl_trait_in_bindings) Handle this case. - tcx.sess.span_fatal( - item.span, - "lifetimes in impl Trait types in bindings are not currently supported", - ); - } concrete_ty } ItemKind::Trait(..) @@ -596,6 +573,60 @@ fn find_opaque_ty_constraints(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Ty<'_> { } } +/// Retrieve the inferred concrete type for let position impl trait. +/// +/// This is different to other kinds of impl trait because: +/// +/// 1. We know which function contains the defining use (the function that +/// contains the let statement) +/// 2. We do not currently allow (free) lifetimes in the return type. `let` +/// statements in some statically unreachable code are removed from the MIR +/// by the time we borrow check, and it's not clear how we should handle +/// those. +fn let_position_impl_trait_type(tcx: TyCtxt<'_>, opaque_ty_id: LocalDefId) -> Ty<'_> { + let scope = tcx.hir().get_defining_scope(tcx.hir().as_local_hir_id(opaque_ty_id)); + let scope_def_id = tcx.hir().local_def_id(scope); + + let opaque_ty_def_id = opaque_ty_id.to_def_id(); + + let owner_tables = tcx.typeck_tables_of(scope_def_id); + let concrete_ty = owner_tables + .concrete_opaque_types + .get(&opaque_ty_def_id) + .map(|opaque| opaque.concrete_type) + .unwrap_or_else(|| { + tcx.sess.delay_span_bug( + DUMMY_SP, + &format!( + "owner {:?} has no opaque type for {:?} in its tables", + scope_def_id, opaque_ty_id + ), + ); + if let Some(ErrorReported) = owner_tables.tainted_by_errors { + // Some error in the owner fn prevented us from populating the + // `concrete_opaque_types` table. + tcx.types.err + } else { + // We failed to resolve the opaque type or it resolves to + // itself. Return the non-revealed type, which should result in + // E0720. + tcx.mk_opaque( + opaque_ty_def_id, + InternalSubsts::identity_for_item(tcx, opaque_ty_def_id), + ) + } + }); + debug!("concrete_ty = {:?}", concrete_ty); + if concrete_ty.has_erased_regions() { + // FIXME(impl_trait_in_bindings) Handle this case. + tcx.sess.span_fatal( + tcx.hir().span(tcx.hir().as_local_hir_id(opaque_ty_id)), + "lifetimes in impl Trait types in bindings are not currently supported", + ); + } + concrete_ty +} + fn infer_placeholder_type( tcx: TyCtxt<'_>, def_id: LocalDefId, diff --git a/src/librustc_typeck/impl_wf_check.rs b/src/librustc_typeck/impl_wf_check.rs index e13d9ea2b2626..37d383db68ab6 100644 --- a/src/librustc_typeck/impl_wf_check.rs +++ b/src/librustc_typeck/impl_wf_check.rs @@ -140,13 +140,6 @@ fn enforce_impl_params_are_constrained( Vec::new() } } - ty::AssocKind::OpaqueTy => { - // We don't know which lifetimes appear in the actual - // opaque type, so use all of the lifetimes that appear - // in the type's predicates. - let predicates = tcx.predicates_of(def_id).instantiate_identity(tcx); - cgp::parameters_for(&predicates, true) - } ty::AssocKind::Fn | ty::AssocKind::Const => Vec::new(), } }) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index dd4df11b1df38..adb2ae9a5d660 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1138,10 +1138,6 @@ impl Clean for hir::ImplItem<'_> { let item_type = type_.def_id().and_then(|did| inline::build_ty(cx, did)); TypedefItem(Typedef { type_, generics: Generics::default(), item_type }, true) } - hir::ImplItemKind::OpaqueTy(ref bounds) => OpaqueTyItem( - OpaqueTy { bounds: bounds.clean(cx), generics: Generics::default() }, - true, - ), }; let local_did = cx.tcx.hir().local_def_id(self.hir_id); Item { @@ -1308,7 +1304,6 @@ impl Clean for ty::AssocItem { ) } } - ty::AssocKind::OpaqueTy => unimplemented!(), }; let visibility = match self.container { @@ -1356,7 +1351,7 @@ impl Clean for hir::Ty<'_> { Array(box ty.clean(cx), length) } TyKind::Tup(ref tys) => Tuple(tys.clean(cx)), - TyKind::Def(item_id, _) => { + TyKind::OpaqueDef(item_id, _) => { let item = cx.tcx.hir().expect_item(item_id.id); if let hir::ItemKind::OpaqueTy(ref ty) = item.kind { ImplTrait(ty.bounds.clean(cx)) diff --git a/src/test/rustdoc/auxiliary/issue-73061.rs b/src/test/rustdoc/auxiliary/issue-73061.rs new file mode 100644 index 0000000000000..e05a3bc6d9180 --- /dev/null +++ b/src/test/rustdoc/auxiliary/issue-73061.rs @@ -0,0 +1,17 @@ +//edition:2018 + +#![feature(type_alias_impl_trait)] + +pub trait Foo { + type X: std::future::Future; + fn x(&self) -> Self::X; +} + +pub struct F; + +impl Foo for F { + type X = impl std::future::Future; + fn x(&self) -> Self::X { + async {} + } +} diff --git a/src/test/rustdoc/issue-73061-cross-crate-opaque-assoc-type.rs b/src/test/rustdoc/issue-73061-cross-crate-opaque-assoc-type.rs new file mode 100644 index 0000000000000..2700f2370eec8 --- /dev/null +++ b/src/test/rustdoc/issue-73061-cross-crate-opaque-assoc-type.rs @@ -0,0 +1,14 @@ +// Regression test for ICE #73061 + +// aux-build:issue-73061.rs + +extern crate issue_73061; + +pub struct Z; + +impl issue_73061::Foo for Z { + type X = ::X; + fn x(&self) -> Self::X { + issue_73061::F.x() + } +} diff --git a/src/test/ui/associated-type-bounds/duplicate.rs b/src/test/ui/associated-type-bounds/duplicate.rs index 8b396f23efd54..8b5c5219430b6 100644 --- a/src/test/ui/associated-type-bounds/duplicate.rs +++ b/src/test/ui/associated-type-bounds/duplicate.rs @@ -108,18 +108,12 @@ type TAW3 where T: Iterator = T; type ETAI1> = impl Copy; //~^ ERROR the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified [E0719] //~| ERROR could not find defining uses -//~| ERROR could not find defining uses -//~| ERROR could not find defining uses type ETAI2> = impl Copy; //~^ ERROR the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified [E0719] //~| ERROR could not find defining uses -//~| ERROR could not find defining uses -//~| ERROR could not find defining uses type ETAI3> = impl Copy; //~^ ERROR the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified [E0719] //~| ERROR could not find defining uses -//~| ERROR could not find defining uses -//~| ERROR could not find defining uses type ETAI4 = impl Iterator; //~^ ERROR the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified [E0719] //~| ERROR could not find defining uses diff --git a/src/test/ui/associated-type-bounds/duplicate.stderr b/src/test/ui/associated-type-bounds/duplicate.stderr index 71f6e4ff8b62d..712211e60cbac 100644 --- a/src/test/ui/associated-type-bounds/duplicate.stderr +++ b/src/test/ui/associated-type-bounds/duplicate.stderr @@ -223,30 +223,6 @@ LL | fn FAPIT3(_: impl Iterator) {} | | | `Item` bound here first -error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:62:42 - | -LL | fn FRPIT1() -> impl Iterator { iter::empty() } - | ---------- ^^^^^^^^^^ re-bound here - | | - | `Item` bound here first - -error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:64:42 - | -LL | fn FRPIT2() -> impl Iterator { iter::empty() } - | ---------- ^^^^^^^^^^ re-bound here - | | - | `Item` bound here first - -error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:66:45 - | -LL | fn FRPIT3() -> impl Iterator { iter::empty() } - | ------------- ^^^^^^^^^^^^^ re-bound here - | | - | `Item` bound here first - error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified --> $DIR/duplicate.rs:75:39 | @@ -367,12 +343,6 @@ LL | type TAW3 where T: Iterator = T; | | | `Item` bound here first -error: could not find defining uses - --> $DIR/duplicate.rs:108:1 - | -LL | type ETAI1> = impl Copy; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified --> $DIR/duplicate.rs:108:36 | @@ -381,14 +351,38 @@ LL | type ETAI1> = impl Copy; | | | `Item` bound here first +error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:62:42 + | +LL | fn FRPIT1() -> impl Iterator { iter::empty() } + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:64:42 + | +LL | fn FRPIT2() -> impl Iterator { iter::empty() } + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:66:45 + | +LL | fn FRPIT3() -> impl Iterator { iter::empty() } + | ------------- ^^^^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + error: could not find defining uses - --> $DIR/duplicate.rs:113:1 + --> $DIR/duplicate.rs:108:51 | -LL | type ETAI2> = impl Copy; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | type ETAI1> = impl Copy; + | ^^^^^^^^^ error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:113:36 + --> $DIR/duplicate.rs:111:36 | LL | type ETAI2> = impl Copy; | ---------- ^^^^^^^^^^ re-bound here @@ -396,13 +390,13 @@ LL | type ETAI2> = impl Copy; | `Item` bound here first error: could not find defining uses - --> $DIR/duplicate.rs:118:1 + --> $DIR/duplicate.rs:111:51 | -LL | type ETAI3> = impl Copy; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | type ETAI2> = impl Copy; + | ^^^^^^^^^ error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:118:39 + --> $DIR/duplicate.rs:114:39 | LL | type ETAI3> = impl Copy; | ------------- ^^^^^^^^^^^^^ re-bound here @@ -410,13 +404,19 @@ LL | type ETAI3> = impl Copy; | `Item` bound here first error: could not find defining uses - --> $DIR/duplicate.rs:123:1 + --> $DIR/duplicate.rs:114:57 + | +LL | type ETAI3> = impl Copy; + | ^^^^^^^^^ + +error: could not find defining uses + --> $DIR/duplicate.rs:117:14 | LL | type ETAI4 = impl Iterator; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:123:40 + --> $DIR/duplicate.rs:117:40 | LL | type ETAI4 = impl Iterator; | ---------- ^^^^^^^^^^ re-bound here @@ -424,13 +424,13 @@ LL | type ETAI4 = impl Iterator; | `Item` bound here first error: could not find defining uses - --> $DIR/duplicate.rs:128:1 + --> $DIR/duplicate.rs:122:14 | LL | type ETAI5 = impl Iterator; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:128:40 + --> $DIR/duplicate.rs:122:40 | LL | type ETAI5 = impl Iterator; | ---------- ^^^^^^^^^^ re-bound here @@ -438,13 +438,13 @@ LL | type ETAI5 = impl Iterator; | `Item` bound here first error: could not find defining uses - --> $DIR/duplicate.rs:133:1 + --> $DIR/duplicate.rs:127:14 | LL | type ETAI6 = impl Iterator; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:133:43 + --> $DIR/duplicate.rs:127:43 | LL | type ETAI6 = impl Iterator; | ------------- ^^^^^^^^^^^^^ re-bound here @@ -452,7 +452,7 @@ LL | type ETAI6 = impl Iterator; | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:139:36 + --> $DIR/duplicate.rs:133:36 | LL | trait TRI1> {} | ---------- ^^^^^^^^^^ re-bound here @@ -460,7 +460,7 @@ LL | trait TRI1> {} | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:141:36 + --> $DIR/duplicate.rs:135:36 | LL | trait TRI2> {} | ---------- ^^^^^^^^^^ re-bound here @@ -468,7 +468,7 @@ LL | trait TRI2> {} | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:143:39 + --> $DIR/duplicate.rs:137:39 | LL | trait TRI3> {} | ------------- ^^^^^^^^^^^^^ re-bound here @@ -476,7 +476,7 @@ LL | trait TRI3> {} | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:145:34 + --> $DIR/duplicate.rs:139:34 | LL | trait TRS1: Iterator {} | ---------- ^^^^^^^^^^ re-bound here @@ -484,7 +484,7 @@ LL | trait TRS1: Iterator {} | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:147:34 + --> $DIR/duplicate.rs:141:34 | LL | trait TRS2: Iterator {} | ---------- ^^^^^^^^^^ re-bound here @@ -492,7 +492,7 @@ LL | trait TRS2: Iterator {} | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:149:37 + --> $DIR/duplicate.rs:143:37 | LL | trait TRS3: Iterator {} | ------------- ^^^^^^^^^^^^^ re-bound here @@ -500,7 +500,7 @@ LL | trait TRS3: Iterator {} | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:151:45 + --> $DIR/duplicate.rs:145:45 | LL | trait TRW1 where T: Iterator {} | ---------- ^^^^^^^^^^ re-bound here @@ -508,7 +508,7 @@ LL | trait TRW1 where T: Iterator {} | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:153:45 + --> $DIR/duplicate.rs:147:45 | LL | trait TRW2 where T: Iterator {} | ---------- ^^^^^^^^^^ re-bound here @@ -516,7 +516,7 @@ LL | trait TRW2 where T: Iterator {} | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:155:48 + --> $DIR/duplicate.rs:149:48 | LL | trait TRW3 where T: Iterator {} | ------------- ^^^^^^^^^^^^^ re-bound here @@ -524,7 +524,7 @@ LL | trait TRW3 where T: Iterator {} | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:157:46 + --> $DIR/duplicate.rs:151:46 | LL | trait TRSW1 where Self: Iterator {} | ---------- ^^^^^^^^^^ re-bound here @@ -532,7 +532,7 @@ LL | trait TRSW1 where Self: Iterator {} | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:157:46 + --> $DIR/duplicate.rs:151:46 | LL | trait TRSW1 where Self: Iterator {} | ---------- ^^^^^^^^^^ re-bound here @@ -540,7 +540,7 @@ LL | trait TRSW1 where Self: Iterator {} | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:160:46 + --> $DIR/duplicate.rs:154:46 | LL | trait TRSW2 where Self: Iterator {} | ---------- ^^^^^^^^^^ re-bound here @@ -548,7 +548,7 @@ LL | trait TRSW2 where Self: Iterator {} | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:160:46 + --> $DIR/duplicate.rs:154:46 | LL | trait TRSW2 where Self: Iterator {} | ---------- ^^^^^^^^^^ re-bound here @@ -556,7 +556,7 @@ LL | trait TRSW2 where Self: Iterator {} | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:163:49 + --> $DIR/duplicate.rs:157:49 | LL | trait TRSW3 where Self: Iterator {} | ------------- ^^^^^^^^^^^^^ re-bound here @@ -564,7 +564,7 @@ LL | trait TRSW3 where Self: Iterator {} | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:163:49 + --> $DIR/duplicate.rs:157:49 | LL | trait TRSW3 where Self: Iterator {} | ------------- ^^^^^^^^^^^^^ re-bound here @@ -572,7 +572,7 @@ LL | trait TRSW3 where Self: Iterator {} | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:166:43 + --> $DIR/duplicate.rs:160:43 | LL | trait TRA1 { type A: Iterator; } | ---------- ^^^^^^^^^^ re-bound here @@ -580,7 +580,7 @@ LL | trait TRA1 { type A: Iterator; } | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:168:43 + --> $DIR/duplicate.rs:162:43 | LL | trait TRA2 { type A: Iterator; } | ---------- ^^^^^^^^^^ re-bound here @@ -588,7 +588,7 @@ LL | trait TRA2 { type A: Iterator; } | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:170:46 + --> $DIR/duplicate.rs:164:46 | LL | trait TRA3 { type A: Iterator; } | ------------- ^^^^^^^^^^^^^ re-bound here @@ -596,7 +596,7 @@ LL | trait TRA3 { type A: Iterator; } | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:173:40 + --> $DIR/duplicate.rs:167:40 | LL | type TADyn1 = dyn Iterator; | ---------- ^^^^^^^^^^ re-bound here @@ -604,7 +604,7 @@ LL | type TADyn1 = dyn Iterator; | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:177:44 + --> $DIR/duplicate.rs:171:44 | LL | type TADyn2 = Box>; | ---------- ^^^^^^^^^^ re-bound here @@ -612,7 +612,7 @@ LL | type TADyn2 = Box>; | `Item` bound here first error[E0719]: the value of the associated type `Item` (from trait `std::iter::Iterator`) is already specified - --> $DIR/duplicate.rs:181:43 + --> $DIR/duplicate.rs:175:43 | LL | type TADyn3 = dyn Iterator; | ------------- ^^^^^^^^^^^^^ re-bound here @@ -620,113 +620,77 @@ LL | type TADyn3 = dyn Iterator; | `Item` bound here first error: could not find defining uses - --> $DIR/duplicate.rs:108:24 - | -LL | type ETAI1> = impl Copy; - | ^^^^^^^^^^ - -error: could not find defining uses - --> $DIR/duplicate.rs:108:36 - | -LL | type ETAI1> = impl Copy; - | ^^^^^^^^^^ - -error: could not find defining uses - --> $DIR/duplicate.rs:113:24 - | -LL | type ETAI2> = impl Copy; - | ^^^^^^^^^^ - -error: could not find defining uses - --> $DIR/duplicate.rs:113:36 - | -LL | type ETAI2> = impl Copy; - | ^^^^^^^^^^ - -error: could not find defining uses - --> $DIR/duplicate.rs:118:24 - | -LL | type ETAI3> = impl Copy; - | ^^^^^^^^^^^^^ - -error: could not find defining uses - --> $DIR/duplicate.rs:118:39 - | -LL | type ETAI3> = impl Copy; - | ^^^^^^^^^^^^^ - -error: could not find defining uses - --> $DIR/duplicate.rs:123:28 + --> $DIR/duplicate.rs:117:28 | LL | type ETAI4 = impl Iterator; | ^^^^^^^^^^ error: could not find defining uses - --> $DIR/duplicate.rs:123:40 + --> $DIR/duplicate.rs:117:40 | LL | type ETAI4 = impl Iterator; | ^^^^^^^^^^ error: could not find defining uses - --> $DIR/duplicate.rs:128:28 + --> $DIR/duplicate.rs:122:28 | LL | type ETAI5 = impl Iterator; | ^^^^^^^^^^ error: could not find defining uses - --> $DIR/duplicate.rs:128:40 + --> $DIR/duplicate.rs:122:40 | LL | type ETAI5 = impl Iterator; | ^^^^^^^^^^ error: could not find defining uses - --> $DIR/duplicate.rs:133:28 + --> $DIR/duplicate.rs:127:28 | LL | type ETAI6 = impl Iterator; | ^^^^^^^^^^^^^ error: could not find defining uses - --> $DIR/duplicate.rs:133:43 + --> $DIR/duplicate.rs:127:43 | LL | type ETAI6 = impl Iterator; | ^^^^^^^^^^^^^ error: could not find defining uses - --> $DIR/duplicate.rs:173:28 + --> $DIR/duplicate.rs:167:28 | LL | type TADyn1 = dyn Iterator; | ^^^^^^^^^^ error: could not find defining uses - --> $DIR/duplicate.rs:173:40 + --> $DIR/duplicate.rs:167:40 | LL | type TADyn1 = dyn Iterator; | ^^^^^^^^^^ error: could not find defining uses - --> $DIR/duplicate.rs:177:32 + --> $DIR/duplicate.rs:171:32 | LL | type TADyn2 = Box>; | ^^^^^^^^^^ error: could not find defining uses - --> $DIR/duplicate.rs:177:44 + --> $DIR/duplicate.rs:171:44 | LL | type TADyn2 = Box>; | ^^^^^^^^^^ error: could not find defining uses - --> $DIR/duplicate.rs:181:28 + --> $DIR/duplicate.rs:175:28 | LL | type TADyn3 = dyn Iterator; | ^^^^^^^^^^^^^ error: could not find defining uses - --> $DIR/duplicate.rs:181:43 + --> $DIR/duplicate.rs:175:43 | LL | type TADyn3 = dyn Iterator; | ^^^^^^^^^^^^^ -error: aborting due to 96 previous errors; 1 warning emitted +error: aborting due to 90 previous errors; 1 warning emitted For more information about this error, try `rustc --explain E0719`. diff --git a/src/test/ui/feature-gates/feature-gate-type_alias_impl_trait.rs b/src/test/ui/feature-gates/feature-gate-type_alias_impl_trait.rs index 6088331cded77..3b6c9791722bb 100644 --- a/src/test/ui/feature-gates/feature-gate-type_alias_impl_trait.rs +++ b/src/test/ui/feature-gates/feature-gate-type_alias_impl_trait.rs @@ -9,10 +9,14 @@ trait Bar { impl Bar for () { type Baa = impl Debug; //~ ERROR `impl Trait` in type aliases is unstable - fn define() -> Self::Baa { 0 } + fn define() -> Self::Baa { + 0 + } } -fn define() -> Foo { 0 } +fn define() -> Foo { + 0 +} trait TraitWithDefault { type Assoc = impl Debug; @@ -26,20 +30,20 @@ type NestedFree = (Vec, impl Debug, impl Iterator //~| ERROR `impl Trait` in type aliases is unstable //~| ERROR `impl Trait` in type aliases is unstable //~| ERROR `impl Trait` in type aliases is unstable -//~| ERROR `impl Trait` not allowed outside of function -//~| ERROR `impl Trait` not allowed outside of function -//~| ERROR `impl Trait` not allowed outside of function + +fn define_multiple() -> NestedFree { + (vec![true], 0u8, 0i32..1) +} impl Bar for u8 { - type Baa = (Vec, impl Debug, impl Iterator); + type Baa = (Vec, impl Debug, impl Iterator + Debug); //~^ ERROR `impl Trait` in type aliases is unstable //~| ERROR `impl Trait` in type aliases is unstable //~| ERROR `impl Trait` in type aliases is unstable //~| ERROR `impl Trait` in type aliases is unstable - //~| ERROR `impl Trait` not allowed outside of function - //~| ERROR `impl Trait` not allowed outside of function - //~| ERROR `impl Trait` not allowed outside of function - fn define() -> Self::Baa { (vec![true], 0u8, 0i32..1) } + fn define() -> Self::Baa { + (vec![true], 0u8, 0i32..1) + } } fn main() {} diff --git a/src/test/ui/feature-gates/feature-gate-type_alias_impl_trait.stderr b/src/test/ui/feature-gates/feature-gate-type_alias_impl_trait.stderr index 55cd2984ab665..8bab0d0c4a95c 100644 --- a/src/test/ui/feature-gates/feature-gate-type_alias_impl_trait.stderr +++ b/src/test/ui/feature-gates/feature-gate-type_alias_impl_trait.stderr @@ -17,7 +17,7 @@ LL | type Baa = impl Debug; = help: add `#![feature(type_alias_impl_trait)]` to the crate attributes to enable error[E0658]: associated type defaults are unstable - --> $DIR/feature-gate-type_alias_impl_trait.rs:18:5 + --> $DIR/feature-gate-type_alias_impl_trait.rs:22:5 | LL | type Assoc = impl Debug; | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -26,7 +26,7 @@ LL | type Assoc = impl Debug; = help: add `#![feature(associated_type_defaults)]` to the crate attributes to enable error[E0658]: `impl Trait` in type aliases is unstable - --> $DIR/feature-gate-type_alias_impl_trait.rs:18:18 + --> $DIR/feature-gate-type_alias_impl_trait.rs:22:18 | LL | type Assoc = impl Debug; | ^^^^^^^^^^ @@ -35,7 +35,7 @@ LL | type Assoc = impl Debug; = help: add `#![feature(type_alias_impl_trait)]` to the crate attributes to enable error[E0658]: `impl Trait` in type aliases is unstable - --> $DIR/feature-gate-type_alias_impl_trait.rs:24:24 + --> $DIR/feature-gate-type_alias_impl_trait.rs:28:24 | LL | type NestedFree = (Vec, impl Debug, impl Iterator); | ^^^^^^^^^^ @@ -44,7 +44,7 @@ LL | type NestedFree = (Vec, impl Debug, impl Iterator $DIR/feature-gate-type_alias_impl_trait.rs:24:37 + --> $DIR/feature-gate-type_alias_impl_trait.rs:28:37 | LL | type NestedFree = (Vec, impl Debug, impl Iterator); | ^^^^^^^^^^ @@ -53,7 +53,7 @@ LL | type NestedFree = (Vec, impl Debug, impl Iterator $DIR/feature-gate-type_alias_impl_trait.rs:24:49 + --> $DIR/feature-gate-type_alias_impl_trait.rs:28:49 | LL | type NestedFree = (Vec, impl Debug, impl Iterator); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -62,7 +62,7 @@ LL | type NestedFree = (Vec, impl Debug, impl Iterator $DIR/feature-gate-type_alias_impl_trait.rs:24:70 + --> $DIR/feature-gate-type_alias_impl_trait.rs:28:70 | LL | type NestedFree = (Vec, impl Debug, impl Iterator); | ^^^^^^^^^^ @@ -71,84 +71,48 @@ LL | type NestedFree = (Vec, impl Debug, impl Iterator $DIR/feature-gate-type_alias_impl_trait.rs:34:21 + --> $DIR/feature-gate-type_alias_impl_trait.rs:39:21 | -LL | type Baa = (Vec, impl Debug, impl Iterator); +LL | type Baa = (Vec, impl Debug, impl Iterator + Debug); | ^^^^^^^^^^ | = note: see issue #63063 for more information = help: add `#![feature(type_alias_impl_trait)]` to the crate attributes to enable error[E0658]: `impl Trait` in type aliases is unstable - --> $DIR/feature-gate-type_alias_impl_trait.rs:34:34 + --> $DIR/feature-gate-type_alias_impl_trait.rs:39:34 | -LL | type Baa = (Vec, impl Debug, impl Iterator); +LL | type Baa = (Vec, impl Debug, impl Iterator + Debug); | ^^^^^^^^^^ | = note: see issue #63063 for more information = help: add `#![feature(type_alias_impl_trait)]` to the crate attributes to enable error[E0658]: `impl Trait` in type aliases is unstable - --> $DIR/feature-gate-type_alias_impl_trait.rs:34:46 + --> $DIR/feature-gate-type_alias_impl_trait.rs:39:46 | -LL | type Baa = (Vec, impl Debug, impl Iterator); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | type Baa = (Vec, impl Debug, impl Iterator + Debug); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: see issue #63063 for more information = help: add `#![feature(type_alias_impl_trait)]` to the crate attributes to enable error[E0658]: `impl Trait` in type aliases is unstable - --> $DIR/feature-gate-type_alias_impl_trait.rs:34:67 + --> $DIR/feature-gate-type_alias_impl_trait.rs:39:67 | -LL | type Baa = (Vec, impl Debug, impl Iterator); +LL | type Baa = (Vec, impl Debug, impl Iterator + Debug); | ^^^^^^^^^^ | = note: see issue #63063 for more information = help: add `#![feature(type_alias_impl_trait)]` to the crate attributes to enable error[E0562]: `impl Trait` not allowed outside of function and inherent method return types - --> $DIR/feature-gate-type_alias_impl_trait.rs:18:18 + --> $DIR/feature-gate-type_alias_impl_trait.rs:22:18 | LL | type Assoc = impl Debug; | ^^^^^^^^^^ -error[E0562]: `impl Trait` not allowed outside of function and inherent method return types - --> $DIR/feature-gate-type_alias_impl_trait.rs:24:24 - | -LL | type NestedFree = (Vec, impl Debug, impl Iterator); - | ^^^^^^^^^^ - -error[E0562]: `impl Trait` not allowed outside of function and inherent method return types - --> $DIR/feature-gate-type_alias_impl_trait.rs:24:37 - | -LL | type NestedFree = (Vec, impl Debug, impl Iterator); - | ^^^^^^^^^^ - -error[E0562]: `impl Trait` not allowed outside of function and inherent method return types - --> $DIR/feature-gate-type_alias_impl_trait.rs:24:49 - | -LL | type NestedFree = (Vec, impl Debug, impl Iterator); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error[E0562]: `impl Trait` not allowed outside of function and inherent method return types - --> $DIR/feature-gate-type_alias_impl_trait.rs:34:21 - | -LL | type Baa = (Vec, impl Debug, impl Iterator); - | ^^^^^^^^^^ - -error[E0562]: `impl Trait` not allowed outside of function and inherent method return types - --> $DIR/feature-gate-type_alias_impl_trait.rs:34:34 - | -LL | type Baa = (Vec, impl Debug, impl Iterator); - | ^^^^^^^^^^ - -error[E0562]: `impl Trait` not allowed outside of function and inherent method return types - --> $DIR/feature-gate-type_alias_impl_trait.rs:34:46 - | -LL | type Baa = (Vec, impl Debug, impl Iterator); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: aborting due to 19 previous errors +error: aborting due to 13 previous errors Some errors have detailed explanations: E0562, E0658. For more information about an error, try `rustc --explain E0562`. diff --git a/src/test/ui/impl-trait/auto-trait.rs b/src/test/ui/impl-trait/auto-trait.rs index c767578120883..cf2773f4ef59d 100644 --- a/src/test/ui/impl-trait/auto-trait.rs +++ b/src/test/ui/impl-trait/auto-trait.rs @@ -2,22 +2,24 @@ // the purposes of coherence checking #![feature(type_alias_impl_trait)] -trait OpaqueTrait { } -impl OpaqueTrait for T { } +trait OpaqueTrait {} +impl OpaqueTrait for T {} type OpaqueType = impl OpaqueTrait; -fn mk_opaque() -> OpaqueType { () } +fn mk_opaque() -> OpaqueType { + () +} #[derive(Debug)] struct D(T); -trait AnotherTrait { } -impl AnotherTrait for T { } +trait AnotherTrait {} +impl AnotherTrait for T {} // This is in error, because we cannot assume that `OpaqueType: !Send`. // (We treat opaque types as "foreign types" that could grow more impls // in the future.) impl AnotherTrait for D { - //~^ ERROR conflicting implementations of trait `AnotherTrait` for type `D` + //~^ ERROR conflicting implementations of trait `AnotherTrait` for type `D` } fn main() {} diff --git a/src/test/ui/impl-trait/auto-trait.stderr b/src/test/ui/impl-trait/auto-trait.stderr index 5e72ca7a47ba1..16fe1b56b50c6 100644 --- a/src/test/ui/impl-trait/auto-trait.stderr +++ b/src/test/ui/impl-trait/auto-trait.stderr @@ -1,11 +1,11 @@ -error[E0119]: conflicting implementations of trait `AnotherTrait` for type `D`: - --> $DIR/auto-trait.rs:19:1 +error[E0119]: conflicting implementations of trait `AnotherTrait` for type `D`: + --> $DIR/auto-trait.rs:21:1 | -LL | impl AnotherTrait for T { } +LL | impl AnotherTrait for T {} | -------------------------------- first implementation here ... LL | impl AnotherTrait for D { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `D` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `D` error: aborting due to previous error diff --git a/src/test/ui/impl-trait/issue-55872-1.stderr b/src/test/ui/impl-trait/issue-55872-1.stderr index 6cb2c9fb892f3..5131509cdf03e 100644 --- a/src/test/ui/impl-trait/issue-55872-1.stderr +++ b/src/test/ui/impl-trait/issue-55872-1.stderr @@ -1,8 +1,8 @@ error[E0277]: the trait bound `S: std::marker::Copy` is not satisfied in `(S, T)` - --> $DIR/issue-55872-1.rs:12:5 + --> $DIR/issue-55872-1.rs:12:14 | LL | type E = impl Copy; - | ^^^^^^^^^^^^^^^^^^^ within `(S, T)`, the trait `std::marker::Copy` is not implemented for `S` + | ^^^^^^^^^ within `(S, T)`, the trait `std::marker::Copy` is not implemented for `S` | = note: required because it appears within the type `(S, T)` = note: the return type of a function must have a statically known size @@ -12,10 +12,10 @@ LL | impl Bar for S { | ^^^^^^^^^^^^^^^^^^^ error[E0277]: the trait bound `T: std::marker::Copy` is not satisfied in `(S, T)` - --> $DIR/issue-55872-1.rs:12:5 + --> $DIR/issue-55872-1.rs:12:14 | LL | type E = impl Copy; - | ^^^^^^^^^^^^^^^^^^^ within `(S, T)`, the trait `std::marker::Copy` is not implemented for `T` + | ^^^^^^^^^ within `(S, T)`, the trait `std::marker::Copy` is not implemented for `T` | = note: required because it appears within the type `(S, T)` = note: the return type of a function must have a statically known size diff --git a/src/test/ui/impl-trait/issue-55872-2.stderr b/src/test/ui/impl-trait/issue-55872-2.stderr index 01371b4d5c61f..649109e4c9324 100644 --- a/src/test/ui/impl-trait/issue-55872-2.stderr +++ b/src/test/ui/impl-trait/issue-55872-2.stderr @@ -1,8 +1,8 @@ error[E0277]: the trait bound `impl std::future::Future: std::marker::Copy` is not satisfied - --> $DIR/issue-55872-2.rs:13:5 + --> $DIR/issue-55872-2.rs:13:14 | LL | type E = impl Copy; - | ^^^^^^^^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `impl std::future::Future` + | ^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `impl std::future::Future` | = note: the return type of a function must have a statically known size diff --git a/src/test/ui/impl-trait/issue-60473.rs b/src/test/ui/impl-trait/issue-60473.rs index 50cf0c8c6d641..2ef86f03d340c 100644 --- a/src/test/ui/impl-trait/issue-60473.rs +++ b/src/test/ui/impl-trait/issue-60473.rs @@ -5,13 +5,11 @@ struct A<'a>(&'a ()); -trait Trait { -} +trait Trait {} -impl Trait for () { -} +impl Trait for () {} fn main() { - let x: impl Trait = (); // FIXME: The error doesn't seem correct. - //~^ ERROR: opaque type expands to a recursive type + let x: impl Trait = (); + //~^ ERROR: missing lifetime specifier } diff --git a/src/test/ui/impl-trait/issue-60473.stderr b/src/test/ui/impl-trait/issue-60473.stderr index 2d95be4e52c61..367b5db5d2dce 100644 --- a/src/test/ui/impl-trait/issue-60473.stderr +++ b/src/test/ui/impl-trait/issue-60473.stderr @@ -1,11 +1,15 @@ -error[E0720]: opaque type expands to a recursive type - --> $DIR/issue-60473.rs:15:12 +error[E0106]: missing lifetime specifier + --> $DIR/issue-60473.rs:13:23 | -LL | let x: impl Trait = (); // FIXME: The error doesn't seem correct. - | ^^^^^^^^^^^^^ expands to a recursive type +LL | let x: impl Trait = (); + | ^ expected named lifetime parameter + | +help: consider introducing a named lifetime parameter + | +LL | fn main<'a>() { +LL | let x: impl Trait> = (); | - = note: type resolves to itself error: aborting due to previous error -For more information about this error, try `rustc --explain E0720`. +For more information about this error, try `rustc --explain E0106`. diff --git a/src/test/ui/impl-trait/issue-67166.rs b/src/test/ui/impl-trait/issue-67166.rs index de7433a9bfc4c..efa67558bd7c1 100644 --- a/src/test/ui/impl-trait/issue-67166.rs +++ b/src/test/ui/impl-trait/issue-67166.rs @@ -4,8 +4,8 @@ #![allow(incomplete_features)] pub fn run() { - let _foo: Box = Box::new(()); // FIXME: The error doesn't much make sense. - //~^ ERROR: opaque type expands to a recursive type + let _foo: Box = Box::new(()); + //~^ ERROR: missing lifetime specifier } fn main() {} diff --git a/src/test/ui/impl-trait/issue-67166.stderr b/src/test/ui/impl-trait/issue-67166.stderr index 56cba3cff0b55..14c78684e3e2f 100644 --- a/src/test/ui/impl-trait/issue-67166.stderr +++ b/src/test/ui/impl-trait/issue-67166.stderr @@ -1,11 +1,15 @@ -error[E0720]: opaque type expands to a recursive type - --> $DIR/issue-67166.rs:7:19 +error[E0106]: missing lifetime specifier + --> $DIR/issue-67166.rs:7:31 | -LL | let _foo: Box = Box::new(()); // FIXME: The error doesn't much make sense. - | ^^^^^^^^^^^^^^ expands to a recursive type +LL | let _foo: Box = Box::new(()); + | ^^ expected named lifetime parameter + | +help: consider introducing a named lifetime parameter + | +LL | pub fn run<'a>() { +LL | let _foo: Box = Box::new(()); | - = note: type resolves to itself error: aborting due to previous error -For more information about this error, try `rustc --explain E0720`. +For more information about this error, try `rustc --explain E0106`. diff --git a/src/test/ui/impl-trait/negative-reasoning.rs b/src/test/ui/impl-trait/negative-reasoning.rs index 4977f9bdbacd9..d173fe83fb791 100644 --- a/src/test/ui/impl-trait/negative-reasoning.rs +++ b/src/test/ui/impl-trait/negative-reasoning.rs @@ -2,21 +2,22 @@ // other trait #![feature(type_alias_impl_trait)] -trait OpaqueTrait { } -impl OpaqueTrait for T { } +trait OpaqueTrait {} +impl OpaqueTrait for T {} type OpaqueType = impl OpaqueTrait; -fn mk_opaque() -> OpaqueType { () } +fn mk_opaque() -> OpaqueType { + () +} #[derive(Debug)] struct D(T); -trait AnotherTrait { } -impl AnotherTrait for T { } - +trait AnotherTrait {} +impl AnotherTrait for T {} // This is in error, because we cannot assume that `OpaqueType: !Debug` impl AnotherTrait for D { - //~^ ERROR conflicting implementations of trait `AnotherTrait` for type `D` + //~^ ERROR conflicting implementations of trait `AnotherTrait` for type `D` } fn main() {} diff --git a/src/test/ui/impl-trait/negative-reasoning.stderr b/src/test/ui/impl-trait/negative-reasoning.stderr index 526a664726ac2..e43d8c857b257 100644 --- a/src/test/ui/impl-trait/negative-reasoning.stderr +++ b/src/test/ui/impl-trait/negative-reasoning.stderr @@ -1,13 +1,13 @@ -error[E0119]: conflicting implementations of trait `AnotherTrait` for type `D`: - --> $DIR/negative-reasoning.rs:18:1 +error[E0119]: conflicting implementations of trait `AnotherTrait` for type `D`: + --> $DIR/negative-reasoning.rs:19:1 | -LL | impl AnotherTrait for T { } +LL | impl AnotherTrait for T {} | ------------------------------------------- first implementation here ... LL | impl AnotherTrait for D { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `D` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `D` | - = note: upstream crates may add a new impl of trait `std::fmt::Debug` for type `OpaqueType` in future versions + = note: upstream crates may add a new impl of trait `std::fmt::Debug` for type `impl OpaqueTrait` in future versions error: aborting due to previous error diff --git a/src/test/ui/impl-trait/where-allowed.stderr b/src/test/ui/impl-trait/where-allowed.stderr index 5d9ae6a03018f..7addc006e1900 100644 --- a/src/test/ui/impl-trait/where-allowed.stderr +++ b/src/test/ui/impl-trait/where-allowed.stderr @@ -256,16 +256,16 @@ LL | let _in_return_in_local_variable = || -> impl Fn() { || {} }; | ^^^^^^^^^ error: could not find defining uses - --> $DIR/where-allowed.rs:155:1 + --> $DIR/where-allowed.rs:119:16 | -LL | type InTypeAlias = impl Debug; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | type Out = impl Debug; + | ^^^^^^^^^^ error: could not find defining uses - --> $DIR/where-allowed.rs:119:5 + --> $DIR/where-allowed.rs:155:23 | -LL | type Out = impl Debug; - | ^^^^^^^^^^^^^^^^^^^^^^ +LL | type InTypeAlias = impl Debug; + | ^^^^^^^^^^ error: aborting due to 42 previous errors diff --git a/src/test/ui/issues/issue-60662.stdout b/src/test/ui/issues/issue-60662.stdout index 5a4b49cfa1e76..cebe834824a61 100644 --- a/src/test/ui/issues/issue-60662.stdout +++ b/src/test/ui/issues/issue-60662.stdout @@ -10,5 +10,5 @@ extern crate std; trait Animal { } fn main() { - pub type ServeFut = impl Animal; + pub type ServeFut = /*impl Trait*/; } diff --git a/src/test/ui/lint/inline-trait-and-foreign-items.stderr b/src/test/ui/lint/inline-trait-and-foreign-items.stderr index 15aaf8961b7b1..ae04612a4dd69 100644 --- a/src/test/ui/lint/inline-trait-and-foreign-items.stderr +++ b/src/test/ui/lint/inline-trait-and-foreign-items.stderr @@ -62,10 +62,10 @@ LL | type U = impl Trait; | -------------------- not a function or closure error: could not find defining uses - --> $DIR/inline-trait-and-foreign-items.rs:26:5 + --> $DIR/inline-trait-and-foreign-items.rs:26:14 | LL | type U = impl Trait; - | ^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^ error: aborting due to 6 previous errors; 2 warnings emitted diff --git a/src/test/ui/lint/opaque-ty-ffi-unsafe.rs b/src/test/ui/lint/opaque-ty-ffi-unsafe.rs index 25d5f8ec68aa0..3cbc084ecae7c 100644 --- a/src/test/ui/lint/opaque-ty-ffi-unsafe.rs +++ b/src/test/ui/lint/opaque-ty-ffi-unsafe.rs @@ -1,5 +1,4 @@ #![feature(type_alias_impl_trait)] - #![deny(improper_ctypes)] type A = impl Fn(); @@ -10,7 +9,7 @@ pub fn ret_closure() -> A { extern "C" { pub fn a(_: A); - //~^ ERROR `extern` block uses type `A`, which is not FFI-safe +//~^ ERROR `extern` block uses type `impl std::ops::Fn<()>`, which is not FFI-safe } fn main() {} diff --git a/src/test/ui/lint/opaque-ty-ffi-unsafe.stderr b/src/test/ui/lint/opaque-ty-ffi-unsafe.stderr index 712095e3208bd..06dfb7b8fbeca 100644 --- a/src/test/ui/lint/opaque-ty-ffi-unsafe.stderr +++ b/src/test/ui/lint/opaque-ty-ffi-unsafe.stderr @@ -1,11 +1,11 @@ -error: `extern` block uses type `A`, which is not FFI-safe - --> $DIR/opaque-ty-ffi-unsafe.rs:12:17 +error: `extern` block uses type `impl std::ops::Fn<()>`, which is not FFI-safe + --> $DIR/opaque-ty-ffi-unsafe.rs:11:17 | LL | pub fn a(_: A); | ^ not FFI-safe | note: the lint level is defined here - --> $DIR/opaque-ty-ffi-unsafe.rs:3:9 + --> $DIR/opaque-ty-ffi-unsafe.rs:2:9 | LL | #![deny(improper_ctypes)] | ^^^^^^^^^^^^^^^ diff --git a/src/test/ui/privacy/private-in-public-assoc-ty.rs b/src/test/ui/privacy/private-in-public-assoc-ty.rs index 62faae1f399e8..cd7c37cb04b22 100644 --- a/src/test/ui/privacy/private-in-public-assoc-ty.rs +++ b/src/test/ui/privacy/private-in-public-assoc-ty.rs @@ -9,7 +9,9 @@ mod m { trait PrivTr {} impl PrivTr for Priv {} pub trait PubTrAux1 {} - pub trait PubTrAux2 { type A; } + pub trait PubTrAux2 { + type A; + } impl PubTrAux1 for u8 {} impl PubTrAux2 for u8 { type A = Priv; @@ -41,8 +43,9 @@ mod m { type Exist = impl PrivTr; //~^ ERROR private trait `m::PrivTr` in public interface - //~| ERROR private trait `m::PrivTr` in public interface - fn infer_exist() -> Self::Exist { Priv } + fn infer_exist() -> Self::Exist { + Priv + } } } diff --git a/src/test/ui/privacy/private-in-public-assoc-ty.stderr b/src/test/ui/privacy/private-in-public-assoc-ty.stderr index dd2ea7481f331..1a3ca3f16ed4c 100644 --- a/src/test/ui/privacy/private-in-public-assoc-ty.stderr +++ b/src/test/ui/privacy/private-in-public-assoc-ty.stderr @@ -1,5 +1,5 @@ error[E0446]: private type `m::Priv` in public interface - --> $DIR/private-in-public-assoc-ty.rs:15:9 + --> $DIR/private-in-public-assoc-ty.rs:17:9 | LL | struct Priv; | - `m::Priv` declared as private @@ -8,7 +8,7 @@ LL | type A = Priv; | ^^^^^^^^^^^^^^ can't leak private type warning: private trait `m::PrivTr` in public interface (error E0445) - --> $DIR/private-in-public-assoc-ty.rs:21:5 + --> $DIR/private-in-public-assoc-ty.rs:23:5 | LL | / pub trait PubTr { LL | | @@ -24,7 +24,7 @@ LL | | } = note: for more information, see issue #34537 warning: private type `m::Priv` in public interface (error E0446) - --> $DIR/private-in-public-assoc-ty.rs:21:5 + --> $DIR/private-in-public-assoc-ty.rs:23:5 | LL | / pub trait PubTr { LL | | @@ -39,7 +39,7 @@ LL | | } = note: for more information, see issue #34537 warning: private type `m::Priv` in public interface (error E0446) - --> $DIR/private-in-public-assoc-ty.rs:21:5 + --> $DIR/private-in-public-assoc-ty.rs:23:5 | LL | / pub trait PubTr { LL | | @@ -54,7 +54,7 @@ LL | | } = note: for more information, see issue #34537 error[E0446]: private type `m::Priv` in public interface - --> $DIR/private-in-public-assoc-ty.rs:32:9 + --> $DIR/private-in-public-assoc-ty.rs:34:9 | LL | struct Priv; | - `m::Priv` declared as private @@ -63,7 +63,7 @@ LL | type Alias4 = Priv; | ^^^^^^^^^^^^^^^^^^^ can't leak private type error[E0446]: private type `m::Priv` in public interface - --> $DIR/private-in-public-assoc-ty.rs:39:9 + --> $DIR/private-in-public-assoc-ty.rs:41:9 | LL | struct Priv; | - `m::Priv` declared as private @@ -72,7 +72,7 @@ LL | type Alias1 = Priv; | ^^^^^^^^^^^^^^^^^^^ can't leak private type error[E0445]: private trait `m::PrivTr` in public interface - --> $DIR/private-in-public-assoc-ty.rs:42:9 + --> $DIR/private-in-public-assoc-ty.rs:44:9 | LL | trait PrivTr {} | - `m::PrivTr` declared as private @@ -80,16 +80,7 @@ LL | trait PrivTr {} LL | type Exist = impl PrivTr; | ^^^^^^^^^^^^^^^^^^^^^^^^^ can't leak private trait -error[E0445]: private trait `m::PrivTr` in public interface - --> $DIR/private-in-public-assoc-ty.rs:42:9 - | -LL | trait PrivTr {} - | - `m::PrivTr` declared as private -... -LL | type Exist = impl PrivTr; - | ^^^^^^^^^^^^^^^^^^^^^^^^^ can't leak private trait - -error: aborting due to 5 previous errors; 3 warnings emitted +error: aborting due to 4 previous errors; 3 warnings emitted Some errors have detailed explanations: E0445, E0446. For more information about an error, try `rustc --explain E0445`. diff --git a/src/test/ui/save-analysis/issue-68621.stderr b/src/test/ui/save-analysis/issue-68621.stderr index 2c5bbd7782b35..3af6d0a3e076e 100644 --- a/src/test/ui/save-analysis/issue-68621.stderr +++ b/src/test/ui/save-analysis/issue-68621.stderr @@ -1,8 +1,8 @@ error: could not find defining uses - --> $DIR/issue-68621.rs:14:5 + --> $DIR/issue-68621.rs:14:19 | LL | type Future = impl Trait; - | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^ error: aborting due to previous error 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 b871f79aa1dc5..9ebf63468e773 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,8 @@ error[E0277]: the trait bound `T: TraitWithAssoc` is not satisfied - --> $DIR/bound_reduction2.rs:10:1 + --> $DIR/bound_reduction2.rs:10:15 | LL | type Foo = impl Trait; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `TraitWithAssoc` is not implemented for `T` + | ^^^^^^^^^^^^^ the trait `TraitWithAssoc` is not implemented for `T` | help: consider further restricting this bound | diff --git a/src/test/ui/type-alias-impl-trait/declared_but_never_defined.stderr b/src/test/ui/type-alias-impl-trait/declared_but_never_defined.stderr index ae0fee4333b5b..21c2e8a9db618 100644 --- a/src/test/ui/type-alias-impl-trait/declared_but_never_defined.stderr +++ b/src/test/ui/type-alias-impl-trait/declared_but_never_defined.stderr @@ -1,8 +1,8 @@ error: could not find defining uses - --> $DIR/declared_but_never_defined.rs:6:1 + --> $DIR/declared_but_never_defined.rs:6:12 | LL | type Bar = impl std::fmt::Debug; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/type-alias-impl-trait/declared_but_not_defined_in_scope.stderr b/src/test/ui/type-alias-impl-trait/declared_but_not_defined_in_scope.stderr index 0642407aba3cd..c0cb94b15d033 100644 --- a/src/test/ui/type-alias-impl-trait/declared_but_not_defined_in_scope.stderr +++ b/src/test/ui/type-alias-impl-trait/declared_but_not_defined_in_scope.stderr @@ -1,8 +1,8 @@ error: could not find defining uses - --> $DIR/declared_but_not_defined_in_scope.rs:7:5 + --> $DIR/declared_but_not_defined_in_scope.rs:7:20 | LL | pub type Boo = impl ::std::fmt::Debug; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.nll.stderr b/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.nll.stderr index 9549074d4bf78..76654d7a718b8 100644 --- a/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.nll.stderr +++ b/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.nll.stderr @@ -13,10 +13,10 @@ LL | let z: i32 = x; | expected due to this ... LL | type WrongGeneric = impl 'static; - | ------------------------------------ the found opaque type + | ------------ the found opaque type | = note: expected type `i32` - found opaque type `WrongGeneric::<&{integer}>` + found opaque type `impl Sized` error: aborting due to 2 previous errors diff --git a/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.stderr b/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.stderr index e2540e424cb19..18d8daa05e63d 100644 --- a/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.stderr +++ b/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.stderr @@ -13,16 +13,16 @@ LL | let z: i32 = x; | expected due to this ... LL | type WrongGeneric = impl 'static; - | ------------------------------------ the found opaque type + | ------------ the found opaque type | = note: expected type `i32` - found opaque type `WrongGeneric::<&{integer}>` + found opaque type `impl Sized` error[E0310]: the parameter type `T` may not live long enough - --> $DIR/generic_type_does_not_live_long_enough.rs:9:1 + --> $DIR/generic_type_does_not_live_long_enough.rs:9:24 | LL | type WrongGeneric = impl 'static; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds + | ^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds ... LL | fn wrong_generic(t: T) -> WrongGeneric { | - help: consider adding an explicit lifetime bound...: `T: 'static` diff --git a/src/test/ui/type-alias-impl-trait/generic_underconstrained.stderr b/src/test/ui/type-alias-impl-trait/generic_underconstrained.stderr index f7a04263259f6..911f592f73f27 100644 --- a/src/test/ui/type-alias-impl-trait/generic_underconstrained.stderr +++ b/src/test/ui/type-alias-impl-trait/generic_underconstrained.stderr @@ -5,10 +5,10 @@ LL | type Underconstrained = impl 'static; | ^^^^^^^^^^^^ error[E0277]: the trait bound `T: Trait` is not satisfied - --> $DIR/generic_underconstrained.rs:6:1 + --> $DIR/generic_underconstrained.rs:6:35 | LL | type Underconstrained = impl 'static; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Trait` is not implemented for `T` + | ^^^^^^^^^^^^ the trait `Trait` is not implemented for `T` | = note: the return type of a function must have a statically known size help: consider restricting type parameter `T` diff --git a/src/test/ui/type-alias-impl-trait/generic_underconstrained2.stderr b/src/test/ui/type-alias-impl-trait/generic_underconstrained2.stderr index ad160abcbd573..247d68ef2a1f0 100644 --- a/src/test/ui/type-alias-impl-trait/generic_underconstrained2.stderr +++ b/src/test/ui/type-alias-impl-trait/generic_underconstrained2.stderr @@ -11,10 +11,10 @@ LL | type Underconstrained2 = impl 'static; | ^^^^^^^^^^^^ error[E0277]: `U` doesn't implement `std::fmt::Debug` - --> $DIR/generic_underconstrained2.rs:5:1 + --> $DIR/generic_underconstrained2.rs:5:45 | LL | type Underconstrained = impl 'static; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `U` cannot be formatted using `{:?}` because it doesn't implement `std::fmt::Debug` + | ^^^^^^^^^^^^ `U` cannot be formatted using `{:?}` because it doesn't implement `std::fmt::Debug` ... LL | 5u32 | ---- this returned value is of type `u32` @@ -27,10 +27,10 @@ LL | fn underconstrained(_: U) -> Underconstrained { | ^^^^^^^^^^^^^^^^^ error[E0277]: `V` doesn't implement `std::fmt::Debug` - --> $DIR/generic_underconstrained2.rs:14:1 + --> $DIR/generic_underconstrained2.rs:14:46 | LL | type Underconstrained2 = impl 'static; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `V` cannot be formatted using `{:?}` because it doesn't implement `std::fmt::Debug` + | ^^^^^^^^^^^^ `V` cannot be formatted using `{:?}` because it doesn't implement `std::fmt::Debug` ... LL | 5u32 | ---- this returned value is of type `u32` diff --git a/src/test/ui/type-alias-impl-trait/impl-with-unconstrained-param.rs b/src/test/ui/type-alias-impl-trait/impl-with-unconstrained-param.rs new file mode 100644 index 0000000000000..bc6543a9229db --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/impl-with-unconstrained-param.rs @@ -0,0 +1,18 @@ +// Ensure that we don't ICE if associated type impl trait is used in an impl +// with an unconstrained type parameter. + +#![feature(type_alias_impl_trait)] + +trait X { + type I; + fn f() -> Self::I; +} + +impl X for () { + type I = impl Sized; + //~^ ERROR could not find defining uses + fn f() -> Self::I {} + //~^ ERROR type annotations needed +} + +fn main() {} diff --git a/src/test/ui/type-alias-impl-trait/impl-with-unconstrained-param.stderr b/src/test/ui/type-alias-impl-trait/impl-with-unconstrained-param.stderr new file mode 100644 index 0000000000000..e8b677113dba7 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/impl-with-unconstrained-param.stderr @@ -0,0 +1,15 @@ +error[E0282]: type annotations needed + --> $DIR/impl-with-unconstrained-param.rs:14:23 + | +LL | fn f() -> Self::I {} + | ^^ cannot infer type for type parameter `T` + +error: could not find defining uses + --> $DIR/impl-with-unconstrained-param.rs:12:14 + | +LL | type I = impl Sized; + | ^^^^^^^^^^ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0282`. diff --git a/src/test/ui/type-alias-impl-trait/issue-57188-associate-impl-capture.rs b/src/test/ui/type-alias-impl-trait/issue-57188-associate-impl-capture.rs new file mode 100644 index 0000000000000..3a7a5da075f11 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-57188-associate-impl-capture.rs @@ -0,0 +1,24 @@ +// Regression test for #57188 + +// check-pass + +#![feature(type_alias_impl_trait)] + +struct Baz<'a> { + source: &'a str, +} + +trait Foo<'a> { + type T: Iterator> + 'a; + fn foo(source: &'a str) -> Self::T; +} + +struct Bar; +impl<'a> Foo<'a> for Bar { + type T = impl Iterator> + 'a; + fn foo(source: &'a str) -> Self::T { + std::iter::once(Baz { source }) + } +} + +fn main() {} diff --git a/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.stderr b/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.stderr index f648b7bfc991d..cc121ac89fb8d 100644 --- a/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.stderr +++ b/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.stderr @@ -1,8 +1,8 @@ error[E0631]: type mismatch in closure arguments - --> $DIR/issue-57611-trait-alias.rs:17:5 + --> $DIR/issue-57611-trait-alias.rs:17:16 | LL | type Bar = impl Baz; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected signature of `for<'r> fn(&'r X) -> _` + | ^^^^^^^^^^^^^^^^^^^^ expected signature of `for<'r> fn(&'r X) -> _` ... LL | |x| x | ----- found signature of `fn(_) -> _` @@ -10,10 +10,10 @@ LL | |x| x = note: the return type of a function must have a statically known size error[E0271]: type mismatch resolving `for<'r> <[closure@$DIR/issue-57611-trait-alias.rs:21:9: 21:14] as std::ops::FnOnce<(&'r X,)>>::Output == &'r X` - --> $DIR/issue-57611-trait-alias.rs:17:5 + --> $DIR/issue-57611-trait-alias.rs:17:16 | LL | type Bar = impl Baz; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected bound lifetime parameter, found concrete lifetime + | ^^^^^^^^^^^^^^^^^^^^ expected bound lifetime parameter, found concrete lifetime | = note: the return type of a function must have a statically known size 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 2796c77baa1c4..bf2d612fcdb41 100644 --- a/src/test/ui/type-alias-impl-trait/issue-60371.stderr +++ b/src/test/ui/type-alias-impl-trait/issue-60371.stderr @@ -8,20 +8,20 @@ LL | type Item = impl Bug; = help: add `#![feature(type_alias_impl_trait)]` to the crate attributes to enable error[E0277]: the trait bound `(): Bug` is not satisfied - --> $DIR/issue-60371.rs:8:5 + --> $DIR/issue-60371.rs:8:17 | LL | type Item = impl Bug; - | ^^^^^^^^^^^^^^^^^^^^^ the trait `Bug` is not implemented for `()` + | ^^^^^^^^ the trait `Bug` is not implemented for `()` | = help: the following implementations were found: <&() as Bug> = note: the return type of a function must have a statically known size error: could not find defining uses - --> $DIR/issue-60371.rs:8:5 + --> $DIR/issue-60371.rs:8:17 | LL | type Item = impl Bug; - | ^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^ 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 4eb7f7836d869..78def0d1136de 100644 --- a/src/test/ui/type-alias-impl-trait/issue-60564.rs +++ b/src/test/ui/type-alias-impl-trait/issue-60564.rs @@ -17,11 +17,8 @@ where { type BitsIter = IterBitsIter; fn iter_bits(self, n: u8) -> Self::BitsIter { - //~^ 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()) + //~^ 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 55984609437b0..66fa862ef9d7a 100644 --- a/src/test/ui/type-alias-impl-trait/issue-60564.stderr +++ b/src/test/ui/type-alias-impl-trait/issue-60564.stderr @@ -1,15 +1,3 @@ -error: non-defining opaque type use in defining scope - --> $DIR/issue-60564.rs:19:34 - | -LL | fn iter_bits(self, n: u8) -> Self::BitsIter { - | ^^^^^^^^^^^^^^ - | -note: used non-generic type `_` for generic parameter - --> $DIR/issue-60564.rs:8:22 - | -LL | type IterBitsIter = impl std::iter::Iterator; - | ^ - error: non-defining opaque type use in defining scope --> $DIR/issue-60564.rs:19:34 | @@ -22,5 +10,5 @@ note: used non-generic type `u8` for generic parameter LL | type IterBitsIter = impl std::iter::Iterator; | ^ -error: aborting due to 2 previous errors +error: aborting due to previous error diff --git a/src/test/ui/type-alias-impl-trait/issue-62000-associate-impl-trait-lifetimes.rs b/src/test/ui/type-alias-impl-trait/issue-62000-associate-impl-trait-lifetimes.rs new file mode 100644 index 0000000000000..36779a0ce89c3 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-62000-associate-impl-trait-lifetimes.rs @@ -0,0 +1,38 @@ +// Regression test for #62988 + +// check-pass + +#![feature(type_alias_impl_trait)] + +trait MyTrait { + type AssocType: Send; + fn ret(&self) -> Self::AssocType; +} + +impl MyTrait for () { + type AssocType = impl Send; + fn ret(&self) -> Self::AssocType { + () + } +} + +impl<'a> MyTrait for &'a () { + type AssocType = impl Send; + fn ret(&self) -> Self::AssocType { + () + } +} + +trait MyLifetimeTrait<'a> { + type AssocType: Send + 'a; + fn ret(&self) -> Self::AssocType; +} + +impl<'a> MyLifetimeTrait<'a> for &'a () { + type AssocType = impl Send + 'a; + fn ret(&self) -> Self::AssocType { + *self + } +} + +fn main() {} diff --git a/src/test/ui/type-alias-impl-trait/issue-63279.stderr b/src/test/ui/type-alias-impl-trait/issue-63279.stderr index bef4d01093c62..d07f64c3312d3 100644 --- a/src/test/ui/type-alias-impl-trait/issue-63279.stderr +++ b/src/test/ui/type-alias-impl-trait/issue-63279.stderr @@ -1,10 +1,10 @@ error[E0271]: type mismatch resolving `<[closure@$DIR/issue-63279.rs:8:5: 8:28] as std::ops::FnOnce<()>>::Output == ()` - --> $DIR/issue-63279.rs:5:1 + --> $DIR/issue-63279.rs:5:16 | LL | type Closure = impl FnOnce(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected opaque type, found `()` + | ^^^^^^^^^^^^^ expected opaque type, found `()` | - = note: expected opaque type `Closure` + = note: expected opaque type `impl std::ops::FnOnce<()>` found unit type `()` = note: the return type of a function must have a statically known size diff --git a/src/test/ui/type-alias-impl-trait/issue-69136-inner-lifetime-resolve-error.rs b/src/test/ui/type-alias-impl-trait/issue-69136-inner-lifetime-resolve-error.rs new file mode 100644 index 0000000000000..6732902c09a50 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-69136-inner-lifetime-resolve-error.rs @@ -0,0 +1,22 @@ +// Regression test for #69136 + +#![feature(type_alias_impl_trait)] + +trait SomeTrait {} + +impl SomeTrait for () {} + +trait WithAssoc { + type AssocType; +} + +impl WithAssoc for () { + type AssocType = (); +} + +type Return = impl WithAssoc; +//~^ ERROR use of undeclared lifetime name `'a` + +fn my_fun() -> Return<()> {} + +fn main() {} diff --git a/src/test/ui/type-alias-impl-trait/issue-69136-inner-lifetime-resolve-error.stderr b/src/test/ui/type-alias-impl-trait/issue-69136-inner-lifetime-resolve-error.stderr new file mode 100644 index 0000000000000..fe45e39d938f0 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-69136-inner-lifetime-resolve-error.stderr @@ -0,0 +1,11 @@ +error[E0261]: use of undeclared lifetime name `'a` + --> $DIR/issue-69136-inner-lifetime-resolve-error.rs:17:65 + | +LL | type Return = impl WithAssoc; + | - ^^ undeclared lifetime + | | + | help: consider introducing lifetime `'a` here: `'a,` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0261`. diff --git a/src/test/ui/type-alias-impl-trait/issue-69136-inner-lifetime-resolve-ok.rs b/src/test/ui/type-alias-impl-trait/issue-69136-inner-lifetime-resolve-ok.rs new file mode 100644 index 0000000000000..a6916eda8b093 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-69136-inner-lifetime-resolve-ok.rs @@ -0,0 +1,23 @@ +// Test-pass variant of #69136 + +// check-pass + +#![feature(type_alias_impl_trait)] + +trait SomeTrait {} + +impl SomeTrait for () {} + +trait WithAssoc { + type AssocType; +} + +impl WithAssoc for () { + type AssocType = (); +} + +type Return<'a> = impl WithAssoc; + +fn my_fun<'a>() -> Return<'a> {} + +fn main() {} diff --git a/src/test/ui/type-alias-impl-trait/never_reveal_concrete_type.stderr b/src/test/ui/type-alias-impl-trait/never_reveal_concrete_type.stderr index 70c99c944d654..4fbbf34752803 100644 --- a/src/test/ui/type-alias-impl-trait/never_reveal_concrete_type.stderr +++ b/src/test/ui/type-alias-impl-trait/never_reveal_concrete_type.stderr @@ -2,7 +2,7 @@ error[E0308]: mismatched types --> $DIR/never_reveal_concrete_type.rs:13:27 | LL | type NoReveal = impl std::fmt::Debug; - | ------------------------------------- the found opaque type + | -------------------- the found opaque type ... LL | let _: &'static str = x; | ------------ ^ expected `&str`, found opaque type @@ -10,9 +10,9 @@ LL | let _: &'static str = x; | expected due to this | = note: expected reference `&'static str` - found opaque type `NoReveal` + found opaque type `impl std::fmt::Debug` -error[E0605]: non-primitive cast: `NoReveal` as `&'static str` +error[E0605]: non-primitive cast: `impl std::fmt::Debug` as `&'static str` --> $DIR/never_reveal_concrete_type.rs:14:13 | LL | let _ = x as &'static str; diff --git a/src/test/ui/type-alias-impl-trait/no_inferrable_concrete_type.stderr b/src/test/ui/type-alias-impl-trait/no_inferrable_concrete_type.stderr index 444e6e8214ff2..61025e846921e 100644 --- a/src/test/ui/type-alias-impl-trait/no_inferrable_concrete_type.stderr +++ b/src/test/ui/type-alias-impl-trait/no_inferrable_concrete_type.stderr @@ -1,8 +1,8 @@ error: could not find defining uses - --> $DIR/no_inferrable_concrete_type.rs:6:1 + --> $DIR/no_inferrable_concrete_type.rs:6:12 | LL | type Foo = impl Copy; - | ^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/type-alias-impl-trait/no_revealing_outside_defining_module.stderr b/src/test/ui/type-alias-impl-trait/no_revealing_outside_defining_module.stderr index 375c0bc7fe2ed..d237cc6238ae1 100644 --- a/src/test/ui/type-alias-impl-trait/no_revealing_outside_defining_module.stderr +++ b/src/test/ui/type-alias-impl-trait/no_revealing_outside_defining_module.stderr @@ -2,7 +2,7 @@ error[E0308]: mismatched types --> $DIR/no_revealing_outside_defining_module.rs:15:19 | LL | pub type Boo = impl ::std::fmt::Debug; - | -------------------------------------- the found opaque type + | ---------------------- the found opaque type ... LL | let _: &str = bomp(); | ---- ^^^^^^ expected `&str`, found opaque type @@ -10,20 +10,20 @@ LL | let _: &str = bomp(); | expected due to this | = note: expected reference `&str` - found opaque type `Boo` + found opaque type `impl std::fmt::Debug` error[E0308]: mismatched types --> $DIR/no_revealing_outside_defining_module.rs:19:5 | LL | pub type Boo = impl ::std::fmt::Debug; - | -------------------------------------- the expected opaque type + | ---------------------- the expected opaque type ... LL | fn bomp() -> boo::Boo { - | -------- expected `Boo` because of return type + | -------- expected `impl std::fmt::Debug` because of return type LL | "" | ^^ expected opaque type, found `&str` | - = note: expected opaque type `Boo` + = note: expected opaque type `impl std::fmt::Debug` found reference `&'static str` error: aborting due to 2 previous errors diff --git a/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error.stderr b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error.stderr index 02ab3399ea6fa..726f4ea6e00f7 100644 --- a/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error.stderr +++ b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error.stderr @@ -1,8 +1,8 @@ error: could not find defining uses - --> $DIR/type-alias-impl-trait-with-cycle-error.rs:3:1 + --> $DIR/type-alias-impl-trait-with-cycle-error.rs:3:12 | LL | type Foo = impl Fn() -> Foo; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error2.stderr b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error2.stderr index e9abb79588683..3947cc4d27055 100644 --- a/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error2.stderr +++ b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error2.stderr @@ -1,8 +1,8 @@ error: could not find defining uses - --> $DIR/type-alias-impl-trait-with-cycle-error2.rs:7:1 + --> $DIR/type-alias-impl-trait-with-cycle-error2.rs:7:12 | LL | type Foo = impl Bar; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/type-alias-impl-trait/type-alias-nested-impl-trait.rs b/src/test/ui/type-alias-impl-trait/type-alias-nested-impl-trait.rs new file mode 100644 index 0000000000000..fd954801dc047 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/type-alias-nested-impl-trait.rs @@ -0,0 +1,14 @@ +// run-pass + +#![feature(type_alias_impl_trait)] + +use std::iter::{once, Chain}; + +type I = Chain>; +fn test2>(x: A) -> I { + x.chain(once("5")) +} + +fn main() { + assert_eq!(vec!["1", "3", "5"], test2(["1", "3"].iter().cloned()).collect::>()); +} diff --git a/src/tools/clippy/clippy_lints/src/lifetimes.rs b/src/tools/clippy/clippy_lints/src/lifetimes.rs index d80ad47ab2468..318d0b69d57b7 100644 --- a/src/tools/clippy/clippy_lints/src/lifetimes.rs +++ b/src/tools/clippy/clippy_lints/src/lifetimes.rs @@ -379,7 +379,7 @@ impl<'a, 'tcx> Visitor<'tcx> for RefVisitor<'a, 'tcx> { TyKind::Path(ref path) => { self.collect_anonymous_lifetimes(path, ty); }, - TyKind::Def(item, _) => { + TyKind::OpaqueDef(item, _) => { let map = self.cx.tcx.hir(); if let ItemKind::OpaqueTy(ref exist_ty) = map.expect_item(item.id).kind { for bound in exist_ty.bounds { diff --git a/src/tools/clippy/clippy_lints/src/manual_async_fn.rs b/src/tools/clippy/clippy_lints/src/manual_async_fn.rs index cb72a24058234..03ab274d9ca9c 100644 --- a/src/tools/clippy/clippy_lints/src/manual_async_fn.rs +++ b/src/tools/clippy/clippy_lints/src/manual_async_fn.rs @@ -99,7 +99,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ManualAsyncFn { fn future_trait_ref<'tcx>(cx: &LateContext<'_, 'tcx>, ty: &'tcx Ty<'tcx>) -> Option<&'tcx TraitRef<'tcx>> { if_chain! { - if let TyKind::Def(item_id, _) = ty.kind; + if let TyKind::OpaqueDef(item_id, _) = ty.kind; let item = cx.tcx.hir().item(item_id.id); if let ItemKind::OpaqueTy(opaque) = &item.kind; if opaque.bounds.len() == 1; diff --git a/src/tools/clippy/clippy_lints/src/missing_doc.rs b/src/tools/clippy/clippy_lints/src/missing_doc.rs index 2eefb6bbaf424..0fd1e87f9e415 100644 --- a/src/tools/clippy/clippy_lints/src/missing_doc.rs +++ b/src/tools/clippy/clippy_lints/src/missing_doc.rs @@ -187,7 +187,6 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MissingDoc { hir::ImplItemKind::Const(..) => "an associated constant", hir::ImplItemKind::Fn(..) => "a method", hir::ImplItemKind::TyAlias(_) => "an associated type", - hir::ImplItemKind::OpaqueTy(_) => "an existential type", }; self.check_missing_docs_attrs(cx, &impl_item.attrs, impl_item.span, desc); } diff --git a/src/tools/clippy/clippy_lints/src/missing_inline.rs b/src/tools/clippy/clippy_lints/src/missing_inline.rs index 3ad3d5aee4d4a..1802470b1841e 100644 --- a/src/tools/clippy/clippy_lints/src/missing_inline.rs +++ b/src/tools/clippy/clippy_lints/src/missing_inline.rs @@ -142,7 +142,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MissingInline { let desc = match impl_item.kind { hir::ImplItemKind::Fn(..) => "a method", - hir::ImplItemKind::Const(..) | hir::ImplItemKind::TyAlias(_) | hir::ImplItemKind::OpaqueTy(_) => return, + hir::ImplItemKind::Const(..) | hir::ImplItemKind::TyAlias(_) => return, }; let def_id = cx.tcx.hir().local_def_id(impl_item.hir_id); diff --git a/src/tools/clippy/clippy_lints/src/utils/hir_utils.rs b/src/tools/clippy/clippy_lints/src/utils/hir_utils.rs index 473a730dad500..7a84f1c986aa7 100644 --- a/src/tools/clippy/clippy_lints/src/utils/hir_utils.rs +++ b/src/tools/clippy/clippy_lints/src/utils/hir_utils.rs @@ -710,7 +710,7 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> { segment.ident.name.hash(&mut self.s); }, }, - TyKind::Def(_, arg_list) => { + TyKind::OpaqueDef(_, arg_list) => { for arg in *arg_list { match arg { GenericArg::Lifetime(ref l) => self.hash_lifetime(l), diff --git a/src/tools/clippy/clippy_lints/src/utils/inspector.rs b/src/tools/clippy/clippy_lints/src/utils/inspector.rs index 649b166e98eec..afde971f9df4e 100644 --- a/src/tools/clippy/clippy_lints/src/utils/inspector.rs +++ b/src/tools/clippy/clippy_lints/src/utils/inspector.rs @@ -63,7 +63,6 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for DeepCodeInspector { }, hir::ImplItemKind::Fn(..) => println!("method"), hir::ImplItemKind::TyAlias(_) => println!("associated type"), - hir::ImplItemKind::OpaqueTy(_) => println!("existential type"), } } // fn check_trait_item(&mut self, cx: &LateContext<'a, 'tcx>, item: &'tcx