From 9d97e809d6969796f10f150d9cdd8a2e32348d38 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 3 Nov 2022 17:18:54 +0100 Subject: [PATCH 1/4] Add Identity trait --- compiler/rustc_hir/src/lang_items.rs | 1 + compiler/rustc_span/src/symbol.rs | 1 + library/core/src/marker.rs | 16 ++++++++++++++++ 3 files changed, 18 insertions(+) diff --git a/compiler/rustc_hir/src/lang_items.rs b/compiler/rustc_hir/src/lang_items.rs index 0454633091568..7b994876c1ed7 100644 --- a/compiler/rustc_hir/src/lang_items.rs +++ b/compiler/rustc_hir/src/lang_items.rs @@ -165,6 +165,7 @@ language_item_table! { DynMetadata, sym::dyn_metadata, dyn_metadata, Target::Struct, GenericRequirement::None; Freeze, sym::freeze, freeze_trait, Target::Trait, GenericRequirement::Exact(0); + Identity, sym::identity, identity_trait, Target::Trait, GenericRequirement::Exact(0); Drop, sym::drop, drop_trait, Target::Trait, GenericRequirement::None; Destruct, sym::destruct, destruct_trait, Target::Trait, GenericRequirement::None; diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 1ced75cccbb30..5ddff430d2151 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -790,6 +790,7 @@ symbols! { i64, i8, ident, + identity, identity_future, if_let, if_let_guard, diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs index e11bca5962a15..a3ed7c3b79690 100644 --- a/library/core/src/marker.rs +++ b/library/core/src/marker.rs @@ -779,6 +779,22 @@ unsafe impl Freeze for *mut T {} unsafe impl Freeze for &T {} unsafe impl Freeze for &mut T {} +/// Compiler-internal trait used to handle more easily trait aliases. +/// They get generated like projections. For example: +/// ```ignore (pseudo-code) +/// type Foo = Bar; +/// // becomes: +/// type Foo = ::Identity; +/// ``` +pub(crate) trait Identity: Sized { + #[cfg_attr(not(bootstrap), lang = "identity")] + type Identity; +} + +impl Identity for T { + type Identity = T; +} + /// Types that can be safely moved after being pinned. /// /// Rust itself has no notion of immovable types, and considers moves (e.g., From 08ff70ed6af0036cc9660c1eb370dcd87ffdbd1b Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 3 Nov 2022 17:19:27 +0100 Subject: [PATCH 2/4] Handle TyAlias import differently --- compiler/rustc_hir/src/lang_items.rs | 2 +- .../rustc_hir_analysis/src/astconv/mod.rs | 23 +++++++++++++++---- 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_hir/src/lang_items.rs b/compiler/rustc_hir/src/lang_items.rs index 7b994876c1ed7..736e90ae24890 100644 --- a/compiler/rustc_hir/src/lang_items.rs +++ b/compiler/rustc_hir/src/lang_items.rs @@ -165,7 +165,7 @@ language_item_table! { DynMetadata, sym::dyn_metadata, dyn_metadata, Target::Struct, GenericRequirement::None; Freeze, sym::freeze, freeze_trait, Target::Trait, GenericRequirement::Exact(0); - Identity, sym::identity, identity_trait, Target::Trait, GenericRequirement::Exact(0); + Identity, sym::identity, identity_type, Target::AssocTy, GenericRequirement::None; Drop, sym::drop, drop_trait, Target::Trait, GenericRequirement::None; Destruct, sym::destruct, destruct_trait, Target::Trait, GenericRequirement::None; diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs index 3d5f189e233bb..3455ceb116803 100644 --- a/compiler/rustc_hir_analysis/src/astconv/mod.rs +++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs @@ -2626,12 +2626,25 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { let substs = self.ast_path_substs_for_ty(span, did, item_segment.0); tcx.mk_opaque(did, substs) } + Res::Def(DefKind::TyAlias, def_id) => { + assert_eq!(opt_self_ty, None); + self.prohibit_generics(path.segments.split_last().unwrap().1.iter(), |_| {}); + + if let Some(identity_def_id) = tcx.lang_items().identity_type() { + let item_segment = path.segments.split_last().unwrap(); + + let substs = self.ast_path_substs_for_ty(span, def_id, item_segment.0); + let binder_ty = tcx.bound_type_of(def_id); + let ty = binder_ty.subst(tcx, substs); + + let substs = tcx.mk_substs_trait(ty, []); + tcx.mk_projection(identity_def_id, substs) + } else { + self.ast_path_to_ty(span, def_id, path.segments.last().unwrap()) + } + } Res::Def( - DefKind::Enum - | DefKind::TyAlias - | DefKind::Struct - | DefKind::Union - | DefKind::ForeignTy, + DefKind::Enum | DefKind::Struct | DefKind::Union | DefKind::ForeignTy, did, ) => { assert_eq!(opt_self_ty, None); From 53355303c9068a8f80e356ffe5d323b8ee52bf12 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 13 Jan 2023 13:37:38 +0100 Subject: [PATCH 3/4] Make Identity trait public to run ui test and put projection of type aliases behind an env variable --- compiler/rustc_hir_analysis/src/astconv/mod.rs | 2 +- library/core/src/marker.rs | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs index 3455ceb116803..566654f866c3f 100644 --- a/compiler/rustc_hir_analysis/src/astconv/mod.rs +++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs @@ -2630,7 +2630,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { assert_eq!(opt_self_ty, None); self.prohibit_generics(path.segments.split_last().unwrap().1.iter(), |_| {}); - if let Some(identity_def_id) = tcx.lang_items().identity_type() { + if let Some(identity_def_id) = tcx.lang_items().identity_type() && std::env::var("TEST_WITH_IDENTITY").is_ok() { let item_segment = path.segments.split_last().unwrap(); let substs = self.ast_path_substs_for_ty(span, def_id, item_segment.0); diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs index a3ed7c3b79690..c3e8a40cfed95 100644 --- a/library/core/src/marker.rs +++ b/library/core/src/marker.rs @@ -786,11 +786,15 @@ unsafe impl Freeze for &mut T {} /// // becomes: /// type Foo = ::Identity; /// ``` -pub(crate) trait Identity: Sized { +#[stable(feature = "pin", since = "1.33.0")] +pub trait Identity: Sized { #[cfg_attr(not(bootstrap), lang = "identity")] + #[stable(feature = "pin", since = "1.33.0")] + /// lol type Identity; } +#[stable(feature = "pin", since = "1.33.0")] impl Identity for T { type Identity = T; } From fc334ce9aff3f071094b72d549d8d128c6ece39a Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 9 Feb 2023 16:30:21 +0100 Subject: [PATCH 4/4] Fix Identity trait bounds --- library/core/src/marker.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs index c3e8a40cfed95..83dd77667265f 100644 --- a/library/core/src/marker.rs +++ b/library/core/src/marker.rs @@ -787,15 +787,15 @@ unsafe impl Freeze for &mut T {} /// type Foo = ::Identity; /// ``` #[stable(feature = "pin", since = "1.33.0")] -pub trait Identity: Sized { +pub trait Identity { #[cfg_attr(not(bootstrap), lang = "identity")] #[stable(feature = "pin", since = "1.33.0")] - /// lol - type Identity; + /// doc + type Identity: ?Sized; } #[stable(feature = "pin", since = "1.33.0")] -impl Identity for T { +impl Identity for T { type Identity = T; }