aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src/generics.rs
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2019-09-22 23:01:38 +0100
committerGitHub <[email protected]>2019-09-22 23:01:38 +0100
commitc2d9cca4e42ad052cf8a37ba3f6d9eacae07cbea (patch)
tree9f800613bde5ef6b80ab6a637990a6be69995dd4 /crates/ra_hir/src/generics.rs
parentefcbca95595d31bb4c2c6782530d5a7a64a4191f (diff)
parentbc905d202c613a831f7c1abb846b612900a9b43a (diff)
Merge #1895
1895: Handle associated type shorthand (`T::Item`) (Second attempt) r=flodiebold a=flodiebold This is only allowed for generic parameters (including `Self` in traits), and special care needs to be taken to not run into cycles while resolving it, because we use the where clauses of the generic parameter to find candidates for the trait containing the associated type, but the where clauses may themselves contain instances of short-hand associated types. In some cases this is even fine, e.g. we might have `T: Trait<U::Item>, U: Iterator`. If there is a cycle, we'll currently panic, which isn't great, but better than overflowing the stack... Co-authored-by: Florian Diebold <[email protected]>
Diffstat (limited to 'crates/ra_hir/src/generics.rs')
-rw-r--r--crates/ra_hir/src/generics.rs11
1 files changed, 8 insertions, 3 deletions
diff --git a/crates/ra_hir/src/generics.rs b/crates/ra_hir/src/generics.rs
index 77fb76bfc..ccb777492 100644
--- a/crates/ra_hir/src/generics.rs
+++ b/crates/ra_hir/src/generics.rs
@@ -26,8 +26,9 @@ pub struct GenericParam {
26} 26}
27 27
28/// Data about the generic parameters of a function, struct, impl, etc. 28/// Data about the generic parameters of a function, struct, impl, etc.
29#[derive(Clone, PartialEq, Eq, Debug, Default)] 29#[derive(Clone, PartialEq, Eq, Debug)]
30pub struct GenericParams { 30pub struct GenericParams {
31 pub(crate) def: GenericDef,
31 pub(crate) parent_params: Option<Arc<GenericParams>>, 32 pub(crate) parent_params: Option<Arc<GenericParams>>,
32 pub(crate) params: Vec<GenericParam>, 33 pub(crate) params: Vec<GenericParam>,
33 pub(crate) where_predicates: Vec<WherePredicate>, 34 pub(crate) where_predicates: Vec<WherePredicate>,
@@ -69,7 +70,6 @@ impl GenericParams {
69 db: &(impl DefDatabase + AstDatabase), 70 db: &(impl DefDatabase + AstDatabase),
70 def: GenericDef, 71 def: GenericDef,
71 ) -> Arc<GenericParams> { 72 ) -> Arc<GenericParams> {
72 let mut generics = GenericParams::default();
73 let parent = match def { 73 let parent = match def {
74 GenericDef::Function(it) => it.container(db).map(GenericDef::from), 74 GenericDef::Function(it) => it.container(db).map(GenericDef::from),
75 GenericDef::TypeAlias(it) => it.container(db).map(GenericDef::from), 75 GenericDef::TypeAlias(it) => it.container(db).map(GenericDef::from),
@@ -77,7 +77,12 @@ impl GenericParams {
77 GenericDef::Adt(_) | GenericDef::Trait(_) => None, 77 GenericDef::Adt(_) | GenericDef::Trait(_) => None,
78 GenericDef::ImplBlock(_) => None, 78 GenericDef::ImplBlock(_) => None,
79 }; 79 };
80 generics.parent_params = parent.map(|p| db.generic_params(p)); 80 let mut generics = GenericParams {
81 def,
82 params: Vec::new(),
83 parent_params: parent.map(|p| db.generic_params(p)),
84 where_predicates: Vec::new(),
85 };
81 let start = generics.parent_params.as_ref().map(|p| p.params.len()).unwrap_or(0) as u32; 86 let start = generics.parent_params.as_ref().map(|p| p.params.len()).unwrap_or(0) as u32;
82 // FIXME: add `: Sized` bound for everything except for `Self` in traits 87 // FIXME: add `: Sized` bound for everything except for `Self` in traits
83 match def { 88 match def {