mirror of
https://github.com/rust-lang/rust.git
synced 2025-01-26 06:35:27 +00:00
Fix APIT some more
This commit is contained in:
parent
c6654fd4a7
commit
3397ca679f
@ -479,8 +479,11 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
|
||||
|
||||
fn collect_fn(&mut self, data: &FunctionData) {
|
||||
let body = Arc::clone(&self.body); // avoid borrow checker problem
|
||||
for (type_ref, pat) in data.params.iter().zip(body.params.iter()) {
|
||||
let ty = self.make_ty_with_mode(type_ref, ImplTraitLoweringMode::Param);
|
||||
let ctx = crate::lower::TyLoweringContext::new(self.db, &self.resolver).with_impl_trait_mode(ImplTraitLoweringMode::Param);
|
||||
let param_tys = data.params.iter().map(|type_ref| Ty::from_hir(&ctx, type_ref)).collect::<Vec<_>>();
|
||||
for (ty, pat) in param_tys.into_iter().zip(body.params.iter()) {
|
||||
let ty = self.insert_type_vars(ty);
|
||||
let ty = self.normalize_associated_types_in(ty);
|
||||
|
||||
self.infer_pat(*pat, &ty, BindingMode::default());
|
||||
}
|
||||
|
@ -44,11 +44,11 @@ use std::sync::Arc;
|
||||
use std::{fmt, iter, mem};
|
||||
|
||||
use hir_def::{
|
||||
expr::ExprId, type_ref::Mutability, AdtId, AssocContainerId, DefWithBodyId, GenericDefId,
|
||||
HasModule, Lookup, TraitId, TypeAliasId, TypeParamId, generics::TypeParamProvenance,
|
||||
expr::ExprId, generics::TypeParamProvenance, type_ref::Mutability, AdtId, AssocContainerId,
|
||||
DefWithBodyId, GenericDefId, HasModule, Lookup, TraitId, TypeAliasId, TypeParamId,
|
||||
};
|
||||
use ra_db::{impl_intern_key, salsa, CrateId};
|
||||
use hir_expand::name::Name;
|
||||
use ra_db::{impl_intern_key, salsa, CrateId};
|
||||
|
||||
use crate::{
|
||||
db::HirDatabase,
|
||||
@ -360,9 +360,7 @@ impl Substs {
|
||||
|
||||
/// Return Substs that replace each parameter by itself (i.e. `Ty::Param`).
|
||||
pub(crate) fn type_params(generic_params: &Generics) -> Substs {
|
||||
Substs(
|
||||
generic_params.iter().map(|(id, _)| Ty::Param(id)).collect(),
|
||||
)
|
||||
Substs(generic_params.iter().map(|(id, _)| Ty::Param(id)).collect())
|
||||
}
|
||||
|
||||
/// Return Substs that replace each parameter by a bound variable.
|
||||
@ -448,7 +446,9 @@ pub struct Binders<T> {
|
||||
}
|
||||
|
||||
impl<T> Binders<T> {
|
||||
pub fn new(num_binders: usize, value: T) -> Self { Self { num_binders, value } }
|
||||
pub fn new(num_binders: usize, value: T) -> Self {
|
||||
Self { num_binders, value }
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: TypeWalk> Binders<T> {
|
||||
@ -906,8 +906,7 @@ impl HirDisplay for ApplicationTy {
|
||||
write!(f, ") -> {}", sig.ret().display(f.db))?;
|
||||
}
|
||||
TypeCtor::FnDef(def) => {
|
||||
let sig = f.db.callable_item_signature(def)
|
||||
.subst(&self.parameters);
|
||||
let sig = f.db.callable_item_signature(def).subst(&self.parameters);
|
||||
let name = match def {
|
||||
CallableDef::FunctionId(ff) => f.db.function_data(ff).name.clone(),
|
||||
CallableDef::StructId(s) => f.db.struct_data(s).name.clone(),
|
||||
@ -1037,17 +1036,19 @@ impl HirDisplay for Ty {
|
||||
Ty::Apply(a_ty) => a_ty.hir_fmt(f)?,
|
||||
Ty::Projection(p_ty) => p_ty.hir_fmt(f)?,
|
||||
Ty::Param(id) => {
|
||||
let generic_params = f.db.generic_params(id.parent);
|
||||
let param_data = &generic_params.types[id.local_id];
|
||||
let generics = generics(f.db, id.parent);
|
||||
let param_data = &generics.params.types[id.local_id];
|
||||
match param_data.provenance {
|
||||
TypeParamProvenance::TypeParamList | TypeParamProvenance::TraitSelf => {
|
||||
write!(f, "{}", param_data.name.clone().unwrap_or_else(Name::missing))?
|
||||
}
|
||||
TypeParamProvenance::ArgumentImplTrait => {
|
||||
write!(f, "impl TODO")?
|
||||
let bounds = f.db.generic_predicates_for_param(*id);
|
||||
write!(f, "impl ")?;
|
||||
write_bounds_like_dyn_trait(&bounds, f)?;
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
Ty::Bound(idx) => write!(f, "?{}", idx)?,
|
||||
Ty::Dyn(predicates) | Ty::Opaque(predicates) => {
|
||||
match self {
|
||||
@ -1055,66 +1056,7 @@ impl HirDisplay for Ty {
|
||||
Ty::Opaque(_) => write!(f, "impl ")?,
|
||||
_ => unreachable!(),
|
||||
};
|
||||
// Note: This code is written to produce nice results (i.e.
|
||||
// corresponding to surface Rust) for types that can occur in
|
||||
// actual Rust. It will have weird results if the predicates
|
||||
// aren't as expected (i.e. self types = $0, projection
|
||||
// predicates for a certain trait come after the Implemented
|
||||
// predicate for that trait).
|
||||
let mut first = true;
|
||||
let mut angle_open = false;
|
||||
for p in predicates.iter() {
|
||||
match p {
|
||||
GenericPredicate::Implemented(trait_ref) => {
|
||||
if angle_open {
|
||||
write!(f, ">")?;
|
||||
}
|
||||
if !first {
|
||||
write!(f, " + ")?;
|
||||
}
|
||||
// We assume that the self type is $0 (i.e. the
|
||||
// existential) here, which is the only thing that's
|
||||
// possible in actual Rust, and hence don't print it
|
||||
write!(f, "{}", f.db.trait_data(trait_ref.trait_).name.clone())?;
|
||||
if trait_ref.substs.len() > 1 {
|
||||
write!(f, "<")?;
|
||||
f.write_joined(&trait_ref.substs[1..], ", ")?;
|
||||
// there might be assoc type bindings, so we leave the angle brackets open
|
||||
angle_open = true;
|
||||
}
|
||||
}
|
||||
GenericPredicate::Projection(projection_pred) => {
|
||||
// in types in actual Rust, these will always come
|
||||
// after the corresponding Implemented predicate
|
||||
if angle_open {
|
||||
write!(f, ", ")?;
|
||||
} else {
|
||||
write!(f, "<")?;
|
||||
angle_open = true;
|
||||
}
|
||||
let name =
|
||||
f.db.type_alias_data(projection_pred.projection_ty.associated_ty)
|
||||
.name
|
||||
.clone();
|
||||
write!(f, "{} = ", name)?;
|
||||
projection_pred.ty.hir_fmt(f)?;
|
||||
}
|
||||
GenericPredicate::Error => {
|
||||
if angle_open {
|
||||
// impl Trait<X, {error}>
|
||||
write!(f, ", ")?;
|
||||
} else if !first {
|
||||
// impl Trait + {error}
|
||||
write!(f, " + ")?;
|
||||
}
|
||||
p.hir_fmt(f)?;
|
||||
}
|
||||
}
|
||||
first = false;
|
||||
}
|
||||
if angle_open {
|
||||
write!(f, ">")?;
|
||||
}
|
||||
write_bounds_like_dyn_trait(&predicates, f)?;
|
||||
}
|
||||
Ty::Unknown => write!(f, "{{unknown}}")?,
|
||||
Ty::Infer(..) => write!(f, "_")?,
|
||||
@ -1123,6 +1065,71 @@ impl HirDisplay for Ty {
|
||||
}
|
||||
}
|
||||
|
||||
fn write_bounds_like_dyn_trait(
|
||||
predicates: &[GenericPredicate],
|
||||
f: &mut HirFormatter<impl HirDatabase>,
|
||||
) -> fmt::Result {
|
||||
// Note: This code is written to produce nice results (i.e.
|
||||
// corresponding to surface Rust) for types that can occur in
|
||||
// actual Rust. It will have weird results if the predicates
|
||||
// aren't as expected (i.e. self types = $0, projection
|
||||
// predicates for a certain trait come after the Implemented
|
||||
// predicate for that trait).
|
||||
let mut first = true;
|
||||
let mut angle_open = false;
|
||||
for p in predicates.iter() {
|
||||
match p {
|
||||
GenericPredicate::Implemented(trait_ref) => {
|
||||
if angle_open {
|
||||
write!(f, ">")?;
|
||||
}
|
||||
if !first {
|
||||
write!(f, " + ")?;
|
||||
}
|
||||
// We assume that the self type is $0 (i.e. the
|
||||
// existential) here, which is the only thing that's
|
||||
// possible in actual Rust, and hence don't print it
|
||||
write!(f, "{}", f.db.trait_data(trait_ref.trait_).name.clone())?;
|
||||
if trait_ref.substs.len() > 1 {
|
||||
write!(f, "<")?;
|
||||
f.write_joined(&trait_ref.substs[1..], ", ")?;
|
||||
// there might be assoc type bindings, so we leave the angle brackets open
|
||||
angle_open = true;
|
||||
}
|
||||
}
|
||||
GenericPredicate::Projection(projection_pred) => {
|
||||
// in types in actual Rust, these will always come
|
||||
// after the corresponding Implemented predicate
|
||||
if angle_open {
|
||||
write!(f, ", ")?;
|
||||
} else {
|
||||
write!(f, "<")?;
|
||||
angle_open = true;
|
||||
}
|
||||
let name =
|
||||
f.db.type_alias_data(projection_pred.projection_ty.associated_ty).name.clone();
|
||||
write!(f, "{} = ", name)?;
|
||||
projection_pred.ty.hir_fmt(f)?;
|
||||
}
|
||||
GenericPredicate::Error => {
|
||||
if angle_open {
|
||||
// impl Trait<X, {error}>
|
||||
write!(f, ", ")?;
|
||||
} else if !first {
|
||||
// impl Trait + {error}
|
||||
write!(f, " + ")?;
|
||||
}
|
||||
p.hir_fmt(f)?;
|
||||
}
|
||||
}
|
||||
first = false;
|
||||
}
|
||||
if angle_open {
|
||||
write!(f, ">")?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
impl TraitRef {
|
||||
fn hir_fmt_ext(&self, f: &mut HirFormatter<impl HirDatabase>, use_as: bool) -> fmt::Result {
|
||||
if f.should_truncate() {
|
||||
|
@ -10,12 +10,13 @@ use std::sync::Arc;
|
||||
|
||||
use hir_def::{
|
||||
builtin_type::BuiltinType,
|
||||
generics::{WherePredicate, WherePredicateTarget},
|
||||
generics::{WherePredicate, WherePredicateTarget, TypeParamProvenance},
|
||||
path::{GenericArg, Path, PathSegment, PathSegments},
|
||||
resolver::{HasResolver, Resolver, TypeNs},
|
||||
type_ref::{TypeBound, TypeRef},
|
||||
AdtId, ConstId, EnumId, EnumVariantId, FunctionId, GenericDefId, HasModule, ImplId,
|
||||
LocalStructFieldId, Lookup, StaticId, StructId, TraitId, TypeAliasId, UnionId, VariantId,
|
||||
TypeParamId
|
||||
};
|
||||
use ra_arena::map::ArenaMap;
|
||||
use ra_db::CrateId;
|
||||
@ -30,8 +31,6 @@ use crate::{
|
||||
Binders, FnSig, GenericPredicate, PolyFnSig, ProjectionPredicate, ProjectionTy, Substs,
|
||||
TraitEnvironment, TraitRef, Ty, TypeCtor,
|
||||
};
|
||||
use hir_def::TypeParamId;
|
||||
use hir_def::generics::TypeParamProvenance;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct TyLoweringContext<'a, DB: HirDatabase> {
|
||||
|
@ -856,11 +856,11 @@ trait Trait<T> {
|
||||
fn foo(&self) -> T;
|
||||
fn foo2(&self) -> i64;
|
||||
}
|
||||
fn bar(impl Trait<u64>) {}
|
||||
fn bar(x: impl Trait<u16>) {}
|
||||
struct S<T>(T);
|
||||
impl<T> Trait<T> for S<T> {}
|
||||
|
||||
fn test(x: impl Trait<u64>, y: &impl Trait<u64>) {
|
||||
fn test(x: impl Trait<u64>, y: &impl Trait<u32>) {
|
||||
x;
|
||||
y;
|
||||
let z = S(1);
|
||||
@ -876,27 +876,32 @@ fn test(x: impl Trait<u64>, y: &impl Trait<u64>) {
|
||||
@r###"
|
||||
[30; 34) 'self': &Self
|
||||
[55; 59) 'self': &Self
|
||||
[99; 101) '{}': ()
|
||||
[111; 112) 'x': impl Trait<u64>
|
||||
[131; 132) 'y': &impl Trait<u64>
|
||||
[152; 269) '{ ...2(); }': ()
|
||||
[158; 159) 'x': impl Trait<u64>
|
||||
[165; 166) 'y': &impl Trait<u64>
|
||||
[176; 177) 'z': impl Trait<u64>
|
||||
[180; 183) 'bar': fn bar() -> impl Trait<u64>
|
||||
[180; 185) 'bar()': impl Trait<u64>
|
||||
[191; 192) 'x': impl Trait<u64>
|
||||
[191; 198) 'x.foo()': u64
|
||||
[204; 205) 'y': &impl Trait<u64>
|
||||
[204; 211) 'y.foo()': u64
|
||||
[217; 218) 'z': impl Trait<u64>
|
||||
[217; 224) 'z.foo()': u64
|
||||
[230; 231) 'x': impl Trait<u64>
|
||||
[230; 238) 'x.foo2()': i64
|
||||
[244; 245) 'y': &impl Trait<u64>
|
||||
[244; 252) 'y.foo2()': i64
|
||||
[258; 259) 'z': impl Trait<u64>
|
||||
[258; 266) 'z.foo2()': i64
|
||||
[78; 79) 'x': impl Trait<u16>
|
||||
[98; 100) '{}': ()
|
||||
[155; 156) 'x': impl Trait<u64>
|
||||
[175; 176) 'y': &impl Trait<u32>
|
||||
[196; 324) '{ ...2(); }': ()
|
||||
[202; 203) 'x': impl Trait<u64>
|
||||
[209; 210) 'y': &impl Trait<u32>
|
||||
[220; 221) 'z': S<u16>
|
||||
[224; 225) 'S': S<u16>(u16) -> S<u16>
|
||||
[224; 228) 'S(1)': S<u16>
|
||||
[226; 227) '1': u16
|
||||
[234; 237) 'bar': fn bar<S<u16>>(S<u16>) -> ()
|
||||
[234; 240) 'bar(z)': ()
|
||||
[238; 239) 'z': S<u16>
|
||||
[246; 247) 'x': impl Trait<u64>
|
||||
[246; 253) 'x.foo()': u64
|
||||
[259; 260) 'y': &impl Trait<u32>
|
||||
[259; 266) 'y.foo()': u32
|
||||
[272; 273) 'z': S<u16>
|
||||
[272; 279) 'z.foo()': u16
|
||||
[285; 286) 'x': impl Trait<u64>
|
||||
[285; 293) 'x.foo2()': i64
|
||||
[299; 300) 'y': &impl Trait<u32>
|
||||
[299; 307) 'y.foo2()': i64
|
||||
[313; 314) 'z': S<u16>
|
||||
[313; 321) 'z.foo2()': i64
|
||||
"###
|
||||
);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user