implement new effects desugaring
This commit is contained in:
parent
99f77a2eda
commit
72e8244e64
50 changed files with 636 additions and 228 deletions
|
@ -1,9 +1,13 @@
|
|||
//! Bounds are restrictions applied to some types after they've been lowered from the HIR to the
|
||||
//! [`rustc_middle::ty`] form.
|
||||
|
||||
use rustc_data_structures::fx::FxIndexMap;
|
||||
use rustc_hir::def::DefKind;
|
||||
use rustc_hir::LangItem;
|
||||
use rustc_middle::ty::fold::FnMutDelegate;
|
||||
use rustc_middle::ty::{self, Ty, TyCtxt, Upcast};
|
||||
use rustc_span::Span;
|
||||
use rustc_span::def_id::DefId;
|
||||
use rustc_span::{sym, Span};
|
||||
|
||||
/// Collects together a list of type bounds. These lists of bounds occur in many places
|
||||
/// in Rust's syntax:
|
||||
|
@ -24,6 +28,7 @@ use rustc_span::Span;
|
|||
#[derive(Default, PartialEq, Eq, Clone, Debug)]
|
||||
pub struct Bounds<'tcx> {
|
||||
clauses: Vec<(ty::Clause<'tcx>, Span)>,
|
||||
effects_min_tys: FxIndexMap<Ty<'tcx>, Span>,
|
||||
}
|
||||
|
||||
impl<'tcx> Bounds<'tcx> {
|
||||
|
@ -40,12 +45,14 @@ impl<'tcx> Bounds<'tcx> {
|
|||
pub fn push_trait_bound(
|
||||
&mut self,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
trait_ref: ty::PolyTraitRef<'tcx>,
|
||||
defining_def_id: DefId,
|
||||
bound_trait_ref: ty::PolyTraitRef<'tcx>,
|
||||
span: Span,
|
||||
polarity: ty::PredicatePolarity,
|
||||
constness: ty::BoundConstness,
|
||||
) {
|
||||
let clause = (
|
||||
trait_ref
|
||||
bound_trait_ref
|
||||
.map_bound(|trait_ref| {
|
||||
ty::ClauseKind::Trait(ty::TraitPredicate { trait_ref, polarity })
|
||||
})
|
||||
|
@ -53,11 +60,88 @@ impl<'tcx> Bounds<'tcx> {
|
|||
span,
|
||||
);
|
||||
// FIXME(-Znext-solver): We can likely remove this hack once the new trait solver lands.
|
||||
if tcx.is_lang_item(trait_ref.def_id(), LangItem::Sized) {
|
||||
if tcx.is_lang_item(bound_trait_ref.def_id(), LangItem::Sized) {
|
||||
self.clauses.insert(0, clause);
|
||||
} else {
|
||||
self.clauses.push(clause);
|
||||
}
|
||||
// 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) {
|
||||
// TODO: do we need `T: const Trait` anymore?
|
||||
(_, ty::BoundConstness::Const) => Some(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))
|
||||
}
|
||||
|
||||
(_, ty::BoundConstness::NotConst) => {
|
||||
tcx.has_attr(bound_trait_ref.def_id(), sym::const_trait).then_some(tcx.consts.true_)
|
||||
}
|
||||
|
||||
(
|
||||
DefKind::Trait | DefKind::Impl { of_trait: true },
|
||||
ty::BoundConstness::ConstIfConst,
|
||||
) => {
|
||||
// this is either a where clause on an impl/trait header or on a trait.
|
||||
// push `<T as Tr>::Effects` into the set for the `Min` bound.
|
||||
let Some(assoc) = tcx.associated_type_for_effects(bound_trait_ref.def_id()) else {
|
||||
tcx.dcx().span_delayed_bug(span, "`~const` on trait without Effects assoc");
|
||||
return;
|
||||
};
|
||||
|
||||
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>`.
|
||||
let ty = tcx.replace_bound_vars_uncached(
|
||||
ty,
|
||||
FnMutDelegate {
|
||||
regions: &mut |_| tcx.lifetimes.re_static,
|
||||
types: &mut |_| tcx.types.unit,
|
||||
consts: &mut |_| unimplemented!("`~const` does not support const binders"),
|
||||
},
|
||||
);
|
||||
|
||||
self.effects_min_tys.insert(ty, span);
|
||||
return;
|
||||
}
|
||||
// for
|
||||
// ```
|
||||
// trait Foo { type Bar: ~const Trait }
|
||||
// ```
|
||||
// ensure that `<Self::Bar as Trait>::Effects: TyCompat<Self::Effects>`.
|
||||
//
|
||||
// FIXME(effects) this is equality for now, which wouldn't be helpful for a non-const implementor
|
||||
// that uses a `Bar` that implements `Trait` with `Maybe` effects.
|
||||
(DefKind::AssocTy, ty::BoundConstness::ConstIfConst) => {
|
||||
// TODO write the actual impl
|
||||
return;
|
||||
}
|
||||
// probably illegal in this position.
|
||||
(_, ty::BoundConstness::ConstIfConst) => {
|
||||
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()],
|
||||
);
|
||||
self.clauses.push((bound_trait_ref.rebind(new_trait_ref).upcast(tcx), span));
|
||||
}
|
||||
}
|
||||
|
||||
pub fn push_projection_bound(
|
||||
|
@ -79,7 +163,15 @@ impl<'tcx> Bounds<'tcx> {
|
|||
self.clauses.insert(0, (trait_ref.upcast(tcx), span));
|
||||
}
|
||||
|
||||
pub fn clauses(&self) -> impl Iterator<Item = (ty::Clause<'tcx>, Span)> + '_ {
|
||||
pub fn clauses(
|
||||
&self,
|
||||
// TODO remove tcx
|
||||
_tcx: TyCtxt<'tcx>,
|
||||
) -> impl Iterator<Item = (ty::Clause<'tcx>, Span)> + '_ {
|
||||
self.clauses.iter().cloned()
|
||||
}
|
||||
|
||||
pub fn effects_min_tys(&self) -> impl Iterator<Item = Ty<'tcx>> + '_ {
|
||||
self.effects_min_tys.keys().copied()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -879,7 +879,7 @@ pub(super) fn check_specialization_validity<'tcx>(
|
|||
let result = opt_result.unwrap_or(Ok(()));
|
||||
|
||||
if let Err(parent_impl) = result {
|
||||
if !tcx.is_impl_trait_in_trait(impl_item) {
|
||||
if !tcx.is_impl_trait_in_trait(impl_item) && !tcx.is_effects_desugared_assoc_ty(impl_item) {
|
||||
report_forbidden_specialization(tcx, impl_item, parent_impl);
|
||||
} else {
|
||||
tcx.dcx().delayed_bug(format!("parent item: {parent_impl:?} not marked as default"));
|
||||
|
|
|
@ -1985,10 +1985,10 @@ pub(super) fn check_type_bounds<'tcx>(
|
|||
let infcx = tcx.infer_ctxt().build();
|
||||
let ocx = ObligationCtxt::new_with_diagnostics(&infcx);
|
||||
|
||||
// A synthetic impl Trait for RPITIT desugaring has no HIR, which we currently use to get the
|
||||
// span for an impl's associated type. Instead, for these, use the def_span for the synthesized
|
||||
// associated type.
|
||||
let impl_ty_span = if impl_ty.is_impl_trait_in_trait() {
|
||||
// A synthetic impl Trait for RPITIT desugaring or assoc type for effects desugaring has no HIR,
|
||||
// which we currently use to get the span for an impl's associated type. Instead, for these,
|
||||
// use the def_span for the synthesized associated type.
|
||||
let impl_ty_span = if impl_ty.is_impl_trait_in_trait() || impl_ty.is_effects_desugaring {
|
||||
tcx.def_span(impl_ty_def_id)
|
||||
} else {
|
||||
match tcx.hir_node_by_def_id(impl_ty_def_id) {
|
||||
|
|
|
@ -913,7 +913,12 @@ fn check_param_wf(tcx: TyCtxt<'_>, param: &hir::GenericParam<'_>) -> Result<(),
|
|||
hir::GenericParamKind::Lifetime { .. } | hir::GenericParamKind::Type { .. } => Ok(()),
|
||||
|
||||
// Const parameters are well formed if their type is structural match.
|
||||
hir::GenericParamKind::Const { ty: hir_ty, default: _, is_host_effect: _ } => {
|
||||
hir::GenericParamKind::Const {
|
||||
ty: hir_ty,
|
||||
default: _,
|
||||
is_host_effect: _,
|
||||
synthetic: _,
|
||||
} => {
|
||||
let ty = tcx.type_of(param.def_id).instantiate_identity();
|
||||
|
||||
if tcx.features().adt_const_params {
|
||||
|
|
|
@ -1638,44 +1638,19 @@ fn impl_trait_header(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<ty::ImplTrai
|
|||
let icx = ItemCtxt::new(tcx, def_id);
|
||||
let item = tcx.hir().expect_item(def_id);
|
||||
let impl_ = item.expect_impl();
|
||||
impl_
|
||||
.of_trait
|
||||
.as_ref()
|
||||
.map(|hir_trait_ref| {
|
||||
let self_ty = tcx.type_of(def_id).instantiate_identity();
|
||||
impl_.of_trait.as_ref().map(|ast_trait_ref| {
|
||||
let selfty = tcx.type_of(def_id).instantiate_identity();
|
||||
|
||||
let trait_ref = if let Some(ErrorGuaranteed { .. }) = check_impl_constness(
|
||||
tcx,
|
||||
tcx.is_const_trait_impl_raw(def_id.to_def_id()),
|
||||
hir_trait_ref,
|
||||
) {
|
||||
// we have a const impl, but for a trait without `#[const_trait]`, so
|
||||
// without the host param. If we continue with the HIR trait ref, we get
|
||||
// ICEs for generic arg count mismatch. We do a little HIR editing to
|
||||
// make HIR ty lowering happy.
|
||||
let mut path_segments = hir_trait_ref.path.segments.to_vec();
|
||||
let last_segment = path_segments.len() - 1;
|
||||
let mut args = *path_segments[last_segment].args();
|
||||
let last_arg = args.args.len() - 1;
|
||||
assert!(matches!(args.args[last_arg], hir::GenericArg::Const(anon_const) if anon_const.is_desugared_from_effects));
|
||||
args.args = &args.args[..args.args.len() - 1];
|
||||
path_segments[last_segment].args = Some(tcx.hir_arena.alloc(args));
|
||||
let path = hir::Path {
|
||||
span: hir_trait_ref.path.span,
|
||||
res: hir_trait_ref.path.res,
|
||||
segments: tcx.hir_arena.alloc_slice(&path_segments),
|
||||
};
|
||||
let trait_ref = tcx.hir_arena.alloc(hir::TraitRef { path: tcx.hir_arena.alloc(path), hir_ref_id: hir_trait_ref.hir_ref_id });
|
||||
icx.lowerer().lower_impl_trait_ref(trait_ref, self_ty)
|
||||
} else {
|
||||
icx.lowerer().lower_impl_trait_ref(hir_trait_ref, self_ty)
|
||||
};
|
||||
ty::ImplTraitHeader {
|
||||
trait_ref: ty::EarlyBinder::bind(trait_ref),
|
||||
safety: impl_.safety,
|
||||
polarity: polarity_of_impl(tcx, def_id, impl_, item.span)
|
||||
}
|
||||
})
|
||||
check_impl_constness(tcx, tcx.is_const_trait_impl_raw(def_id.to_def_id()), ast_trait_ref);
|
||||
|
||||
let trait_ref = icx.lowerer().lower_impl_trait_ref(ast_trait_ref, selfty);
|
||||
|
||||
ty::ImplTraitHeader {
|
||||
trait_ref: ty::EarlyBinder::bind(trait_ref),
|
||||
safety: impl_.safety,
|
||||
polarity: polarity_of_impl(tcx, def_id, impl_, item.span),
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn check_impl_constness(
|
||||
|
|
|
@ -354,7 +354,7 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
|
|||
kind,
|
||||
})
|
||||
}
|
||||
GenericParamKind::Const { ty: _, default, is_host_effect } => {
|
||||
GenericParamKind::Const { ty: _, default, is_host_effect, synthetic } => {
|
||||
if !matches!(allow_defaults, Defaults::Allowed)
|
||||
&& default.is_some()
|
||||
// `host` effect params are allowed to have defaults.
|
||||
|
@ -388,6 +388,7 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
|
|||
kind: ty::GenericParamDefKind::Const {
|
||||
has_default: default.is_some(),
|
||||
is_host_effect,
|
||||
synthetic,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
@ -541,7 +542,8 @@ struct AnonConstInParamTyDetector {
|
|||
|
||||
impl<'v> Visitor<'v> for AnonConstInParamTyDetector {
|
||||
fn visit_generic_param(&mut self, p: &'v hir::GenericParam<'v>) {
|
||||
if let GenericParamKind::Const { ty, default: _, is_host_effect: _ } = p.kind {
|
||||
if let GenericParamKind::Const { ty, default: _, is_host_effect: _, synthetic: _ } = p.kind
|
||||
{
|
||||
let prev = self.in_param_ty;
|
||||
self.in_param_ty = true;
|
||||
self.visit_ty(ty);
|
||||
|
|
|
@ -46,7 +46,7 @@ fn associated_type_bounds<'tcx>(
|
|||
}
|
||||
});
|
||||
|
||||
let all_bounds = tcx.arena.alloc_from_iter(bounds.clauses().chain(bounds_from_parent));
|
||||
let all_bounds = tcx.arena.alloc_from_iter(bounds.clauses(tcx).chain(bounds_from_parent));
|
||||
debug!(
|
||||
"associated_type_bounds({}) = {:?}",
|
||||
tcx.def_path_str(assoc_item_def_id.to_def_id()),
|
||||
|
@ -75,7 +75,7 @@ fn opaque_type_bounds<'tcx>(
|
|||
icx.lowerer().add_sized_bound(&mut bounds, item_ty, hir_bounds, None, span);
|
||||
debug!(?bounds);
|
||||
|
||||
tcx.arena.alloc_from_iter(bounds.clauses())
|
||||
tcx.arena.alloc_from_iter(bounds.clauses(tcx))
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -57,6 +57,7 @@ pub(super) fn predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericPredic
|
|||
#[instrument(level = "trace", skip(tcx), ret)]
|
||||
fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::GenericPredicates<'_> {
|
||||
use rustc_hir::*;
|
||||
use rustc_middle::ty::Ty; // to override hir::Ty
|
||||
|
||||
match tcx.opt_rpitit_info(def_id.to_def_id()) {
|
||||
Some(ImplTraitInTraitData::Trait { fn_def_id, .. }) => {
|
||||
|
@ -84,6 +85,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
|
|||
return ty::GenericPredicates {
|
||||
parent: Some(tcx.parent(def_id.to_def_id())),
|
||||
predicates: tcx.arena.alloc_from_iter(predicates),
|
||||
effects_min_tys: ty::List::empty(),
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -105,12 +107,43 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
|
|||
return ty::GenericPredicates {
|
||||
parent: Some(impl_def_id),
|
||||
predicates: tcx.arena.alloc_from_iter(impl_predicates),
|
||||
effects_min_tys: ty::List::empty(),
|
||||
};
|
||||
}
|
||||
|
||||
None => {}
|
||||
}
|
||||
|
||||
if tcx.is_effects_desugared_assoc_ty(def_id.to_def_id()) {
|
||||
let mut predicates = Vec::new();
|
||||
|
||||
// Inherit predicates of parent (impl or trait)
|
||||
let parent = tcx.local_parent(def_id);
|
||||
|
||||
let identity_args = ty::GenericArgs::identity_for_item(tcx, def_id);
|
||||
let preds = tcx.explicit_predicates_of(parent);
|
||||
predicates.extend(preds.instantiate_own(tcx, identity_args));
|
||||
if let ty::AssocItemContainer::TraitContainer = tcx.associated_item(def_id).container {
|
||||
// for traits, emit `type Effects: TyCompat<<(T1::Effects, ..) as Min>::Output>`
|
||||
// TODO do the same for impls
|
||||
let tup = Ty::new(tcx, ty::Tuple(preds.effects_min_tys));
|
||||
// TODO span
|
||||
let span = tcx.def_span(def_id);
|
||||
let assoc = tcx.require_lang_item(LangItem::EffectsMinOutput, Some(span));
|
||||
let proj = Ty::new_projection(tcx, assoc, [tup]);
|
||||
// TODO this is bad
|
||||
let self_proj = Ty::new_projection(tcx, def_id.to_def_id(), identity_args);
|
||||
let trait_ = tcx.require_lang_item(LangItem::EffectsTyCompat, Some(span));
|
||||
let trait_ref = ty::TraitRef::new(tcx, trait_, [self_proj, proj]);
|
||||
predicates.push((ty::Binder::dummy(trait_ref).upcast(tcx), span));
|
||||
}
|
||||
return ty::GenericPredicates {
|
||||
parent: Some(parent.to_def_id()),
|
||||
predicates: tcx.arena.alloc_from_iter(predicates),
|
||||
effects_min_tys: ty::List::empty(),
|
||||
};
|
||||
}
|
||||
|
||||
let hir_id = tcx.local_def_id_to_hir_id(def_id);
|
||||
let node = tcx.hir_node(hir_id);
|
||||
|
||||
|
@ -124,6 +157,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
|
|||
// We use an `IndexSet` to preserve order of insertion.
|
||||
// Preserving the order of insertion is important here so as not to break UI tests.
|
||||
let mut predicates: FxIndexSet<(ty::Clause<'_>, Span)> = FxIndexSet::default();
|
||||
let mut effects_min_tys = Vec::new();
|
||||
|
||||
let hir_generics = node.generics().unwrap_or(NO_GENERICS);
|
||||
if let Node::Item(item) = node {
|
||||
|
@ -150,11 +184,13 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
|
|||
// on a trait we must also consider the bounds that follow the trait's name,
|
||||
// like `trait Foo: A + B + C`.
|
||||
if let Some(self_bounds) = is_trait {
|
||||
predicates.extend(
|
||||
icx.lowerer()
|
||||
.lower_mono_bounds(tcx.types.self_param, self_bounds, PredicateFilter::All)
|
||||
.clauses(),
|
||||
let bounds = icx.lowerer().lower_mono_bounds(
|
||||
tcx.types.self_param,
|
||||
self_bounds,
|
||||
PredicateFilter::All,
|
||||
);
|
||||
predicates.extend(bounds.clauses(tcx));
|
||||
effects_min_tys.extend(bounds.effects_min_tys());
|
||||
}
|
||||
|
||||
// In default impls, we can assume that the self type implements
|
||||
|
@ -187,7 +223,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
|
|||
param.span,
|
||||
);
|
||||
trace!(?bounds);
|
||||
predicates.extend(bounds.clauses());
|
||||
predicates.extend(bounds.clauses(tcx));
|
||||
trace!(?predicates);
|
||||
}
|
||||
hir::GenericParamKind::Const { .. } => {
|
||||
|
@ -238,7 +274,8 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
|
|||
bound_vars,
|
||||
OnlySelfBounds(false),
|
||||
);
|
||||
predicates.extend(bounds.clauses());
|
||||
predicates.extend(bounds.clauses(tcx));
|
||||
effects_min_tys.extend(bounds.effects_min_tys());
|
||||
}
|
||||
|
||||
hir::WherePredicate::RegionPredicate(region_pred) => {
|
||||
|
@ -297,7 +334,8 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
|
|||
// and the duplicated parameter, to ensure that they do not get out of sync.
|
||||
if let Node::Item(&Item { kind: ItemKind::OpaqueTy(..), .. }) = node {
|
||||
let opaque_ty_node = tcx.parent_hir_node(hir_id);
|
||||
let Node::Ty(&Ty { kind: TyKind::OpaqueDef(_, lifetimes, _), .. }) = opaque_ty_node else {
|
||||
let Node::Ty(&hir::Ty { kind: TyKind::OpaqueDef(_, lifetimes, _), .. }) = opaque_ty_node
|
||||
else {
|
||||
bug!("unexpected {opaque_ty_node:?}")
|
||||
};
|
||||
debug!(?lifetimes);
|
||||
|
@ -309,6 +347,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
|
|||
ty::GenericPredicates {
|
||||
parent: generics.parent,
|
||||
predicates: tcx.arena.alloc_from_iter(predicates),
|
||||
effects_min_tys: tcx.mk_type_list(&effects_min_tys),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -459,6 +498,7 @@ pub(super) fn explicit_predicates_of<'tcx>(
|
|||
ty::GenericPredicates {
|
||||
parent: predicates_and_bounds.parent,
|
||||
predicates: tcx.arena.alloc_slice(&predicates),
|
||||
effects_min_tys: predicates_and_bounds.effects_min_tys,
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@ -510,6 +550,7 @@ pub(super) fn explicit_predicates_of<'tcx>(
|
|||
return GenericPredicates {
|
||||
parent: parent_preds.parent,
|
||||
predicates: { tcx.arena.alloc_from_iter(filtered_predicates) },
|
||||
effects_min_tys: parent_preds.effects_min_tys,
|
||||
};
|
||||
}
|
||||
gather_explicit_predicates_of(tcx, def_id)
|
||||
|
@ -587,7 +628,7 @@ pub(super) fn implied_predicates_with_filter(
|
|||
|
||||
// Combine the two lists to form the complete set of superbounds:
|
||||
let implied_bounds =
|
||||
&*tcx.arena.alloc_from_iter(superbounds.clauses().chain(where_bounds_that_match));
|
||||
&*tcx.arena.alloc_from_iter(superbounds.clauses(tcx).chain(where_bounds_that_match));
|
||||
debug!(?implied_bounds);
|
||||
|
||||
// Now require that immediate supertraits are lowered, which will, in
|
||||
|
@ -618,7 +659,11 @@ pub(super) fn implied_predicates_with_filter(
|
|||
_ => {}
|
||||
}
|
||||
|
||||
ty::GenericPredicates { parent: None, predicates: implied_bounds }
|
||||
ty::GenericPredicates {
|
||||
parent: None,
|
||||
predicates: implied_bounds,
|
||||
effects_min_tys: ty::List::empty(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the predicates defined on `item_def_id` of the form
|
||||
|
@ -744,7 +789,7 @@ impl<'tcx> ItemCtxt<'tcx> {
|
|||
);
|
||||
}
|
||||
|
||||
bounds.clauses().collect()
|
||||
bounds.clauses(self.tcx).collect()
|
||||
}
|
||||
|
||||
#[instrument(level = "trace", skip(self))]
|
||||
|
|
|
@ -951,7 +951,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
|
|||
self.visit_ty(ty);
|
||||
}
|
||||
}
|
||||
GenericParamKind::Const { ty, default, is_host_effect: _ } => {
|
||||
GenericParamKind::Const { ty, default, .. } => {
|
||||
self.visit_ty(ty);
|
||||
if let Some(default) = default {
|
||||
self.visit_body(self.tcx.hir().body(default.body));
|
||||
|
|
|
@ -256,6 +256,7 @@ pub fn lower_generic_args<'tcx: 'a, 'a>(
|
|||
| GenericParamDefKind::Lifetime,
|
||||
_,
|
||||
) => {
|
||||
// TODO: this should be removed
|
||||
// SPECIAL CASE FOR DESUGARED EFFECT PARAMS
|
||||
// This comes from the following example:
|
||||
//
|
||||
|
@ -445,7 +446,7 @@ pub(crate) fn check_generic_arg_count(
|
|||
.own_params
|
||||
.iter()
|
||||
.filter(|param| {
|
||||
matches!(param.kind, ty::GenericParamDefKind::Const { is_host_effect: true, .. })
|
||||
matches!(param.kind, ty::GenericParamDefKind::Const { synthetic: true, .. })
|
||||
})
|
||||
.count();
|
||||
let named_const_param_count = param_counts.consts - synth_const_param_count;
|
||||
|
|
|
@ -698,7 +698,14 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
);
|
||||
|
||||
debug!(?poly_trait_ref);
|
||||
bounds.push_trait_bound(tcx, poly_trait_ref, span, polarity);
|
||||
bounds.push_trait_bound(
|
||||
tcx,
|
||||
self.item_def_id().to_def_id(),
|
||||
poly_trait_ref,
|
||||
span,
|
||||
polarity,
|
||||
constness,
|
||||
);
|
||||
|
||||
let mut dup_constraints = FxIndexMap::default();
|
||||
for constraint in trait_segment.args().constraints {
|
||||
|
|
|
@ -59,7 +59,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
|
||||
let mut trait_bounds = vec![];
|
||||
let mut projection_bounds = vec![];
|
||||
for (pred, span) in bounds.clauses() {
|
||||
for (pred, span) in bounds.clauses(tcx) {
|
||||
let bound_pred = pred.kind();
|
||||
match bound_pred.skip_binder() {
|
||||
ty::ClauseKind::Trait(trait_pred) => {
|
||||
|
@ -133,7 +133,9 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
tcx.associated_items(pred.def_id())
|
||||
.in_definition_order()
|
||||
.filter(|item| item.kind == ty::AssocKind::Type)
|
||||
.filter(|item| !item.is_impl_trait_in_trait())
|
||||
.filter(|item| {
|
||||
!item.is_impl_trait_in_trait() && !item.is_effects_desugaring
|
||||
})
|
||||
.map(|item| item.def_id),
|
||||
);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue