diff options
| author | Deadbeef <ent3rm4n@gmail.com> | 2024-06-14 12:16:15 +0000 |
|---|---|---|
| committer | Deadbeef <ent3rm4n@gmail.com> | 2024-06-28 10:57:35 +0000 |
| commit | 72e8244e64b284f8f93a778e804b59c10305fc59 (patch) | |
| tree | 753376943d4ce70ac6da8f56f7e24b3e4f000e97 /compiler/rustc_ty_utils/src | |
| parent | 99f77a2eda555b50b518f74823ab636a20efb87f (diff) | |
implement new effects desugaring
Diffstat (limited to 'compiler/rustc_ty_utils/src')
| -rw-r--r-- | compiler/rustc_ty_utils/src/assoc.rs | 168 |
1 files changed, 165 insertions, 3 deletions
diff --git a/compiler/rustc_ty_utils/src/assoc.rs b/compiler/rustc_ty_utils/src/assoc.rs index 4395eb57cd6..df6c54ab289 100644 --- a/compiler/rustc_ty_utils/src/assoc.rs +++ b/compiler/rustc_ty_utils/src/assoc.rs @@ -4,8 +4,9 @@ use rustc_hir::def::DefKind; use rustc_hir::def_id::{DefId, DefIdMap, LocalDefId}; use rustc_hir::intravisit::{self, Visitor}; use rustc_middle::query::Providers; -use rustc_middle::ty::{self, ImplTraitInTraitData, TyCtxt}; +use rustc_middle::ty::{self, ImplTraitInTraitData, Ty, TyCtxt}; use rustc_middle::{bug, span_bug}; +use rustc_span::sym; use rustc_span::symbol::kw; pub(crate) fn provide(providers: &mut Providers) { @@ -14,6 +15,7 @@ pub(crate) fn provide(providers: &mut Providers) { associated_item_def_ids, associated_items, associated_types_for_impl_traits_in_associated_fn, + associated_type_for_effects, associated_type_for_impl_trait_in_trait, impl_item_implementor_ids, ..*providers @@ -44,7 +46,8 @@ fn associated_item_def_ids(tcx: TyCtxt<'_>, def_id: LocalDefId) -> &[DefId] { ) }) .copied(), - ), + ) + .chain(tcx.associated_type_for_effects(def_id)), ) } hir::ItemKind::Impl(impl_) => { @@ -70,7 +73,8 @@ fn associated_item_def_ids(tcx: TyCtxt<'_>, def_id: LocalDefId) -> &[DefId] { ) }) .copied() - })), + })) + .chain(tcx.associated_type_for_effects(def_id)), ) } _ => span_bug!(item.span, "associated_item_def_ids: not impl or trait"), @@ -143,6 +147,7 @@ fn associated_item_from_trait_item_ref(trait_item_ref: &hir::TraitItemRef) -> ty container: ty::TraitContainer, fn_has_self_parameter: has_self, opt_rpitit_info: None, + is_effects_desugaring: false, } } @@ -162,6 +167,161 @@ fn associated_item_from_impl_item_ref(impl_item_ref: &hir::ImplItemRef) -> ty::A container: ty::ImplContainer, fn_has_self_parameter: has_self, opt_rpitit_info: None, + is_effects_desugaring: false, + } +} + +/// Given an `def_id` of a trait or a trait impl: +/// +/// If `def_id` is a trait that has `#[const_trait]`, then it synthesizes +/// a new def id corresponding to a new associated type for the effects. +/// +/// If `def_id` is an impl, then synthesize the associated type according +/// to the constness of the impl. +fn associated_type_for_effects(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<DefId> { + match tcx.def_kind(def_id) { + DefKind::Trait => { + let trait_def_id = def_id; + let Some(attr) = tcx.get_attr(def_id, sym::const_trait) else { + return None; + }; + + let span = attr.span; + let trait_assoc_ty = tcx.at(span).create_def(trait_def_id, kw::Empty, DefKind::AssocTy); + + let local_def_id = trait_assoc_ty.def_id(); + let def_id = local_def_id.to_def_id(); + + trait_assoc_ty.feed_hir(); + + // Copy span of the attribute. + trait_assoc_ty.def_ident_span(Some(span)); + + trait_assoc_ty.associated_item(ty::AssocItem { + name: kw::Empty, + kind: ty::AssocKind::Type, + def_id, + trait_item_def_id: None, + container: ty::TraitContainer, + fn_has_self_parameter: false, + opt_rpitit_info: None, + is_effects_desugaring: true, + }); + + // visibility is public. + trait_assoc_ty.visibility(ty::Visibility::Public); + + // No default type + trait_assoc_ty.defaultness(hir::Defaultness::Default { has_value: false }); + + trait_assoc_ty.is_type_alias_impl_trait(false); + + // Copy generics_of of the trait, making the trait as parent. + trait_assoc_ty.generics_of({ + let parent_generics = tcx.generics_of(trait_def_id); + let parent_count = parent_generics.parent_count + parent_generics.own_params.len(); + + ty::Generics { + parent: Some(trait_def_id.to_def_id()), + parent_count, + own_params: vec![], + param_def_id_to_index: parent_generics.param_def_id_to_index.clone(), + has_self: false, + has_late_bound_regions: None, + host_effect_index: parent_generics.host_effect_index, + } + }); + + trait_assoc_ty.explicit_item_bounds(ty::EarlyBinder::bind(&[])); + trait_assoc_ty.explicit_item_super_predicates(ty::EarlyBinder::bind(&[])); + + // There are no inferred outlives for the synthesized associated type. + trait_assoc_ty.inferred_outlives_of(&[]); + + Some(def_id) + } + DefKind::Impl { .. } => { + let impl_def_id = def_id; + let Some(trait_id) = tcx.trait_id_of_impl(def_id.to_def_id()) else { return None }; + + // first get the DefId of the assoc type on the trait, if there is not, + // then we don't need to generate it on the impl. + let Some(trait_assoc_id) = tcx.associated_type_for_effects(trait_id) else { + return None; + }; + + // TODO span is bad + let span = tcx.def_ident_span(def_id).unwrap(); + + let impl_assoc_ty = tcx.at(span).create_def(def_id, kw::Empty, DefKind::AssocTy); + + let local_def_id = impl_assoc_ty.def_id(); + let def_id = local_def_id.to_def_id(); + + impl_assoc_ty.feed_hir(); + + impl_assoc_ty.def_ident_span(Some(span)); + + impl_assoc_ty.associated_item(ty::AssocItem { + name: kw::Empty, + kind: ty::AssocKind::Type, + def_id, + trait_item_def_id: Some(trait_assoc_id), + container: ty::ImplContainer, + fn_has_self_parameter: false, + opt_rpitit_info: None, + is_effects_desugaring: true, + }); + + // visibility is public. + impl_assoc_ty.visibility(ty::Visibility::Public); + + // no default value. + impl_assoc_ty.defaultness(hir::Defaultness::Final); + + // set the type of the associated type! If this is a const impl, + // we set to Maybe, otherwise we set to `Runtime`. + let type_def_id = if tcx.is_const_trait_impl_raw(impl_def_id.to_def_id()) { + tcx.require_lang_item(hir::LangItem::EffectsMaybe, Some(span)) + } else { + tcx.require_lang_item(hir::LangItem::EffectsRuntime, Some(span)) + }; + // TODO this is wrong + impl_assoc_ty.type_of(ty::EarlyBinder::bind(Ty::new_adt( + tcx, + tcx.adt_def(type_def_id), + ty::GenericArgs::empty(), + ))); + + // Copy generics_of of the impl, making the impl as parent. + impl_assoc_ty.generics_of({ + let parent_generics = tcx.generics_of(impl_def_id); + let parent_count = parent_generics.parent_count + parent_generics.own_params.len(); + + ty::Generics { + parent: Some(impl_def_id.to_def_id()), + parent_count, + own_params: vec![], + param_def_id_to_index: parent_generics.param_def_id_to_index.clone(), + has_self: false, + has_late_bound_regions: None, + host_effect_index: parent_generics.host_effect_index, + } + }); + + impl_assoc_ty.explicit_item_bounds(ty::EarlyBinder::bind(&[])); + impl_assoc_ty.explicit_item_super_predicates(ty::EarlyBinder::bind(&[])); + + // There are no inferred outlives for the synthesized associated type. + impl_assoc_ty.inferred_outlives_of(&[]); + + Some(def_id) + } + def_kind => bug!( + "associated_type_for_effects: {:?} should be Trait or Impl but is {:?}", + def_id, + def_kind + ), } } @@ -275,6 +435,7 @@ fn associated_type_for_impl_trait_in_trait( fn_def_id: fn_def_id.to_def_id(), opaque_def_id: opaque_ty_def_id.to_def_id(), }), + is_effects_desugaring: false, }); // Copy visility of the containing function. @@ -326,6 +487,7 @@ fn associated_type_for_impl_trait_in_impl( container: ty::ImplContainer, fn_has_self_parameter: false, opt_rpitit_info: Some(ImplTraitInTraitData::Impl { fn_def_id: impl_fn_def_id.to_def_id() }), + is_effects_desugaring: false, }); // Copy visility of the containing function. |
