aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_ty/src/lib.rs
diff options
context:
space:
mode:
authorFlorian Diebold <[email protected]>2020-02-02 12:04:22 +0000
committerFlorian Diebold <[email protected]>2020-02-07 17:28:10 +0000
commit3397ca679fb0156c9f102ab82354e2bcef5f4dd1 (patch)
treee61d0eba1a918b9e6802baf6dbeb99f3d92afd82 /crates/ra_hir_ty/src/lib.rs
parentc6654fd4a70ef149a842e42dc9ef86838148fbe7 (diff)
Fix APIT some more
Diffstat (limited to 'crates/ra_hir_ty/src/lib.rs')
-rw-r--r--crates/ra_hir_ty/src/lib.rs153
1 files changed, 80 insertions, 73 deletions
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;
44use std::{fmt, iter, mem}; 44use std::{fmt, iter, mem};
45 45
46use hir_def::{ 46use hir_def::{
47 expr::ExprId, type_ref::Mutability, AdtId, AssocContainerId, DefWithBodyId, GenericDefId, 47 expr::ExprId, generics::TypeParamProvenance, type_ref::Mutability, AdtId, AssocContainerId,
48 HasModule, Lookup, TraitId, TypeAliasId, TypeParamId, generics::TypeParamProvenance, 48 DefWithBodyId, GenericDefId, HasModule, Lookup, TraitId, TypeAliasId, TypeParamId,
49}; 49};
50use ra_db::{impl_intern_key, salsa, CrateId};
51use hir_expand::name::Name; 50use hir_expand::name::Name;
51use ra_db::{impl_intern_key, salsa, CrateId};
52 52
53use crate::{ 53use crate::{
54 db::HirDatabase, 54 db::HirDatabase,
@@ -360,9 +360,7 @@ impl Substs {
360 360
361 /// Return Substs that replace each parameter by itself (i.e. `Ty::Param`). 361 /// Return Substs that replace each parameter by itself (i.e. `Ty::Param`).
362 pub(crate) fn type_params(generic_params: &Generics) -> Substs { 362 pub(crate) fn type_params(generic_params: &Generics) -> Substs {
363 Substs( 363 Substs(generic_params.iter().map(|(id, _)| Ty::Param(id)).collect())
364 generic_params.iter().map(|(id, _)| Ty::Param(id)).collect(),
365 )
366 } 364 }
367 365
368 /// Return Substs that replace each parameter by a bound variable. 366 /// Return Substs that replace each parameter by a bound variable.
@@ -448,7 +446,9 @@ pub struct Binders<T> {
448} 446}
449 447
450impl<T> Binders<T> { 448impl<T> Binders<T> {
451 pub fn new(num_binders: usize, value: T) -> Self { Self { num_binders, value } } 449 pub fn new(num_binders: usize, value: T) -> Self {
450 Self { num_binders, value }
451 }
452} 452}
453 453
454impl<T: TypeWalk> Binders<T> { 454impl<T: TypeWalk> Binders<T> {
@@ -906,8 +906,7 @@ impl HirDisplay for ApplicationTy {
906 write!(f, ") -> {}", sig.ret().display(f.db))?; 906 write!(f, ") -> {}", sig.ret().display(f.db))?;
907 } 907 }
908 TypeCtor::FnDef(def) => { 908 TypeCtor::FnDef(def) => {
909 let sig = f.db.callable_item_signature(def) 909 let sig = f.db.callable_item_signature(def).subst(&self.parameters);
910 .subst(&self.parameters);
911 let name = match def { 910 let name = match def {
912 CallableDef::FunctionId(ff) => f.db.function_data(ff).name.clone(), 911 CallableDef::FunctionId(ff) => f.db.function_data(ff).name.clone(),
913 CallableDef::StructId(s) => f.db.struct_data(s).name.clone(), 912 CallableDef::StructId(s) => f.db.struct_data(s).name.clone(),
@@ -1037,17 +1036,19 @@ impl HirDisplay for Ty {
1037 Ty::Apply(a_ty) => a_ty.hir_fmt(f)?, 1036 Ty::Apply(a_ty) => a_ty.hir_fmt(f)?,
1038 Ty::Projection(p_ty) => p_ty.hir_fmt(f)?, 1037 Ty::Projection(p_ty) => p_ty.hir_fmt(f)?,
1039 Ty::Param(id) => { 1038 Ty::Param(id) => {
1040 let generic_params = f.db.generic_params(id.parent); 1039 let generics = generics(f.db, id.parent);
1041 let param_data = &generic_params.types[id.local_id]; 1040 let param_data = &generics.params.types[id.local_id];
1042 match param_data.provenance { 1041 match param_data.provenance {
1043 TypeParamProvenance::TypeParamList | TypeParamProvenance::TraitSelf => { 1042 TypeParamProvenance::TypeParamList | TypeParamProvenance::TraitSelf => {
1044 write!(f, "{}", param_data.name.clone().unwrap_or_else(Name::missing))? 1043 write!(f, "{}", param_data.name.clone().unwrap_or_else(Name::missing))?
1045 } 1044 }
1046 TypeParamProvenance::ArgumentImplTrait => { 1045 TypeParamProvenance::ArgumentImplTrait => {
1047 write!(f, "impl TODO")? 1046 let bounds = f.db.generic_predicates_for_param(*id);
1047 write!(f, "impl ")?;
1048 write_bounds_like_dyn_trait(&bounds, f)?;
1048 } 1049 }
1049 } 1050 }
1050 }, 1051 }
1051 Ty::Bound(idx) => write!(f, "?{}", idx)?, 1052 Ty::Bound(idx) => write!(f, "?{}", idx)?,
1052 Ty::Dyn(predicates) | Ty::Opaque(predicates) => { 1053 Ty::Dyn(predicates) | Ty::Opaque(predicates) => {
1053 match self { 1054 match self {
@@ -1055,66 +1056,7 @@ impl HirDisplay for Ty {
1055 Ty::Opaque(_) => write!(f, "impl ")?, 1056 Ty::Opaque(_) => write!(f, "impl ")?,
1056 _ => unreachable!(), 1057 _ => unreachable!(),
1057 }; 1058 };
1058 // Note: This code is written to produce nice results (i.e. 1059 write_bounds_like_dyn_trait(&predicates, f)?;
1059 // corresponding to surface Rust) for types that can occur in
1060 // actual Rust. It will have weird results if the predicates
1061 // aren't as expected (i.e. self types = $0, projection
1062 // predicates for a certain trait come after the Implemented
1063 // predicate for that trait).
1064 let mut first = true;
1065 let mut angle_open = false;
1066 for p in predicates.iter() {
1067 match p {
1068 GenericPredicate::Implemented(trait_ref) => {
1069 if angle_open {
1070 write!(f, ">")?;
1071 }
1072 if !first {
1073 write!(f, " + ")?;
1074 }
1075 // We assume that the self type is $0 (i.e. the
1076 // existential) here, which is the only thing that's
1077 // possible in actual Rust, and hence don't print it
1078 write!(f, "{}", f.db.trait_data(trait_ref.trait_).name.clone())?;
1079 if trait_ref.substs.len() > 1 {
1080 write!(f, "<")?;
1081 f.write_joined(&trait_ref.substs[1..], ", ")?;
1082 // there might be assoc type bindings, so we leave the angle brackets open
1083 angle_open = true;
1084 }
1085 }
1086 GenericPredicate::Projection(projection_pred) => {
1087 // in types in actual Rust, these will always come
1088 // after the corresponding Implemented predicate
1089 if angle_open {
1090 write!(f, ", ")?;
1091 } else {
1092 write!(f, "<")?;
1093 angle_open = true;
1094 }
1095 let name =
1096 f.db.type_alias_data(projection_pred.projection_ty.associated_ty)
1097 .name
1098 .clone();
1099 write!(f, "{} = ", name)?;
1100 projection_pred.ty.hir_fmt(f)?;
1101 }
1102 GenericPredicate::Error => {
1103 if angle_open {
1104 // impl Trait<X, {error}>
1105 write!(f, ", ")?;
1106 } else if !first {
1107 // impl Trait + {error}
1108 write!(f, " + ")?;
1109 }
1110 p.hir_fmt(f)?;
1111 }
1112 }
1113 first = false;
1114 }
1115 if angle_open {
1116 write!(f, ">")?;
1117 }
1118 } 1060 }
1119 Ty::Unknown => write!(f, "{{unknown}}")?, 1061 Ty::Unknown => write!(f, "{{unknown}}")?,
1120 Ty::Infer(..) => write!(f, "_")?, 1062 Ty::Infer(..) => write!(f, "_")?,
@@ -1123,6 +1065,71 @@ impl HirDisplay for Ty {
1123 } 1065 }
1124} 1066}
1125 1067
1068fn write_bounds_like_dyn_trait(
1069 predicates: &[GenericPredicate],
1070 f: &mut HirFormatter<impl HirDatabase>,
1071) -> fmt::Result {
1072 // Note: This code is written to produce nice results (i.e.
1073 // corresponding to surface Rust) for types that can occur in
1074 // actual Rust. It will have weird results if the predicates
1075 // aren't as expected (i.e. self types = $0, projection
1076 // predicates for a certain trait come after the Implemented
1077 // predicate for that trait).
1078 let mut first = true;
1079 let mut angle_open = false;
1080 for p in predicates.iter() {
1081 match p {
1082 GenericPredicate::Implemented(trait_ref) => {
1083 if angle_open {
1084 write!(f, ">")?;
1085 }
1086 if !first {
1087 write!(f, " + ")?;
1088 }
1089 // We assume that the self type is $0 (i.e. the
1090 // existential) here, which is the only thing that's
1091 // possible in actual Rust, and hence don't print it
1092 write!(f, "{}", f.db.trait_data(trait_ref.trait_).name.clone())?;
1093 if trait_ref.substs.len() > 1 {
1094 write!(f, "<")?;
1095 f.write_joined(&trait_ref.substs[1..], ", ")?;
1096 // there might be assoc type bindings, so we leave the angle brackets open
1097 angle_open = true;
1098 }
1099 }
1100 GenericPredicate::Projection(projection_pred) => {
1101 // in types in actual Rust, these will always come
1102 // after the corresponding Implemented predicate
1103 if angle_open {
1104 write!(f, ", ")?;
1105 } else {
1106 write!(f, "<")?;
1107 angle_open = true;
1108 }
1109 let name =
1110 f.db.type_alias_data(projection_pred.projection_ty.associated_ty).name.clone();
1111 write!(f, "{} = ", name)?;
1112 projection_pred.ty.hir_fmt(f)?;
1113 }
1114 GenericPredicate::Error => {
1115 if angle_open {
1116 // impl Trait<X, {error}>
1117 write!(f, ", ")?;
1118 } else if !first {
1119 // impl Trait + {error}
1120 write!(f, " + ")?;
1121 }
1122 p.hir_fmt(f)?;
1123 }
1124 }
1125 first = false;
1126 }
1127 if angle_open {
1128 write!(f, ">")?;
1129 }
1130 Ok(())
1131}
1132
1126impl TraitRef { 1133impl TraitRef {
1127 fn hir_fmt_ext(&self, f: &mut HirFormatter<impl HirDatabase>, use_as: bool) -> fmt::Result { 1134 fn hir_fmt_ext(&self, f: &mut HirFormatter<impl HirDatabase>, use_as: bool) -> fmt::Result {
1128 if f.should_truncate() { 1135 if f.should_truncate() {