Support GATs in bounds for associated types
This commit is contained in:
parent
e175595985
commit
9fd5f8c670
@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
use tracing::debug;
|
use tracing::debug;
|
||||||
|
|
||||||
use chalk_ir::{cast::Cast, fold::shift::Shift, CanonicalVarKinds};
|
use chalk_ir::{cast::Caster, fold::shift::Shift, CanonicalVarKinds};
|
||||||
use chalk_solve::rust_ir::{self, OpaqueTyDatumBound, WellKnownTrait};
|
use chalk_solve::rust_ir::{self, OpaqueTyDatumBound, WellKnownTrait};
|
||||||
|
|
||||||
use base_db::CrateId;
|
use base_db::CrateId;
|
||||||
@ -846,28 +846,34 @@ pub(super) fn generic_predicate_to_inline_bound(
|
|||||||
}
|
}
|
||||||
let args_no_self = trait_ref.substitution.as_slice(Interner)[1..]
|
let args_no_self = trait_ref.substitution.as_slice(Interner)[1..]
|
||||||
.iter()
|
.iter()
|
||||||
.map(|ty| ty.clone().cast(Interner))
|
.cloned()
|
||||||
|
.casted(Interner)
|
||||||
.collect();
|
.collect();
|
||||||
let trait_bound = rust_ir::TraitBound { trait_id: trait_ref.trait_id, args_no_self };
|
let trait_bound = rust_ir::TraitBound { trait_id: trait_ref.trait_id, args_no_self };
|
||||||
Some(chalk_ir::Binders::new(binders, rust_ir::InlineBound::TraitBound(trait_bound)))
|
Some(chalk_ir::Binders::new(binders, rust_ir::InlineBound::TraitBound(trait_bound)))
|
||||||
}
|
}
|
||||||
WhereClause::AliasEq(AliasEq { alias: AliasTy::Projection(projection_ty), ty }) => {
|
WhereClause::AliasEq(AliasEq { alias: AliasTy::Projection(projection_ty), ty }) => {
|
||||||
let trait_ = projection_ty.trait_(db);
|
let generics =
|
||||||
if projection_ty.self_type_parameter(db) != self_ty_shifted_in {
|
generics(db.upcast(), from_assoc_type_id(projection_ty.associated_ty_id).into());
|
||||||
|
let (assoc_args, trait_args) =
|
||||||
|
projection_ty.substitution.as_slice(Interner).split_at(generics.len_self());
|
||||||
|
let (self_ty, args_no_self) =
|
||||||
|
trait_args.split_first().expect("projection without trait self type");
|
||||||
|
if self_ty.assert_ty_ref(Interner) != &self_ty_shifted_in {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
let args_no_self = projection_ty.substitution.as_slice(Interner)[1..]
|
|
||||||
.iter()
|
let args_no_self = args_no_self.iter().cloned().casted(Interner).collect();
|
||||||
.map(|ty| ty.clone().cast(Interner))
|
let parameters = assoc_args.to_vec();
|
||||||
.collect();
|
|
||||||
let alias_eq_bound = rust_ir::AliasEqBound {
|
let alias_eq_bound = rust_ir::AliasEqBound {
|
||||||
value: ty.clone(),
|
value: ty.clone(),
|
||||||
trait_bound: rust_ir::TraitBound {
|
trait_bound: rust_ir::TraitBound {
|
||||||
trait_id: to_chalk_trait_id(trait_),
|
trait_id: to_chalk_trait_id(projection_ty.trait_(db)),
|
||||||
args_no_self,
|
args_no_self,
|
||||||
},
|
},
|
||||||
associated_ty_id: projection_ty.associated_ty_id,
|
associated_ty_id: projection_ty.associated_ty_id,
|
||||||
parameters: Vec::new(), // FIXME we don't support generic associated types yet
|
parameters,
|
||||||
};
|
};
|
||||||
Some(chalk_ir::Binders::new(
|
Some(chalk_ir::Binders::new(
|
||||||
binders,
|
binders,
|
||||||
|
@ -4148,6 +4148,30 @@ fn f<T>(t: T)
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn gats_in_bounds_for_assoc() {
|
||||||
|
check_types(
|
||||||
|
r#"
|
||||||
|
trait Trait {
|
||||||
|
type Assoc: Another<Gat<i32> = usize>;
|
||||||
|
type Assoc2<T>: Another<Gat<T> = T>;
|
||||||
|
}
|
||||||
|
trait Another {
|
||||||
|
type Gat<T>;
|
||||||
|
fn foo(&self) -> Self::Gat<i32>;
|
||||||
|
fn bar<T>(&self) -> Self::Gat<T>;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test<T: Trait>(a: T::Assoc, b: T::Assoc2<isize>) {
|
||||||
|
let v = a.foo();
|
||||||
|
//^ usize
|
||||||
|
let v = b.bar::<isize>();
|
||||||
|
//^ isize
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn bin_op_with_scalar_fallback() {
|
fn bin_op_with_scalar_fallback() {
|
||||||
// Extra impls are significant so that chalk doesn't give us definite guidances.
|
// Extra impls are significant so that chalk doesn't give us definite guidances.
|
||||||
|
Loading…
Reference in New Issue
Block a user