Do not consider associated type bounds for super_predicates_that_define_assoc_type
This commit is contained in:
parent
0bcfff48a5
commit
8ea71f264e
5 changed files with 94 additions and 16 deletions
|
@ -56,6 +56,9 @@ use std::slice;
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct PathSeg(pub DefId, pub usize);
|
pub struct PathSeg(pub DefId, pub usize);
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Debug)]
|
||||||
|
pub struct OnlySelfBounds(pub bool);
|
||||||
|
|
||||||
pub trait AstConv<'tcx> {
|
pub trait AstConv<'tcx> {
|
||||||
fn tcx(&self) -> TyCtxt<'tcx>;
|
fn tcx(&self) -> TyCtxt<'tcx>;
|
||||||
|
|
||||||
|
@ -670,6 +673,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
args: &GenericArgs<'_>,
|
args: &GenericArgs<'_>,
|
||||||
infer_args: bool,
|
infer_args: bool,
|
||||||
self_ty: Ty<'tcx>,
|
self_ty: Ty<'tcx>,
|
||||||
|
only_self_bounds: OnlySelfBounds,
|
||||||
) -> GenericArgCountResult {
|
) -> GenericArgCountResult {
|
||||||
let (substs, arg_count) = self.create_substs_for_ast_path(
|
let (substs, arg_count) = self.create_substs_for_ast_path(
|
||||||
trait_ref_span,
|
trait_ref_span,
|
||||||
|
@ -706,6 +710,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
&mut dup_bindings,
|
&mut dup_bindings,
|
||||||
binding_span.unwrap_or(binding.span),
|
binding_span.unwrap_or(binding.span),
|
||||||
constness,
|
constness,
|
||||||
|
only_self_bounds,
|
||||||
);
|
);
|
||||||
// Okay to ignore `Err` because of `ErrorGuaranteed` (see above).
|
// Okay to ignore `Err` because of `ErrorGuaranteed` (see above).
|
||||||
}
|
}
|
||||||
|
@ -741,6 +746,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
self_ty: Ty<'tcx>,
|
self_ty: Ty<'tcx>,
|
||||||
bounds: &mut Bounds<'tcx>,
|
bounds: &mut Bounds<'tcx>,
|
||||||
speculative: bool,
|
speculative: bool,
|
||||||
|
only_self_bounds: OnlySelfBounds,
|
||||||
) -> GenericArgCountResult {
|
) -> GenericArgCountResult {
|
||||||
let hir_id = trait_ref.hir_ref_id;
|
let hir_id = trait_ref.hir_ref_id;
|
||||||
let binding_span = None;
|
let binding_span = None;
|
||||||
|
@ -766,6 +772,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
args,
|
args,
|
||||||
infer_args,
|
infer_args,
|
||||||
self_ty,
|
self_ty,
|
||||||
|
only_self_bounds,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -777,6 +784,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
args: &GenericArgs<'_>,
|
args: &GenericArgs<'_>,
|
||||||
self_ty: Ty<'tcx>,
|
self_ty: Ty<'tcx>,
|
||||||
bounds: &mut Bounds<'tcx>,
|
bounds: &mut Bounds<'tcx>,
|
||||||
|
only_self_bounds: OnlySelfBounds,
|
||||||
) {
|
) {
|
||||||
let binding_span = Some(span);
|
let binding_span = Some(span);
|
||||||
let constness = ty::BoundConstness::NotConst;
|
let constness = ty::BoundConstness::NotConst;
|
||||||
|
@ -799,6 +807,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
args,
|
args,
|
||||||
infer_args,
|
infer_args,
|
||||||
self_ty,
|
self_ty,
|
||||||
|
only_self_bounds,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -947,6 +956,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
ast_bounds: I,
|
ast_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,
|
||||||
) {
|
) {
|
||||||
for ast_bound in ast_bounds {
|
for ast_bound in ast_bounds {
|
||||||
match ast_bound {
|
match ast_bound {
|
||||||
|
@ -964,11 +974,18 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
param_ty,
|
param_ty,
|
||||||
bounds,
|
bounds,
|
||||||
false,
|
false,
|
||||||
|
only_self_bounds,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
&hir::GenericBound::LangItemTrait(lang_item, span, hir_id, args) => {
|
&hir::GenericBound::LangItemTrait(lang_item, span, hir_id, args) => {
|
||||||
self.instantiate_lang_item_trait_ref(
|
self.instantiate_lang_item_trait_ref(
|
||||||
lang_item, span, hir_id, args, param_ty, bounds,
|
lang_item,
|
||||||
|
span,
|
||||||
|
hir_id,
|
||||||
|
args,
|
||||||
|
param_ty,
|
||||||
|
bounds,
|
||||||
|
only_self_bounds,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
hir::GenericBound::Outlives(lifetime) => {
|
hir::GenericBound::Outlives(lifetime) => {
|
||||||
|
@ -1006,9 +1023,16 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
&self,
|
&self,
|
||||||
param_ty: Ty<'tcx>,
|
param_ty: Ty<'tcx>,
|
||||||
ast_bounds: &[hir::GenericBound<'_>],
|
ast_bounds: &[hir::GenericBound<'_>],
|
||||||
|
only_self_bounds: OnlySelfBounds,
|
||||||
) -> Bounds<'tcx> {
|
) -> Bounds<'tcx> {
|
||||||
let mut bounds = Bounds::default();
|
let mut bounds = Bounds::default();
|
||||||
self.add_bounds(param_ty, ast_bounds.iter(), &mut bounds, ty::List::empty());
|
self.add_bounds(
|
||||||
|
param_ty,
|
||||||
|
ast_bounds.iter(),
|
||||||
|
&mut bounds,
|
||||||
|
ty::List::empty(),
|
||||||
|
only_self_bounds,
|
||||||
|
);
|
||||||
debug!(?bounds);
|
debug!(?bounds);
|
||||||
|
|
||||||
bounds
|
bounds
|
||||||
|
@ -1034,7 +1058,13 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut bounds = Bounds::default();
|
let mut bounds = Bounds::default();
|
||||||
self.add_bounds(param_ty, result.iter(), &mut bounds, ty::List::empty());
|
self.add_bounds(
|
||||||
|
param_ty,
|
||||||
|
result.iter(),
|
||||||
|
&mut bounds,
|
||||||
|
ty::List::empty(),
|
||||||
|
OnlySelfBounds(true),
|
||||||
|
);
|
||||||
debug!(?bounds);
|
debug!(?bounds);
|
||||||
|
|
||||||
bounds
|
bounds
|
||||||
|
@ -1057,6 +1087,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
dup_bindings: &mut FxHashMap<DefId, Span>,
|
dup_bindings: &mut FxHashMap<DefId, Span>,
|
||||||
path_span: Span,
|
path_span: Span,
|
||||||
constness: ty::BoundConstness,
|
constness: ty::BoundConstness,
|
||||||
|
only_self_bounds: OnlySelfBounds,
|
||||||
) -> Result<(), ErrorGuaranteed> {
|
) -> Result<(), ErrorGuaranteed> {
|
||||||
// Given something like `U: SomeTrait<T = X>`, we want to produce a
|
// Given something like `U: SomeTrait<T = X>`, we want to produce a
|
||||||
// predicate like `<U as SomeTrait>::T = X`. This is somewhat
|
// predicate like `<U as SomeTrait>::T = X`. This is somewhat
|
||||||
|
@ -1356,8 +1387,20 @@ 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_alias(ty::Projection, projection_ty.skip_binder());
|
//
|
||||||
self.add_bounds(param_ty, ast_bounds.iter(), bounds, projection_ty.bound_vars());
|
// NOTE: If `only_self_bounds` is true, do NOT expand this associated
|
||||||
|
// type bound into a trait predicate, since we only want to add predicates
|
||||||
|
// for the `Self` type.
|
||||||
|
if !only_self_bounds.0 {
|
||||||
|
let param_ty = tcx.mk_alias(ty::Projection, projection_ty.skip_binder());
|
||||||
|
self.add_bounds(
|
||||||
|
param_ty,
|
||||||
|
ast_bounds.iter(),
|
||||||
|
bounds,
|
||||||
|
projection_ty.bound_vars(),
|
||||||
|
only_self_bounds,
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -1398,6 +1441,10 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
dummy_self,
|
dummy_self,
|
||||||
&mut bounds,
|
&mut bounds,
|
||||||
false,
|
false,
|
||||||
|
// FIXME: This should be `true`, but we don't really handle
|
||||||
|
// associated type bounds or type aliases in objects in a way
|
||||||
|
// that makes this meaningful, I think.
|
||||||
|
OnlySelfBounds(false),
|
||||||
) {
|
) {
|
||||||
potential_assoc_types.extend(cur_potential_assoc_types);
|
potential_assoc_types.extend(cur_potential_assoc_types);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use super::ItemCtxt;
|
use super::ItemCtxt;
|
||||||
use crate::astconv::AstConv;
|
use crate::astconv::{AstConv, OnlySelfBounds};
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
use rustc_infer::traits::util;
|
use rustc_infer::traits::util;
|
||||||
use rustc_middle::ty::subst::InternalSubsts;
|
use rustc_middle::ty::subst::InternalSubsts;
|
||||||
|
@ -26,7 +26,7 @@ fn associated_type_bounds<'tcx>(
|
||||||
);
|
);
|
||||||
|
|
||||||
let icx = ItemCtxt::new(tcx, assoc_item_def_id);
|
let icx = ItemCtxt::new(tcx, assoc_item_def_id);
|
||||||
let mut bounds = icx.astconv().compute_bounds(item_ty, ast_bounds);
|
let mut bounds = icx.astconv().compute_bounds(item_ty, ast_bounds, OnlySelfBounds(false));
|
||||||
// Associated types are implicitly sized unless a `?Sized` bound is found
|
// Associated types are implicitly sized unless a `?Sized` bound is found
|
||||||
icx.astconv().add_implicitly_sized(&mut bounds, item_ty, ast_bounds, None, span);
|
icx.astconv().add_implicitly_sized(&mut bounds, item_ty, ast_bounds, None, span);
|
||||||
|
|
||||||
|
@ -67,7 +67,7 @@ fn opaque_type_bounds<'tcx>(
|
||||||
) -> &'tcx [(ty::Predicate<'tcx>, Span)] {
|
) -> &'tcx [(ty::Predicate<'tcx>, Span)] {
|
||||||
ty::print::with_no_queries!({
|
ty::print::with_no_queries!({
|
||||||
let icx = ItemCtxt::new(tcx, opaque_def_id);
|
let icx = ItemCtxt::new(tcx, opaque_def_id);
|
||||||
let mut bounds = icx.astconv().compute_bounds(item_ty, ast_bounds);
|
let mut bounds = icx.astconv().compute_bounds(item_ty, ast_bounds, OnlySelfBounds(false));
|
||||||
// Opaque types are implicitly sized unless a `?Sized` bound is found
|
// Opaque types are implicitly sized unless a `?Sized` bound is found
|
||||||
icx.astconv().add_implicitly_sized(&mut bounds, item_ty, ast_bounds, None, span);
|
icx.astconv().add_implicitly_sized(&mut bounds, item_ty, ast_bounds, None, span);
|
||||||
debug!(?bounds);
|
debug!(?bounds);
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use crate::astconv::AstConv;
|
use crate::astconv::{AstConv, OnlySelfBounds};
|
||||||
use crate::bounds::Bounds;
|
use crate::bounds::Bounds;
|
||||||
use crate::collect::ItemCtxt;
|
use crate::collect::ItemCtxt;
|
||||||
use crate::constrained_generic_params as cgp;
|
use crate::constrained_generic_params as cgp;
|
||||||
|
@ -14,9 +14,6 @@ use rustc_middle::ty::{GenericPredicates, ToPredicate};
|
||||||
use rustc_span::symbol::{sym, Ident};
|
use rustc_span::symbol::{sym, Ident};
|
||||||
use rustc_span::{Span, DUMMY_SP};
|
use rustc_span::{Span, DUMMY_SP};
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
struct OnlySelfBounds(bool);
|
|
||||||
|
|
||||||
/// 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 `predicates_defined_on`, plus
|
/// ID `def_id`. This includes all predicates returned by `predicates_defined_on`, plus
|
||||||
/// `Self: Trait` predicates for traits.
|
/// `Self: Trait` predicates for traits.
|
||||||
|
@ -225,7 +222,13 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut bounds = Bounds::default();
|
let mut bounds = Bounds::default();
|
||||||
icx.astconv().add_bounds(ty, bound_pred.bounds.iter(), &mut bounds, bound_vars);
|
icx.astconv().add_bounds(
|
||||||
|
ty,
|
||||||
|
bound_pred.bounds.iter(),
|
||||||
|
&mut bounds,
|
||||||
|
bound_vars,
|
||||||
|
OnlySelfBounds(false),
|
||||||
|
);
|
||||||
predicates.extend(bounds.predicates());
|
predicates.extend(bounds.predicates());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -608,7 +611,7 @@ pub(super) fn implied_predicates_with_filter(
|
||||||
let (superbounds, where_bounds_that_match) = match filter {
|
let (superbounds, where_bounds_that_match) = match filter {
|
||||||
PredicateFilter::All => (
|
PredicateFilter::All => (
|
||||||
// Convert the bounds that follow the colon (or equal in trait aliases)
|
// Convert the bounds that follow the colon (or equal in trait aliases)
|
||||||
icx.astconv().compute_bounds(self_param_ty, bounds),
|
icx.astconv().compute_bounds(self_param_ty, bounds, OnlySelfBounds(false)),
|
||||||
// Also include all where clause bounds
|
// Also include all where clause bounds
|
||||||
icx.type_parameter_bounds_in_generics(
|
icx.type_parameter_bounds_in_generics(
|
||||||
generics,
|
generics,
|
||||||
|
@ -620,7 +623,7 @@ pub(super) fn implied_predicates_with_filter(
|
||||||
),
|
),
|
||||||
PredicateFilter::SelfOnly => (
|
PredicateFilter::SelfOnly => (
|
||||||
// Convert the bounds that follow the colon (or equal in trait aliases)
|
// Convert the bounds that follow the colon (or equal in trait aliases)
|
||||||
icx.astconv().compute_bounds(self_param_ty, bounds),
|
icx.astconv().compute_bounds(self_param_ty, bounds, OnlySelfBounds(true)),
|
||||||
// Include where clause bounds for `Self`
|
// Include where clause bounds for `Self`
|
||||||
icx.type_parameter_bounds_in_generics(
|
icx.type_parameter_bounds_in_generics(
|
||||||
generics,
|
generics,
|
||||||
|
@ -798,6 +801,7 @@ impl<'tcx> ItemCtxt<'tcx> {
|
||||||
}),
|
}),
|
||||||
&mut bounds,
|
&mut bounds,
|
||||||
bound_vars,
|
bound_vars,
|
||||||
|
only_self_bounds,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -116,7 +116,7 @@ use rustc_trait_selection::traits::{self, ObligationCause, ObligationCauseCode,
|
||||||
|
|
||||||
use std::ops::Not;
|
use std::ops::Not;
|
||||||
|
|
||||||
use astconv::AstConv;
|
use astconv::{AstConv, OnlySelfBounds};
|
||||||
use bounds::Bounds;
|
use bounds::Bounds;
|
||||||
|
|
||||||
fluent_messages! { "../messages.ftl" }
|
fluent_messages! { "../messages.ftl" }
|
||||||
|
@ -531,6 +531,7 @@ pub fn hir_trait_to_predicates<'tcx>(
|
||||||
self_ty,
|
self_ty,
|
||||||
&mut bounds,
|
&mut bounds,
|
||||||
true,
|
true,
|
||||||
|
OnlySelfBounds(false),
|
||||||
);
|
);
|
||||||
|
|
||||||
bounds
|
bounds
|
||||||
|
|
26
tests/ui/associated-type-bounds/supertrait-defines-ty.rs
Normal file
26
tests/ui/associated-type-bounds/supertrait-defines-ty.rs
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
// check-pass
|
||||||
|
|
||||||
|
// Make sure that we don't look into associated type bounds when looking for
|
||||||
|
// supertraits that define an associated type. Fixes #76593.
|
||||||
|
|
||||||
|
#![feature(associated_type_bounds)]
|
||||||
|
|
||||||
|
trait Load: Sized {
|
||||||
|
type Blob;
|
||||||
|
}
|
||||||
|
|
||||||
|
trait Primitive: Load<Blob = Self> {}
|
||||||
|
|
||||||
|
trait BlobPtr: Primitive {}
|
||||||
|
|
||||||
|
trait CleanPtr: Load<Blob: BlobPtr> {
|
||||||
|
fn to_blob(&self) -> Self::Blob;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Load for () {
|
||||||
|
type Blob = Self;
|
||||||
|
}
|
||||||
|
impl Primitive for () {}
|
||||||
|
impl BlobPtr for () {}
|
||||||
|
|
||||||
|
fn main() {}
|
Loading…
Add table
Add a link
Reference in a new issue