Use PredicateFilter instead of OnlySelfBounds
This commit is contained in:
parent
a2a1206811
commit
9989b1b0d5
@ -9,7 +9,7 @@
|
|||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
use rustc_span::def_id::DefId;
|
use rustc_span::def_id::DefId;
|
||||||
|
|
||||||
use crate::hir_ty_lowering::OnlySelfBounds;
|
use crate::hir_ty_lowering::PredicateFilter;
|
||||||
|
|
||||||
/// Collects together a list of type bounds. These lists of bounds occur in many places
|
/// Collects together a list of type bounds. These lists of bounds occur in many places
|
||||||
/// in Rust's syntax:
|
/// in Rust's syntax:
|
||||||
@ -52,7 +52,7 @@ pub(crate) fn push_trait_bound(
|
|||||||
span: Span,
|
span: Span,
|
||||||
polarity: ty::PredicatePolarity,
|
polarity: ty::PredicatePolarity,
|
||||||
constness: ty::BoundConstness,
|
constness: ty::BoundConstness,
|
||||||
only_self_bounds: OnlySelfBounds,
|
predicate_filter: PredicateFilter,
|
||||||
) {
|
) {
|
||||||
let clause = (
|
let clause = (
|
||||||
bound_trait_ref
|
bound_trait_ref
|
||||||
@ -72,9 +72,18 @@ pub(crate) fn push_trait_bound(
|
|||||||
// FIXME(effects): Lift this out of `push_trait_bound`, and move it somewhere else.
|
// FIXME(effects): Lift this out of `push_trait_bound`, and move it somewhere else.
|
||||||
// Perhaps moving this into `lower_poly_trait_ref`, just like we lower associated
|
// Perhaps moving this into `lower_poly_trait_ref`, just like we lower associated
|
||||||
// type bounds.
|
// type bounds.
|
||||||
if !tcx.features().effects || only_self_bounds.0 {
|
if !tcx.features().effects {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
match predicate_filter {
|
||||||
|
PredicateFilter::SelfOnly | PredicateFilter::SelfThatDefines(_) => {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
PredicateFilter::All | PredicateFilter::SelfAndAssociatedTypeBounds => {
|
||||||
|
// Ok.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 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.
|
||||||
let compat_val = match (tcx.def_kind(defining_def_id), constness) {
|
let compat_val = match (tcx.def_kind(defining_def_id), constness) {
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
use crate::collect::ItemCtxt;
|
use crate::collect::ItemCtxt;
|
||||||
use crate::constrained_generic_params as cgp;
|
use crate::constrained_generic_params as cgp;
|
||||||
use crate::delegation::inherit_predicates_for_delegation_item;
|
use crate::delegation::inherit_predicates_for_delegation_item;
|
||||||
use crate::hir_ty_lowering::{HirTyLowerer, OnlySelfBounds, PredicateFilter, RegionInferReason};
|
use crate::hir_ty_lowering::{HirTyLowerer, PredicateFilter, RegionInferReason};
|
||||||
|
|
||||||
/// Returns a list of all type predicates (explicit and implicit) for the definition with
|
/// Returns a list of all type predicates (explicit and implicit) for the definition with
|
||||||
/// ID `def_id`. This includes all predicates returned by `explicit_predicates_of`, plus
|
/// ID `def_id`. This includes all predicates returned by `explicit_predicates_of`, plus
|
||||||
@ -270,7 +270,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
|
|||||||
bound_pred.bounds.iter(),
|
bound_pred.bounds.iter(),
|
||||||
&mut bounds,
|
&mut bounds,
|
||||||
bound_vars,
|
bound_vars,
|
||||||
OnlySelfBounds(false),
|
PredicateFilter::All,
|
||||||
);
|
);
|
||||||
predicates.extend(bounds.clauses(tcx));
|
predicates.extend(bounds.clauses(tcx));
|
||||||
effects_min_tys.extend(bounds.effects_min_tys());
|
effects_min_tys.extend(bounds.effects_min_tys());
|
||||||
@ -825,20 +825,6 @@ fn probe_ty_param_bounds_in_generics(
|
|||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Subtle: If we're collecting `SelfAndAssociatedTypeBounds`, then we
|
|
||||||
// want to only consider predicates with `Self: ...`, but we don't want
|
|
||||||
// `OnlySelfBounds(true)` since we want to collect the nested associated
|
|
||||||
// type bound as well.
|
|
||||||
let (only_self_bounds, assoc_name) = match filter {
|
|
||||||
PredicateFilter::All | PredicateFilter::SelfAndAssociatedTypeBounds => {
|
|
||||||
(OnlySelfBounds(false), None)
|
|
||||||
}
|
|
||||||
PredicateFilter::SelfOnly => (OnlySelfBounds(true), None),
|
|
||||||
PredicateFilter::SelfThatDefines(assoc_name) => {
|
|
||||||
(OnlySelfBounds(true), Some(assoc_name))
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let bound_ty = if predicate.is_param_bound(param_def_id.to_def_id()) {
|
let bound_ty = if predicate.is_param_bound(param_def_id.to_def_id()) {
|
||||||
ty
|
ty
|
||||||
} else if matches!(filter, PredicateFilter::All) {
|
} else if matches!(filter, PredicateFilter::All) {
|
||||||
@ -850,31 +836,13 @@ fn probe_ty_param_bounds_in_generics(
|
|||||||
let bound_vars = self.tcx.late_bound_vars(predicate.hir_id);
|
let bound_vars = self.tcx.late_bound_vars(predicate.hir_id);
|
||||||
self.lowerer().lower_poly_bounds(
|
self.lowerer().lower_poly_bounds(
|
||||||
bound_ty,
|
bound_ty,
|
||||||
predicate.bounds.iter().filter(|bound| {
|
predicate.bounds.iter(),
|
||||||
assoc_name
|
|
||||||
.map_or(true, |assoc_name| self.bound_defines_assoc_item(bound, assoc_name))
|
|
||||||
}),
|
|
||||||
&mut bounds,
|
&mut bounds,
|
||||||
bound_vars,
|
bound_vars,
|
||||||
only_self_bounds,
|
filter,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
bounds.clauses(self.tcx).collect()
|
bounds.clauses(self.tcx).collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[instrument(level = "trace", skip(self))]
|
|
||||||
fn bound_defines_assoc_item(&self, b: &hir::GenericBound<'_>, assoc_name: Ident) -> bool {
|
|
||||||
match b {
|
|
||||||
hir::GenericBound::Trait(poly_trait_ref) => {
|
|
||||||
let trait_ref = &poly_trait_ref.trait_ref;
|
|
||||||
if let Some(trait_did) = trait_ref.trait_def_id() {
|
|
||||||
self.tcx.trait_may_define_assoc_item(trait_did, assoc_name)
|
|
||||||
} else {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => false,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -19,9 +19,7 @@
|
|||||||
use super::errors::GenericsArgsErrExtend;
|
use super::errors::GenericsArgsErrExtend;
|
||||||
use crate::bounds::Bounds;
|
use crate::bounds::Bounds;
|
||||||
use crate::errors;
|
use crate::errors;
|
||||||
use crate::hir_ty_lowering::{
|
use crate::hir_ty_lowering::{AssocItemQSelf, HirTyLowerer, PredicateFilter, RegionInferReason};
|
||||||
AssocItemQSelf, HirTyLowerer, OnlySelfBounds, PredicateFilter, RegionInferReason,
|
|
||||||
};
|
|
||||||
|
|
||||||
impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||||
/// Add a `Sized` bound to the `bounds` if appropriate.
|
/// Add a `Sized` bound to the `bounds` if appropriate.
|
||||||
@ -150,11 +148,25 @@ pub(crate) fn lower_poly_bounds<'hir, I: Iterator<Item = &'hir hir::GenericBound
|
|||||||
hir_bounds: I,
|
hir_bounds: I,
|
||||||
bounds: &mut Bounds<'tcx>,
|
bounds: &mut Bounds<'tcx>,
|
||||||
bound_vars: &'tcx ty::List<ty::BoundVariableKind>,
|
bound_vars: &'tcx ty::List<ty::BoundVariableKind>,
|
||||||
only_self_bounds: OnlySelfBounds,
|
predicate_filter: PredicateFilter,
|
||||||
) where
|
) where
|
||||||
'tcx: 'hir,
|
'tcx: 'hir,
|
||||||
{
|
{
|
||||||
for hir_bound in hir_bounds {
|
for hir_bound in hir_bounds {
|
||||||
|
// In order to avoid cycles, when we're lowering `SelfThatDefines`,
|
||||||
|
// we skip over any traits that don't define the given associated type.
|
||||||
|
|
||||||
|
if let PredicateFilter::SelfThatDefines(assoc_name) = predicate_filter {
|
||||||
|
if let Some(trait_ref) = hir_bound.trait_ref()
|
||||||
|
&& let Some(trait_did) = trait_ref.trait_def_id()
|
||||||
|
&& self.tcx().trait_may_define_assoc_item(trait_did, assoc_name)
|
||||||
|
{
|
||||||
|
// Okay
|
||||||
|
} else {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
match hir_bound {
|
match hir_bound {
|
||||||
hir::GenericBound::Trait(poly_trait_ref) => {
|
hir::GenericBound::Trait(poly_trait_ref) => {
|
||||||
let (constness, polarity) = match poly_trait_ref.modifiers {
|
let (constness, polarity) = match poly_trait_ref.modifiers {
|
||||||
@ -179,7 +191,7 @@ pub(crate) fn lower_poly_bounds<'hir, I: Iterator<Item = &'hir hir::GenericBound
|
|||||||
polarity,
|
polarity,
|
||||||
param_ty,
|
param_ty,
|
||||||
bounds,
|
bounds,
|
||||||
only_self_bounds,
|
predicate_filter,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
hir::GenericBound::Outlives(lifetime) => {
|
hir::GenericBound::Outlives(lifetime) => {
|
||||||
@ -213,37 +225,16 @@ pub(crate) fn lower_mono_bounds(
|
|||||||
&self,
|
&self,
|
||||||
param_ty: Ty<'tcx>,
|
param_ty: Ty<'tcx>,
|
||||||
hir_bounds: &[hir::GenericBound<'tcx>],
|
hir_bounds: &[hir::GenericBound<'tcx>],
|
||||||
filter: PredicateFilter,
|
predicate_filter: PredicateFilter,
|
||||||
) -> Bounds<'tcx> {
|
) -> Bounds<'tcx> {
|
||||||
let mut bounds = Bounds::default();
|
let mut bounds = Bounds::default();
|
||||||
|
|
||||||
let only_self_bounds = match filter {
|
|
||||||
PredicateFilter::All | PredicateFilter::SelfAndAssociatedTypeBounds => {
|
|
||||||
OnlySelfBounds(false)
|
|
||||||
}
|
|
||||||
PredicateFilter::SelfOnly | PredicateFilter::SelfThatDefines(_) => OnlySelfBounds(true),
|
|
||||||
};
|
|
||||||
|
|
||||||
self.lower_poly_bounds(
|
self.lower_poly_bounds(
|
||||||
param_ty,
|
param_ty,
|
||||||
hir_bounds.iter().filter(|bound| match filter {
|
hir_bounds.iter(),
|
||||||
PredicateFilter::All
|
|
||||||
| PredicateFilter::SelfOnly
|
|
||||||
| PredicateFilter::SelfAndAssociatedTypeBounds => true,
|
|
||||||
PredicateFilter::SelfThatDefines(assoc_name) => {
|
|
||||||
if let Some(trait_ref) = bound.trait_ref()
|
|
||||||
&& let Some(trait_did) = trait_ref.trait_def_id()
|
|
||||||
&& self.tcx().trait_may_define_assoc_item(trait_did, assoc_name)
|
|
||||||
{
|
|
||||||
true
|
|
||||||
} else {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
&mut bounds,
|
&mut bounds,
|
||||||
ty::List::empty(),
|
ty::List::empty(),
|
||||||
only_self_bounds,
|
predicate_filter,
|
||||||
);
|
);
|
||||||
debug!(?bounds);
|
debug!(?bounds);
|
||||||
|
|
||||||
@ -267,7 +258,7 @@ pub(super) fn lower_assoc_item_constraint(
|
|||||||
bounds: &mut Bounds<'tcx>,
|
bounds: &mut Bounds<'tcx>,
|
||||||
duplicates: &mut FxIndexMap<DefId, Span>,
|
duplicates: &mut FxIndexMap<DefId, Span>,
|
||||||
path_span: Span,
|
path_span: Span,
|
||||||
only_self_bounds: OnlySelfBounds,
|
predicate_filter: PredicateFilter,
|
||||||
) -> Result<(), ErrorGuaranteed> {
|
) -> Result<(), ErrorGuaranteed> {
|
||||||
let tcx = self.tcx();
|
let tcx = self.tcx();
|
||||||
|
|
||||||
@ -444,24 +435,26 @@ pub(super) fn lower_assoc_item_constraint(
|
|||||||
// Lower a constraint like `Item: Debug` as found in HIR bound `T: Iterator<Item: Debug>`
|
// Lower a constraint like `Item: Debug` as found in HIR bound `T: Iterator<Item: Debug>`
|
||||||
// to a bound involving a projection: `<T as Iterator>::Item: Debug`.
|
// to a bound involving a projection: `<T as Iterator>::Item: Debug`.
|
||||||
hir::AssocItemConstraintKind::Bound { bounds: hir_bounds } => {
|
hir::AssocItemConstraintKind::Bound { bounds: hir_bounds } => {
|
||||||
// NOTE: If `only_self_bounds` is true, do NOT expand this associated type bound into
|
match predicate_filter {
|
||||||
// a trait predicate, since we only want to add predicates for the `Self` type.
|
PredicateFilter::SelfOnly | PredicateFilter::SelfThatDefines(_) => {}
|
||||||
if !only_self_bounds.0 {
|
PredicateFilter::All | PredicateFilter::SelfAndAssociatedTypeBounds => {
|
||||||
let projection_ty = projection_term
|
let projection_ty = projection_term
|
||||||
.map_bound(|projection_term| projection_term.expect_ty(self.tcx()));
|
.map_bound(|projection_term| projection_term.expect_ty(self.tcx()));
|
||||||
// Calling `skip_binder` is okay, because `lower_bounds` expects the `param_ty`
|
// Calling `skip_binder` is okay, because `lower_bounds` expects the `param_ty`
|
||||||
// parameter to have a skipped binder.
|
// parameter to have a skipped binder.
|
||||||
let param_ty = Ty::new_alias(tcx, ty::Projection, projection_ty.skip_binder());
|
let param_ty =
|
||||||
|
Ty::new_alias(tcx, ty::Projection, projection_ty.skip_binder());
|
||||||
self.lower_poly_bounds(
|
self.lower_poly_bounds(
|
||||||
param_ty,
|
param_ty,
|
||||||
hir_bounds.iter(),
|
hir_bounds.iter(),
|
||||||
bounds,
|
bounds,
|
||||||
projection_ty.bound_vars(),
|
projection_ty.bound_vars(),
|
||||||
only_self_bounds,
|
predicate_filter,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
use super::HirTyLowerer;
|
use super::HirTyLowerer;
|
||||||
use crate::bounds::Bounds;
|
use crate::bounds::Bounds;
|
||||||
use crate::hir_ty_lowering::{
|
use crate::hir_ty_lowering::{
|
||||||
GenericArgCountMismatch, GenericArgCountResult, OnlySelfBounds, RegionInferReason,
|
GenericArgCountMismatch, GenericArgCountResult, PredicateFilter, RegionInferReason,
|
||||||
};
|
};
|
||||||
|
|
||||||
impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||||
@ -55,9 +55,7 @@ pub(super) fn lower_trait_object_ty(
|
|||||||
ty::PredicatePolarity::Positive,
|
ty::PredicatePolarity::Positive,
|
||||||
dummy_self,
|
dummy_self,
|
||||||
&mut bounds,
|
&mut bounds,
|
||||||
// True so we don't populate `bounds` with associated type bounds, even
|
PredicateFilter::SelfOnly,
|
||||||
// though they're disallowed from object types.
|
|
||||||
OnlySelfBounds(true),
|
|
||||||
) {
|
) {
|
||||||
potential_assoc_types.extend(cur_potential_assoc_types);
|
potential_assoc_types.extend(cur_potential_assoc_types);
|
||||||
}
|
}
|
||||||
|
@ -64,9 +64,6 @@
|
|||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct GenericPathSegment(pub DefId, pub usize);
|
pub struct GenericPathSegment(pub DefId, pub usize);
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug)]
|
|
||||||
pub struct OnlySelfBounds(pub bool);
|
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug)]
|
#[derive(Copy, Clone, Debug)]
|
||||||
pub enum PredicateFilter {
|
pub enum PredicateFilter {
|
||||||
/// All predicates may be implied by the trait.
|
/// All predicates may be implied by the trait.
|
||||||
@ -76,7 +73,8 @@ pub enum PredicateFilter {
|
|||||||
SelfOnly,
|
SelfOnly,
|
||||||
|
|
||||||
/// Only traits that reference `Self: ..` and define an associated type
|
/// Only traits that reference `Self: ..` and define an associated type
|
||||||
/// with the given ident are implied by the trait.
|
/// with the given ident are implied by the trait. This mode exists to
|
||||||
|
/// side-step query cycles when lowering associated types.
|
||||||
SelfThatDefines(Ident),
|
SelfThatDefines(Ident),
|
||||||
|
|
||||||
/// Only traits that reference `Self: ..` and their associated type bounds.
|
/// Only traits that reference `Self: ..` and their associated type bounds.
|
||||||
@ -683,7 +681,7 @@ pub(crate) fn lower_poly_trait_ref(
|
|||||||
polarity: ty::PredicatePolarity,
|
polarity: ty::PredicatePolarity,
|
||||||
self_ty: Ty<'tcx>,
|
self_ty: Ty<'tcx>,
|
||||||
bounds: &mut Bounds<'tcx>,
|
bounds: &mut Bounds<'tcx>,
|
||||||
only_self_bounds: OnlySelfBounds,
|
predicate_filter: PredicateFilter,
|
||||||
) -> GenericArgCountResult {
|
) -> GenericArgCountResult {
|
||||||
let trait_def_id = trait_ref.trait_def_id().unwrap_or_else(|| FatalError.raise());
|
let trait_def_id = trait_ref.trait_def_id().unwrap_or_else(|| FatalError.raise());
|
||||||
let trait_segment = trait_ref.path.segments.last().unwrap();
|
let trait_segment = trait_ref.path.segments.last().unwrap();
|
||||||
@ -720,7 +718,7 @@ pub(crate) fn lower_poly_trait_ref(
|
|||||||
span,
|
span,
|
||||||
polarity,
|
polarity,
|
||||||
constness,
|
constness,
|
||||||
only_self_bounds,
|
predicate_filter,
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut dup_constraints = FxIndexMap::default();
|
let mut dup_constraints = FxIndexMap::default();
|
||||||
@ -744,7 +742,7 @@ pub(crate) fn lower_poly_trait_ref(
|
|||||||
bounds,
|
bounds,
|
||||||
&mut dup_constraints,
|
&mut dup_constraints,
|
||||||
constraint.span,
|
constraint.span,
|
||||||
only_self_bounds,
|
predicate_filter,
|
||||||
);
|
);
|
||||||
// Okay to ignore `Err` because of `ErrorGuaranteed` (see above).
|
// Okay to ignore `Err` because of `ErrorGuaranteed` (see above).
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user