mirror of https://github.com/rust-lang/rust.git
address review comments
This commit is contained in:
parent
8b2fac9612
commit
65a0bee0b7
|
@ -397,8 +397,8 @@ language_item_table! {
|
||||||
EffectsRuntime, sym::EffectsRuntime, effects_runtime, Target::Struct, GenericRequirement::None;
|
EffectsRuntime, sym::EffectsRuntime, effects_runtime, Target::Struct, GenericRequirement::None;
|
||||||
EffectsNoRuntime, sym::EffectsNoRuntime, effects_no_runtime, Target::Struct, GenericRequirement::None;
|
EffectsNoRuntime, sym::EffectsNoRuntime, effects_no_runtime, Target::Struct, GenericRequirement::None;
|
||||||
EffectsMaybe, sym::EffectsMaybe, effects_maybe, Target::Struct, GenericRequirement::None;
|
EffectsMaybe, sym::EffectsMaybe, effects_maybe, Target::Struct, GenericRequirement::None;
|
||||||
EffectsMin, sym::EffectsMin, effects_min, Target::Trait, GenericRequirement::None;
|
EffectsIntersection, sym::EffectsIntersection, effects_intersection, Target::Trait, GenericRequirement::None;
|
||||||
EffectsMinOutput, sym::EffectsMinOutput, effects_min_output, Target::AssocTy, GenericRequirement::None;
|
EffectsIntersectionOutput, sym::EffectsIntersectionOutput, effects_intersection_output, Target::AssocTy, GenericRequirement::None;
|
||||||
EffectsCompat, sym::EffectsCompat, effects_compat, Target::Trait, GenericRequirement::Exact(1);
|
EffectsCompat, sym::EffectsCompat, effects_compat, Target::Trait, GenericRequirement::Exact(1);
|
||||||
EffectsTyCompat, sym::EffectsTyCompat, effects_ty_compat, Target::Trait, GenericRequirement::Exact(1);
|
EffectsTyCompat, sym::EffectsTyCompat, effects_ty_compat, Target::Trait, GenericRequirement::Exact(1);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
// 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.
|
// 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
|
// 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
|
// body owners that can have trait bounds
|
||||||
(DefKind::Const | DefKind::Fn | DefKind::AssocFn, ty::BoundConstness::ConstIfConst) => {
|
(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) => {
|
(_, 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
|
let ty = bound_trait_ref
|
||||||
.map_bound(|trait_ref| Ty::new_projection(tcx, assoc, trait_ref.args));
|
.map_bound(|trait_ref| Ty::new_projection(tcx, assoc, trait_ref.args));
|
||||||
|
|
||||||
// Replace the binder with dummy types/lifetimes. This should work for any
|
// When the user has written `for<'a, T> X<'a, T>: ~const Foo`, replace the
|
||||||
// binder as long as they don't have any bounds e.g. `for<T: Trait>`.
|
// 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(
|
let ty = tcx.replace_bound_vars_uncached(
|
||||||
ty,
|
ty,
|
||||||
FnMutDelegate {
|
FnMutDelegate {
|
||||||
|
@ -128,24 +135,23 @@ impl<'tcx> Bounds<'tcx> {
|
||||||
tcx.dcx().span_delayed_bug(span, "invalid `~const` encountered");
|
tcx.dcx().span_delayed_bug(span, "invalid `~const` encountered");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} {
|
};
|
||||||
// create a new projection type `<T as Tr>::Effects`
|
// create a new projection type `<T as Tr>::Effects`
|
||||||
let Some(assoc) = tcx.associated_type_for_effects(bound_trait_ref.def_id()) else {
|
let Some(assoc) = tcx.associated_type_for_effects(bound_trait_ref.def_id()) else {
|
||||||
tcx.dcx().span_delayed_bug(
|
tcx.dcx().span_delayed_bug(
|
||||||
span,
|
span,
|
||||||
"`~const` trait bound has no effect assoc yet no errors encountered?",
|
"`~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()],
|
|
||||||
);
|
);
|
||||||
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(
|
pub fn push_projection_bound(
|
||||||
|
|
|
@ -137,7 +137,7 @@ pub(super) fn explicit_item_bounds_with_filter(
|
||||||
let tup = Ty::new(tcx, ty::Tuple(preds.effects_min_tys));
|
let tup = Ty::new(tcx, ty::Tuple(preds.effects_min_tys));
|
||||||
// FIXME(effects) span
|
// FIXME(effects) span
|
||||||
let span = tcx.def_span(def_id);
|
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 proj = Ty::new_projection(tcx, assoc, [tup]);
|
||||||
let self_proj = Ty::new_projection(
|
let self_proj = Ty::new_projection(
|
||||||
tcx,
|
tcx,
|
||||||
|
|
|
@ -599,8 +599,8 @@ fn trait_lang_item_to_lang_item(lang_item: TraitSolverLangItem) -> LangItem {
|
||||||
TraitSolverLangItem::DiscriminantKind => LangItem::DiscriminantKind,
|
TraitSolverLangItem::DiscriminantKind => LangItem::DiscriminantKind,
|
||||||
TraitSolverLangItem::DynMetadata => LangItem::DynMetadata,
|
TraitSolverLangItem::DynMetadata => LangItem::DynMetadata,
|
||||||
TraitSolverLangItem::EffectsMaybe => LangItem::EffectsMaybe,
|
TraitSolverLangItem::EffectsMaybe => LangItem::EffectsMaybe,
|
||||||
TraitSolverLangItem::EffectsMin => LangItem::EffectsMin,
|
TraitSolverLangItem::EffectsIntersection => LangItem::EffectsIntersection,
|
||||||
TraitSolverLangItem::EffectsMinOutput => LangItem::EffectsMinOutput,
|
TraitSolverLangItem::EffectsIntersectionOutput => LangItem::EffectsIntersectionOutput,
|
||||||
TraitSolverLangItem::EffectsNoRuntime => LangItem::EffectsNoRuntime,
|
TraitSolverLangItem::EffectsNoRuntime => LangItem::EffectsNoRuntime,
|
||||||
TraitSolverLangItem::EffectsRuntime => LangItem::EffectsRuntime,
|
TraitSolverLangItem::EffectsRuntime => LangItem::EffectsRuntime,
|
||||||
TraitSolverLangItem::FnPtrTrait => LangItem::FnPtrTrait,
|
TraitSolverLangItem::FnPtrTrait => LangItem::FnPtrTrait,
|
||||||
|
|
|
@ -270,7 +270,7 @@ where
|
||||||
goal: Goal<I, Self>,
|
goal: Goal<I, Self>,
|
||||||
) -> Vec<Candidate<I>>;
|
) -> Vec<Candidate<I>>;
|
||||||
|
|
||||||
fn consider_builtin_effects_min_candidate(
|
fn consider_builtin_effects_intersection_candidate(
|
||||||
ecx: &mut EvalCtxt<'_, D>,
|
ecx: &mut EvalCtxt<'_, D>,
|
||||||
goal: Goal<I, Self>,
|
goal: Goal<I, Self>,
|
||||||
) -> Result<Candidate<I>, NoSolution>;
|
) -> Result<Candidate<I>, NoSolution>;
|
||||||
|
@ -425,8 +425,8 @@ where
|
||||||
G::consider_builtin_destruct_candidate(self, goal)
|
G::consider_builtin_destruct_candidate(self, goal)
|
||||||
} else if cx.is_lang_item(trait_def_id, TraitSolverLangItem::TransmuteTrait) {
|
} else if cx.is_lang_item(trait_def_id, TraitSolverLangItem::TransmuteTrait) {
|
||||||
G::consider_builtin_transmute_candidate(self, goal)
|
G::consider_builtin_transmute_candidate(self, goal)
|
||||||
} else if tcx.is_lang_item(trait_def_id, TraitSolverLangItem::EffectsMin) {
|
} else if cx.is_lang_item(trait_def_id, TraitSolverLangItem::EffectsIntersection) {
|
||||||
G::consider_builtin_effects_min_candidate(self, goal)
|
G::consider_builtin_effects_intersection_candidate(self, goal)
|
||||||
} else {
|
} else {
|
||||||
Err(NoSolution)
|
Err(NoSolution)
|
||||||
};
|
};
|
||||||
|
|
|
@ -865,7 +865,7 @@ where
|
||||||
panic!("`BikeshedIntrinsicFrom` does not have an associated type: {:?}", goal)
|
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>,
|
ecx: &mut EvalCtxt<'_, D>,
|
||||||
goal: Goal<I, Self>,
|
goal: Goal<I, Self>,
|
||||||
) -> Result<Candidate<I>, NoSolution> {
|
) -> Result<Candidate<I>, NoSolution> {
|
||||||
|
@ -903,11 +903,15 @@ where
|
||||||
let mut min = ty::EffectKind::Maybe;
|
let mut min = ty::EffectKind::Maybe;
|
||||||
|
|
||||||
for ty in types.iter() {
|
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 {
|
let Some(kind) = ty::EffectKind::try_from_ty(cx, ty) else {
|
||||||
return Err(NoSolution);
|
return Err(NoSolution);
|
||||||
};
|
};
|
||||||
|
|
||||||
let Some(result) = ty::EffectKind::min(min, kind) else {
|
let Some(result) = ty::EffectKind::intersection(min, kind) else {
|
||||||
return Err(NoSolution);
|
return Err(NoSolution);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -703,7 +703,7 @@ where
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn consider_builtin_effects_min_candidate(
|
fn consider_builtin_effects_intersection_candidate(
|
||||||
ecx: &mut EvalCtxt<'_, D>,
|
ecx: &mut EvalCtxt<'_, D>,
|
||||||
goal: Goal<I, Self>,
|
goal: Goal<I, Self>,
|
||||||
) -> Result<Candidate<I>, NoSolution> {
|
) -> Result<Candidate<I>, NoSolution> {
|
||||||
|
@ -732,7 +732,7 @@ where
|
||||||
return Err(NoSolution);
|
return Err(NoSolution);
|
||||||
};
|
};
|
||||||
|
|
||||||
let Some(result) = ty::EffectKind::min(min, kind) else {
|
let Some(result) = ty::EffectKind::intersection(min, kind) else {
|
||||||
return Err(NoSolution);
|
return Err(NoSolution);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -195,9 +195,9 @@ symbols! {
|
||||||
DoubleEndedIterator,
|
DoubleEndedIterator,
|
||||||
Duration,
|
Duration,
|
||||||
EffectsCompat,
|
EffectsCompat,
|
||||||
|
EffectsIntersection,
|
||||||
|
EffectsIntersectionOutput,
|
||||||
EffectsMaybe,
|
EffectsMaybe,
|
||||||
EffectsMin,
|
|
||||||
EffectsMinOutput,
|
|
||||||
EffectsNoRuntime,
|
EffectsNoRuntime,
|
||||||
EffectsRuntime,
|
EffectsRuntime,
|
||||||
EffectsTyCompat,
|
EffectsTyCompat,
|
||||||
|
|
|
@ -184,12 +184,10 @@ fn associated_type_for_effects(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<De
|
||||||
if !tcx.features().effects {
|
if !tcx.features().effects {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
match tcx.def_kind(def_id) {
|
let (feed, parent_did) = match tcx.def_kind(def_id) {
|
||||||
DefKind::Trait => {
|
DefKind::Trait => {
|
||||||
let trait_def_id = def_id;
|
let trait_def_id = def_id;
|
||||||
let Some(attr) = tcx.get_attr(def_id, sym::const_trait) else {
|
let attr = tcx.get_attr(def_id, sym::const_trait)?;
|
||||||
return None;
|
|
||||||
};
|
|
||||||
|
|
||||||
let span = attr.span;
|
let span = attr.span;
|
||||||
let trait_assoc_ty = tcx.at(span).create_def(trait_def_id, kw::Empty, DefKind::AssocTy);
|
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 local_def_id = trait_assoc_ty.def_id();
|
||||||
let def_id = local_def_id.to_def_id();
|
let def_id = local_def_id.to_def_id();
|
||||||
|
|
||||||
trait_assoc_ty.feed_hir();
|
|
||||||
|
|
||||||
// Copy span of the attribute.
|
// Copy span of the attribute.
|
||||||
trait_assoc_ty.def_ident_span(Some(span));
|
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,
|
is_effects_desugaring: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
// visibility is public.
|
|
||||||
trait_assoc_ty.visibility(ty::Visibility::Public);
|
|
||||||
|
|
||||||
// No default type
|
// No default type
|
||||||
trait_assoc_ty.defaultness(hir::Defaultness::Default { has_value: false });
|
trait_assoc_ty.defaultness(hir::Defaultness::Default { has_value: false });
|
||||||
|
|
||||||
trait_assoc_ty.is_type_alias_impl_trait(false);
|
trait_assoc_ty.is_type_alias_impl_trait(false);
|
||||||
|
|
||||||
// Copy generics_of of the trait, making the trait as parent.
|
(trait_assoc_ty, trait_def_id)
|
||||||
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 { .. } => {
|
DefKind::Impl { .. } => {
|
||||||
let impl_def_id = def_id;
|
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,
|
// 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.
|
// then we don't need to generate it on the impl.
|
||||||
let Some(trait_assoc_id) = tcx.associated_type_for_effects(trait_id) else {
|
let trait_assoc_id = tcx.associated_type_for_effects(trait_id)?;
|
||||||
return None;
|
|
||||||
};
|
|
||||||
|
|
||||||
// FIXME(effects): span
|
// FIXME(effects): span
|
||||||
let span = tcx.def_ident_span(def_id).unwrap();
|
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 local_def_id = impl_assoc_ty.def_id();
|
||||||
let def_id = local_def_id.to_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.def_ident_span(Some(span));
|
||||||
|
|
||||||
impl_assoc_ty.associated_item(ty::AssocItem {
|
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,
|
is_effects_desugaring: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
// visibility is public.
|
|
||||||
impl_assoc_ty.visibility(ty::Visibility::Public);
|
|
||||||
|
|
||||||
// no default value.
|
// no default value.
|
||||||
impl_assoc_ty.defaultness(hir::Defaultness::Final);
|
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(),
|
ty::GenericArgs::empty(),
|
||||||
)));
|
)));
|
||||||
|
|
||||||
// Copy generics_of of the impl, making the impl as parent.
|
(impl_assoc_ty, impl_def_id)
|
||||||
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!(
|
def_kind => bug!(
|
||||||
"associated_type_for_effects: {:?} should be Trait or Impl but is {:?}",
|
"associated_type_for_effects: {:?} should be Trait or Impl but is {:?}",
|
||||||
def_id,
|
def_id,
|
||||||
def_kind
|
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:
|
/// Given an `fn_def_id` of a trait or a trait implementation:
|
||||||
|
|
|
@ -44,7 +44,10 @@ impl EffectKind {
|
||||||
I::Ty::new_adt(tcx, tcx.adt_def(self.to_def_id(tcx)), Default::default())
|
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::*;
|
use EffectKind::*;
|
||||||
match (a, b) {
|
match (a, b) {
|
||||||
(Maybe, x) | (x, Maybe) => Some(x),
|
(Maybe, x) | (x, Maybe) => Some(x),
|
||||||
|
|
|
@ -17,9 +17,9 @@ pub enum TraitSolverLangItem {
|
||||||
Destruct,
|
Destruct,
|
||||||
DiscriminantKind,
|
DiscriminantKind,
|
||||||
DynMetadata,
|
DynMetadata,
|
||||||
|
EffectsIntersection,
|
||||||
|
EffectsIntersectionOutput,
|
||||||
EffectsMaybe,
|
EffectsMaybe,
|
||||||
EffectsMin,
|
|
||||||
EffectsMinOutput,
|
|
||||||
EffectsNoRuntime,
|
EffectsNoRuntime,
|
||||||
EffectsRuntime,
|
EffectsRuntime,
|
||||||
FnPtrTrait,
|
FnPtrTrait,
|
||||||
|
|
|
@ -1062,9 +1062,14 @@ pub mod effects {
|
||||||
impl<T: ?Sized> TyCompat<T> for Maybe {}
|
impl<T: ?Sized> TyCompat<T> for Maybe {}
|
||||||
impl<T: ?Sized> TyCompat<Maybe> for T {}
|
impl<T: ?Sized> TyCompat<Maybe> for T {}
|
||||||
|
|
||||||
#[lang = "EffectsMin"]
|
#[lang = "EffectsIntersection"]
|
||||||
pub trait Min {
|
pub trait Intersection {
|
||||||
#[lang = "EffectsMinOutput"]
|
#[lang = "EffectsIntersectionOutput"]
|
||||||
type Output: ?Sized;
|
type Output: ?Sized;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FIXME(effects): remove this after next trait solver lands
|
||||||
|
impl Intersection for () {
|
||||||
|
type Output = Maybe;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -104,15 +104,18 @@ fn main() {}
|
||||||
|
|
||||||
struct D;
|
struct D;
|
||||||
|
|
||||||
|
/* FIXME(effects)
|
||||||
impl const Drop for D {
|
impl const Drop for D {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
todo!();
|
todo!();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
// Lint this, since it can be dropped in const contexts
|
// Lint this, since it can be dropped in const contexts
|
||||||
// FIXME(effects)
|
// FIXME(effects)
|
||||||
fn d(this: D) {}
|
const fn d(this: D) {}
|
||||||
|
//~^ ERROR: this could be a `const fn`
|
||||||
|
|
||||||
mod msrv {
|
mod msrv {
|
||||||
struct Foo(*const u8, &'static u8);
|
struct Foo(*const u8, &'static u8);
|
||||||
|
|
|
@ -161,6 +161,11 @@ error: this could be a `const fn`
|
||||||
|
|
|
|
||||||
LL | fn d(this: D) {}
|
LL | fn d(this: D) {}
|
||||||
| ^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
help: make the function `const`
|
||||||
|
|
|
||||||
|
LL | const fn d(this: D) {}
|
||||||
|
| +++++
|
||||||
|
|
||||||
error: this could be a `const fn`
|
error: this could be a `const fn`
|
||||||
--> tests/ui/missing_const_for_fn/could_be_const.rs:125:9
|
--> tests/ui/missing_const_for_fn/could_be_const.rs:125:9
|
||||||
|
|
|
@ -126,10 +126,10 @@ pub mod effects {
|
||||||
#[stable(feature = "minicore", since = "1.0.0")]
|
#[stable(feature = "minicore", since = "1.0.0")]
|
||||||
impl<T: ?Sized> TyCompat<Maybe> for T {}
|
impl<T: ?Sized> TyCompat<Maybe> for T {}
|
||||||
|
|
||||||
#[lang = "EffectsMin"]
|
#[lang = "EffectsIntersection"]
|
||||||
#[stable(feature = "minicore", since = "1.0.0")]
|
#[stable(feature = "minicore", since = "1.0.0")]
|
||||||
pub trait Min {
|
pub trait Intersection {
|
||||||
#[lang = "EffectsMinOutput"]
|
#[lang = "EffectsIntersectionOutput"]
|
||||||
#[stable(feature = "minicore", since = "1.0.0")]
|
#[stable(feature = "minicore", since = "1.0.0")]
|
||||||
type Output: ?Sized;
|
type Output: ?Sized;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
//@ check-pass
|
//@ check-pass
|
||||||
|
//@ compile-flags: -Znext-solver
|
||||||
|
|
||||||
#![allow(incomplete_features)]
|
#![allow(incomplete_features)]
|
||||||
#![feature(const_trait_impl, effects)]
|
#![feature(const_trait_impl, effects)]
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
// FIXME(effects) check-pass
|
// FIXME(effects) check-pass
|
||||||
//@ known-bug: #110395
|
//@ known-bug: #110395
|
||||||
|
//@ compile-flags: -Znext-solver
|
||||||
|
#![allow(incomplete_features)]
|
||||||
#![feature(const_trait_impl, effects)]
|
#![feature(const_trait_impl, effects)]
|
||||||
|
|
||||||
#[const_trait]
|
#[const_trait]
|
||||||
|
|
|
@ -1,20 +1,11 @@
|
||||||
warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes
|
|
||||||
--> $DIR/super-traits.rs:3:30
|
|
||||||
|
|
|
||||||
LL | #![feature(const_trait_impl, effects)]
|
|
||||||
| ^^^^^^^
|
|
||||||
|
|
|
||||||
= note: see issue #102090 <https://github.com/rust-lang/rust/issues/102090> for more information
|
|
||||||
= note: `#[warn(incomplete_features)]` on by default
|
|
||||||
|
|
||||||
error[E0277]: the trait bound `Foo::{synthetic#0}: ~const Compat` is not satisfied
|
error[E0277]: the trait bound `Foo::{synthetic#0}: ~const Compat` is not satisfied
|
||||||
--> $DIR/super-traits.rs:21:7
|
--> $DIR/super-traits.rs:23:7
|
||||||
|
|
|
|
||||||
LL | t.a();
|
LL | t.a();
|
||||||
| ^ the trait `~const Compat` is not implemented for `Foo::{synthetic#0}`
|
| ^ the trait `~const Compat` is not implemented for `Foo::{synthetic#0}`
|
||||||
|
|
|
|
||||||
note: required by a bound in `Foo::a`
|
note: required by a bound in `Foo::a`
|
||||||
--> $DIR/super-traits.rs:5:1
|
--> $DIR/super-traits.rs:7:1
|
||||||
|
|
|
|
||||||
LL | #[const_trait]
|
LL | #[const_trait]
|
||||||
| ^^^^^^^^^^^^^^ required by this bound in `Foo::a`
|
| ^^^^^^^^^^^^^^ required by this bound in `Foo::a`
|
||||||
|
@ -26,6 +17,6 @@ help: consider further restricting the associated type
|
||||||
LL | const fn foo<T: ~const Bar>(t: &T) where Foo::{synthetic#0}: ~const Compat {
|
LL | const fn foo<T: ~const Bar>(t: &T) where Foo::{synthetic#0}: ~const Compat {
|
||||||
| +++++++++++++++++++++++++++++++++++++++
|
| +++++++++++++++++++++++++++++++++++++++
|
||||||
|
|
||||||
error: aborting due to 1 previous error; 1 warning emitted
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0277`.
|
For more information about this error, try `rustc --explain E0277`.
|
||||||
|
|
Loading…
Reference in New Issue