Skip to content

Commit 65a0bee

Browse files
committed
address review comments
1 parent 8b2fac9 commit 65a0bee

File tree

18 files changed

+113
-124
lines changed

18 files changed

+113
-124
lines changed

compiler/rustc_hir/src/lang_items.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -397,8 +397,8 @@ language_item_table! {
397397
EffectsRuntime, sym::EffectsRuntime, effects_runtime, Target::Struct, GenericRequirement::None;
398398
EffectsNoRuntime, sym::EffectsNoRuntime, effects_no_runtime, Target::Struct, GenericRequirement::None;
399399
EffectsMaybe, sym::EffectsMaybe, effects_maybe, Target::Struct, GenericRequirement::None;
400-
EffectsMin, sym::EffectsMin, effects_min, Target::Trait, GenericRequirement::None;
401-
EffectsMinOutput, sym::EffectsMinOutput, effects_min_output, Target::AssocTy, GenericRequirement::None;
400+
EffectsIntersection, sym::EffectsIntersection, effects_intersection, Target::Trait, GenericRequirement::None;
401+
EffectsIntersectionOutput, sym::EffectsIntersectionOutput, effects_intersection_output, Target::AssocTy, GenericRequirement::None;
402402
EffectsCompat, sym::EffectsCompat, effects_compat, Target::Trait, GenericRequirement::Exact(1);
403403
EffectsTyCompat, sym::EffectsTyCompat, effects_ty_compat, Target::Trait, GenericRequirement::Exact(1);
404404
}

compiler/rustc_hir_analysis/src/bounds.rs

