about summary refs log tree commit diff
path: root/compiler
diff options
context:
space:
mode:
authorDeadbeef <ent3rm4n@gmail.com>2024-06-26 16:36:42 +0000
committerDeadbeef <ent3rm4n@gmail.com>2024-06-28 15:44:20 +0000
commit65a0bee0b77bad05c1bf29bd2dd855e554a9eaf5 (patch)
treeb3ef6f32a2b9602222ab6a4b6b2d967267b17d3d /compiler
parent8b2fac9612e3840f9736bed31502b3b91ba01a08 (diff)
downloadrust-65a0bee0b77bad05c1bf29bd2dd855e554a9eaf5.tar.gz
rust-65a0bee0b77bad05c1bf29bd2dd855e554a9eaf5.zip
address review comments
Diffstat (limited to 'compiler')
-rw-r--r--compiler/rustc_hir/src/lang_items.rs4
-rw-r--r--compiler/rustc_hir_analysis/src/bounds.rs52
-rw-r--r--compiler/rustc_hir_analysis/src/collect/item_bounds.rs2
-rw-r--r--compiler/rustc_middle/src/ty/context.rs4
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs6
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs8
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/trait_goals.rs4
-rw-r--r--compiler/rustc_span/src/symbol.rs4
-rw-r--r--compiler/rustc_ty_utils/src/assoc.rs99
-rw-r--r--compiler/rustc_type_ir/src/effects.rs5
-rw-r--r--compiler/rustc_type_ir/src/lang_items.rs4
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,