aboutsummaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
Diffstat (limited to 'crates')
-rw-r--r--crates/hir_def/src/nameres/mod_resolution.rs13
-rw-r--r--crates/hir_expand/src/builtin_macro.rs66
-rw-r--r--crates/hir_expand/src/eager.rs13
-rw-r--r--crates/hir_expand/src/lib.rs23
-rw-r--r--crates/hir_ty/src/infer/expr.rs6
-rw-r--r--crates/hir_ty/src/infer/pat.rs32
-rw-r--r--crates/hir_ty/src/tests/macros.rs23
-rw-r--r--crates/hir_ty/src/tests/patterns.rs22
-rw-r--r--crates/ide_db/src/helpers/insert_use.rs4
-rw-r--r--crates/rust-analyzer/src/config.rs3
-rw-r--r--crates/rust-analyzer/src/to_proto.rs6
11 files changed, 167 insertions, 44 deletions
diff --git a/crates/hir_def/src/nameres/mod_resolution.rs b/crates/hir_def/src/nameres/mod_resolution.rs
index d5de9899c..d9cec0e27 100644
--- a/crates/hir_def/src/nameres/mod_resolution.rs
+++ b/crates/hir_def/src/nameres/mod_resolution.rs
@@ -62,7 +62,7 @@ impl ModDir {
62 name: &Name, 62 name: &Name,
63 attr_path: Option<&SmolStr>, 63 attr_path: Option<&SmolStr>,
64 ) -> Result<(FileId, bool, ModDir), String> { 64 ) -> Result<(FileId, bool, ModDir), String> {
65 let file_id = file_id.original_file(db.upcast()); 65 let orig_file_id = file_id.original_file(db.upcast());
66 66
67 let mut candidate_files = Vec::new(); 67 let mut candidate_files = Vec::new();
68 match attr_path { 68 match attr_path {
@@ -70,13 +70,18 @@ impl ModDir {
70 candidate_files.push(self.dir_path.join_attr(attr_path, self.root_non_dir_owner)) 70 candidate_files.push(self.dir_path.join_attr(attr_path, self.root_non_dir_owner))
71 } 71 }
72 None => { 72 None => {
73 candidate_files.push(format!("{}{}.rs", self.dir_path.0, name)); 73 if file_id.is_include_macro(db.upcast()) {
74 candidate_files.push(format!("{}{}/mod.rs", self.dir_path.0, name)); 74 candidate_files.push(format!("{}.rs", name));
75 candidate_files.push(format!("{}/mod.rs", name));
76 } else {
77 candidate_files.push(format!("{}{}.rs", self.dir_path.0, name));
78 candidate_files.push(format!("{}{}/mod.rs", self.dir_path.0, name));
79 }
75 } 80 }
76 }; 81 };
77 82
78 for candidate in candidate_files.iter() { 83 for candidate in candidate_files.iter() {
79 let path = AnchoredPath { anchor: file_id, path: candidate.as_str() }; 84 let path = AnchoredPath { anchor: orig_file_id, path: candidate.as_str() };
80 if let Some(file_id) = db.resolve_path(path) { 85 if let Some(file_id) = db.resolve_path(path) {
81 let is_mod_rs = candidate.ends_with("/mod.rs"); 86 let is_mod_rs = candidate.ends_with("/mod.rs");
82 87
diff --git a/crates/hir_expand/src/builtin_macro.rs b/crates/hir_expand/src/builtin_macro.rs
index 8529b43b6..4d52904b9 100644
--- a/crates/hir_expand/src/builtin_macro.rs
+++ b/crates/hir_expand/src/builtin_macro.rs
@@ -43,7 +43,7 @@ macro_rules! register_builtin {
43 db: &dyn AstDatabase, 43 db: &dyn AstDatabase,
44 arg_id: EagerMacroId, 44 arg_id: EagerMacroId,
45 tt: &tt::Subtree, 45 tt: &tt::Subtree,
46 ) -> ExpandResult<Option<(tt::Subtree, FragmentKind)>> { 46 ) -> ExpandResult<Option<ExpandedEager>> {
47 let expander = match *self { 47 let expander = match *self {
48 $( EagerExpander::$e_kind => $e_expand, )* 48 $( EagerExpander::$e_kind => $e_expand, )*
49 }; 49 };
@@ -61,6 +61,20 @@ macro_rules! register_builtin {
61 }; 61 };
62} 62}
63 63
64#[derive(Debug)]
65pub struct ExpandedEager {
66 pub(crate) subtree: tt::Subtree,
67 pub(crate) fragment: FragmentKind,
68 /// The included file ID of the include macro.
69 pub(crate) included_file: Option<FileId>,
70}
71
72impl ExpandedEager {
73 fn new(subtree: tt::Subtree, fragment: FragmentKind) -> Self {
74 ExpandedEager { subtree, fragment, included_file: None }
75 }
76}
77
64pub fn find_builtin_macro( 78pub fn find_builtin_macro(
65 ident: &name::Name, 79 ident: &name::Name,
66 krate: CrateId, 80 krate: CrateId,
@@ -280,7 +294,7 @@ fn compile_error_expand(
280 _db: &dyn AstDatabase, 294 _db: &dyn AstDatabase,
281 _id: EagerMacroId, 295 _id: EagerMacroId,
282 tt: &tt::Subtree, 296 tt: &tt::Subtree,
283) -> ExpandResult<Option<(tt::Subtree, FragmentKind)>> { 297) -> ExpandResult<Option<ExpandedEager>> {
284 let err = match &*tt.token_trees { 298 let err = match &*tt.token_trees {
285 [tt::TokenTree::Leaf(tt::Leaf::Literal(it))] => { 299 [tt::TokenTree::Leaf(tt::Leaf::Literal(it))] => {
286 let text = it.text.as_str(); 300 let text = it.text.as_str();
@@ -294,14 +308,14 @@ fn compile_error_expand(
294 _ => mbe::ExpandError::BindingError("`compile_error!` argument must be a string".into()), 308 _ => mbe::ExpandError::BindingError("`compile_error!` argument must be a string".into()),
295 }; 309 };
296 310
297 ExpandResult { value: Some((quote! {}, FragmentKind::Items)), err: Some(err) } 311 ExpandResult { value: Some(ExpandedEager::new(quote! {}, FragmentKind::Items)), err: Some(err) }
298} 312}
299 313
300fn concat_expand( 314fn concat_expand(
301 _db: &dyn AstDatabase, 315 _db: &dyn AstDatabase,
302 _arg_id: EagerMacroId, 316 _arg_id: EagerMacroId,
303 tt: &tt::Subtree, 317 tt: &tt::Subtree,
304) -> ExpandResult<Option<(tt::Subtree, FragmentKind)>> { 318) -> ExpandResult<Option<ExpandedEager>> {
305 let mut err = None; 319 let mut err = None;
306 let mut text = String::new(); 320 let mut text = String::new();
307 for (i, t) in tt.token_trees.iter().enumerate() { 321 for (i, t) in tt.token_trees.iter().enumerate() {
@@ -325,7 +339,7 @@ fn concat_expand(
325 } 339 }
326 } 340 }
327 } 341 }
328 ExpandResult { value: Some((quote!(#text), FragmentKind::Expr)), err } 342 ExpandResult { value: Some(ExpandedEager::new(quote!(#text), FragmentKind::Expr)), err }
329} 343}
330 344
331fn relative_file( 345fn relative_file(
@@ -361,21 +375,27 @@ fn include_expand(
361 db: &dyn AstDatabase, 375 db: &dyn AstDatabase,
362 arg_id: EagerMacroId, 376 arg_id: EagerMacroId,
363 tt: &tt::Subtree, 377 tt: &tt::Subtree,
364) -> ExpandResult<Option<(tt::Subtree, FragmentKind)>> { 378) -> ExpandResult<Option<ExpandedEager>> {
365 let res = (|| { 379 let res = (|| {
366 let path = parse_string(tt)?; 380 let path = parse_string(tt)?;
367 let file_id = relative_file(db, arg_id.into(), &path, false)?; 381 let file_id = relative_file(db, arg_id.into(), &path, false)?;
368 382
369 Ok(parse_to_token_tree(&db.file_text(file_id)) 383 let subtree = parse_to_token_tree(&db.file_text(file_id))
370 .ok_or_else(|| mbe::ExpandError::ConversionError)? 384 .ok_or_else(|| mbe::ExpandError::ConversionError)?
371 .0) 385 .0;
386 Ok((subtree, file_id))
372 })(); 387 })();
373 388
374 match res { 389 match res {
375 Ok(res) => { 390 Ok((subtree, file_id)) => {
376 // FIXME: 391 // FIXME:
377 // Handle include as expression 392 // Handle include as expression
378 ExpandResult::ok(Some((res, FragmentKind::Items))) 393
394 ExpandResult::ok(Some(ExpandedEager {
395 subtree,
396 fragment: FragmentKind::Items,
397 included_file: Some(file_id),
398 }))
379 } 399 }
380 Err(e) => ExpandResult::only_err(e), 400 Err(e) => ExpandResult::only_err(e),
381 } 401 }
@@ -385,7 +405,7 @@ fn include_bytes_expand(
385 _db: &dyn AstDatabase, 405 _db: &dyn AstDatabase,
386 _arg_id: EagerMacroId, 406 _arg_id: EagerMacroId,
387 tt: &tt::Subtree, 407 tt: &tt::Subtree,
388) -> ExpandResult<Option<(tt::Subtree, FragmentKind)>> { 408) -> ExpandResult<Option<ExpandedEager>> {
389 if let Err(e) = parse_string(tt) { 409 if let Err(e) = parse_string(tt) {
390 return ExpandResult::only_err(e); 410 return ExpandResult::only_err(e);
391 } 411 }
@@ -398,14 +418,14 @@ fn include_bytes_expand(
398 id: tt::TokenId::unspecified(), 418 id: tt::TokenId::unspecified(),
399 }))], 419 }))],
400 }; 420 };
401 ExpandResult::ok(Some((res, FragmentKind::Expr))) 421 ExpandResult::ok(Some(ExpandedEager::new(res, FragmentKind::Expr)))
402} 422}
403 423
404fn include_str_expand( 424fn include_str_expand(
405 db: &dyn AstDatabase, 425 db: &dyn AstDatabase,
406 arg_id: EagerMacroId, 426 arg_id: EagerMacroId,
407 tt: &tt::Subtree, 427 tt: &tt::Subtree,
408) -> ExpandResult<Option<(tt::Subtree, FragmentKind)>> { 428) -> ExpandResult<Option<ExpandedEager>> {
409 let path = match parse_string(tt) { 429 let path = match parse_string(tt) {
410 Ok(it) => it, 430 Ok(it) => it,
411 Err(e) => return ExpandResult::only_err(e), 431 Err(e) => return ExpandResult::only_err(e),
@@ -418,14 +438,14 @@ fn include_str_expand(
418 let file_id = match relative_file(db, arg_id.into(), &path, true) { 438 let file_id = match relative_file(db, arg_id.into(), &path, true) {
419 Ok(file_id) => file_id, 439 Ok(file_id) => file_id,
420 Err(_) => { 440 Err(_) => {
421 return ExpandResult::ok(Some((quote!(""), FragmentKind::Expr))); 441 return ExpandResult::ok(Some(ExpandedEager::new(quote!(""), FragmentKind::Expr)));
422 } 442 }
423 }; 443 };
424 444
425 let text = db.file_text(file_id); 445 let text = db.file_text(file_id);
426 let text = &*text; 446 let text = &*text;
427 447
428 ExpandResult::ok(Some((quote!(#text), FragmentKind::Expr))) 448 ExpandResult::ok(Some(ExpandedEager::new(quote!(#text), FragmentKind::Expr)))
429} 449}
430 450
431fn get_env_inner(db: &dyn AstDatabase, arg_id: EagerMacroId, key: &str) -> Option<String> { 451fn get_env_inner(db: &dyn AstDatabase, arg_id: EagerMacroId, key: &str) -> Option<String> {
@@ -437,7 +457,7 @@ fn env_expand(
437 db: &dyn AstDatabase, 457 db: &dyn AstDatabase,
438 arg_id: EagerMacroId, 458 arg_id: EagerMacroId,
439 tt: &tt::Subtree, 459 tt: &tt::Subtree,
440) -> ExpandResult<Option<(tt::Subtree, FragmentKind)>> { 460) -> ExpandResult<Option<ExpandedEager>> {
441 let key = match parse_string(tt) { 461 let key = match parse_string(tt) {
442 Ok(it) => it, 462 Ok(it) => it,
443 Err(e) => return ExpandResult::only_err(e), 463 Err(e) => return ExpandResult::only_err(e),
@@ -461,14 +481,14 @@ fn env_expand(
461 }); 481 });
462 let expanded = quote! { #s }; 482 let expanded = quote! { #s };
463 483
464 ExpandResult { value: Some((expanded, FragmentKind::Expr)), err } 484 ExpandResult { value: Some(ExpandedEager::new(expanded, FragmentKind::Expr)), err }
465} 485}
466 486
467fn option_env_expand( 487fn option_env_expand(
468 db: &dyn AstDatabase, 488 db: &dyn AstDatabase,
469 arg_id: EagerMacroId, 489 arg_id: EagerMacroId,
470 tt: &tt::Subtree, 490 tt: &tt::Subtree,
471) -> ExpandResult<Option<(tt::Subtree, FragmentKind)>> { 491) -> ExpandResult<Option<ExpandedEager>> {
472 let key = match parse_string(tt) { 492 let key = match parse_string(tt) {
473 Ok(it) => it, 493 Ok(it) => it,
474 Err(e) => return ExpandResult::only_err(e), 494 Err(e) => return ExpandResult::only_err(e),
@@ -479,7 +499,7 @@ fn option_env_expand(
479 Some(s) => quote! { std::option::Some(#s) }, 499 Some(s) => quote! { std::option::Some(#s) },
480 }; 500 };
481 501
482 ExpandResult::ok(Some((expanded, FragmentKind::Expr))) 502 ExpandResult::ok(Some(ExpandedEager::new(expanded, FragmentKind::Expr)))
483} 503}
484 504
485#[cfg(test)] 505#[cfg(test)]
@@ -553,16 +573,18 @@ mod tests {
553 subtree: Arc::new(parsed_args.clone()), 573 subtree: Arc::new(parsed_args.clone()),
554 krate, 574 krate,
555 call: call_id, 575 call: call_id,
576 included_file: None,
556 } 577 }
557 }); 578 });
558 579
559 let (subtree, fragment) = expander.expand(&db, arg_id, &parsed_args).value.unwrap(); 580 let expanded = expander.expand(&db, arg_id, &parsed_args).value.unwrap();
560 let eager = EagerCallLoc { 581 let eager = EagerCallLoc {
561 def, 582 def,
562 fragment, 583 fragment: expanded.fragment,
563 subtree: Arc::new(subtree), 584 subtree: Arc::new(expanded.subtree),
564 krate, 585 krate,
565 call: call_id, 586 call: call_id,
587 included_file: expanded.included_file,
566 }; 588 };
567 589
568 let id: MacroCallId = db.intern_eager_expansion(eager).into(); 590 let id: MacroCallId = db.intern_eager_expansion(eager).into();
diff --git a/crates/hir_expand/src/eager.rs b/crates/hir_expand/src/eager.rs
index 04f374a29..9eedc8461 100644
--- a/crates/hir_expand/src/eager.rs
+++ b/crates/hir_expand/src/eager.rs
@@ -124,6 +124,7 @@ pub fn expand_eager_macro(
124 subtree: Arc::new(parsed_args.clone()), 124 subtree: Arc::new(parsed_args.clone()),
125 krate, 125 krate,
126 call: call_id, 126 call: call_id,
127 included_file: None,
127 } 128 }
128 }); 129 });
129 let arg_file_id: MacroCallId = arg_id.into(); 130 let arg_file_id: MacroCallId = arg_id.into();
@@ -143,9 +144,15 @@ pub fn expand_eager_macro(
143 if let MacroDefKind::BuiltInEager(eager, _) = def.kind { 144 if let MacroDefKind::BuiltInEager(eager, _) = def.kind {
144 let res = eager.expand(db, arg_id, &subtree); 145 let res = eager.expand(db, arg_id, &subtree);
145 146
146 let (subtree, fragment) = diagnostic_sink.expand_result_option(res)?; 147 let expanded = diagnostic_sink.expand_result_option(res)?;
147 let eager = 148 let eager = EagerCallLoc {
148 EagerCallLoc { def, fragment, subtree: Arc::new(subtree), krate, call: call_id }; 149 def,
150 fragment: expanded.fragment,
151 subtree: Arc::new(expanded.subtree),
152 krate,
153 call: call_id,
154 included_file: expanded.included_file,
155 };
149 156
150 Ok(db.intern_eager_expansion(eager)) 157 Ok(db.intern_eager_expansion(eager))
151 } else { 158 } else {
diff --git a/crates/hir_expand/src/lib.rs b/crates/hir_expand/src/lib.rs
index f49fd4fda..b8045fda9 100644
--- a/crates/hir_expand/src/lib.rs
+++ b/crates/hir_expand/src/lib.rs
@@ -84,7 +84,11 @@ impl HirFileId {
84 } 84 }
85 MacroCallId::EagerMacro(id) => { 85 MacroCallId::EagerMacro(id) => {
86 let loc = db.lookup_intern_eager_expansion(id); 86 let loc = db.lookup_intern_eager_expansion(id);
87 loc.call.file_id 87 if let Some(included_file) = loc.included_file {
88 return included_file;
89 } else {
90 loc.call.file_id
91 }
88 } 92 }
89 }; 93 };
90 file_id.original_file(db) 94 file_id.original_file(db)
@@ -188,6 +192,21 @@ impl HirFileId {
188 } 192 }
189 } 193 }
190 } 194 }
195
196 /// Return whether this file is an include macro
197 pub fn is_include_macro(&self, db: &dyn db::AstDatabase) -> bool {
198 match self.0 {
199 HirFileIdRepr::MacroFile(macro_file) => match macro_file.macro_call_id {
200 MacroCallId::EagerMacro(id) => {
201 let loc = db.lookup_intern_eager_expansion(id);
202 return loc.included_file.is_some();
203 }
204 _ => {}
205 },
206 _ => {}
207 }
208 false
209 }
191} 210}
192 211
193#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 212#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
@@ -315,6 +334,8 @@ pub struct EagerCallLoc {
315 pub(crate) subtree: Arc<tt::Subtree>, 334 pub(crate) subtree: Arc<tt::Subtree>,
316 pub(crate) krate: CrateId, 335 pub(crate) krate: CrateId,
317 pub(crate) call: AstId<ast::MacroCall>, 336 pub(crate) call: AstId<ast::MacroCall>,
337 // The included file ID of the include macro.
338 pub(crate) included_file: Option<FileId>,
318} 339}
319 340
320/// ExpansionInfo mainly describes how to map text range between src and expanded macro 341/// ExpansionInfo mainly describes how to map text range between src and expanded macro
diff --git a/crates/hir_ty/src/infer/expr.rs b/crates/hir_ty/src/infer/expr.rs
index 17849d552..05cbde4e3 100644
--- a/crates/hir_ty/src/infer/expr.rs
+++ b/crates/hir_ty/src/infer/expr.rs
@@ -514,10 +514,10 @@ impl<'a> InferenceContext<'a> {
514 let inner_ty = self.infer_expr_inner(*expr, &Expectation::none()); 514 let inner_ty = self.infer_expr_inner(*expr, &Expectation::none());
515 if let Some(box_) = self.resolve_boxed_box() { 515 if let Some(box_) = self.resolve_boxed_box() {
516 let mut sb = 516 let mut sb =
517 Substitution::builder(generics(self.db.upcast(), box_.into()).len()); 517 Substitution::build_for_generics(&generics(self.db.upcast(), box_.into()));
518 sb = sb.push(inner_ty); 518 sb = sb.push(inner_ty);
519 match self.db.generic_defaults(box_.into()).as_ref() { 519 match self.db.generic_defaults(box_.into()).get(1) {
520 [_, alloc_ty, ..] if !alloc_ty.value.is_unknown() => { 520 Some(alloc_ty) if !alloc_ty.value.is_unknown() && sb.remaining() > 0 => {
521 sb = sb.push(alloc_ty.value.clone()); 521 sb = sb.push(alloc_ty.value.clone());
522 } 522 }
523 _ => (), 523 _ => (),
diff --git a/crates/hir_ty/src/infer/pat.rs b/crates/hir_ty/src/infer/pat.rs
index ec491648f..474363709 100644
--- a/crates/hir_ty/src/infer/pat.rs
+++ b/crates/hir_ty/src/infer/pat.rs
@@ -13,7 +13,9 @@ use hir_expand::name::Name;
13 13
14use super::{BindingMode, Expectation, InferenceContext}; 14use super::{BindingMode, Expectation, InferenceContext};
15use crate::{ 15use crate::{
16 lower::lower_to_chalk_mutability, utils::variant_data, Interner, Substitution, Ty, TyKind, 16 lower::lower_to_chalk_mutability,
17 utils::{generics, variant_data},
18 Interner, Substitution, Ty, TyKind,
17}; 19};
18 20
19impl<'a> InferenceContext<'a> { 21impl<'a> InferenceContext<'a> {
@@ -233,13 +235,31 @@ impl<'a> InferenceContext<'a> {
233 Pat::Lit(expr) => self.infer_expr(*expr, &Expectation::has_type(expected.clone())), 235 Pat::Lit(expr) => self.infer_expr(*expr, &Expectation::has_type(expected.clone())),
234 Pat::Box { inner } => match self.resolve_boxed_box() { 236 Pat::Box { inner } => match self.resolve_boxed_box() {
235 Some(box_adt) => { 237 Some(box_adt) => {
236 let inner_expected = match expected.as_adt() { 238 let (inner_ty, alloc_ty) = match expected.as_adt() {
237 Some((adt, substs)) if adt == box_adt => substs.as_single().clone(), 239 Some((adt, subst)) if adt == box_adt => {
238 _ => self.result.standard_types.unknown.clone(), 240 (subst[0].clone(), subst.get(1).cloned())
241 }
242 _ => (self.result.standard_types.unknown.clone(), None),
239 }; 243 };
240 244
241 let inner_ty = self.infer_pat(*inner, &inner_expected, default_bm); 245 let inner_ty = self.infer_pat(*inner, &inner_ty, default_bm);
242 Ty::adt_ty(box_adt, Substitution::single(inner_ty)) 246 let mut sb = Substitution::build_for_generics(&generics(
247 self.db.upcast(),
248 box_adt.into(),
249 ));
250 sb = sb.push(inner_ty);
251 if sb.remaining() == 1 {
252 sb = sb.push(match alloc_ty {
253 Some(alloc_ty) if !alloc_ty.is_unknown() => alloc_ty,
254 _ => match self.db.generic_defaults(box_adt.into()).get(1) {
255 Some(alloc_ty) if !alloc_ty.value.is_unknown() => {
256 alloc_ty.value.clone()
257 }
258 _ => self.table.new_type_var(),
259 },
260 });
261 }
262 Ty::adt_ty(box_adt, sb.build())
243 } 263 }
244 None => self.err_ty(), 264 None => self.err_ty(),
245 }, 265 },
diff --git a/crates/hir_ty/src/tests/macros.rs b/crates/hir_ty/src/tests/macros.rs
index c1e605740..12951fb16 100644
--- a/crates/hir_ty/src/tests/macros.rs
+++ b/crates/hir_ty/src/tests/macros.rs
@@ -607,6 +607,29 @@ fn bar() -> u32 {0}
607} 607}
608 608
609#[test] 609#[test]
610fn infer_builtin_macros_include_child_mod() {
611 check_types(
612 r#"
613//- /main.rs
614#[rustc_builtin_macro]
615macro_rules! include {() => {}}
616
617include!("f/foo.rs");
618
619fn main() {
620 bar::bar();
621} //^ u32
622
623//- /f/foo.rs
624pub mod bar;
625
626//- /f/bar.rs
627pub fn bar() -> u32 {0}
628"#,
629 );
630}
631
632#[test]
610fn infer_builtin_macros_include_str() { 633fn infer_builtin_macros_include_str() {
611 check_types( 634 check_types(
612 r#" 635 r#"
diff --git a/crates/hir_ty/src/tests/patterns.rs b/crates/hir_ty/src/tests/patterns.rs
index 5da19ba5f..85a28e76b 100644
--- a/crates/hir_ty/src/tests/patterns.rs
+++ b/crates/hir_ty/src/tests/patterns.rs
@@ -658,6 +658,28 @@ fn slice_tail_pattern() {
658fn box_pattern() { 658fn box_pattern() {
659 check_infer( 659 check_infer(
660 r#" 660 r#"
661 pub struct Global;
662 #[lang = "owned_box"]
663 pub struct Box<T, A = Global>(T);
664
665 fn foo(params: Box<i32>) {
666 match params {
667 box integer => {}
668 }
669 }
670 "#,
671 expect![[r#"
672 83..89 'params': Box<i32, Global>
673 101..155 '{ ... } }': ()
674 107..153 'match ... }': ()
675 113..119 'params': Box<i32, Global>
676 130..141 'box integer': Box<i32, Global>
677 134..141 'integer': i32
678 145..147 '{}': ()
679 "#]],
680 );
681 check_infer(
682 r#"
661 #[lang = "owned_box"] 683 #[lang = "owned_box"]
662 pub struct Box<T>(T); 684 pub struct Box<T>(T);
663 685
diff --git a/crates/ide_db/src/helpers/insert_use.rs b/crates/ide_db/src/helpers/insert_use.rs
index 9e0cb91c3..37acf95f0 100644
--- a/crates/ide_db/src/helpers/insert_use.rs
+++ b/crates/ide_db/src/helpers/insert_use.rs
@@ -14,10 +14,12 @@ use syntax::{
14 AstToken, InsertPosition, NodeOrToken, SyntaxElement, SyntaxNode, SyntaxToken, 14 AstToken, InsertPosition, NodeOrToken, SyntaxElement, SyntaxNode, SyntaxToken,
15}; 15};
16 16
17pub use hir::PrefixKind;
18
17#[derive(Clone, Copy, Debug, PartialEq, Eq)] 19#[derive(Clone, Copy, Debug, PartialEq, Eq)]
18pub struct InsertUseConfig { 20pub struct InsertUseConfig {
19 pub merge: Option<MergeBehavior>, 21 pub merge: Option<MergeBehavior>,
20 pub prefix_kind: hir::PrefixKind, 22 pub prefix_kind: PrefixKind,
21 pub group: bool, 23 pub group: bool,
22} 24}
23 25
diff --git a/crates/rust-analyzer/src/config.rs b/crates/rust-analyzer/src/config.rs
index 8f541976e..5c88c3a9b 100644
--- a/crates/rust-analyzer/src/config.rs
+++ b/crates/rust-analyzer/src/config.rs
@@ -10,10 +10,9 @@
10use std::{ffi::OsString, iter, path::PathBuf}; 10use std::{ffi::OsString, iter, path::PathBuf};
11 11
12use flycheck::FlycheckConfig; 12use flycheck::FlycheckConfig;
13use hir::PrefixKind;
14use ide::{AssistConfig, CompletionConfig, DiagnosticsConfig, HoverConfig, InlayHintsConfig}; 13use ide::{AssistConfig, CompletionConfig, DiagnosticsConfig, HoverConfig, InlayHintsConfig};
15use ide_db::helpers::{ 14use ide_db::helpers::{
16 insert_use::{InsertUseConfig, MergeBehavior}, 15 insert_use::{InsertUseConfig, MergeBehavior, PrefixKind},
17 SnippetCap, 16 SnippetCap,
18}; 17};
19use lsp_types::{ClientCapabilities, MarkupKind}; 18use lsp_types::{ClientCapabilities, MarkupKind};
diff --git a/crates/rust-analyzer/src/to_proto.rs b/crates/rust-analyzer/src/to_proto.rs
index 1ddea9278..c1ca7ff9b 100644
--- a/crates/rust-analyzer/src/to_proto.rs
+++ b/crates/rust-analyzer/src/to_proto.rs
@@ -1073,9 +1073,11 @@ pub(crate) fn rename_error(err: RenameError) -> crate::LspError {
1073mod tests { 1073mod tests {
1074 use std::sync::Arc; 1074 use std::sync::Arc;
1075 1075
1076 use hir::PrefixKind;
1077 use ide::Analysis; 1076 use ide::Analysis;
1078 use ide_db::helpers::{insert_use::InsertUseConfig, SnippetCap}; 1077 use ide_db::helpers::{
1078 insert_use::{InsertUseConfig, PrefixKind},
1079 SnippetCap,
1080 };
1079 1081
1080 use super::*; 1082 use super::*;
1081 1083