diff options
Diffstat (limited to 'crates/hir_ty')
-rw-r--r-- | crates/hir_ty/src/infer/expr.rs | 6 | ||||
-rw-r--r-- | crates/hir_ty/src/infer/pat.rs | 32 | ||||
-rw-r--r-- | crates/hir_ty/src/tests/macros.rs | 23 | ||||
-rw-r--r-- | crates/hir_ty/src/tests/patterns.rs | 22 |
4 files changed, 74 insertions, 9 deletions
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 | ||
14 | use super::{BindingMode, Expectation, InferenceContext}; | 14 | use super::{BindingMode, Expectation, InferenceContext}; |
15 | use crate::{ | 15 | use 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 | ||
19 | impl<'a> InferenceContext<'a> { | 21 | impl<'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] |
610 | fn infer_builtin_macros_include_child_mod() { | ||
611 | check_types( | ||
612 | r#" | ||
613 | //- /main.rs | ||
614 | #[rustc_builtin_macro] | ||
615 | macro_rules! include {() => {}} | ||
616 | |||
617 | include!("f/foo.rs"); | ||
618 | |||
619 | fn main() { | ||
620 | bar::bar(); | ||
621 | } //^ u32 | ||
622 | |||
623 | //- /f/foo.rs | ||
624 | pub mod bar; | ||
625 | |||
626 | //- /f/bar.rs | ||
627 | pub fn bar() -> u32 {0} | ||
628 | "#, | ||
629 | ); | ||
630 | } | ||
631 | |||
632 | #[test] | ||
610 | fn infer_builtin_macros_include_str() { | 633 | fn 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() { | |||
658 | fn box_pattern() { | 658 | fn 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 | ||