Skip to content

Commit

Permalink
pass PredicateFilter to compute_bounds
Browse files Browse the repository at this point in the history
  • Loading branch information
compiler-errors committed Jun 27, 2023
1 parent 858a861 commit de0e7d3
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 72 deletions.
62 changes: 27 additions & 35 deletions compiler/rustc_hir_analysis/src/astconv/bounds.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@ use rustc_span::symbol::Ident;
use rustc_span::{ErrorGuaranteed, Span};
use rustc_trait_selection::traits;

use crate::astconv::{AstConv, ConvertedBinding, ConvertedBindingKind};
use crate::astconv::{
AstConv, ConvertedBinding, ConvertedBindingKind, OnlySelfBounds, PredicateFilter,
};
use crate::bounds::Bounds;
use crate::errors::{MultipleRelaxedDefaultBounds, ValueOfAssociatedStructAlreadySpecified};

use super::OnlySelfBounds;

impl<'tcx> dyn AstConv<'tcx> + '_ {
/// Sets `implicitly_sized` to true on `Bounds` if necessary
pub(crate) fn add_implicitly_sized(
Expand Down Expand Up @@ -176,47 +176,39 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
&self,
param_ty: Ty<'tcx>,
ast_bounds: &[hir::GenericBound<'_>],
only_self_bounds: OnlySelfBounds,
filter: PredicateFilter,
) -> Bounds<'tcx> {
let mut bounds = Bounds::default();
self.add_bounds(
param_ty,
ast_bounds.iter(),
&mut bounds,
ty::List::empty(),
only_self_bounds,
);
debug!(?bounds);

bounds
}

