diff options
Diffstat (limited to 'crates/ra_hir_ty')
-rw-r--r-- | crates/ra_hir_ty/src/method_resolution.rs | 28 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/test_db.rs | 7 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/tests/macros.rs | 40 |
3 files changed, 72 insertions, 3 deletions
diff --git a/crates/ra_hir_ty/src/method_resolution.rs b/crates/ra_hir_ty/src/method_resolution.rs index b7e8855fb..7f5e1469e 100644 --- a/crates/ra_hir_ty/src/method_resolution.rs +++ b/crates/ra_hir_ty/src/method_resolution.rs | |||
@@ -516,9 +516,31 @@ pub(crate) fn inherent_impl_substs( | |||
516 | let self_ty_with_vars = | 516 | let self_ty_with_vars = |
517 | Canonical { num_vars: vars.len() + self_ty.num_vars, value: self_ty_with_vars }; | 517 | Canonical { num_vars: vars.len() + self_ty.num_vars, value: self_ty_with_vars }; |
518 | let substs = super::infer::unify(&self_ty_with_vars, self_ty); | 518 | let substs = super::infer::unify(&self_ty_with_vars, self_ty); |
519 | // we only want the substs for the vars we added, not the ones from self_ty | 519 | // We only want the substs for the vars we added, not the ones from self_ty. |
520 | let result = substs.map(|s| s.suffix(vars.len())); | 520 | // Also, if any of the vars we added are still in there, we replace them by |
521 | result | 521 | // Unknown. I think this can only really happen if self_ty contained |
522 | // Unknown, and in that case we want the result to contain Unknown in those | ||
523 | // places again. | ||
524 | substs.map(|s| fallback_bound_vars(s.suffix(vars.len()), self_ty.num_vars)) | ||
525 | } | ||
526 | |||
527 | /// This replaces any 'free' Bound vars in `s` (i.e. those with indices past | ||
528 | /// num_vars_to_keep) by `Ty::Unknown`. | ||
529 | fn fallback_bound_vars(s: Substs, num_vars_to_keep: usize) -> Substs { | ||
530 | s.fold_binders( | ||
531 | &mut |ty, binders| { | ||
532 | if let Ty::Bound(idx) = &ty { | ||
533 | if *idx >= binders as u32 { | ||
534 | Ty::Unknown | ||
535 | } else { | ||
536 | ty | ||
537 | } | ||
538 | } else { | ||
539 | ty | ||
540 | } | ||
541 | }, | ||
542 | num_vars_to_keep, | ||
543 | ) | ||
522 | } | 544 | } |
523 | 545 | ||
524 | fn transform_receiver_ty( | 546 | fn transform_receiver_ty( |
diff --git a/crates/ra_hir_ty/src/test_db.rs b/crates/ra_hir_ty/src/test_db.rs index c794f7b84..0be2fea4b 100644 --- a/crates/ra_hir_ty/src/test_db.rs +++ b/crates/ra_hir_ty/src/test_db.rs | |||
@@ -67,6 +67,13 @@ impl FileLoader for TestDB { | |||
67 | fn relevant_crates(&self, file_id: FileId) -> Arc<Vec<CrateId>> { | 67 | fn relevant_crates(&self, file_id: FileId) -> Arc<Vec<CrateId>> { |
68 | FileLoaderDelegate(self).relevant_crates(file_id) | 68 | FileLoaderDelegate(self).relevant_crates(file_id) |
69 | } | 69 | } |
70 | fn resolve_extern_path( | ||
71 | &self, | ||
72 | extern_id: ra_db::ExternSourceId, | ||
73 | relative_path: &RelativePath, | ||
74 | ) -> Option<FileId> { | ||
75 | FileLoaderDelegate(self).resolve_extern_path(extern_id, relative_path) | ||
76 | } | ||
70 | } | 77 | } |
71 | 78 | ||
72 | impl TestDB { | 79 | impl TestDB { |
diff --git a/crates/ra_hir_ty/src/tests/macros.rs b/crates/ra_hir_ty/src/tests/macros.rs index ffa78b046..3b7022ad5 100644 --- a/crates/ra_hir_ty/src/tests/macros.rs +++ b/crates/ra_hir_ty/src/tests/macros.rs | |||
@@ -363,6 +363,26 @@ fn main() { | |||
363 | } | 363 | } |
364 | 364 | ||
365 | #[test] | 365 | #[test] |
366 | fn infer_local_macro() { | ||
367 | assert_snapshot!( | ||
368 | infer(r#" | ||
369 | fn main() { | ||
370 | macro_rules! foo { | ||
371 | () => { 1usize } | ||
372 | } | ||
373 | let _a = foo!(); | ||
374 | } | ||
375 | "#), | ||
376 | @r###" | ||
377 | ![0; 6) '1usize': usize | ||
378 | [11; 90) '{ ...!(); }': () | ||
379 | [17; 66) 'macro_... }': {unknown} | ||
380 | [75; 77) '_a': usize | ||
381 | "### | ||
382 | ); | ||
383 | } | ||
384 | |||
385 | #[test] | ||
366 | fn infer_builtin_macros_line() { | 386 | fn infer_builtin_macros_line() { |
367 | assert_snapshot!( | 387 | assert_snapshot!( |
368 | infer(r#" | 388 | infer(r#" |
@@ -550,6 +570,26 @@ fn main() { | |||
550 | } | 570 | } |
551 | 571 | ||
552 | #[test] | 572 | #[test] |
573 | fn infer_builtin_macros_env() { | ||
574 | assert_snapshot!( | ||
575 | infer(r#" | ||
576 | //- /main.rs env:foo=bar | ||
577 | #[rustc_builtin_macro] | ||
578 | macro_rules! env {() => {}} | ||
579 | |||
580 | fn main() { | ||
581 | let x = env!("foo"); | ||
582 | } | ||
583 | "#), | ||
584 | @r###" | ||
585 | ![0; 5) '"bar"': &str | ||
586 | [88; 116) '{ ...o"); }': () | ||
587 | [98; 99) 'x': &str | ||
588 | "### | ||
589 | ); | ||
590 | } | ||
591 | |||
592 | #[test] | ||
553 | fn infer_derive_clone_simple() { | 593 | fn infer_derive_clone_simple() { |
554 | let (db, pos) = TestDB::with_position( | 594 | let (db, pos) = TestDB::with_position( |
555 | r#" | 595 | r#" |