diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2019-09-27 03:58:26 +0100 |
---|---|---|
committer | GitHub <[email protected]> | 2019-09-27 03:58:26 +0100 |
commit | 2b69c84396cf376b496e7de3c954400e51b5fc24 (patch) | |
tree | 385a5a3cb167877096534bad2a7c3efdee3c9c1d /crates/ra_hir/src/ty | |
parent | fc218ec0d04577e33db509e956a044293c12ea67 (diff) | |
parent | edadeb95be16a69175e94a0e211ae9bb74267abb (diff) |
Merge #1815
1815: Support correct `$crate` expansion in macros r=uHOOCCOOHu a=uHOOCCOOHu
This PR makes normal use cases of `$crate` from macros work as expected.
It makes more macros from `std` work. Type inference works well with `panic`, `unimplemented`, `format`, and maybe more.
Sadly that `vec![1, 2, 3]` still not works, but it is not longer an issue about macro.
Screenshot:
![Screenshot_20190927_022136](https://user-images.githubusercontent.com/14816024/65714465-b4568f80-e0cd-11e9-8043-dd44c2ae8040.png)
Co-authored-by: uHOOCCOOHu <[email protected]>
Diffstat (limited to 'crates/ra_hir/src/ty')
-rw-r--r-- | crates/ra_hir/src/ty/infer.rs | 9 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/tests.rs | 33 |
2 files changed, 37 insertions, 5 deletions
diff --git a/crates/ra_hir/src/ty/infer.rs b/crates/ra_hir/src/ty/infer.rs index 8e07fc186..2e4a489a0 100644 --- a/crates/ra_hir/src/ty/infer.rs +++ b/crates/ra_hir/src/ty/infer.rs | |||
@@ -609,7 +609,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
609 | 609 | ||
610 | for (i, &subpat) in subpats.iter().enumerate() { | 610 | for (i, &subpat) in subpats.iter().enumerate() { |
611 | let expected_ty = def | 611 | let expected_ty = def |
612 | .and_then(|d| d.field(self.db, &Name::tuple_field_name(i))) | 612 | .and_then(|d| d.field(self.db, &Name::new_tuple_field(i))) |
613 | .map_or(Ty::Unknown, |field| field.ty(self.db)) | 613 | .map_or(Ty::Unknown, |field| field.ty(self.db)) |
614 | .subst(&substs); | 614 | .subst(&substs); |
615 | let expected_ty = self.normalize_associated_types_in(expected_ty); | 615 | let expected_ty = self.normalize_associated_types_in(expected_ty); |
@@ -1374,10 +1374,9 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
1374 | ) | 1374 | ) |
1375 | .find_map(|derefed_ty| match canonicalized.decanonicalize_ty(derefed_ty.value) { | 1375 | .find_map(|derefed_ty| match canonicalized.decanonicalize_ty(derefed_ty.value) { |
1376 | Ty::Apply(a_ty) => match a_ty.ctor { | 1376 | Ty::Apply(a_ty) => match a_ty.ctor { |
1377 | TypeCtor::Tuple { .. } => { | 1377 | TypeCtor::Tuple { .. } => name |
1378 | let i = name.to_string().parse::<usize>().ok(); | 1378 | .as_tuple_index() |
1379 | i.and_then(|i| a_ty.parameters.0.get(i).cloned()) | 1379 | .and_then(|idx| a_ty.parameters.0.get(idx).cloned()), |
1380 | } | ||
1381 | TypeCtor::Adt(Adt::Struct(s)) => s.field(self.db, name).map(|field| { | 1380 | TypeCtor::Adt(Adt::Struct(s)) => s.field(self.db, name).map(|field| { |
1382 | self.write_field_resolution(tgt_expr, field); | 1381 | self.write_field_resolution(tgt_expr, field); |
1383 | field.ty(self.db).subst(&a_ty.parameters) | 1382 | field.ty(self.db).subst(&a_ty.parameters) |
diff --git a/crates/ra_hir/src/ty/tests.rs b/crates/ra_hir/src/ty/tests.rs index 7de434180..4df39c191 100644 --- a/crates/ra_hir/src/ty/tests.rs +++ b/crates/ra_hir/src/ty/tests.rs | |||
@@ -3130,6 +3130,39 @@ fn test() { S.foo()<|>; } | |||
3130 | assert_eq!(t, "u128"); | 3130 | assert_eq!(t, "u128"); |
3131 | } | 3131 | } |
3132 | 3132 | ||
3133 | #[test] | ||
3134 | fn infer_macro_with_dollar_crate_is_correct_in_expr() { | ||
3135 | covers!(macro_dollar_crate_other); | ||
3136 | let (mut db, pos) = MockDatabase::with_position( | ||
3137 | r#" | ||
3138 | //- /main.rs | ||
3139 | fn test() { | ||
3140 | let x = (foo::foo!(1), foo::foo!(2)); | ||
3141 | x<|>; | ||
3142 | } | ||
3143 | |||
3144 | //- /lib.rs | ||
3145 | #[macro_export] | ||
3146 | macro_rules! foo { | ||
3147 | (1) => { $crate::bar!() }; | ||
3148 | (2) => { 1 + $crate::baz() }; | ||
3149 | } | ||
3150 | |||
3151 | #[macro_export] | ||
3152 | macro_rules! bar { | ||
3153 | () => { 42 } | ||
3154 | } | ||
3155 | |||
3156 | pub fn baz() -> usize { 31usize } | ||
3157 | "#, | ||
3158 | ); | ||
3159 | db.set_crate_graph_from_fixture(crate_graph! { | ||
3160 | "main": ("/main.rs", ["foo"]), | ||
3161 | "foo": ("/lib.rs", []), | ||
3162 | }); | ||
3163 | assert_eq!("(i32, usize)", type_at_pos(&db, pos)); | ||
3164 | } | ||
3165 | |||
3133 | #[ignore] | 3166 | #[ignore] |
3134 | #[test] | 3167 | #[test] |
3135 | fn method_resolution_trait_before_autoref() { | 3168 | fn method_resolution_trait_before_autoref() { |