+29-23
Original file line numberDiff line numberDiff line change
@@ -71,16 +71,19 @@ impl<'tcx> Bounds<'tcx> {
7171
}
7272
// For `T: ~const Tr` or `T: const Tr`, we need to add an additional bound on the
7373
// associated type of `<T as Tr>` and make sure that the effect is compatible.
74-
if let Some(compat_val) = match (tcx.def_kind(defining_def_id), constness) {
74+
let compat_val = match (tcx.def_kind(defining_def_id), constness) {
7575
// FIXME(effects): revisit the correctness of this
76-
(_, ty::BoundConstness::Const) => Some(tcx.consts.false_),
76+
(_, ty::BoundConstness::Const) => tcx.consts.false_,
7777
// body owners that can have trait bounds
7878
(DefKind::Const | DefKind::Fn | DefKind::AssocFn, ty::BoundConstness::ConstIfConst) => {
79-
Some(tcx.expected_host_effect_param_for_body(defining_def_id))
79+
tcx.expected_host_effect_param_for_body(defining_def_id)
8080
}
8181

8282
(_, ty::BoundConstness::NotConst) => {
83-
tcx.has_attr(bound_trait_ref.def_id(), sym::const_trait).then_some(tcx.consts.true_)
83+
if !tcx.has_attr(bound_trait_ref.def_id(), sym::const_trait) {
84+
return;
85+
}
86+
tcx.consts.true_
8487
}
8588

8689
(
@@ -97,8 +100,12 @@ impl<'tcx> Bounds<'tcx> {
97100
let ty = bound_trait_ref
98101
.map_bound(|trait_ref| Ty::new_projection(tcx, assoc, trait_ref.args));
99102

100-
// Replace the binder with dummy types/lifetimes. This should work for any
101-
// binder as long as they don't have any bounds e.g. `for<T: Trait>`.
103+
// When the user has written `for<'a, T> X<'a, T>: ~const Foo`, replace the
104+
// binders to dummy ones i.e. `X<'static, ()>` so they can be referenced in
105+
// the `Min` associated type properly (which doesn't allow using `for<>`)
106+
// This should work for any bound variables as long as they don't have any
107+
// bounds e.g. `for<T: Trait>`.
108+
// FIXME(effects) reconsider this approach to allow compatibility with `for<T: Tr>`
102109
let ty = tcx.replace_bound_vars_uncached(
103110
ty,
104111
FnMutDelegate {
@@ -128,24 +135,23 @@ impl<'tcx> Bounds<'tcx> {
128135
tcx.dcx().span_delayed_bug(span, "invalid `~const` encountered");
129136
return;
130137
}
131-
} {
132-
// create a new projection type `<T as Tr>::Effects`
133-
let Some(assoc) = tcx.associated_type_for_effects(bound_trait_ref.def_id()) else {
134-
tcx.dcx().span_delayed_bug(
135-
span,
136-
"`~const` trait bound has no effect assoc yet no errors encountered?",
137-
);
138-
return;
139-
};
140-
let self_ty = Ty::new_projection(tcx, assoc, bound_trait_ref.skip_binder().args);
141-
// make `<T as Tr>::Effects: Compat<runtime>`
142-
let new_trait_ref = ty::TraitRef::new(
143-
tcx,
144-
tcx.require_lang_item(LangItem::EffectsCompat, Some(span)),
145-
[ty::GenericArg::from(self_ty), compat_val.into()],
138+
};
139+
// create a new projection type `<T as Tr>::Effects`
140+
let Some(assoc) = tcx.associated_type_for_effects(bound_trait_ref.def_id()) else {
141+
tcx.dcx().span_delayed_bug(
142+
span,
143+
"`~const` trait bound has no effect assoc yet no errors encountered?",
146144
);
147-
self.clauses.push((bound_trait_ref.rebind(new_trait_ref).upcast(tcx), span));
148-
}
145+
return;
146+
};
147+
let self_ty = Ty::new_projection(tcx, assoc, bound_trait_ref.skip_binder().args);
148+
// make `<T as Tr>::Effects: Compat<runtime>`
149+
let new_trait_ref = ty::TraitRef::new(
150+
tcx,
151+
tcx.require_lang_item(LangItem::EffectsCompat, Some(span)),
152+
[ty::GenericArg::from(self_ty), compat_val.into()],
153+
);
154+
self.clauses.push((bound_trait_ref.rebind(new_trait_ref).upcast(tcx), span));
149155
}
150156

151157
pub fn push_projection_bound(

compiler/rustc_hir_analysis/src/collect/item_bounds.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ pub(super) fn explicit_item_bounds_with_filter(
137137
let tup = Ty::new(tcx, ty::Tuple(preds.effects_min_tys));
138138
// FIXME(effects) span
139139
let span = tcx.def_span(def_id);
140-
let assoc = tcx.require_lang_item(hir::LangItem::EffectsMinOutput, Some(span));
140+
let assoc = tcx.require_lang_item(hir::LangItem::EffectsIntersectionOutput, Some(span));
141141
let proj = Ty::new_projection(tcx, assoc, [tup]);
142142
let self_proj = Ty::new_projection(
143143
tcx,

compiler/rustc_middle/src/ty/context.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -599,8 +599,8 @@ fn trait_lang_item_to_lang_item(lang_item: TraitSolverLangItem) -> LangItem {
599599
TraitSolverLangItem::DiscriminantKind => LangItem::DiscriminantKind,
600600
TraitSolverLangItem::DynMetadata => LangItem::DynMetadata,
601601
TraitSolverLangItem::EffectsMaybe => LangItem::EffectsMaybe,
602-
TraitSolverLangItem::EffectsMin => LangItem::EffectsMin,
603-
TraitSolverLangItem::EffectsMinOutput => LangItem::EffectsMinOutput,
602+
TraitSolverLangItem::EffectsIntersection => LangItem::EffectsIntersection,
603+
TraitSolverLangItem::EffectsIntersectionOutput => LangItem::EffectsIntersectionOutput,
604604
TraitSolverLangItem::EffectsNoRuntime => LangItem::EffectsNoRuntime,
605605
TraitSolverLangItem::EffectsRuntime => LangItem::EffectsRuntime,
606606
TraitSolverLangItem::FnPtrTrait => LangItem::FnPtrTrait,

compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -270,7 +270,7 @@ where
270270
goal: Goal<I, Self>,
271271
) -> Vec<Candidate<I>>;
272272

273-
fn consider_builtin_effects_min_candidate(
273+
fn consider_builtin_effects_intersection_candidate(
274274
ecx: &mut EvalCtxt<'_, D>,
275275
goal: Goal<I, Self>,
276276
) -> Result<Candidate<I>, NoSolution>;
@@ -425,8 +425,8 @@ where
425425
G::consider_builtin_destruct_candidate(self, goal)
426426
} else if cx.is_lang_item(trait_def_id, TraitSolverLangItem::TransmuteTrait) {
427427
G::consider_builtin_transmute_candidate(self, goal)
428-
} else if tcx.is_lang_item(trait_def_id, TraitSolverLangItem::EffectsMin) {
429-
G::consider_builtin_effects_min_candidate(self, goal)
428+
} else if cx.is_lang_item(trait_def_id, TraitSolverLangItem::EffectsIntersection) {
429+
G::consider_builtin_effects_intersection_candidate(self, goal)
430430
} else {
431431
Err(NoSolution)
432432
};

compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs

+6-2
Original file line numberDiff line numberDiff line change
@@ -865,7 +865,7 @@ where
865865
panic!("`BikeshedIntrinsicFrom` does not have an associated type: {:?}", goal)
866866
}
867867

868-
fn consider_builtin_effects_min_candidate(
868+
fn consider_builtin_effects_intersection_candidate(
869869
ecx: &mut EvalCtxt<'_, D>,
870870
goal: Goal<I, Self>,
871871
) -> Result<Candidate<I>, NoSolution> {
@@ -903,11 +903,15 @@ where
903903
let mut min = ty::EffectKind::Maybe;
904904

905905
for ty in types.iter() {
906+
// We can't find the intersection if the types used are generic.
907+
//
908+
// FIXME(effects) do we want to look at where clauses to get some
909+
// clue for the case where generic types are being used?
906910
let Some(kind) = ty::EffectKind::try_from_ty(cx, ty) else {
907911
return Err(NoSolution);
908912
};
909913

910-
let Some(result) = ty::EffectKind::min(min, kind) else {
914+
let Some(result) = ty::EffectKind::intersection(min, kind) else {
911915
return Err(NoSolution);
912916
};
913917

compiler/rustc_next_trait_solver/src/solve/trait_goals.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -703,7 +703,7 @@ where
703703
})
704704
}
705705

706-
fn consider_builtin_effects_min_candidate(
706+
fn consider_builtin_effects_intersection_candidate(
707707
ecx: &mut EvalCtxt<'_, D>,
708708
goal: Goal<I, Self>,
709709
) -> Result<Candidate<I>, NoSolution> {
@@ -732,7 +732,7 @@ where
732732
return Err(NoSolution);
733733
};
734734

735-
let Some(result) = ty::EffectKind::min(min, kind) else {
735+
let Some(result) = ty::EffectKind::intersection(min, kind) else {
736736
return Err(NoSolution);
737737
};
738738

compiler/rustc_span/src/symbol.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -195,9 +195,9 @@ symbols! {
195195
DoubleEndedIterator,
196196
Duration,
197197
EffectsCompat,
198+
EffectsIntersection,
199+
EffectsIntersectionOutput,
198200
EffectsMaybe,
199-
EffectsMin,
200-
EffectsMinOutput,
201201
EffectsNoRuntime,
202202
EffectsRuntime,
203203
EffectsTyCompat,

compiler/rustc_ty_utils/src/assoc.rs

+34-65
Original file line numberDiff line numberDiff line change
@@ -184,21 +184,17 @@ fn associated_type_for_effects(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<De
184184
if !tcx.features().effects {
185185
return None;
186186
}
187-
match tcx.def_kind(def_id) {
187+
let (feed, parent_did) = match tcx.def_kind(def_id) {
188188
DefKind::Trait => {
189189
let trait_def_id = def_id;
190-
let Some(attr) = tcx.get_attr(def_id, sym::const_trait) else {
191-
return None;
192-
};
190+
let attr = tcx.get_attr(def_id, sym::const_trait)?;
193191

194192
let span = attr.span;
195193
let trait_assoc_ty = tcx.at(span).create_def(trait_def_id, kw::Empty, DefKind::AssocTy);
196194

197195
let local_def_id = trait_assoc_ty.def_id();
198196
let def_id = local_def_id.to_def_id();
199197

200-
trait_assoc_ty.feed_hir();
201-
202198
// Copy span of the attribute.
203199
trait_assoc_ty.def_ident_span(Some(span));
204200

@@ -213,47 +209,20 @@ fn associated_type_for_effects(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<De
213209
is_effects_desugaring: true,
214210
});
215211

216-
// visibility is public.
217-
trait_assoc_ty.visibility(ty::Visibility::Public);
218-
219212
// No default type
220213
trait_assoc_ty.defaultness(hir::Defaultness::Default { has_value: false });
221214

222215
trait_assoc_ty.is_type_alias_impl_trait(false);
223216

224-
// Copy generics_of of the trait, making the trait as parent.
225-
trait_assoc_ty.generics_of({
226-
let parent_generics = tcx.generics_of(trait_def_id);
227-
let parent_count = parent_generics.parent_count + parent_generics.own_params.len();
228-
229-
ty::Generics {
230-
parent: Some(trait_def_id.to_def_id()),
231-
parent_count,
232-
own_params: vec![],
233-
param_def_id_to_index: parent_generics.param_def_id_to_index.clone(),
234-
has_self: false,
235-
has_late_bound_regions: None,
236-
host_effect_index: parent_generics.host_effect_index,
237-
}
238-
});
239-
240-
trait_assoc_ty.explicit_item_bounds(ty::EarlyBinder::bind(&[]));
241-
trait_assoc_ty.explicit_item_super_predicates(ty::EarlyBinder::bind(&[]));
242-
243-
// There are no inferred outlives for the synthesized associated type.
244-
trait_assoc_ty.inferred_outlives_of(&[]);
245-
246-
Some(def_id)
217+
(trait_assoc_ty, trait_def_id)
247218
}
248219
DefKind::Impl { .. } => {
249220
let impl_def_id = def_id;
250-
let Some(trait_id) = tcx.trait_id_of_impl(def_id.to_def_id()) else { return None };
221+
let trait_id = tcx.trait_id_of_impl(def_id.to_def_id())?;
251222

252223
// first get the DefId of the assoc type on the trait, if there is not,
253224
// then we don't need to generate it on the impl.
254-
let Some(trait_assoc_id) = tcx.associated_type_for_effects(trait_id) else {
255-
return None;
256-
};
225+
let trait_assoc_id = tcx.associated_type_for_effects(trait_id)?;
257226

258227
// FIXME(effects): span
259228
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
263232
let local_def_id = impl_assoc_ty.def_id();
264233
let def_id = local_def_id.to_def_id();
265234

266-
impl_assoc_ty.feed_hir();
267-
268235
impl_assoc_ty.def_ident_span(Some(span));
269236

270237
impl_assoc_ty.associated_item(ty::AssocItem {
@@ -278,9 +245,6 @@ fn associated_type_for_effects(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<De
278245
is_effects_desugaring: true,
279246
});
280247

281-
// visibility is public.
282-
impl_assoc_ty.visibility(ty::Visibility::Public);
283-
284248
// no default value.
285249
impl_assoc_ty.defaultness(hir::Defaultness::Final);
286250

@@ -298,36 +262,41 @@ fn associated_type_for_effects(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<De
298262
ty::GenericArgs::empty(),
299263
)));
300264

301-
// Copy generics_of of the impl, making the impl as parent.
302-
impl_assoc_ty.generics_of({
303-
let parent_generics = tcx.generics_of(impl_def_id);
304-
let parent_count = parent_generics.parent_count + parent_generics.own_params.len();
305-
306-
ty::Generics {
307-
parent: Some(impl_def_id.to_def_id()),
308-
parent_count,
309-
own_params: vec![],
310-
param_def_id_to_index: parent_generics.param_def_id_to_index.clone(),
311-
has_self: false,
312-
has_late_bound_regions: None,
313-
host_effect_index: parent_generics.host_effect_index,
314-
}
315-
});
316-
317-
// impl_assoc_ty.explicit_item_bounds(ty::EarlyBinder::bind(&[]));
318-
impl_assoc_ty.explicit_item_super_predicates(ty::EarlyBinder::bind(&[]));
319-
320-
// There are no inferred outlives for the synthesized associated type.
321-
impl_assoc_ty.inferred_outlives_of(&[]);
322-
323-
Some(def_id)
265+
(impl_assoc_ty, impl_def_id)
324266
}
325267
def_kind => bug!(
326268
"associated_type_for_effects: {:?} should be Trait or Impl but is {:?}",
327269
def_id,
328270
def_kind
329271
),
330-
}
272+
};
273+
274+
feed.feed_hir();
275+
276+
// visibility is public.
277+
feed.visibility(ty::Visibility::Public);
278+
279+
// Copy generics_of of the trait/impl, making the trait/impl as parent.
280+
feed.generics_of({
281+
let parent_generics = tcx.generics_of(parent_did);
282+
let parent_count = parent_generics.parent_count + parent_generics.own_params.len();
283+
284+
ty::Generics {
285+
parent: Some(parent_did.to_def_id()),
286+
parent_count,
287+
own_params: vec![],
288+
param_def_id_to_index: parent_generics.param_def_id_to_index.clone(),
289+
has_self: false,
290+
has_late_bound_regions: None,
291+
host_effect_index: parent_generics.host_effect_index,
292+
}
293+
});
294+
feed.explicit_item_super_predicates(ty::EarlyBinder::bind(&[]));
295+
296+
// There are no inferred outlives for the synthesized associated type.
297+
feed.inferred_outlives_of(&[]);
298+
299+
Some(feed.def_id().to_def_id())
331300
}
332301

333302
/// Given an `fn_def_id` of a trait or a trait implementation:

compiler/rustc_type_ir/src/effects.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,10 @@ impl EffectKind {
4444
I::Ty::new_adt(tcx, tcx.adt_def(self.to_def_id(tcx)), Default::default())
4545
}
4646

47-
pub fn min(a: Self, b: Self) -> Option<Self> {
47+
/// Returns an intersection between two effect kinds. If one effect kind
48+
/// is more permissive than the other (e.g. `Maybe` vs `Runtime`), this
49+
/// returns the less permissive effect kind (`Runtime`).
50+
pub fn intersection(a: Self, b: Self) -> Option<Self> {
4851
use EffectKind::*;
4952
match (a, b) {
5053
(Maybe, x) | (x, Maybe) => Some(x),

compiler/rustc_type_ir/src/lang_items.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,9 @@ pub enum TraitSolverLangItem {
1717
Destruct,
1818
DiscriminantKind,
1919
DynMetadata,
20+
EffectsIntersection,
21+
EffectsIntersectionOutput,
2022
EffectsMaybe,
21-
EffectsMin,
22-
EffectsMinOutput,
2323
EffectsNoRuntime,
2424
EffectsRuntime,
2525
FnPtrTrait,

library/core/src/marker.rs

+8-3
Original file line numberDiff line numberDiff line change
@@ -1062,9 +1062,14 @@ pub mod effects {
10621062
impl<T: ?Sized> TyCompat<T> for Maybe {}
10631063
impl<T: ?Sized> TyCompat<Maybe> for T {}
10641064

1065-
#[lang = "EffectsMin"]
1066-
pub trait Min {
1067-
#[lang = "EffectsMinOutput"]
1065+
#[lang = "EffectsIntersection"]
1066+
pub trait Intersection {
1067+
#[lang = "EffectsIntersectionOutput"]
10681068
type Output: ?Sized;
10691069
}
1070+
1071+
// FIXME(effects): remove this after next trait solver lands
1072+
impl Intersection for () {
1073+
type Output = Maybe;
1074+
}
10701075
}

0 commit comments

Comments
 (0)