mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-23 07:14:28 +00:00
Allow to self reference associated types in where clauses
This commit is contained in:
parent
24dcf6f7a2
commit
2ca4964db5
@ -4,6 +4,7 @@ use crate::traits::{Obligation, ObligationCause, PredicateObligation};
|
|||||||
use rustc_data_structures::fx::FxHashSet;
|
use rustc_data_structures::fx::FxHashSet;
|
||||||
use rustc_middle::ty::outlives::Component;
|
use rustc_middle::ty::outlives::Component;
|
||||||
use rustc_middle::ty::{self, ToPredicate, TyCtxt, WithConstness};
|
use rustc_middle::ty::{self, ToPredicate, TyCtxt, WithConstness};
|
||||||
|
use rustc_span::symbol::Ident;
|
||||||
|
|
||||||
pub fn anonymize_predicate<'tcx>(
|
pub fn anonymize_predicate<'tcx>(
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
@ -89,6 +90,32 @@ pub fn elaborate_trait_refs<'tcx>(
|
|||||||
elaborate_predicates(tcx, predicates)
|
elaborate_predicates(tcx, predicates)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn elaborate_trait_refs_that_define_assoc_type<'tcx>(
|
||||||
|
tcx: TyCtxt<'tcx>,
|
||||||
|
trait_refs: impl Iterator<Item = ty::PolyTraitRef<'tcx>>,
|
||||||
|
assoc_name: Ident,
|
||||||
|
) -> FxHashSet<ty::PolyTraitRef<'tcx>> {
|
||||||
|
let mut stack: Vec<_> = trait_refs.collect();
|
||||||
|
let mut trait_refs = FxHashSet::default();
|
||||||
|
|
||||||
|
while let Some(trait_ref) = stack.pop() {
|
||||||
|
if trait_refs.insert(trait_ref) {
|
||||||
|
let super_predicates =
|
||||||
|
tcx.super_predicates_that_define_assoc_type((trait_ref.def_id(), Some(assoc_name)));
|
||||||
|
for (super_predicate, _) in super_predicates.predicates {
|
||||||
|
let bound_predicate = super_predicate.bound_atom();
|
||||||
|
let subst_predicate = super_predicate
|
||||||
|
.subst_supertrait(tcx, &bound_predicate.rebind(trait_ref.skip_binder()));
|
||||||
|
if let Some(binder) = subst_predicate.to_opt_poly_trait_ref() {
|
||||||
|
stack.push(binder.value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
trait_refs
|
||||||
|
}
|
||||||
|
|
||||||
pub fn elaborate_predicates<'tcx>(
|
pub fn elaborate_predicates<'tcx>(
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
predicates: impl Iterator<Item = ty::Predicate<'tcx>>,
|
predicates: impl Iterator<Item = ty::Predicate<'tcx>>,
|
||||||
@ -287,6 +314,14 @@ pub fn transitive_bounds<'tcx>(
|
|||||||
elaborate_trait_refs(tcx, bounds).filter_to_traits()
|
elaborate_trait_refs(tcx, bounds).filter_to_traits()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn transitive_bounds_that_define_assoc_type<'tcx>(
|
||||||
|
tcx: TyCtxt<'tcx>,
|
||||||
|
bounds: impl Iterator<Item = ty::PolyTraitRef<'tcx>>,
|
||||||
|
assoc_name: Ident,
|
||||||
|
) -> FxHashSet<ty::PolyTraitRef<'tcx>> {
|
||||||
|
elaborate_trait_refs_that_define_assoc_type(tcx, bounds, assoc_name)
|
||||||
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
// Other
|
// Other
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -436,6 +436,16 @@ rustc_queries! {
|
|||||||
desc { |tcx| "computing the supertraits of `{}`", tcx.def_path_str(key) }
|
desc { |tcx| "computing the supertraits of `{}`", tcx.def_path_str(key) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Maps from the `DefId` of a trait to the list of
|
||||||
|
/// super-predicates. This is a subset of the full list of
|
||||||
|
/// predicates. We store these in a separate map because we must
|
||||||
|
/// evaluate them even during type conversion, often before the
|
||||||
|
/// full predicates are available (note that supertraits have
|
||||||
|
/// additional acyclicity requirements).
|
||||||
|
query super_predicates_that_define_assoc_type(key: (DefId, Option<rustc_span::symbol::Ident>)) -> ty::GenericPredicates<'tcx> {
|
||||||
|
desc { |tcx| "computing the supertraits of `{}`", tcx.def_path_str(key.0) }
|
||||||
|
}
|
||||||
|
|
||||||
/// To avoid cycles within the predicates of a single item we compute
|
/// To avoid cycles within the predicates of a single item we compute
|
||||||
/// per-type-parameter predicates for resolving `T::AssocTy`.
|
/// per-type-parameter predicates for resolving `T::AssocTy`.
|
||||||
query type_param_predicates(key: (DefId, LocalDefId, rustc_span::symbol::Ident)) -> ty::GenericPredicates<'tcx> {
|
query type_param_predicates(key: (DefId, LocalDefId, rustc_span::symbol::Ident)) -> ty::GenericPredicates<'tcx> {
|
||||||
|
@ -149,6 +149,17 @@ impl Key for (LocalDefId, DefId) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Key for (DefId, Option<Ident>) {
|
||||||
|
type CacheSelector = DefaultCacheSelector;
|
||||||
|
|
||||||
|
fn query_crate(&self) -> CrateNum {
|
||||||
|
self.0.krate
|
||||||
|
}
|
||||||
|
fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
|
||||||
|
tcx.def_span(self.0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Key for (DefId, LocalDefId, Ident) {
|
impl Key for (DefId, LocalDefId, Ident) {
|
||||||
type CacheSelector = DefaultCacheSelector;
|
type CacheSelector = DefaultCacheSelector;
|
||||||
|
|
||||||
|
@ -65,7 +65,8 @@ pub use self::util::{
|
|||||||
get_vtable_index_of_object_method, impl_item_is_final, predicate_for_trait_def, upcast_choices,
|
get_vtable_index_of_object_method, impl_item_is_final, predicate_for_trait_def, upcast_choices,
|
||||||
};
|
};
|
||||||
pub use self::util::{
|
pub use self::util::{
|
||||||
supertrait_def_ids, supertraits, transitive_bounds, SupertraitDefIds, Supertraits,
|
supertrait_def_ids, supertraits, transitive_bounds, transitive_bounds_that_define_assoc_type,
|
||||||
|
SupertraitDefIds, Supertraits,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub use self::chalk_fulfill::FulfillmentContext as ChalkFulfillmentContext;
|
pub use self::chalk_fulfill::FulfillmentContext as ChalkFulfillmentContext;
|
||||||
|
@ -6,6 +6,7 @@ mod errors;
|
|||||||
mod generics;
|
mod generics;
|
||||||
|
|
||||||
use crate::bounds::Bounds;
|
use crate::bounds::Bounds;
|
||||||
|
use crate::collect::super_traits_of;
|
||||||
use crate::collect::PlaceholderHirTyCollector;
|
use crate::collect::PlaceholderHirTyCollector;
|
||||||
use crate::errors::{
|
use crate::errors::{
|
||||||
AmbiguousLifetimeBound, MultipleRelaxedDefaultBounds, TraitObjectDeclaredWithNoTraits,
|
AmbiguousLifetimeBound, MultipleRelaxedDefaultBounds, TraitObjectDeclaredWithNoTraits,
|
||||||
@ -768,7 +769,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Returns `true` if a bounds list includes `?Sized`.
|
// Returns `true` if a bounds list includes `?Sized`.
|
||||||
pub fn is_unsized(&self, ast_bounds: &[hir::GenericBound<'_>], span: Span) -> bool {
|
pub fn is_unsized(&self, ast_bounds: &[&hir::GenericBound<'_>], span: Span) -> bool {
|
||||||
let tcx = self.tcx();
|
let tcx = self.tcx();
|
||||||
|
|
||||||
// Try to find an unbound in bounds.
|
// Try to find an unbound in bounds.
|
||||||
@ -826,7 +827,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||||||
fn add_bounds(
|
fn add_bounds(
|
||||||
&self,
|
&self,
|
||||||
param_ty: Ty<'tcx>,
|
param_ty: Ty<'tcx>,
|
||||||
ast_bounds: &[hir::GenericBound<'_>],
|
ast_bounds: &[&hir::GenericBound<'_>],
|
||||||
bounds: &mut Bounds<'tcx>,
|
bounds: &mut Bounds<'tcx>,
|
||||||
) {
|
) {
|
||||||
let mut trait_bounds = Vec::new();
|
let mut trait_bounds = Vec::new();
|
||||||
@ -844,7 +845,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||||||
hir::GenericBound::Trait(_, hir::TraitBoundModifier::Maybe) => {}
|
hir::GenericBound::Trait(_, hir::TraitBoundModifier::Maybe) => {}
|
||||||
hir::GenericBound::LangItemTrait(lang_item, span, hir_id, args) => self
|
hir::GenericBound::LangItemTrait(lang_item, span, hir_id, args) => self
|
||||||
.instantiate_lang_item_trait_ref(
|
.instantiate_lang_item_trait_ref(
|
||||||
lang_item, span, hir_id, args, param_ty, bounds,
|
*lang_item, *span, *hir_id, args, param_ty, bounds,
|
||||||
),
|
),
|
||||||
hir::GenericBound::Outlives(ref l) => region_bounds.push(l),
|
hir::GenericBound::Outlives(ref l) => region_bounds.push(l),
|
||||||
}
|
}
|
||||||
@ -878,7 +879,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||||||
pub fn compute_bounds(
|
pub fn compute_bounds(
|
||||||
&self,
|
&self,
|
||||||
param_ty: Ty<'tcx>,
|
param_ty: Ty<'tcx>,
|
||||||
ast_bounds: &[hir::GenericBound<'_>],
|
ast_bounds: &[&hir::GenericBound<'_>],
|
||||||
sized_by_default: SizedByDefault,
|
sized_by_default: SizedByDefault,
|
||||||
span: Span,
|
span: Span,
|
||||||
) -> Bounds<'tcx> {
|
) -> Bounds<'tcx> {
|
||||||
@ -896,6 +897,39 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||||||
bounds
|
bounds
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn compute_bounds_that_match_assoc_type(
|
||||||
|
&self,
|
||||||
|
param_ty: Ty<'tcx>,
|
||||||
|
ast_bounds: &[hir::GenericBound<'_>],
|
||||||
|
sized_by_default: SizedByDefault,
|
||||||
|
span: Span,
|
||||||
|
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() {
|
||||||
|
if let Some(trait_did) = trait_ref.trait_def_id() {
|
||||||
|
if super_traits_of(self.tcx(), trait_did).any(|trait_did| {
|
||||||
|
self.tcx()
|
||||||
|
.associated_items(trait_did)
|
||||||
|
.find_by_name_and_kind(
|
||||||
|
self.tcx(),
|
||||||
|
assoc_name,
|
||||||
|
ty::AssocKind::Type,
|
||||||
|
trait_did,
|
||||||
|
)
|
||||||
|
.is_some()
|
||||||
|
}) {
|
||||||
|
result.push(ast_bound);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
self.compute_bounds(param_ty, &result, sized_by_default, span)
|
||||||
|
}
|
||||||
|
|
||||||
/// Given an HIR binding like `Item = Foo` or `Item: Foo`, pushes the corresponding predicates
|
/// Given an HIR binding like `Item = Foo` or `Item: Foo`, pushes the corresponding predicates
|
||||||
/// onto `bounds`.
|
/// onto `bounds`.
|
||||||
///
|
///
|
||||||
@ -1050,7 +1084,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||||||
// Calling `skip_binder` is okay, because `add_bounds` expects the `param_ty`
|
// Calling `skip_binder` is okay, because `add_bounds` expects the `param_ty`
|
||||||
// parameter to have a skipped binder.
|
// parameter to have a skipped binder.
|
||||||
let param_ty = tcx.mk_projection(assoc_ty.def_id, candidate.skip_binder().substs);
|
let param_ty = tcx.mk_projection(assoc_ty.def_id, candidate.skip_binder().substs);
|
||||||
self.add_bounds(param_ty, ast_bounds, bounds);
|
let ast_bounds: Vec<_> = ast_bounds.iter().collect();
|
||||||
|
self.add_bounds(param_ty, &ast_bounds, bounds);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -1377,12 +1412,14 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||||||
let param_name = tcx.hir().ty_param_name(param_hir_id);
|
let param_name = tcx.hir().ty_param_name(param_hir_id);
|
||||||
self.one_bound_for_assoc_type(
|
self.one_bound_for_assoc_type(
|
||||||
|| {
|
|| {
|
||||||
traits::transitive_bounds(
|
traits::transitive_bounds_that_define_assoc_type(
|
||||||
tcx,
|
tcx,
|
||||||
predicates.iter().filter_map(|(p, _)| {
|
predicates.iter().filter_map(|(p, _)| {
|
||||||
p.to_opt_poly_trait_ref().map(|trait_ref| trait_ref.value)
|
p.to_opt_poly_trait_ref().map(|trait_ref| trait_ref.value)
|
||||||
}),
|
}),
|
||||||
|
assoc_name,
|
||||||
)
|
)
|
||||||
|
.into_iter()
|
||||||
},
|
},
|
||||||
|| param_name.to_string(),
|
|| param_name.to_string(),
|
||||||
assoc_name,
|
assoc_name,
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
// ignore-tidy-filelength
|
||||||
//! "Collection" is the process of determining the type and other external
|
//! "Collection" is the process of determining the type and other external
|
||||||
//! details of each item in Rust. Collection is specifically concerned
|
//! details of each item in Rust. Collection is specifically concerned
|
||||||
//! with *inter-procedural* things -- for example, for a function
|
//! with *inter-procedural* things -- for example, for a function
|
||||||
@ -79,6 +80,7 @@ pub fn provide(providers: &mut Providers) {
|
|||||||
projection_ty_from_predicates,
|
projection_ty_from_predicates,
|
||||||
explicit_predicates_of,
|
explicit_predicates_of,
|
||||||
super_predicates_of,
|
super_predicates_of,
|
||||||
|
super_predicates_that_define_assoc_type,
|
||||||
trait_explicit_predicates_and_bounds,
|
trait_explicit_predicates_and_bounds,
|
||||||
type_param_predicates,
|
type_param_predicates,
|
||||||
trait_def,
|
trait_def,
|
||||||
@ -651,17 +653,10 @@ impl ItemCtxt<'tcx> {
|
|||||||
hir::GenericBound::Trait(poly_trait_ref, _) => {
|
hir::GenericBound::Trait(poly_trait_ref, _) => {
|
||||||
let trait_ref = &poly_trait_ref.trait_ref;
|
let trait_ref = &poly_trait_ref.trait_ref;
|
||||||
let trait_did = trait_ref.trait_def_id().unwrap();
|
let trait_did = trait_ref.trait_def_id().unwrap();
|
||||||
let traits_did = super_traits_of(self.tcx, trait_did);
|
super_traits_of(self.tcx, trait_did).any(|trait_did| {
|
||||||
|
|
||||||
traits_did.iter().any(|trait_did| {
|
|
||||||
self.tcx
|
self.tcx
|
||||||
.associated_items(*trait_did)
|
.associated_items(trait_did)
|
||||||
.find_by_name_and_kind(
|
.find_by_name_and_kind(self.tcx, assoc_name, ty::AssocKind::Type, trait_did)
|
||||||
self.tcx,
|
|
||||||
assoc_name,
|
|
||||||
ty::AssocKind::Type,
|
|
||||||
*trait_did,
|
|
||||||
)
|
|
||||||
.is_some()
|
.is_some()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -1035,6 +1030,22 @@ fn adt_def(tcx: TyCtxt<'_>, def_id: DefId) -> &ty::AdtDef {
|
|||||||
/// the transitive super-predicates are converted.
|
/// the transitive super-predicates are converted.
|
||||||
fn super_predicates_of(tcx: TyCtxt<'_>, trait_def_id: DefId) -> ty::GenericPredicates<'_> {
|
fn super_predicates_of(tcx: TyCtxt<'_>, trait_def_id: DefId) -> ty::GenericPredicates<'_> {
|
||||||
debug!("super_predicates(trait_def_id={:?})", trait_def_id);
|
debug!("super_predicates(trait_def_id={:?})", trait_def_id);
|
||||||
|
tcx.super_predicates_that_define_assoc_type((trait_def_id, None))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 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.
|
||||||
|
fn super_predicates_that_define_assoc_type(
|
||||||
|
tcx: TyCtxt<'_>,
|
||||||
|
(trait_def_id, assoc_name): (DefId, Option<Ident>),
|
||||||
|
) -> ty::GenericPredicates<'_> {
|
||||||
|
debug!(
|
||||||
|
"super_predicates_that_define_assoc_type(trait_def_id={:?}, assoc_name={:?})",
|
||||||
|
trait_def_id, assoc_name
|
||||||
|
);
|
||||||
|
if trait_def_id.is_local() {
|
||||||
|
debug!("super_predicates_that_define_assoc_type: local trait_def_id={:?}", trait_def_id);
|
||||||
let trait_hir_id = tcx.hir().local_def_id_to_hir_id(trait_def_id.expect_local());
|
let trait_hir_id = tcx.hir().local_def_id_to_hir_id(trait_def_id.expect_local());
|
||||||
|
|
||||||
let item = match tcx.hir().get(trait_hir_id) {
|
let item = match tcx.hir().get(trait_hir_id) {
|
||||||
@ -1052,8 +1063,19 @@ fn super_predicates_of(tcx: TyCtxt<'_>, trait_def_id: DefId) -> ty::GenericPredi
|
|||||||
|
|
||||||
// Convert the bounds that follow the colon, e.g., `Bar + Zed` in `trait Foo: Bar + Zed`.
|
// Convert the bounds that follow the colon, e.g., `Bar + Zed` in `trait Foo: Bar + Zed`.
|
||||||
let self_param_ty = tcx.types.self_param;
|
let self_param_ty = tcx.types.self_param;
|
||||||
let superbounds1 =
|
let superbounds1 = if let Some(assoc_name) = assoc_name {
|
||||||
AstConv::compute_bounds(&icx, self_param_ty, bounds, SizedByDefault::No, item.span);
|
AstConv::compute_bounds_that_match_assoc_type(
|
||||||
|
&icx,
|
||||||
|
self_param_ty,
|
||||||
|
&bounds,
|
||||||
|
SizedByDefault::No,
|
||||||
|
item.span,
|
||||||
|
assoc_name,
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
let bounds: Vec<_> = bounds.iter().collect();
|
||||||
|
AstConv::compute_bounds(&icx, self_param_ty, &bounds, SizedByDefault::No, item.span)
|
||||||
|
};
|
||||||
|
|
||||||
let superbounds1 = superbounds1.predicates(tcx, self_param_ty);
|
let superbounds1 = superbounds1.predicates(tcx, self_param_ty);
|
||||||
|
|
||||||
@ -1068,7 +1090,7 @@ fn super_predicates_of(tcx: TyCtxt<'_>, trait_def_id: DefId) -> ty::GenericPredi
|
|||||||
item.hir_id,
|
item.hir_id,
|
||||||
self_param_ty,
|
self_param_ty,
|
||||||
OnlySelfBounds(!is_trait_alias),
|
OnlySelfBounds(!is_trait_alias),
|
||||||
None,
|
assoc_name,
|
||||||
);
|
);
|
||||||
|
|
||||||
// Combine the two lists to form the complete set of superbounds:
|
// Combine the two lists to form the complete set of superbounds:
|
||||||
@ -1076,14 +1098,23 @@ fn super_predicates_of(tcx: TyCtxt<'_>, trait_def_id: DefId) -> ty::GenericPredi
|
|||||||
|
|
||||||
// Now require that immediate supertraits are converted,
|
// Now require that immediate supertraits are converted,
|
||||||
// which will, in turn, reach indirect supertraits.
|
// which will, in turn, reach indirect supertraits.
|
||||||
|
if assoc_name.is_none() {
|
||||||
|
// FIXME: move this into the `super_predicates_of` query
|
||||||
for &(pred, span) in superbounds {
|
for &(pred, span) in superbounds {
|
||||||
debug!("superbound: {:?}", pred);
|
debug!("superbound: {:?}", pred);
|
||||||
if let ty::PredicateAtom::Trait(bound, _) = pred.skip_binders() {
|
if let ty::PredicateAtom::Trait(bound, _) = pred.skip_binders() {
|
||||||
tcx.at(span).super_predicates_of(bound.def_id());
|
tcx.at(span).super_predicates_of(bound.def_id());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ty::GenericPredicates { parent: None, predicates: superbounds }
|
ty::GenericPredicates { parent: None, predicates: superbounds }
|
||||||
|
} else {
|
||||||
|
// if `assoc_name` is None, then the query should've been redirected to an
|
||||||
|
// external provider
|
||||||
|
assert!(assoc_name.is_some());
|
||||||
|
tcx.super_predicates_of(trait_def_id)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn super_traits_of(tcx: TyCtxt<'_>, trait_def_id: DefId) -> impl Iterator<Item = DefId> {
|
pub fn super_traits_of(tcx: TyCtxt<'_>, trait_def_id: DefId) -> impl Iterator<Item = DefId> {
|
||||||
@ -1123,6 +1154,8 @@ pub fn super_traits_of(tcx: TyCtxt<'_>, trait_def_id: DefId) -> impl Iterator<It
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
set.into_iter()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn trait_def(tcx: TyCtxt<'_>, def_id: DefId) -> ty::TraitDef {
|
fn trait_def(tcx: TyCtxt<'_>, def_id: DefId) -> ty::TraitDef {
|
||||||
@ -1976,8 +2009,8 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericP
|
|||||||
index += 1;
|
index += 1;
|
||||||
|
|
||||||
let sized = SizedByDefault::Yes;
|
let sized = SizedByDefault::Yes;
|
||||||
let bounds =
|
let bounds: Vec<_> = param.bounds.iter().collect();
|
||||||
AstConv::compute_bounds(&icx, param_ty, ¶m.bounds, sized, param.span);
|
let bounds = AstConv::compute_bounds(&icx, param_ty, &bounds, sized, param.span);
|
||||||
predicates.extend(bounds.predicates(tcx, param_ty));
|
predicates.extend(bounds.predicates(tcx, param_ty));
|
||||||
}
|
}
|
||||||
GenericParamKind::Const { .. } => {
|
GenericParamKind::Const { .. } => {
|
||||||
|
@ -25,10 +25,11 @@ fn associated_type_bounds<'tcx>(
|
|||||||
InternalSubsts::identity_for_item(tcx, assoc_item_def_id),
|
InternalSubsts::identity_for_item(tcx, assoc_item_def_id),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
let bounds: Vec<_> = bounds.iter().collect();
|
||||||
let bounds = AstConv::compute_bounds(
|
let bounds = AstConv::compute_bounds(
|
||||||
&ItemCtxt::new(tcx, assoc_item_def_id),
|
&ItemCtxt::new(tcx, assoc_item_def_id),
|
||||||
item_ty,
|
item_ty,
|
||||||
bounds,
|
&bounds,
|
||||||
SizedByDefault::Yes,
|
SizedByDefault::Yes,
|
||||||
span,
|
span,
|
||||||
);
|
);
|
||||||
@ -65,10 +66,11 @@ fn opaque_type_bounds<'tcx>(
|
|||||||
let item_ty =
|
let item_ty =
|
||||||
tcx.mk_opaque(opaque_def_id, InternalSubsts::identity_for_item(tcx, opaque_def_id));
|
tcx.mk_opaque(opaque_def_id, InternalSubsts::identity_for_item(tcx, opaque_def_id));
|
||||||
|
|
||||||
|
let bounds: Vec<_> = bounds.iter().collect();
|
||||||
let bounds = AstConv::compute_bounds(
|
let bounds = AstConv::compute_bounds(
|
||||||
&ItemCtxt::new(tcx, opaque_def_id),
|
&ItemCtxt::new(tcx, opaque_def_id),
|
||||||
item_ty,
|
item_ty,
|
||||||
bounds,
|
&bounds,
|
||||||
SizedByDefault::Yes,
|
SizedByDefault::Yes,
|
||||||
span,
|
span,
|
||||||
)
|
)
|
||||||
|
@ -0,0 +1,12 @@
|
|||||||
|
// check-pass
|
||||||
|
trait Foo {
|
||||||
|
type Bar;
|
||||||
|
}
|
||||||
|
trait Qux: Foo + AsRef<Self::Bar> {}
|
||||||
|
trait Foo2 {}
|
||||||
|
|
||||||
|
trait Qux2: Foo2 + AsRef<Self::Bar> {
|
||||||
|
type Bar;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
Loading…
Reference in New Issue
Block a user