diff options
-rw-r--r-- | crates/ra_hir/src/generics.rs | 8 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/tests.rs | 29 | ||||
-rw-r--r-- | crates/ra_syntax/src/ast/extensions.rs | 12 |
3 files changed, 49 insertions, 0 deletions
diff --git a/crates/ra_hir/src/generics.rs b/crates/ra_hir/src/generics.rs index e6482180d..e75337cdf 100644 --- a/crates/ra_hir/src/generics.rs +++ b/crates/ra_hir/src/generics.rs | |||
@@ -75,6 +75,7 @@ impl GenericParams { | |||
75 | }; | 75 | }; |
76 | generics.parent_params = parent.map(|p| db.generic_params(p)); | 76 | generics.parent_params = parent.map(|p| db.generic_params(p)); |
77 | let start = generics.parent_params.as_ref().map(|p| p.params.len()).unwrap_or(0) as u32; | 77 | let start = generics.parent_params.as_ref().map(|p| p.params.len()).unwrap_or(0) as u32; |
78 | // FIXME: add `: Sized` bound for everything except for `Self` in traits | ||
78 | match def { | 79 | match def { |
79 | GenericDef::Function(it) => generics.fill(&it.source(db).ast, start), | 80 | GenericDef::Function(it) => generics.fill(&it.source(db).ast, start), |
80 | GenericDef::Struct(it) => generics.fill(&it.source(db).ast, start), | 81 | GenericDef::Struct(it) => generics.fill(&it.source(db).ast, start), |
@@ -86,6 +87,9 @@ impl GenericParams { | |||
86 | generics.fill(&it.source(db).ast, start + 1); | 87 | generics.fill(&it.source(db).ast, start + 1); |
87 | } | 88 | } |
88 | GenericDef::TypeAlias(it) => generics.fill(&it.source(db).ast, start), | 89 | GenericDef::TypeAlias(it) => generics.fill(&it.source(db).ast, start), |
90 | // Note that we don't add `Self` here: in `impl`s, `Self` is not a | ||
91 | // type-parameter, but rather is a type-alias for impl's target | ||
92 | // type, so this is handled by the resovler. | ||
89 | GenericDef::ImplBlock(it) => generics.fill(&it.source(db).ast, start), | 93 | GenericDef::ImplBlock(it) => generics.fill(&it.source(db).ast, start), |
90 | GenericDef::EnumVariant(_) => {} | 94 | GenericDef::EnumVariant(_) => {} |
91 | } | 95 | } |
@@ -135,6 +139,10 @@ impl GenericParams { | |||
135 | } | 139 | } |
136 | 140 | ||
137 | fn add_where_predicate_from_bound(&mut self, bound: ast::TypeBound, type_ref: TypeRef) { | 141 | fn add_where_predicate_from_bound(&mut self, bound: ast::TypeBound, type_ref: TypeRef) { |
142 | if bound.has_question_mark() { | ||
143 | // FIXME: remove this bound | ||
144 | return; | ||
145 | } | ||
138 | let path = bound | 146 | let path = bound |
139 | .type_ref() | 147 | .type_ref() |
140 | .and_then(|tr| match tr { | 148 | .and_then(|tr| match tr { |
diff --git a/crates/ra_hir/src/ty/tests.rs b/crates/ra_hir/src/ty/tests.rs index 6c2d857bc..57fd5492d 100644 --- a/crates/ra_hir/src/ty/tests.rs +++ b/crates/ra_hir/src/ty/tests.rs | |||
@@ -3029,6 +3029,35 @@ fn test(s: S) { | |||
3029 | } | 3029 | } |
3030 | 3030 | ||
3031 | #[test] | 3031 | #[test] |
3032 | fn deref_trait_with_question_mark_size() { | ||
3033 | let t = type_at( | ||
3034 | r#" | ||
3035 | //- /main.rs | ||
3036 | #[lang = "deref"] | ||
3037 | trait Deref { | ||
3038 | type Target; | ||
3039 | fn deref(&self) -> &Self::Target; | ||
3040 | } | ||
3041 | |||
3042 | struct Arc<T>; | ||
3043 | impl<T: ?Sized> Deref for Arc<T> { | ||
3044 | type Target = T; | ||
3045 | } | ||
3046 | |||
3047 | struct S; | ||
3048 | impl S { | ||
3049 | fn foo(&self) -> u128 {} | ||
3050 | } | ||
3051 | |||
3052 | fn test(s: Arc<S>) { | ||
3053 | (*s, s.foo())<|> | ||
3054 | } | ||
3055 | "#, | ||
3056 | ); | ||
3057 | assert_eq!(t, "(S, u128)"); | ||
3058 | } | ||
3059 | |||
3060 | #[test] | ||
3032 | fn obligation_from_function_clause() { | 3061 | fn obligation_from_function_clause() { |
3033 | let t = type_at( | 3062 | let t = type_at( |
3034 | r#" | 3063 | r#" |
diff --git a/crates/ra_syntax/src/ast/extensions.rs b/crates/ra_syntax/src/ast/extensions.rs index 2a59cf653..efe261fc2 100644 --- a/crates/ra_syntax/src/ast/extensions.rs +++ b/crates/ra_syntax/src/ast/extensions.rs | |||
@@ -382,6 +382,18 @@ impl ast::WherePred { | |||
382 | } | 382 | } |
383 | } | 383 | } |
384 | 384 | ||
385 | impl ast::TypeBound { | ||
386 | pub fn question_mark_token(&self) -> Option<SyntaxToken> { | ||
387 | self.syntax() | ||
388 | .children_with_tokens() | ||
389 | .filter_map(|it| it.into_token()) | ||
390 | .find(|it| it.kind() == T![?]) | ||
391 | } | ||
392 | pub fn has_question_mark(&self) -> bool { | ||
393 | self.question_mark_token().is_some() | ||
394 | } | ||
395 | } | ||
396 | |||
385 | impl ast::TraitDef { | 397 | impl ast::TraitDef { |
386 | pub fn is_auto(&self) -> bool { | 398 | pub fn is_auto(&self) -> bool { |
387 | self.syntax().children_with_tokens().any(|t| t.kind() == T![auto]) | 399 | self.syntax().children_with_tokens().any(|t| t.kind() == T![auto]) |