aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/ra_hir/src/source_binder.rs2
-rw-r--r--crates/ra_hir_def/src/body.rs7
-rw-r--r--crates/ra_hir_def/src/nameres.rs30
-rw-r--r--crates/ra_hir_def/src/nameres/collector.rs4
-rw-r--r--crates/ra_hir_def/src/nameres/path_resolution.rs71
-rw-r--r--crates/ra_hir_def/src/resolver.rs38
-rw-r--r--crates/ra_hir_ty/src/tests.rs36
7 files changed, 157 insertions, 31 deletions
diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_binder.rs
index 1661d92a2..0df7a7cb4 100644
--- a/crates/ra_hir/src/source_binder.rs
+++ b/crates/ra_hir/src/source_binder.rs
@@ -286,7 +286,7 @@ impl SourceAnalyzer {
286 286
287 let items = self 287 let items = self
288 .resolver 288 .resolver
289 .resolve_module_path(db, &path) 289 .resolve_module_path_in_items(db, &path)
290 .take_types() 290 .take_types()
291 .map(|it| PathResolution::Def(it.into())); 291 .map(|it| PathResolution::Def(it.into()));
292 types.or(values).or(items).or_else(|| { 292 types.or(values).or(items).or_else(|| {
diff --git a/crates/ra_hir_def/src/body.rs b/crates/ra_hir_def/src/body.rs
index 69508dd8a..239f35229 100644
--- a/crates/ra_hir_def/src/body.rs
+++ b/crates/ra_hir_def/src/body.rs
@@ -15,7 +15,7 @@ use rustc_hash::FxHashMap;
15use crate::{ 15use crate::{
16 db::DefDatabase, 16 db::DefDatabase,
17 expr::{Expr, ExprId, Pat, PatId}, 17 expr::{Expr, ExprId, Pat, PatId},
18 nameres::CrateDefMap, 18 nameres::{BuiltinShadowMode, CrateDefMap},
19 path::Path, 19 path::Path,
20 src::HasSource, 20 src::HasSource,
21 DefWithBodyId, HasModule, Lookup, ModuleId, 21 DefWithBodyId, HasModule, Lookup, ModuleId,
@@ -83,7 +83,10 @@ impl Expander {
83 } 83 }
84 84
85 fn resolve_path_as_macro(&self, db: &impl DefDatabase, path: &Path) -> Option<MacroDefId> { 85 fn resolve_path_as_macro(&self, db: &impl DefDatabase, path: &Path) -> Option<MacroDefId> {
86 self.crate_def_map.resolve_path(db, self.module.local_id, path).0.take_macros() 86 self.crate_def_map
87 .resolve_path(db, self.module.local_id, path, BuiltinShadowMode::Other)
88 .0
89 .take_macros()
87 } 90 }
88} 91}
89 92
diff --git a/crates/ra_hir_def/src/nameres.rs b/crates/ra_hir_def/src/nameres.rs
index df42ea84a..9aaf7736b 100644
--- a/crates/ra_hir_def/src/nameres.rs
+++ b/crates/ra_hir_def/src/nameres.rs
@@ -149,6 +149,16 @@ static BUILTIN_SCOPE: Lazy<FxHashMap<Name, Resolution>> = Lazy::new(|| {
149 .collect() 149 .collect()
150}); 150});
151 151
152/// Shadow mode for builtin type
153/// Builtin type can be shadowed by same name mode
154#[derive(Debug, Copy, Clone, PartialEq, Eq)]
155pub enum BuiltinShadowMode {
156 // Prefer Module
157 Module,
158 // Prefer Other Types
159 Other,
160}
161
152/// Legacy macros can only be accessed through special methods like `get_legacy_macros`. 162/// Legacy macros can only be accessed through special methods like `get_legacy_macros`.
153/// Other methods will only resolve values, types and module scoped macros only. 163/// Other methods will only resolve values, types and module scoped macros only.
154impl ModuleScope { 164impl ModuleScope {
@@ -178,8 +188,20 @@ impl ModuleScope {
178 } 188 }
179 189
180 /// Get a name from current module scope, legacy macros are not included 190 /// Get a name from current module scope, legacy macros are not included
181 pub fn get(&self, name: &Name) -> Option<&Resolution> { 191 pub fn get(&self, name: &Name, shadow: BuiltinShadowMode) -> Option<&Resolution> {
182 self.items.get(name).or_else(|| BUILTIN_SCOPE.get(name)) 192 match shadow {
193 BuiltinShadowMode::Module => self.items.get(name).or_else(|| BUILTIN_SCOPE.get(name)),
194 BuiltinShadowMode::Other => {
195 let item = self.items.get(name);
196 if let Some(res) = item {
197 if let Some(ModuleDefId::ModuleId(_)) = res.def.take_types() {
198 return BUILTIN_SCOPE.get(name).or(item);
199 }
200 }
201
202 item.or_else(|| BUILTIN_SCOPE.get(name))
203 }
204 }
183 } 205 }
184 206
185 pub fn traits<'a>(&'a self) -> impl Iterator<Item = TraitId> + 'a { 207 pub fn traits<'a>(&'a self) -> impl Iterator<Item = TraitId> + 'a {
@@ -250,8 +272,10 @@ impl CrateDefMap {
250 db: &impl DefDatabase, 272 db: &impl DefDatabase,
251 original_module: LocalModuleId, 273 original_module: LocalModuleId,
252 path: &Path, 274 path: &Path,
275 shadow: BuiltinShadowMode,
253 ) -> (PerNs, Option<usize>) { 276 ) -> (PerNs, Option<usize>) {
254 let res = self.resolve_path_fp_with_macro(db, ResolveMode::Other, original_module, path); 277 let res =
278 self.resolve_path_fp_with_macro(db, ResolveMode::Other, original_module, path, shadow);
255 (res.resolved_def, res.segment_index) 279 (res.resolved_def, res.segment_index)
256 } 280 }
257} 281}
diff --git a/crates/ra_hir_def/src/nameres/collector.rs b/crates/ra_hir_def/src/nameres/collector.rs
index fd8245113..d4bfcae1d 100644
--- a/crates/ra_hir_def/src/nameres/collector.rs
+++ b/crates/ra_hir_def/src/nameres/collector.rs
@@ -19,7 +19,7 @@ use crate::{
19 db::DefDatabase, 19 db::DefDatabase,
20 nameres::{ 20 nameres::{
21 diagnostics::DefDiagnostic, mod_resolution::ModDir, path_resolution::ReachedFixedPoint, 21 diagnostics::DefDiagnostic, mod_resolution::ModDir, path_resolution::ReachedFixedPoint,
22 raw, CrateDefMap, ModuleData, Resolution, ResolveMode, 22 raw, BuiltinShadowMode, CrateDefMap, ModuleData, Resolution, ResolveMode,
23 }, 23 },
24 path::{Path, PathKind}, 24 path::{Path, PathKind},
25 per_ns::PerNs, 25 per_ns::PerNs,
@@ -299,6 +299,7 @@ where
299 ResolveMode::Import, 299 ResolveMode::Import,
300 module_id, 300 module_id,
301 &import.path, 301 &import.path,
302 BuiltinShadowMode::Module,
302 ); 303 );
303 304
304 (res.resolved_def, res.reached_fixedpoint) 305 (res.resolved_def, res.reached_fixedpoint)
@@ -477,6 +478,7 @@ where
477 ResolveMode::Other, 478 ResolveMode::Other,
478 *module_id, 479 *module_id,
479 path, 480 path,
481 BuiltinShadowMode::Module,
480 ); 482 );
481 483
482 if let Some(def) = resolved_res.resolved_def.take_macros() { 484 if let Some(def) = resolved_res.resolved_def.take_macros() {
diff --git a/crates/ra_hir_def/src/nameres/path_resolution.rs b/crates/ra_hir_def/src/nameres/path_resolution.rs
index b72c55bd1..174ae9d38 100644
--- a/crates/ra_hir_def/src/nameres/path_resolution.rs
+++ b/crates/ra_hir_def/src/nameres/path_resolution.rs
@@ -16,7 +16,7 @@ use test_utils::tested_by;
16 16
17use crate::{ 17use crate::{
18 db::DefDatabase, 18 db::DefDatabase,
19 nameres::CrateDefMap, 19 nameres::{BuiltinShadowMode, CrateDefMap},
20 path::{Path, PathKind}, 20 path::{Path, PathKind},
21 per_ns::PerNs, 21 per_ns::PerNs,
22 AdtId, EnumVariantId, LocalModuleId, ModuleDefId, ModuleId, 22 AdtId, EnumVariantId, LocalModuleId, ModuleDefId, ModuleId,
@@ -68,8 +68,10 @@ impl CrateDefMap {
68 mode: ResolveMode, 68 mode: ResolveMode,
69 original_module: LocalModuleId, 69 original_module: LocalModuleId,
70 path: &Path, 70 path: &Path,
71 shadow: BuiltinShadowMode,
71 ) -> ResolvePathResult { 72 ) -> ResolvePathResult {
72 let mut segments = path.segments.iter().enumerate(); 73 let mut segments = path.segments.iter().enumerate().peekable();
74
73 let mut curr_per_ns: PerNs = match path.kind { 75 let mut curr_per_ns: PerNs = match path.kind {
74 PathKind::DollarCrate(krate) => { 76 PathKind::DollarCrate(krate) => {
75 if krate == self.krate { 77 if krate == self.krate {
@@ -101,7 +103,11 @@ impl CrateDefMap {
101 None => return ResolvePathResult::empty(ReachedFixedPoint::Yes), 103 None => return ResolvePathResult::empty(ReachedFixedPoint::Yes),
102 }; 104 };
103 log::debug!("resolving {:?} in crate root (+ extern prelude)", segment); 105 log::debug!("resolving {:?} in crate root (+ extern prelude)", segment);
104 self.resolve_name_in_crate_root_or_extern_prelude(&segment.name) 106
107 self.resolve_name_in_crate_root_or_extern_prelude(
108 &segment.name,
109 prefer_module(&mut segments, shadow),
110 )
105 } 111 }
106 PathKind::Plain => { 112 PathKind::Plain => {
107 let segment = match segments.next() { 113 let segment = match segments.next() {
@@ -109,7 +115,12 @@ impl CrateDefMap {
109 None => return ResolvePathResult::empty(ReachedFixedPoint::Yes), 115 None => return ResolvePathResult::empty(ReachedFixedPoint::Yes),
110 }; 116 };
111 log::debug!("resolving {:?} in module", segment); 117 log::debug!("resolving {:?} in module", segment);
112 self.resolve_name_in_module(db, original_module, &segment.name) 118 self.resolve_name_in_module(
119 db,
120 original_module,
121 &segment.name,
122 prefer_module(&mut segments, shadow),
123 )
113 } 124 }
114 PathKind::Super => { 125 PathKind::Super => {
115 if let Some(p) = self.modules[original_module].parent { 126 if let Some(p) = self.modules[original_module].parent {
@@ -139,7 +150,7 @@ impl CrateDefMap {
139 } 150 }
140 }; 151 };
141 152
142 for (i, segment) in segments { 153 while let Some((i, segment)) = segments.next() {
143 let curr = match curr_per_ns.take_types() { 154 let curr = match curr_per_ns.take_types() {
144 Some(r) => r, 155 Some(r) => r,
145 None => { 156 None => {
@@ -160,7 +171,7 @@ impl CrateDefMap {
160 Path { segments: path.segments[i..].to_vec(), kind: PathKind::Self_ }; 171 Path { segments: path.segments[i..].to_vec(), kind: PathKind::Self_ };
161 log::debug!("resolving {:?} in other crate", path); 172 log::debug!("resolving {:?} in other crate", path);
162 let defp_map = db.crate_def_map(module.krate); 173 let defp_map = db.crate_def_map(module.krate);
163 let (def, s) = defp_map.resolve_path(db, module.local_id, &path); 174 let (def, s) = defp_map.resolve_path(db, module.local_id, &path, shadow);
164 return ResolvePathResult::with( 175 return ResolvePathResult::with(
165 def, 176 def,
166 ReachedFixedPoint::Yes, 177 ReachedFixedPoint::Yes,
@@ -169,7 +180,10 @@ impl CrateDefMap {
169 } 180 }
170 181
171 // Since it is a qualified path here, it should not contains legacy macros 182 // Since it is a qualified path here, it should not contains legacy macros
172 match self[module.local_id].scope.get(&segment.name) { 183 match self[module.local_id]
184 .scope
185 .get(&segment.name, prefer_module(&mut segments, shadow))
186 {
173 Some(res) => res.def, 187 Some(res) => res.def,
174 _ => { 188 _ => {
175 log::debug!("path segment {:?} not found", segment.name); 189 log::debug!("path segment {:?} not found", segment.name);
@@ -212,7 +226,22 @@ impl CrateDefMap {
212 } 226 }
213 }; 227 };
214 } 228 }
215 ResolvePathResult::with(curr_per_ns, ReachedFixedPoint::Yes, None) 229 return ResolvePathResult::with(curr_per_ns, ReachedFixedPoint::Yes, None);
230
231 // if it is not the last segment, we prefer builtin as module
232 fn prefer_module<I>(
233 segments: &mut std::iter::Peekable<I>,
234 shadow: BuiltinShadowMode,
235 ) -> BuiltinShadowMode
236 where
237 I: Iterator,
238 {
239 if segments.peek().is_some() {
240 BuiltinShadowMode::Module
241 } else {
242 shadow
243 }
244 }
216 } 245 }
217 246
218 fn resolve_name_in_module( 247 fn resolve_name_in_module(
@@ -220,6 +249,7 @@ impl CrateDefMap {
220 db: &impl DefDatabase, 249 db: &impl DefDatabase,
221 module: LocalModuleId, 250 module: LocalModuleId,
222 name: &Name, 251 name: &Name,
252 shadow: BuiltinShadowMode,
223 ) -> PerNs { 253 ) -> PerNs {
224 // Resolve in: 254 // Resolve in:
225 // - legacy scope of macro 255 // - legacy scope of macro
@@ -228,23 +258,33 @@ impl CrateDefMap {
228 // - std prelude 258 // - std prelude
229 let from_legacy_macro = 259 let from_legacy_macro =
230 self[module].scope.get_legacy_macro(name).map_or_else(PerNs::none, PerNs::macros); 260 self[module].scope.get_legacy_macro(name).map_or_else(PerNs::none, PerNs::macros);
231 let from_scope = self[module].scope.get(name).map_or_else(PerNs::none, |res| res.def); 261 let from_scope =
262 self[module].scope.get(name, shadow).map_or_else(PerNs::none, |res| res.def);
232 let from_extern_prelude = 263 let from_extern_prelude =
233 self.extern_prelude.get(name).map_or(PerNs::none(), |&it| PerNs::types(it)); 264 self.extern_prelude.get(name).map_or(PerNs::none(), |&it| PerNs::types(it));
234 let from_prelude = self.resolve_in_prelude(db, name); 265 let from_prelude = self.resolve_in_prelude(db, name, shadow);
235 266
236 from_legacy_macro.or(from_scope).or(from_extern_prelude).or(from_prelude) 267 from_legacy_macro.or(from_scope).or(from_extern_prelude).or(from_prelude)
237 } 268 }
238 269
239 fn resolve_name_in_crate_root_or_extern_prelude(&self, name: &Name) -> PerNs { 270 fn resolve_name_in_crate_root_or_extern_prelude(
271 &self,
272 name: &Name,
273 shadow: BuiltinShadowMode,
274 ) -> PerNs {
240 let from_crate_root = 275 let from_crate_root =
241 self[self.root].scope.get(name).map_or_else(PerNs::none, |res| res.def); 276 self[self.root].scope.get(name, shadow).map_or_else(PerNs::none, |res| res.def);
242 let from_extern_prelude = self.resolve_name_in_extern_prelude(name); 277 let from_extern_prelude = self.resolve_name_in_extern_prelude(name);
243 278
244 from_crate_root.or(from_extern_prelude) 279 from_crate_root.or(from_extern_prelude)
245 } 280 }
246 281
247 fn resolve_in_prelude(&self, db: &impl DefDatabase, name: &Name) -> PerNs { 282 fn resolve_in_prelude(
283 &self,
284 db: &impl DefDatabase,
285 name: &Name,
286 shadow: BuiltinShadowMode,
287 ) -> PerNs {
248 if let Some(prelude) = self.prelude { 288 if let Some(prelude) = self.prelude {
249 let keep; 289 let keep;
250 let def_map = if prelude.krate == self.krate { 290 let def_map = if prelude.krate == self.krate {
@@ -254,7 +294,10 @@ impl CrateDefMap {
254 keep = db.crate_def_map(prelude.krate); 294 keep = db.crate_def_map(prelude.krate);
255 &keep 295 &keep
256 }; 296 };
257 def_map[prelude.local_id].scope.get(name).map_or_else(PerNs::none, |res| res.def) 297 def_map[prelude.local_id]
298 .scope
299 .get(name, shadow)
300 .map_or_else(PerNs::none, |res| res.def)
258 } else { 301 } else {
259 PerNs::none() 302 PerNs::none()
260 } 303 }
diff --git a/crates/ra_hir_def/src/resolver.rs b/crates/ra_hir_def/src/resolver.rs
index 0847f6dcf..7d4df222e 100644
--- a/crates/ra_hir_def/src/resolver.rs
+++ b/crates/ra_hir_def/src/resolver.rs
@@ -14,7 +14,7 @@ use crate::{
14 db::DefDatabase, 14 db::DefDatabase,
15 expr::{ExprId, PatId}, 15 expr::{ExprId, PatId},
16 generics::GenericParams, 16 generics::GenericParams,
17 nameres::CrateDefMap, 17 nameres::{BuiltinShadowMode, CrateDefMap},
18 path::{Path, PathKind}, 18 path::{Path, PathKind},
19 per_ns::PerNs, 19 per_ns::PerNs,
20 AdtId, AstItemDef, ConstId, ContainerId, DefWithBodyId, EnumId, EnumVariantId, FunctionId, 20 AdtId, AstItemDef, ConstId, ContainerId, DefWithBodyId, EnumId, EnumVariantId, FunctionId,
@@ -91,7 +91,7 @@ pub enum ValueNs {
91impl Resolver { 91impl Resolver {
92 /// Resolve known trait from std, like `std::futures::Future` 92 /// Resolve known trait from std, like `std::futures::Future`
93 pub fn resolve_known_trait(&self, db: &impl DefDatabase, path: &Path) -> Option<TraitId> { 93 pub fn resolve_known_trait(&self, db: &impl DefDatabase, path: &Path) -> Option<TraitId> {
94 let res = self.resolve_module_path(db, path).take_types()?; 94 let res = self.resolve_module_path(db, path, BuiltinShadowMode::Other).take_types()?;
95 match res { 95 match res {
96 ModuleDefId::TraitId(it) => Some(it), 96 ModuleDefId::TraitId(it) => Some(it),
97 _ => None, 97 _ => None,
@@ -100,7 +100,7 @@ impl Resolver {
100 100
101 /// Resolve known struct from std, like `std::boxed::Box` 101 /// Resolve known struct from std, like `std::boxed::Box`
102 pub fn resolve_known_struct(&self, db: &impl DefDatabase, path: &Path) -> Option<StructId> { 102 pub fn resolve_known_struct(&self, db: &impl DefDatabase, path: &Path) -> Option<StructId> {
103 let res = self.resolve_module_path(db, path).take_types()?; 103 let res = self.resolve_module_path(db, path, BuiltinShadowMode::Other).take_types()?;
104 match res { 104 match res {
105 ModuleDefId::AdtId(AdtId::StructId(it)) => Some(it), 105 ModuleDefId::AdtId(AdtId::StructId(it)) => Some(it),
106 _ => None, 106 _ => None,
@@ -109,26 +109,34 @@ impl Resolver {
109 109
110 /// Resolve known enum from std, like `std::result::Result` 110 /// Resolve known enum from std, like `std::result::Result`
111 pub fn resolve_known_enum(&self, db: &impl DefDatabase, path: &Path) -> Option<EnumId> { 111 pub fn resolve_known_enum(&self, db: &impl DefDatabase, path: &Path) -> Option<EnumId> {
112 let res = self.resolve_module_path(db, path).take_types()?; 112 let res = self.resolve_module_path(db, path, BuiltinShadowMode::Other).take_types()?;
113 match res { 113 match res {
114 ModuleDefId::AdtId(AdtId::EnumId(it)) => Some(it), 114 ModuleDefId::AdtId(AdtId::EnumId(it)) => Some(it),
115 _ => None, 115 _ => None,
116 } 116 }
117 } 117 }
118 118
119 /// pub only for source-binder 119 fn resolve_module_path(
120 pub fn resolve_module_path(&self, db: &impl DefDatabase, path: &Path) -> PerNs { 120 &self,
121 db: &impl DefDatabase,
122 path: &Path,
123 shadow: BuiltinShadowMode,
124 ) -> PerNs {
121 let (item_map, module) = match self.module() { 125 let (item_map, module) = match self.module() {
122 Some(it) => it, 126 Some(it) => it,
123 None => return PerNs::none(), 127 None => return PerNs::none(),
124 }; 128 };
125 let (module_res, segment_index) = item_map.resolve_path(db, module, path); 129 let (module_res, segment_index) = item_map.resolve_path(db, module, path, shadow);
126 if segment_index.is_some() { 130 if segment_index.is_some() {
127 return PerNs::none(); 131 return PerNs::none();
128 } 132 }
129 module_res 133 module_res
130 } 134 }
131 135
136 pub fn resolve_module_path_in_items(&self, db: &impl DefDatabase, path: &Path) -> PerNs {
137 self.resolve_module_path(db, path, BuiltinShadowMode::Module)
138 }
139
132 pub fn resolve_path_in_type_ns( 140 pub fn resolve_path_in_type_ns(
133 &self, 141 &self,
134 db: &impl DefDatabase, 142 db: &impl DefDatabase,
@@ -163,7 +171,12 @@ impl Resolver {
163 } 171 }
164 } 172 }
165 Scope::ModuleScope(m) => { 173 Scope::ModuleScope(m) => {
166 let (module_def, idx) = m.crate_def_map.resolve_path(db, m.module_id, path); 174 let (module_def, idx) = m.crate_def_map.resolve_path(
175 db,
176 m.module_id,
177 path,
178 BuiltinShadowMode::Other,
179 );
167 let res = match module_def.take_types()? { 180 let res = match module_def.take_types()? {
168 ModuleDefId::AdtId(it) => TypeNs::AdtId(it), 181 ModuleDefId::AdtId(it) => TypeNs::AdtId(it),
169 ModuleDefId::EnumVariantId(it) => TypeNs::EnumVariantId(it), 182 ModuleDefId::EnumVariantId(it) => TypeNs::EnumVariantId(it),
@@ -256,7 +269,12 @@ impl Resolver {
256 Scope::ImplBlockScope(_) | Scope::AdtScope(_) => continue, 269 Scope::ImplBlockScope(_) | Scope::AdtScope(_) => continue,
257 270
258 Scope::ModuleScope(m) => { 271 Scope::ModuleScope(m) => {
259 let (module_def, idx) = m.crate_def_map.resolve_path(db, m.module_id, path); 272 let (module_def, idx) = m.crate_def_map.resolve_path(
273 db,
274 m.module_id,
275 path,
276 BuiltinShadowMode::Other,
277 );
260 return match idx { 278 return match idx {
261 None => { 279 None => {
262 let value = match module_def.take_values()? { 280 let value = match module_def.take_values()? {
@@ -310,7 +328,7 @@ impl Resolver {
310 328
311 pub fn resolve_path_as_macro(&self, db: &impl DefDatabase, path: &Path) -> Option<MacroDefId> { 329 pub fn resolve_path_as_macro(&self, db: &impl DefDatabase, path: &Path) -> Option<MacroDefId> {
312 let (item_map, module) = self.module()?; 330 let (item_map, module) = self.module()?;
313 item_map.resolve_path(db, module, path).0.take_macros() 331 item_map.resolve_path(db, module, path, BuiltinShadowMode::Other).0.take_macros()
314 } 332 }
315 333
316 pub fn process_all_names(&self, db: &impl DefDatabase, f: &mut dyn FnMut(Name, ScopeDef)) { 334 pub fn process_all_names(&self, db: &impl DefDatabase, f: &mut dyn FnMut(Name, ScopeDef)) {
diff --git a/crates/ra_hir_ty/src/tests.rs b/crates/ra_hir_ty/src/tests.rs
index abbc1546c..3766ab981 100644
--- a/crates/ra_hir_ty/src/tests.rs
+++ b/crates/ra_hir_ty/src/tests.rs
@@ -3642,6 +3642,42 @@ fn main() {
3642} 3642}
3643 3643
3644#[test] 3644#[test]
3645fn not_shadowing_primitive_by_module() {
3646 let t = type_at(
3647 r#"
3648//- /str.rs
3649fn foo() {}
3650
3651//- /main.rs
3652mod str;
3653fn foo() -> &'static str { "" }
3654
3655fn main() {
3656 foo()<|>;
3657}"#,
3658 );
3659 assert_eq!(t, "&str");
3660}
3661
3662#[test]
3663fn not_shadowing_module_by_primitive() {
3664 let t = type_at(
3665 r#"
3666//- /str.rs
3667fn foo() -> u32 {0}
3668
3669//- /main.rs
3670mod str;
3671fn foo() -> &'static str { "" }
3672
3673fn main() {
3674 str::foo()<|>;
3675}"#,
3676 );
3677 assert_eq!(t, "u32");
3678}
3679
3680#[test]
3645fn deref_trait() { 3681fn deref_trait() {
3646 let t = type_at( 3682 let t = type_at(
3647 r#" 3683 r#"