/// Convert the bounds in `ast_bounds` that refer to traits which define an associated type
/// named `assoc_name` into ty::Bounds. Ignore the rest.
pub(crate) fn compute_bounds_that_match_assoc_item(
&self,
param_ty: Ty<'tcx>,
ast_bounds: &[hir::GenericBound<'_>],
assoc_name: Ident,
) -> Bounds<'tcx> {
let mut result = Vec::new();

for ast_bound in ast_bounds {
if let Some(trait_ref) = ast_bound.trait_ref()
&& let Some(trait_did) = trait_ref.trait_def_id()
&& self.tcx().trait_may_define_assoc_item(trait_did, assoc_name)
{
result.push(ast_bound.clone());
let only_self_bounds = match filter {
PredicateFilter::All | PredicateFilter::SelfAndAssociatedTypeBounds => {
OnlySelfBounds(false)
}
}
PredicateFilter::SelfOnly | PredicateFilter::SelfThatDefines(_) => OnlySelfBounds(true),
};

let mut bounds = Bounds::default();
self.add_bounds(
param_ty,
result.iter(),
ast_bounds.iter().filter(|bound| {
match filter {
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,
ty::List::empty(),
OnlySelfBounds(true),
only_self_bounds,
);
debug!(?bounds);

Expand Down
18 changes: 18 additions & 0 deletions compiler/rustc_hir_analysis/src/astconv/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,24 @@ pub struct PathSeg(pub DefId, pub usize);
#[derive(Copy, Clone, Debug)]
pub struct OnlySelfBounds(pub bool);

#[derive(Copy, Clone, Debug)]
pub enum PredicateFilter {
/// All predicates may be implied by the trait.
All,

/// Only traits that reference `Self: ..` are implied by the trait.
SelfOnly,

/// Only traits that reference `Self: ..` and define an associated type
/// with the given ident are implied by the trait.
SelfThatDefines(Ident),

/// Only traits that reference `Self: ..` and their associated type bounds.
/// For example, given `Self: Tr<A: B>`, this would expand to `Self: Tr`
/// and `<Self as Tr>::A: B`.
SelfAndAssociatedTypeBounds,
}

pub trait AstConv<'tcx> {
fn tcx(&self) -> TyCtxt<'tcx>;

Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_hir_analysis/src/collect/item_bounds.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use super::ItemCtxt;
use crate::astconv::{AstConv, OnlySelfBounds};
use crate::astconv::{AstConv, PredicateFilter};
use rustc_hir as hir;
use rustc_infer::traits::util;
use rustc_middle::ty::subst::InternalSubsts;
Expand All @@ -26,7 +26,7 @@ fn associated_type_bounds<'tcx>(
);

let icx = ItemCtxt::new(tcx, assoc_item_def_id);
let mut bounds = icx.astconv().compute_bounds(item_ty, ast_bounds, OnlySelfBounds(false));
let mut bounds = icx.astconv().compute_bounds(item_ty, ast_bounds, PredicateFilter::All);
// Associated types are implicitly sized unless a `?Sized` bound is found
icx.astconv().add_implicitly_sized(&mut bounds, item_ty, ast_bounds, None, span);

Expand Down Expand Up @@ -68,7 +68,7 @@ fn opaque_type_bounds<'tcx>(
) -> &'tcx [(ty::Clause<'tcx>, Span)] {
ty::print::with_no_queries!({
let icx = ItemCtxt::new(tcx, opaque_def_id);
let mut bounds = icx.astconv().compute_bounds(item_ty, ast_bounds, OnlySelfBounds(false));
let mut bounds = icx.astconv().compute_bounds(item_ty, ast_bounds, PredicateFilter::All);
// Opaque types are implicitly sized unless a `?Sized` bound is found
icx.astconv().add_implicitly_sized(&mut bounds, item_ty, ast_bounds, None, span);
debug!(?bounds);
Expand Down
37 changes: 3 additions & 34 deletions compiler/rustc_hir_analysis/src/collect/predicates_of.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::astconv::{AstConv, OnlySelfBounds};
use crate::astconv::{AstConv, OnlySelfBounds, PredicateFilter};
use crate::bounds::Bounds;
use crate::collect::ItemCtxt;
use crate::constrained_generic_params as cgp;
Expand Down Expand Up @@ -125,7 +125,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
if let Some(self_bounds) = is_trait {
predicates.extend(
icx.astconv()
.compute_bounds(tcx.types.self_param, self_bounds, OnlySelfBounds(false))
.compute_bounds(tcx.types.self_param, self_bounds, PredicateFilter::All)
.clauses(),
);
}
Expand Down Expand Up @@ -530,24 +530,6 @@ pub(super) fn explicit_predicates_of<'tcx>(
}
}

#[derive(Copy, Clone, Debug)]
pub enum PredicateFilter {
/// All predicates may be implied by the trait.
All,

/// Only traits that reference `Self: ..` are implied by the trait.
SelfOnly,

/// Only traits that reference `Self: ..` and define an associated type
/// with the given ident are implied by the trait.
SelfThatDefines(Ident),

/// Only traits that reference `Self: ..` and their associated type bounds.
/// For example, given `Self: Tr<A: B>`, this would expand to `Self: Tr`
/// and `<Self as Tr>::A: B`.
SelfAndAssociatedTypeBounds,
}

/// Ensures that the super-predicates of the trait with a `DefId`
/// of `trait_def_id` are converted and stored. This also ensures that
/// the transitive super-predicates are converted.
Expand Down Expand Up @@ -610,20 +592,7 @@ pub(super) fn implied_predicates_with_filter(
let icx = ItemCtxt::new(tcx, trait_def_id);

let self_param_ty = tcx.types.self_param;
let superbounds = match filter {
// Should imply both "real" supertraits, and also associated type bounds
// from the supertraits position.
PredicateFilter::All | PredicateFilter::SelfAndAssociatedTypeBounds => {
icx.astconv().compute_bounds(self_param_ty, bounds, OnlySelfBounds(false))
}
// Should only imply "real" supertraits, i.e. predicates with the self type `Self`.
PredicateFilter::SelfOnly => {
icx.astconv().compute_bounds(self_param_ty, bounds, OnlySelfBounds(true))
}
PredicateFilter::SelfThatDefines(assoc_name) => {
icx.astconv().compute_bounds_that_match_assoc_item(self_param_ty, bounds, assoc_name)
}
};
let superbounds = icx.astconv().compute_bounds(self_param_ty, bounds, filter);

let where_bounds_that_match = icx.type_parameter_bounds_in_generics(
generics,
Expand Down

0 comments on commit de0e7d3

Please sign in to comment.