From 6ca19b2188aa0f45b0484246abde35d0ded8a846 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Tue, 28 Jan 2020 15:31:43 +0100 Subject: Standard formatting for array types --- crates/ra_hir_ty/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'crates/ra_hir_ty/src/lib.rs') diff --git a/crates/ra_hir_ty/src/lib.rs b/crates/ra_hir_ty/src/lib.rs index 908e4862d..08d501ccd 100644 --- a/crates/ra_hir_ty/src/lib.rs +++ b/crates/ra_hir_ty/src/lib.rs @@ -847,7 +847,7 @@ impl HirDisplay for ApplicationTy { } TypeCtor::Array => { let t = self.parameters.as_single(); - write!(f, "[{};_]", t.display(f.db))?; + write!(f, "[{}; _]", t.display(f.db))?; } TypeCtor::RawPtr(m) => { let t = self.parameters.as_single(); -- cgit v1.2.3 From 22a65b11b3a69b3dae561b34c6b28cb2107169d1 Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Fri, 24 Jan 2020 14:32:47 +0100 Subject: Introduce TyLoweringContext --- crates/ra_hir_ty/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'crates/ra_hir_ty/src/lib.rs') diff --git a/crates/ra_hir_ty/src/lib.rs b/crates/ra_hir_ty/src/lib.rs index 08d501ccd..6f0e8b481 100644 --- a/crates/ra_hir_ty/src/lib.rs +++ b/crates/ra_hir_ty/src/lib.rs @@ -60,7 +60,7 @@ use display::{HirDisplay, HirFormatter}; pub use autoderef::autoderef; pub use infer::{do_infer_query, InferTy, InferenceResult}; pub use lower::CallableDef; -pub use lower::{callable_item_sig, TyDefId, ValueTyDefId}; +pub use lower::{callable_item_sig, TyDefId, TyLoweringContext, ValueTyDefId}; pub use traits::{InEnvironment, Obligation, ProjectionPredicate, TraitEnvironment}; /// A type constructor or type name: this might be something like the primitive -- cgit v1.2.3 From 7ea4bce1b292d455c313f914b3aa3051293c502b Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Fri, 24 Jan 2020 15:22:00 +0100 Subject: Add impl trait lowering mode --- crates/ra_hir_ty/src/lib.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'crates/ra_hir_ty/src/lib.rs') diff --git a/crates/ra_hir_ty/src/lib.rs b/crates/ra_hir_ty/src/lib.rs index 6f0e8b481..c64b81f98 100644 --- a/crates/ra_hir_ty/src/lib.rs +++ b/crates/ra_hir_ty/src/lib.rs @@ -60,7 +60,9 @@ use display::{HirDisplay, HirFormatter}; pub use autoderef::autoderef; pub use infer::{do_infer_query, InferTy, InferenceResult}; pub use lower::CallableDef; -pub use lower::{callable_item_sig, TyDefId, TyLoweringContext, ValueTyDefId}; +pub use lower::{ + callable_item_sig, ImplTraitLoweringMode, TyDefId, TyLoweringContext, ValueTyDefId, +}; pub use traits::{InEnvironment, Obligation, ProjectionPredicate, TraitEnvironment}; /// A type constructor or type name: this might be something like the primitive -- cgit v1.2.3 From 93aa166748eef9560df2435391dc3f3b53f8262d Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Fri, 24 Jan 2020 19:35:09 +0100 Subject: wip lower impl trait to type args --- crates/ra_hir_ty/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'crates/ra_hir_ty/src/lib.rs') diff --git a/crates/ra_hir_ty/src/lib.rs b/crates/ra_hir_ty/src/lib.rs index c64b81f98..cb7a60352 100644 --- a/crates/ra_hir_ty/src/lib.rs +++ b/crates/ra_hir_ty/src/lib.rs @@ -368,7 +368,7 @@ impl Substs { /// Return Substs that replace each parameter by itself (i.e. `Ty::Param`). pub(crate) fn identity(generic_params: &Generics) -> Substs { Substs( - generic_params.iter().map(|(idx, p)| Ty::Param { idx, name: p.name.clone() }).collect(), + generic_params.iter().map(|(idx, p)| Ty::Param { idx, name: p.name.clone().unwrap_or_else(Name::missing) }).collect(), ) } -- cgit v1.2.3 From 16c69374471a0072541c21a5551b4fd97f7e12ba Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Sat, 25 Jan 2020 23:38:33 +0100 Subject: Lower impl trait to variables, move away from using placeholders where they don't belong --- crates/ra_hir_ty/src/lib.rs | 34 ++++++++++++++++++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) (limited to 'crates/ra_hir_ty/src/lib.rs') diff --git a/crates/ra_hir_ty/src/lib.rs b/crates/ra_hir_ty/src/lib.rs index cb7a60352..79084bb3e 100644 --- a/crates/ra_hir_ty/src/lib.rs +++ b/crates/ra_hir_ty/src/lib.rs @@ -453,6 +453,30 @@ impl Deref for Substs { } } +#[derive(Copy, Clone, PartialEq, Eq, Debug)] +pub struct Binders { + pub num_binders: usize, + pub value: T, +} + +impl Binders { + pub fn new(num_binders: usize, value: T) -> Self { Self { num_binders, value } } +} + +impl Binders { + /// Substitutes all variables. + pub fn subst(self, subst: &Substs) -> T { + assert_eq!(subst.len(), self.num_binders); + self.value.subst_bound_vars(subst) + } + + /// Substitutes just a prefix of the variables (shifting the rest). + pub fn subst_prefix(self, subst: &Substs) -> Binders { + assert!(subst.len() < self.num_binders); + Binders::new(self.num_binders - subst.len(), self.value.subst_bound_vars(subst)) + } +} + /// A trait with type parameters. This includes the `Self`, so this represents a concrete type implementing the trait. /// Name to be bikeshedded: TraitBound? TraitImplements? #[derive(Clone, PartialEq, Eq, Debug, Hash)] @@ -553,6 +577,9 @@ pub struct FnSig { params_and_return: Arc<[Ty]>, } +/// A polymorphic function signature. +pub type PolyFnSig = Binders; + impl FnSig { pub fn from_params_and_return(mut params: Vec, ret: Ty) -> FnSig { params.push(ret); @@ -757,6 +784,9 @@ pub trait TypeWalk { &mut Ty::Bound(idx) => { if idx as usize >= binders && (idx as usize - binders) < substs.len() { *ty = substs.0[idx as usize - binders].clone(); + } else if idx as usize >= binders + substs.len() { + // shift free binders + *ty = Ty::Bound(idx - substs.len() as u32); } } _ => {} @@ -903,8 +933,8 @@ impl HirDisplay for ApplicationTy { write!(f, ">")?; } write!(f, "(")?; - f.write_joined(sig.params(), ", ")?; - write!(f, ") -> {}", sig.ret().display(f.db))?; + f.write_joined(sig.value.params(), ", ")?; + write!(f, ") -> {}", sig.value.ret().display(f.db))?; } TypeCtor::Adt(def_id) => { let name = match def_id { -- cgit v1.2.3 From 4789a993eb26963a2411dcc3041733a3b034634a Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Tue, 28 Jan 2020 21:42:58 +0100 Subject: Fix printing of function types --- crates/ra_hir_ty/src/lib.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'crates/ra_hir_ty/src/lib.rs') diff --git a/crates/ra_hir_ty/src/lib.rs b/crates/ra_hir_ty/src/lib.rs index 79084bb3e..1f0fd1128 100644 --- a/crates/ra_hir_ty/src/lib.rs +++ b/crates/ra_hir_ty/src/lib.rs @@ -912,7 +912,8 @@ impl HirDisplay for ApplicationTy { write!(f, ") -> {}", sig.ret().display(f.db))?; } TypeCtor::FnDef(def) => { - let sig = f.db.callable_item_signature(def); + 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(), @@ -933,8 +934,8 @@ impl HirDisplay for ApplicationTy { write!(f, ">")?; } write!(f, "(")?; - f.write_joined(sig.value.params(), ", ")?; - write!(f, ") -> {}", sig.value.ret().display(f.db))?; + f.write_joined(sig.params(), ", ")?; + write!(f, ") -> {}", sig.ret().display(f.db))?; } TypeCtor::Adt(def_id) => { let name = match def_id { -- cgit v1.2.3 From ed25cf70d5e0df9c7a33deb503ea14c2d97bd7a7 Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Fri, 31 Jan 2020 16:52:43 +0100 Subject: Change Ty::Param to contain param ID --- crates/ra_hir_ty/src/lib.rs | 49 +++++++++++++++++++++++++-------------------- 1 file changed, 27 insertions(+), 22 deletions(-) (limited to 'crates/ra_hir_ty/src/lib.rs') diff --git a/crates/ra_hir_ty/src/lib.rs b/crates/ra_hir_ty/src/lib.rs index 1f0fd1128..1e162943c 100644 --- a/crates/ra_hir_ty/src/lib.rs +++ b/crates/ra_hir_ty/src/lib.rs @@ -45,10 +45,10 @@ use std::{fmt, iter, mem}; use hir_def::{ expr::ExprId, type_ref::Mutability, AdtId, AssocContainerId, DefWithBodyId, GenericDefId, - HasModule, Lookup, TraitId, TypeAliasId, + HasModule, Lookup, TraitId, TypeAliasId, TypeParamId, generics::TypeParamProvenance, }; -use hir_expand::name::Name; use ra_db::{impl_intern_key, salsa, CrateId}; +use hir_expand::name::Name; use crate::{ db::HirDatabase, @@ -288,14 +288,7 @@ pub enum Ty { Projection(ProjectionTy), /// A type parameter; for example, `T` in `fn f(x: T) {} - Param { - /// The index of the parameter (starting with parameters from the - /// surrounding impl, then the current function). - idx: u32, - /// The name of the parameter, for displaying. - // FIXME get rid of this - name: Name, - }, + Param(TypeParamId), /// A bound type variable. Used during trait resolution to represent Chalk /// variables, and in `Dyn` and `Opaque` bounds to represent the `Self` type. @@ -366,15 +359,15 @@ impl Substs { } /// Return Substs that replace each parameter by itself (i.e. `Ty::Param`). - pub(crate) fn identity(generic_params: &Generics) -> Substs { + pub(crate) fn type_params(generic_params: &Generics) -> Substs { Substs( - generic_params.iter().map(|(idx, p)| Ty::Param { idx, name: p.name.clone().unwrap_or_else(Name::missing) }).collect(), + generic_params.iter().map(|(id, _)| Ty::Param(id)).collect(), ) } /// Return Substs that replace each parameter by a bound variable. pub(crate) fn bound_vars(generic_params: &Generics) -> Substs { - Substs(generic_params.iter().map(|(idx, _p)| Ty::Bound(idx)).collect()) + Substs(generic_params.iter().enumerate().map(|(idx, _)| Ty::Bound(idx as u32)).collect()) } pub fn build_for_def(db: &impl HirDatabase, def: impl Into) -> SubstsBuilder { @@ -422,11 +415,6 @@ impl SubstsBuilder { self.fill((starting_from..).map(Ty::Bound)) } - pub fn fill_with_params(self) -> Self { - let start = self.vec.len() as u32; - self.fill((start..).map(|idx| Ty::Param { idx, name: Name::missing() })) - } - pub fn fill_with_unknown(self) -> Self { self.fill(iter::repeat(Ty::Unknown)) } @@ -762,13 +750,19 @@ pub trait TypeWalk { /// Replaces type parameters in this type using the given `Substs`. (So e.g. /// if `self` is `&[T]`, where type parameter T has index 0, and the /// `Substs` contain `u32` at index 0, we'll have `&[u32]` afterwards.) - fn subst(self, substs: &Substs) -> Self + // TODO: this should mostly not be used anymore + fn subst_type_params(self, db: &impl HirDatabase, def: GenericDefId, substs: &Substs) -> Self where Self: Sized, { + let generics = generics(db, def); self.fold(&mut |ty| match ty { - Ty::Param { idx, name } => { - substs.get(idx as usize).cloned().unwrap_or(Ty::Param { idx, name }) + Ty::Param(id) => { + if let Some(idx) = generics.param_idx(id) { + substs.get(idx as usize).cloned().unwrap_or(Ty::Param(id)) + } else { + ty + } } ty => ty, }) @@ -1042,7 +1036,18 @@ impl HirDisplay for Ty { match self { Ty::Apply(a_ty) => a_ty.hir_fmt(f)?, Ty::Projection(p_ty) => p_ty.hir_fmt(f)?, - Ty::Param { name, .. } => write!(f, "{}", name)?, + Ty::Param(id) => { + let generic_params = f.db.generic_params(id.parent); + let param_data = &generic_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")? + } + } + }, Ty::Bound(idx) => write!(f, "?{}", idx)?, Ty::Dyn(predicates) | Ty::Opaque(predicates) => { match self { -- cgit v1.2.3 From 3397ca679fb0156c9f102ab82354e2bcef5f4dd1 Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Sun, 2 Feb 2020 13:04:22 +0100 Subject: Fix APIT some more --- crates/ra_hir_ty/src/lib.rs | 153 +++++++++++++++++++++++--------------------- 1 file changed, 80 insertions(+), 73 deletions(-) (limited to 'crates/ra_hir_ty/src/lib.rs') diff --git a/crates/ra_hir_ty/src/lib.rs b/crates/ra_hir_ty/src/lib.rs index 1e162943c..6eccd7fa8 100644 --- a/crates/ra_hir_ty/src/lib.rs +++ b/crates/ra_hir_ty/src/lib.rs @@ -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 { } impl Binders { - 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 Binders { @@ -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 - 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, +) -> 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 + 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, use_as: bool) -> fmt::Result { if f.should_truncate() { -- cgit v1.2.3 From 86348f5994cdc3831edf3a5582d6d9d576fd1d80 Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Sun, 2 Feb 2020 13:43:04 +0100 Subject: Comment fixes / todos --- crates/ra_hir_ty/src/lib.rs | 2 ++ 1 file changed, 2 insertions(+) (limited to 'crates/ra_hir_ty/src/lib.rs') diff --git a/crates/ra_hir_ty/src/lib.rs b/crates/ra_hir_ty/src/lib.rs index 6eccd7fa8..1da4bcc19 100644 --- a/crates/ra_hir_ty/src/lib.rs +++ b/crates/ra_hir_ty/src/lib.rs @@ -288,10 +288,12 @@ pub enum Ty { Projection(ProjectionTy), /// A type parameter; for example, `T` in `fn f(x: T) {} + // TODO fix documentation Param(TypeParamId), /// A bound type variable. Used during trait resolution to represent Chalk /// variables, and in `Dyn` and `Opaque` bounds to represent the `Self` type. + // TODO fix documentation Bound(u32), /// A type variable used during type checking. Not to be confused with a -- cgit v1.2.3 From a3d8cffde39bfb0d50b87a8ded5e0534adec4cd5 Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Sun, 2 Feb 2020 17:11:54 +0100 Subject: Use variables in predicates as well --- crates/ra_hir_ty/src/lib.rs | 28 ++++------------------------ 1 file changed, 4 insertions(+), 24 deletions(-) (limited to 'crates/ra_hir_ty/src/lib.rs') diff --git a/crates/ra_hir_ty/src/lib.rs b/crates/ra_hir_ty/src/lib.rs index 1da4bcc19..a685e70c2 100644 --- a/crates/ra_hir_ty/src/lib.rs +++ b/crates/ra_hir_ty/src/lib.rs @@ -749,28 +749,7 @@ pub trait TypeWalk { self } - /// Replaces type parameters in this type using the given `Substs`. (So e.g. - /// if `self` is `&[T]`, where type parameter T has index 0, and the - /// `Substs` contain `u32` at index 0, we'll have `&[u32]` afterwards.) - // TODO: this should mostly not be used anymore - fn subst_type_params(self, db: &impl HirDatabase, def: GenericDefId, substs: &Substs) -> Self - where - Self: Sized, - { - let generics = generics(db, def); - self.fold(&mut |ty| match ty { - Ty::Param(id) => { - if let Some(idx) = generics.param_idx(id) { - substs.get(idx as usize).cloned().unwrap_or(Ty::Param(id)) - } else { - ty - } - } - ty => ty, - }) - } - - /// Substitutes `Ty::Bound` vars (as opposed to type parameters). + /// Substitutes `Ty::Bound` vars with the given substitution. fn subst_bound_vars(mut self, substs: &Substs) -> Self where Self: Sized, @@ -1045,9 +1024,10 @@ impl HirDisplay for Ty { write!(f, "{}", param_data.name.clone().unwrap_or_else(Name::missing))? } TypeParamProvenance::ArgumentImplTrait => { - let bounds = f.db.generic_predicates_for_param(*id); write!(f, "impl ")?; - write_bounds_like_dyn_trait(&bounds, f)?; + let bounds = f.db.generic_predicates_for_param(*id); + let substs = Substs::type_params(&generics); + write_bounds_like_dyn_trait(&bounds.iter().map(|b| b.clone().subst(&substs)).collect::>(), f)?; } } } -- cgit v1.2.3 From 0718682cffaae34e5c106c793c60f6706fc04b05 Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Tue, 4 Feb 2020 21:33:03 +0100 Subject: Fix compilation of other crates --- crates/ra_hir_ty/src/lib.rs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'crates/ra_hir_ty/src/lib.rs') diff --git a/crates/ra_hir_ty/src/lib.rs b/crates/ra_hir_ty/src/lib.rs index a685e70c2..314be17b8 100644 --- a/crates/ra_hir_ty/src/lib.rs +++ b/crates/ra_hir_ty/src/lib.rs @@ -361,10 +361,16 @@ impl Substs { } /// Return Substs that replace each parameter by itself (i.e. `Ty::Param`). - pub(crate) fn type_params(generic_params: &Generics) -> Substs { + pub(crate) fn type_params_for_generics(generic_params: &Generics) -> Substs { Substs(generic_params.iter().map(|(id, _)| Ty::Param(id)).collect()) } + /// Return Substs that replace each parameter by itself (i.e. `Ty::Param`). + pub fn type_params(db: &impl HirDatabase, def: impl Into) -> Substs { + let params = generics(db, def.into()); + Substs::type_params_for_generics(¶ms) + } + /// Return Substs that replace each parameter by a bound variable. pub(crate) fn bound_vars(generic_params: &Generics) -> Substs { Substs(generic_params.iter().enumerate().map(|(idx, _)| Ty::Bound(idx as u32)).collect()) @@ -1026,7 +1032,7 @@ impl HirDisplay for Ty { TypeParamProvenance::ArgumentImplTrait => { write!(f, "impl ")?; let bounds = f.db.generic_predicates_for_param(*id); - let substs = Substs::type_params(&generics); + let substs = Substs::type_params_for_generics(&generics); write_bounds_like_dyn_trait(&bounds.iter().map(|b| b.clone().subst(&substs)).collect::>(), f)?; } } -- cgit v1.2.3 From dded90a748737c3661aad043524f2248e324c867 Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Fri, 7 Feb 2020 15:13:15 +0100 Subject: Formatting --- crates/ra_hir_ty/src/lib.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'crates/ra_hir_ty/src/lib.rs') diff --git a/crates/ra_hir_ty/src/lib.rs b/crates/ra_hir_ty/src/lib.rs index 314be17b8..60c7fd0e5 100644 --- a/crates/ra_hir_ty/src/lib.rs +++ b/crates/ra_hir_ty/src/lib.rs @@ -1033,7 +1033,10 @@ impl HirDisplay for Ty { write!(f, "impl ")?; let bounds = f.db.generic_predicates_for_param(*id); let substs = Substs::type_params_for_generics(&generics); - write_bounds_like_dyn_trait(&bounds.iter().map(|b| b.clone().subst(&substs)).collect::>(), f)?; + write_bounds_like_dyn_trait( + &bounds.iter().map(|b| b.clone().subst(&substs)).collect::>(), + f, + )?; } } } -- cgit v1.2.3 From b0bb8622eea7cb447ebadb8b5fba43850305e913 Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Fri, 7 Feb 2020 16:39:48 +0100 Subject: Don't print implicit type args from impl Trait --- crates/ra_hir_ty/src/lib.rs | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'crates/ra_hir_ty/src/lib.rs') diff --git a/crates/ra_hir_ty/src/lib.rs b/crates/ra_hir_ty/src/lib.rs index 60c7fd0e5..68c2f0b06 100644 --- a/crates/ra_hir_ty/src/lib.rs +++ b/crates/ra_hir_ty/src/lib.rs @@ -909,9 +909,16 @@ impl HirDisplay for ApplicationTy { } } if self.parameters.len() > 0 { - write!(f, "<")?; - f.write_joined(&*self.parameters.0, ", ")?; - write!(f, ">")?; + let generics = generics(f.db, def.into()); + let (parent_params, self_param, type_params, _impl_trait_params) = + generics.provenance_split(); + let total_len = parent_params + self_param + type_params; + // We print all params except implicit impl Trait params. Still a bit weird; should we leave out parent and self? + if total_len > 0 { + write!(f, "<")?; + f.write_joined(&self.parameters.0[..total_len], ", ")?; + write!(f, ">")?; + } } write!(f, "(")?; f.write_joined(sig.params(), ", ")?; -- cgit v1.2.3 From 9d6061f3bb935c914a6d58df803dd42770f2f7e2 Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Fri, 7 Feb 2020 18:17:23 +0100 Subject: Fix some TODOs --- crates/ra_hir_ty/src/lib.rs | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) (limited to 'crates/ra_hir_ty/src/lib.rs') diff --git a/crates/ra_hir_ty/src/lib.rs b/crates/ra_hir_ty/src/lib.rs index 68c2f0b06..c5fe18c85 100644 --- a/crates/ra_hir_ty/src/lib.rs +++ b/crates/ra_hir_ty/src/lib.rs @@ -287,17 +287,20 @@ pub enum Ty { /// trait and all its parameters are fully known. Projection(ProjectionTy), - /// A type parameter; for example, `T` in `fn f(x: T) {} - // TODO fix documentation + /// A placeholder for a type parameter; for example, `T` in `fn f(x: T) + /// {}` when we're type-checking the body of that function. In this + /// situation, we know this stands for *some* type, but don't know the exact + /// type. Param(TypeParamId), - /// A bound type variable. Used during trait resolution to represent Chalk - /// variables, and in `Dyn` and `Opaque` bounds to represent the `Self` type. - // TODO fix documentation + /// A bound type variable. This is used in various places: when representing + /// some polymorphic type like the type of function `fn f`, the type + /// parameters get turned into variables; during trait resolution, inference + /// variables get turned into bound variables and back; and in `Dyn` the + /// `Self` type is represented with a bound variable as well. Bound(u32), - /// A type variable used during type checking. Not to be confused with a - /// type parameter. + /// A type variable used during type checking. Infer(InferTy), /// A trait object (`dyn Trait` or bare `Trait` in pre-2018 Rust). -- cgit v1.2.3