diff options
Diffstat (limited to 'crates/ra_hir/src')
| -rw-r--r-- | crates/ra_hir/src/code_model.rs | 4 | ||||
| -rw-r--r-- | crates/ra_hir/src/resolve.rs | 32 | ||||
| -rw-r--r-- | crates/ra_hir/src/source_binder.rs | 2 | ||||
| -rw-r--r-- | crates/ra_hir/src/ty/infer.rs | 3 | ||||
| -rw-r--r-- | crates/ra_hir/src/ty/lower.rs | 1 | ||||
| -rw-r--r-- | crates/ra_hir/src/ty/tests.rs | 19 |
6 files changed, 53 insertions, 8 deletions
diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs index e3a7e8e3c..cd501d1f6 100644 --- a/crates/ra_hir/src/code_model.rs +++ b/crates/ra_hir/src/code_model.rs | |||
| @@ -24,7 +24,7 @@ use crate::{ | |||
| 24 | U8, USIZE, | 24 | U8, USIZE, |
| 25 | }, | 25 | }, |
| 26 | nameres::{CrateModuleId, ImportId, ModuleScope, Namespace}, | 26 | nameres::{CrateModuleId, ImportId, ModuleScope, Namespace}, |
| 27 | resolve::{Resolver, TypeNs}, | 27 | resolve::{Resolver, Scope, TypeNs}, |
| 28 | traits::TraitData, | 28 | traits::TraitData, |
| 29 | ty::{ | 29 | ty::{ |
| 30 | primitive::{FloatBitness, FloatTy, IntBitness, IntTy, Signedness}, | 30 | primitive::{FloatBitness, FloatTy, IntBitness, IntTy, Signedness}, |
| @@ -465,7 +465,7 @@ impl Enum { | |||
| 465 | // ...and add generic params, if present | 465 | // ...and add generic params, if present |
| 466 | let p = self.generic_params(db); | 466 | let p = self.generic_params(db); |
| 467 | let r = if !p.params.is_empty() { r.push_generic_params_scope(p) } else { r }; | 467 | let r = if !p.params.is_empty() { r.push_generic_params_scope(p) } else { r }; |
| 468 | r | 468 | r.push_scope(Scope::AdtScope(From::from(self))) |
| 469 | } | 469 | } |
| 470 | } | 470 | } |
| 471 | 471 | ||
diff --git a/crates/ra_hir/src/resolve.rs b/crates/ra_hir/src/resolve.rs index 39f8e1d8a..c46f7e157 100644 --- a/crates/ra_hir/src/resolve.rs +++ b/crates/ra_hir/src/resolve.rs | |||
| @@ -43,8 +43,10 @@ pub(crate) enum Scope { | |||
| 43 | ModuleScope(ModuleItemMap), | 43 | ModuleScope(ModuleItemMap), |
| 44 | /// Brings the generic parameters of an item into scope | 44 | /// Brings the generic parameters of an item into scope |
| 45 | GenericParams(Arc<GenericParams>), | 45 | GenericParams(Arc<GenericParams>), |
| 46 | /// Brings `Self` into scope | 46 | /// Brings `Self` in `impl` block into scope |
| 47 | ImplBlockScope(ImplBlock), | 47 | ImplBlockScope(ImplBlock), |
| 48 | /// Brings `Self` in enum definition into scope | ||
| 49 | AdtScope(Adt), | ||
| 48 | /// Local bindings | 50 | /// Local bindings |
| 49 | ExprScope(ExprScope), | 51 | ExprScope(ExprScope), |
| 50 | } | 52 | } |
| @@ -54,6 +56,7 @@ pub enum TypeNs { | |||
| 54 | SelfType(ImplBlock), | 56 | SelfType(ImplBlock), |
| 55 | GenericParam(u32), | 57 | GenericParam(u32), |
| 56 | Adt(Adt), | 58 | Adt(Adt), |
| 59 | AdtSelfType(Adt), | ||
| 57 | EnumVariant(EnumVariant), | 60 | EnumVariant(EnumVariant), |
| 58 | TypeAlias(TypeAlias), | 61 | TypeAlias(TypeAlias), |
| 59 | BuiltinType(BuiltinType), | 62 | BuiltinType(BuiltinType), |
| @@ -151,6 +154,12 @@ impl Resolver { | |||
| 151 | return Some((TypeNs::SelfType(*impl_), idx)); | 154 | return Some((TypeNs::SelfType(*impl_), idx)); |
| 152 | } | 155 | } |
| 153 | } | 156 | } |
| 157 | Scope::AdtScope(adt) => { | ||
| 158 | if first_name == &SELF_TYPE { | ||
| 159 | let idx = if path.segments.len() == 1 { None } else { Some(1) }; | ||
| 160 | return Some((TypeNs::AdtSelfType(*adt), idx)); | ||
| 161 | } | ||
| 162 | } | ||
| 154 | Scope::ModuleScope(m) => { | 163 | Scope::ModuleScope(m) => { |
| 155 | let (module_def, idx) = m.crate_def_map.resolve_path(db, m.module_id, path); | 164 | let (module_def, idx) = m.crate_def_map.resolve_path(db, m.module_id, path); |
| 156 | let res = match module_def.take_types()? { | 165 | let res = match module_def.take_types()? { |
| @@ -200,7 +209,10 @@ impl Resolver { | |||
| 200 | let skip_to_mod = path.kind != PathKind::Plain && !path.is_self(); | 209 | let skip_to_mod = path.kind != PathKind::Plain && !path.is_self(); |
| 201 | for scope in self.scopes.iter().rev() { | 210 | for scope in self.scopes.iter().rev() { |
| 202 | match scope { | 211 | match scope { |
| 203 | Scope::ExprScope(_) | Scope::GenericParams(_) | Scope::ImplBlockScope(_) | 212 | Scope::AdtScope(_) |
| 213 | | Scope::ExprScope(_) | ||
| 214 | | Scope::GenericParams(_) | ||
| 215 | | Scope::ImplBlockScope(_) | ||
| 204 | if skip_to_mod => | 216 | if skip_to_mod => |
| 205 | { | 217 | { |
| 206 | continue | 218 | continue |
| @@ -233,7 +245,13 @@ impl Resolver { | |||
| 233 | return Some(ResolveValueResult::Partial(ty, 1)); | 245 | return Some(ResolveValueResult::Partial(ty, 1)); |
| 234 | } | 246 | } |
| 235 | } | 247 | } |
| 236 | Scope::ImplBlockScope(_) => continue, | 248 | Scope::AdtScope(adt) if n_segments > 1 => { |
| 249 | if first_name == &SELF_TYPE { | ||
| 250 | let ty = TypeNs::AdtSelfType(*adt); | ||
| 251 | return Some(ResolveValueResult::Partial(ty, 1)); | ||
| 252 | } | ||
| 253 | } | ||
| 254 | Scope::ImplBlockScope(_) | Scope::AdtScope(_) => continue, | ||
| 237 | 255 | ||
| 238 | Scope::ModuleScope(m) => { | 256 | Scope::ModuleScope(m) => { |
| 239 | let (module_def, idx) = m.crate_def_map.resolve_path(db, m.module_id, path); | 257 | let (module_def, idx) = m.crate_def_map.resolve_path(db, m.module_id, path); |
| @@ -389,7 +407,8 @@ pub enum ScopeDef { | |||
| 389 | ModuleDef(ModuleDef), | 407 | ModuleDef(ModuleDef), |
| 390 | MacroDef(MacroDef), | 408 | MacroDef(MacroDef), |
| 391 | GenericParam(u32), | 409 | GenericParam(u32), |
| 392 | SelfType(ImplBlock), | 410 | ImplSelfType(ImplBlock), |
| 411 | AdtSelfType(Adt), | ||
| 393 | LocalBinding(PatId), | 412 | LocalBinding(PatId), |
| 394 | Unknown, | 413 | Unknown, |
| 395 | } | 414 | } |
| @@ -437,7 +456,10 @@ impl Scope { | |||
| 437 | } | 456 | } |
| 438 | } | 457 | } |
| 439 | Scope::ImplBlockScope(i) => { | 458 | Scope::ImplBlockScope(i) => { |
| 440 | f(SELF_TYPE, ScopeDef::SelfType(*i)); | 459 | f(SELF_TYPE, ScopeDef::ImplSelfType(*i)); |
| 460 | } | ||
| 461 | Scope::AdtScope(i) => { | ||
| 462 | f(SELF_TYPE, ScopeDef::AdtSelfType(*i)); | ||
| 441 | } | 463 | } |
| 442 | Scope::ExprScope(e) => { | 464 | Scope::ExprScope(e) => { |
| 443 | e.expr_scopes.entries(e.scope_id).iter().for_each(|e| { | 465 | e.expr_scopes.entries(e.scope_id).iter().for_each(|e| { |
diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_binder.rs index 088335e66..a907d6a9f 100644 --- a/crates/ra_hir/src/source_binder.rs +++ b/crates/ra_hir/src/source_binder.rs | |||
| @@ -216,7 +216,7 @@ impl SourceAnalyzer { | |||
| 216 | let types = self.resolver.resolve_path_in_type_ns_fully(db, &path).map(|ty| match ty { | 216 | let types = self.resolver.resolve_path_in_type_ns_fully(db, &path).map(|ty| match ty { |
| 217 | TypeNs::SelfType(it) => PathResolution::SelfType(it), | 217 | TypeNs::SelfType(it) => PathResolution::SelfType(it), |
| 218 | TypeNs::GenericParam(it) => PathResolution::GenericParam(it), | 218 | TypeNs::GenericParam(it) => PathResolution::GenericParam(it), |
| 219 | TypeNs::Adt(it) => PathResolution::Def(it.into()), | 219 | TypeNs::AdtSelfType(it) | TypeNs::Adt(it) => PathResolution::Def(it.into()), |
| 220 | TypeNs::EnumVariant(it) => PathResolution::Def(it.into()), | 220 | TypeNs::EnumVariant(it) => PathResolution::Def(it.into()), |
| 221 | TypeNs::TypeAlias(it) => PathResolution::Def(it.into()), | 221 | TypeNs::TypeAlias(it) => PathResolution::Def(it.into()), |
| 222 | TypeNs::BuiltinType(it) => PathResolution::Def(it.into()), | 222 | TypeNs::BuiltinType(it) => PathResolution::Def(it.into()), |
diff --git a/crates/ra_hir/src/ty/infer.rs b/crates/ra_hir/src/ty/infer.rs index ca9aefc42..9e5d42509 100644 --- a/crates/ra_hir/src/ty/infer.rs +++ b/crates/ra_hir/src/ty/infer.rs | |||
| @@ -559,6 +559,9 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
| 559 | match resolver.resolve_path_in_type_ns_fully(self.db, &path) { | 559 | match resolver.resolve_path_in_type_ns_fully(self.db, &path) { |
| 560 | Some(TypeNs::Adt(Adt::Struct(it))) => it.into(), | 560 | Some(TypeNs::Adt(Adt::Struct(it))) => it.into(), |
| 561 | Some(TypeNs::Adt(Adt::Union(it))) => it.into(), | 561 | Some(TypeNs::Adt(Adt::Union(it))) => it.into(), |
| 562 | Some(TypeNs::AdtSelfType(Adt::Struct(it))) => it.into(), | ||
| 563 | Some(TypeNs::AdtSelfType(Adt::Union(it))) => it.into(), | ||
| 564 | Some(TypeNs::AdtSelfType(Adt::Enum(it))) => it.into(), | ||
| 562 | Some(TypeNs::EnumVariant(it)) => it.into(), | 565 | Some(TypeNs::EnumVariant(it)) => it.into(), |
| 563 | Some(TypeNs::TypeAlias(it)) => it.into(), | 566 | Some(TypeNs::TypeAlias(it)) => it.into(), |
| 564 | 567 | ||
diff --git a/crates/ra_hir/src/ty/lower.rs b/crates/ra_hir/src/ty/lower.rs index 4b67c82e7..a604c02e2 100644 --- a/crates/ra_hir/src/ty/lower.rs +++ b/crates/ra_hir/src/ty/lower.rs | |||
| @@ -175,6 +175,7 @@ impl Ty { | |||
| 175 | Ty::Param { idx, name } | 175 | Ty::Param { idx, name } |
| 176 | } | 176 | } |
| 177 | TypeNs::SelfType(impl_block) => impl_block.target_ty(db), | 177 | TypeNs::SelfType(impl_block) => impl_block.target_ty(db), |
| 178 | TypeNs::AdtSelfType(adt) => adt.ty(db), | ||
| 178 | 179 | ||
| 179 | TypeNs::Adt(it) => Ty::from_hir_path_inner(db, resolver, resolved_segment, it.into()), | 180 | TypeNs::Adt(it) => Ty::from_hir_path_inner(db, resolver, resolved_segment, it.into()), |
| 180 | TypeNs::BuiltinType(it) => { | 181 | TypeNs::BuiltinType(it) => { |
diff --git a/crates/ra_hir/src/ty/tests.rs b/crates/ra_hir/src/ty/tests.rs index 25dad81eb..03b30adcd 100644 --- a/crates/ra_hir/src/ty/tests.rs +++ b/crates/ra_hir/src/ty/tests.rs | |||
| @@ -135,6 +135,25 @@ mod boxed { | |||
| 135 | } | 135 | } |
| 136 | 136 | ||
| 137 | #[test] | 137 | #[test] |
| 138 | fn infer_adt_self() { | ||
| 139 | let (db, pos) = MockDatabase::with_position( | ||
| 140 | r#" | ||
| 141 | //- /main.rs | ||
| 142 | enum Nat { Succ(Self), Demo(Nat), Zero } | ||
| 143 | |||
| 144 | fn test() { | ||
| 145 | let foo: Nat = Nat::Zero; | ||
| 146 | if let Nat::Succ(x) = foo { | ||
| 147 | x<|> | ||
| 148 | } | ||
| 149 | } | ||
| 150 | |||
| 151 | "#, | ||
| 152 | ); | ||
| 153 | assert_eq!("Nat", type_at_pos(&db, pos)); | ||
| 154 | } | ||
| 155 | |||
| 156 | #[test] | ||
| 138 | fn infer_try() { | 157 | fn infer_try() { |
| 139 | let (mut db, pos) = MockDatabase::with_position( | 158 | let (mut db, pos) = MockDatabase::with_position( |
| 140 | r#" | 159 | r#" |
