diff options
| author | Deadbeef <ent3rm4n@gmail.com> | 2024-06-26 16:36:42 +0000 |
|---|---|---|
| committer | Deadbeef <ent3rm4n@gmail.com> | 2024-06-28 15:44:20 +0000 |
| commit | 65a0bee0b77bad05c1bf29bd2dd855e554a9eaf5 (patch) | |
| tree | b3ef6f32a2b9602222ab6a4b6b2d967267b17d3d /compiler | |
| parent | 8b2fac9612e3840f9736bed31502b3b91ba01a08 (diff) | |
| download | rust-65a0bee0b77bad05c1bf29bd2dd855e554a9eaf5.tar.gz rust-65a0bee0b77bad05c1bf29bd2dd855e554a9eaf5.zip | |
address review comments
Diffstat (limited to 'compiler')
| -rw-r--r-- | compiler/rustc_hir/src/lang_items.rs | 4 | ||||
| -rw-r--r-- | compiler/rustc_hir_analysis/src/bounds.rs | 52 | ||||
| -rw-r--r-- | compiler/rustc_hir_analysis/src/collect/item_bounds.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/context.rs | 4 | ||||
| -rw-r--r-- | compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs | 6 | ||||
| -rw-r--r-- | compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs | 8 | ||||
| -rw-r--r-- | compiler/rustc_next_trait_solver/src/solve/trait_goals.rs | 4 | ||||
| -rw-r--r-- | compiler/rustc_span/src/symbol.rs | 4 | ||||
| -rw-r--r-- | compiler/rustc_ty_utils/src/assoc.rs | 99 | ||||
| -rw-r--r-- | compiler/rustc_type_ir/src/effects.rs | 5 | ||||
| -rw-r--r-- | compiler/rustc_type_ir/src/lang_items.rs | 4 |
11 files changed, 87 insertions, 105 deletions
diff --git a/compiler/rustc_hir/src/lang_items.rs b/compiler/rustc_hir/src/lang_items.rs index d49eb4ece99..3c44acb1657 100644 --- a/compiler/rustc_hir/src/lang_items.rs +++ b/compiler/rustc_hir/src/lang_items.rs @@ -397,8 +397,8 @@ language_item_table! { EffectsRuntime, sym::EffectsRuntime, effects_runtime, Target::Struct, GenericRequirement::None; EffectsNoRuntime, sym::EffectsNoRuntime, effects_no_runtime, Target::Struct, GenericRequirement::None; EffectsMaybe, sym::EffectsMaybe, effects_maybe, Target::Struct, GenericRequirement::None; - EffectsMin, sym::EffectsMin, effects_min, Target::Trait, GenericRequirement::None; - EffectsMinOutput, sym::EffectsMinOutput, effects_min_output, Target::AssocTy, GenericRequirement::None; + EffectsIntersection, sym::EffectsIntersection, effects_intersection, Target::Trait, GenericRequirement::None; + EffectsIntersectionOutput, sym::EffectsIntersectionOutput, effects_intersection_output, Target::AssocTy, GenericRequirement::None; EffectsCompat, sym::EffectsCompat, effects_compat, Target::Trait, GenericRequirement::Exact(1); EffectsTyCompat, sym::EffectsTyCompat, effects_ty_compat, Target::Trait, GenericRequirement::Exact(1); } diff --git a/compiler/rustc_hir_analysis/src/bounds.rs b/compiler/rustc_hir_analysis/src/bounds.rs index 61b7dd8bb8c..c7ee89e73c2 100644 --- a/compiler/rustc_hir_analysis/src/bounds.rs +++ b/compiler/rustc_hir_analysis/src/bounds.rs @@ -71,16 +71,19 @@ impl<'tcx> Bounds<'tcx> { } // For `T: ~const Tr` or `T: const Tr`, we need to add an additional bound on the // associated type of `<T as Tr>` and make sure that the effect is compatible. - if let Some(compat_val) = match (tcx.def_kind(defining_def_id), constness) { + let compat_val = match (tcx.def_kind(defining_def_id), constness) { // FIXME(effects): revisit the correctness of this - (_, ty::BoundConstness::Const) => Some(tcx.consts.false_), + (_, ty::BoundConstness::Const) => tcx.consts.false_, // body owners that can have trait bounds (DefKind::Const | DefKind::Fn | DefKind::AssocFn, ty::BoundConstness::ConstIfConst) => { - Some(tcx.expected_host_effect_param_for_body(defining_def_id)) + tcx.expected_host_effect_param_for_body(defining_def_id) } (_, ty::BoundConstness::NotConst) => { - tcx.has_attr(bound_trait_ref.def_id(), sym::const_trait).then_some(tcx.consts.true_) + if !tcx.has_attr(bound_trait_ref.def_id(), sym::const_trait) { + return; + } + tcx.consts.true_ } ( @@ -97,8 +100,12 @@ impl<'tcx> Bounds<'tcx> { let ty = bound_trait_ref .map_bound(|trait_ref| Ty::new_projection(tcx, assoc, trait_ref.args)); - // Replace the binder with dummy types/lifetimes. This should work for any - // binder as long as they don't have any bounds e.g. `for<T: Trait>`. + // When the user has written `for<'a, T> X<'a, T>: ~const Foo`, replace the + // binders to dummy ones i.e. `X<'static, ()>` so they can be referenced in + // the `Min` associated type properly (which doesn't allow using `for<>`) + // This should work for any bound variables as long as they don't have any + // bounds e.g. `for<T: Trait>`. + // FIXME(effects) reconsider this approach to allow compatibility with `for<T: Tr>` let ty = tcx.replace_bound_vars_uncached( ty, FnMutDelegate { @@ -128,24 +135,23 @@ impl<'tcx> Bounds<'tcx> { tcx.dcx().span_delayed_bug(span, "invalid `~const` encountered"); return; } - } { - // create a new projection type `<T as Tr>::Effects` - let Some(assoc) = tcx.associated_type_for_effects(bound_trait_ref.def_id()) else { - tcx.dcx().span_delayed_bug( - span, - "`~const` trait bound has no effect assoc yet no errors encountered?", - ); - return; - }; - let self_ty = Ty::new_projection(tcx, assoc, bound_trait_ref.skip_binder().args); - // make `<T as Tr>::Effects: Compat<runtime>` - let new_trait_ref = ty::TraitRef::new( - tcx, - tcx.require_lang_item(LangItem::EffectsCompat, Some(span)), - [ty::GenericArg::from(self_ty), compat_val.into()], + }; + // create a new projection type `<T as Tr>::Effects` + let Some(assoc) = tcx.associated_type_for_effects(bound_trait_ref.def_id()) else { + tcx.dcx().span_delayed_bug( + span, + "`~const` trait bound has no effect assoc yet no errors encountered?", ); - self.clauses.push((bound_trait_ref.rebind(new_trait_ref).upcast(tcx), span)); - } + return; + }; + let self_ty = Ty::new_projection(tcx, assoc, bound_trait_ref.skip_binder().args); + // make `<T as Tr>::Effects: Compat<runtime>` + let new_trait_ref = ty::TraitRef::new( + tcx, + tcx.require_lang_item(LangItem::EffectsCompat, Some(span)), + [ty::GenericArg::from(self_ty), compat_val.into()], + ); + self.clauses.push((bound_trait_ref.rebind(new_trait_ref).upcast(tcx), span)); } pub fn push_projection_bound( diff --git a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs index b32067ebd6a..c03e074c80b 100644 --- a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs +++ b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs @@ -137,7 +137,7 @@ pub(super) fn explicit_item_bounds_with_filter( let tup = Ty::new(tcx, ty::Tuple(preds.effects_min_tys)); // FIXME(effects) span let span = tcx.def_span(def_id); - let assoc = tcx.require_lang_item(hir::LangItem::EffectsMinOutput, Some(span)); + let assoc = tcx.require_lang_item(hir::LangItem::EffectsIntersectionOutput, Some(span)); let proj = Ty::new_projection(tcx, assoc, [tup]); let self_proj = Ty::new_projection( tcx, diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index c0ebad9616d..fabbec68350 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -599,8 +599,8 @@ fn trait_lang_item_to_lang_item(lang_item: TraitSolverLangItem) -> LangItem { TraitSolverLangItem::DiscriminantKind => LangItem::DiscriminantKind, TraitSolverLangItem::DynMetadata => LangItem::DynMetadata, TraitSolverLangItem::EffectsMaybe => LangItem::EffectsMaybe, - TraitSolverLangItem::EffectsMin => LangItem::EffectsMin, - TraitSolverLangItem::EffectsMinOutput => LangItem::EffectsMinOutput, + TraitSolverLangItem::EffectsIntersection => LangItem::EffectsIntersection, + TraitSolverLangItem::EffectsIntersectionOutput => LangItem::EffectsIntersectionOutput, TraitSolverLangItem::EffectsNoRuntime => LangItem::EffectsNoRuntime, TraitSolverLangItem::EffectsRuntime => LangItem::EffectsRuntime, TraitSolverLangItem::FnPtrTrait => LangItem::FnPtrTrait, diff --git a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs index 8d57c3d9af0..6ee684605ac 100644 --- a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs @@ -270,7 +270,7 @@ where goal: Goal<I, Self>, ) -> Vec<Candidate<I>>; - fn consider_builtin_effects_min_candidate( + fn consider_builtin_effects_intersection_candidate( ecx: &mut EvalCtxt<'_, D>, goal: Goal<I, Self>, ) -> Result<Candidate<I>, NoSolution>; @@ -425,8 +425,8 @@ where G::consider_builtin_destruct_candidate(self, goal) } else if cx.is_lang_item(trait_def_id, TraitSolverLangItem::TransmuteTrait) { G::consider_builtin_transmute_candidate(self, goal) - } else if tcx.is_lang_item(trait_def_id, TraitSolverLangItem::EffectsMin) { - G::consider_builtin_effects_min_candidate(self, goal) + } else if cx.is_lang_item(trait_def_id, TraitSolverLangItem::EffectsIntersection) { + G::consider_builtin_effects_intersection_candidate(self, goal) } else { Err(NoSolution) }; diff --git a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs index 7a81c210c5d..9275bcc8e97 100644 --- a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs @@ -865,7 +865,7 @@ where panic!("`BikeshedIntrinsicFrom` does not have an associated type: {:?}", goal) } - fn consider_builtin_effects_min_candidate( + fn consider_builtin_effects_intersection_candidate( ecx: &mut EvalCtxt<'_, D>, goal: Goal<I, Self>, ) -> Result<Candidate<I>, NoSolution> { @@ -903,11 +903,15 @@ where let mut min = ty::EffectKind::Maybe; for ty in types.iter() { + // We can't find the intersection if the types used are generic. + // + // FIXME(effects) do we want to look at where clauses to get some + // clue for the case where generic types are being used? let Some(kind) = ty::EffectKind::try_from_ty(cx, ty) else { return Err(NoSolution); }; - let Some(result) = ty::EffectKind::min(min, kind) else { + let Some(result) = ty::EffectKind::intersection(min, kind) else { return Err(NoSolution); }; diff --git a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs index 08ed729b144..f5832f7e5b4 100644 --- a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs +++ b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs @@ -703,7 +703,7 @@ where }) } - fn consider_builtin_effects_min_candidate( + fn consider_builtin_effects_intersection_candidate( ecx: &mut EvalCtxt<'_, D>, goal: Goal<I, Self>, ) -> Result<Candidate<I>, NoSolution> { @@ -732,7 +732,7 @@ where return Err(NoSolution); }; - let Some(result) = ty::EffectKind::min(min, kind) else { + let Some(result) = ty::EffectKind::intersection(min, kind) else { return Err(NoSolution); }; diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 4a26e8ae097..8b7a63f5eb9 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -195,9 +195,9 @@ symbols! { DoubleEndedIterator, Duration, EffectsCompat, + EffectsIntersection, + EffectsIntersectionOutput, EffectsMaybe, - EffectsMin, - EffectsMinOutput, EffectsNoRuntime, EffectsRuntime, EffectsTyCompat, diff --git a/compiler/rustc_ty_utils/src/assoc.rs b/compiler/rustc_ty_utils/src/assoc.rs index 6a55e83786c..6726db8bb54 100644 --- a/compiler/rustc_ty_utils/src/assoc.rs +++ b/compiler/rustc_ty_utils/src/assoc.rs @@ -184,12 +184,10 @@ fn associated_type_for_effects(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<De if !tcx.features().effects { return None; } - match tcx.def_kind(def_id) { + let (feed, parent_did) = 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 attr = tcx.get_attr(def_id, sym::const_trait)?; let span = attr.span; let trait_assoc_ty = tcx.at(span).create_def(trait_def_id, kw::Empty, DefKind::AssocTy); @@ -197,8 +195,6 @@ fn associated_type_for_effects(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<De 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)); @@ -213,47 +209,20 @@ fn associated_type_for_effects(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<De 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) + (trait_assoc_ty, trait_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 }; + let trait_id = tcx.trait_id_of_impl(def_id.to_def_id())?; // 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; - }; + let trait_assoc_id = tcx.associated_type_for_effects(trait_id)?; // FIXME(effects): span let span = tcx.def_ident_span(def_id).unwrap(); @@ -263,8 +232,6 @@ fn associated_type_for_effects(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<De 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 { @@ -278,9 +245,6 @@ fn associated_type_for_effects(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<De is_effects_desugaring: true, }); - // visibility is public. - impl_assoc_ty.visibility(ty::Visibility::Public); - // no default value. impl_assoc_ty.defaultness(hir::Defaultness::Final); @@ -298,36 +262,41 @@ fn associated_type_for_effects(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<De 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) + (impl_assoc_ty, impl_def_id) } def_kind => bug!( "associated_type_for_effects: {:?} should be Trait or Impl but is {:?}", def_id, def_kind ), - } + }; + + feed.feed_hir(); + + // visibility is public. + feed.visibility(ty::Visibility::Public); + + // Copy generics_of of the trait/impl, making the trait/impl as parent. + feed.generics_of({ + let parent_generics = tcx.generics_of(parent_did); + let parent_count = parent_generics.parent_count + parent_generics.own_params.len(); + + ty::Generics { + parent: Some(parent_did.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, + } + }); + feed.explicit_item_super_predicates(ty::EarlyBinder::bind(&[])); + + // There are no inferred outlives for the synthesized associated type. + feed.inferred_outlives_of(&[]); + + Some(feed.def_id().to_def_id()) } /// Given an `fn_def_id` of a trait or a trait implementation: diff --git a/compiler/rustc_type_ir/src/effects.rs b/compiler/rustc_type_ir/src/effects.rs index 39605936e30..f7942f2f982 100644 --- a/compiler/rustc_type_ir/src/effects.rs +++ b/compiler/rustc_type_ir/src/effects.rs @@ -44,7 +44,10 @@ impl EffectKind { I::Ty::new_adt(tcx, tcx.adt_def(self.to_def_id(tcx)), Default::default()) } - pub fn min(a: Self, b: Self) -> Option<Self> { + /// Returns an intersection between two effect kinds. If one effect kind + /// is more permissive than the other (e.g. `Maybe` vs `Runtime`), this + /// returns the less permissive effect kind (`Runtime`). + pub fn intersection(a: Self, b: Self) -> Option<Self> { use EffectKind::*; match (a, b) { (Maybe, x) | (x, Maybe) => Some(x), diff --git a/compiler/rustc_type_ir/src/lang_items.rs b/compiler/rustc_type_ir/src/lang_items.rs index 55b9709b668..cf00c37caa2 100644 --- a/compiler/rustc_type_ir/src/lang_items.rs +++ b/compiler/rustc_type_ir/src/lang_items.rs @@ -17,9 +17,9 @@ pub enum TraitSolverLangItem { Destruct, DiscriminantKind, DynMetadata, + EffectsIntersection, + EffectsIntersectionOutput, EffectsMaybe, - EffectsMin, - EffectsMinOutput, EffectsNoRuntime, EffectsRuntime, FnPtrTrait, |
