diff options
Diffstat (limited to 'crates/ra_hir_ty/src')
-rw-r--r-- | crates/ra_hir_ty/src/infer/expr.rs | 37 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/lib.rs | 18 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/tests/coercion.rs | 17 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/tests/simple.rs | 20 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/tests/traits.rs | 54 |
5 files changed, 119 insertions, 27 deletions
diff --git a/crates/ra_hir_ty/src/infer/expr.rs b/crates/ra_hir_ty/src/infer/expr.rs index b28724f0e..54bab3476 100644 --- a/crates/ra_hir_ty/src/infer/expr.rs +++ b/crates/ra_hir_ty/src/infer/expr.rs | |||
@@ -17,8 +17,8 @@ use crate::{ | |||
17 | autoderef, method_resolution, op, | 17 | autoderef, method_resolution, op, |
18 | traits::InEnvironment, | 18 | traits::InEnvironment, |
19 | utils::{generics, variant_data, Generics}, | 19 | utils::{generics, variant_data, Generics}, |
20 | ApplicationTy, Binders, CallableDef, InferTy, IntTy, Mutability, Obligation, Substs, TraitRef, | 20 | ApplicationTy, Binders, CallableDef, InferTy, IntTy, Mutability, Obligation, Rawness, Substs, |
21 | Ty, TypeCtor, Uncertain, | 21 | TraitRef, Ty, TypeCtor, Uncertain, |
22 | }; | 22 | }; |
23 | 23 | ||
24 | use super::{ | 24 | use super::{ |
@@ -350,19 +350,28 @@ impl<'a> InferenceContext<'a> { | |||
350 | // FIXME check the cast... | 350 | // FIXME check the cast... |
351 | cast_ty | 351 | cast_ty |
352 | } | 352 | } |
353 | Expr::Ref { expr, mutability } => { | 353 | Expr::Ref { expr, rawness, mutability } => { |
354 | let expectation = | 354 | let expectation = if let Some((exp_inner, exp_rawness, exp_mutability)) = |
355 | if let Some((exp_inner, exp_mutability)) = &expected.ty.as_reference() { | 355 | &expected.ty.as_reference_or_ptr() |
356 | if *exp_mutability == Mutability::Mut && *mutability == Mutability::Shared { | 356 | { |
357 | // FIXME: throw type error - expected mut reference but found shared ref, | 357 | if *exp_mutability == Mutability::Mut && *mutability == Mutability::Shared { |
358 | // which cannot be coerced | 358 | // FIXME: throw type error - expected mut reference but found shared ref, |
359 | } | 359 | // which cannot be coerced |
360 | Expectation::rvalue_hint(Ty::clone(exp_inner)) | 360 | } |
361 | } else { | 361 | if *exp_rawness == Rawness::Ref && *rawness == Rawness::RawPtr { |
362 | Expectation::none() | 362 | // FIXME: throw type error - expected reference but found ptr, |
363 | }; | 363 | // which cannot be coerced |
364 | } | ||
365 | Expectation::rvalue_hint(Ty::clone(exp_inner)) | ||
366 | } else { | ||
367 | Expectation::none() | ||
368 | }; | ||
364 | let inner_ty = self.infer_expr_inner(*expr, &expectation); | 369 | let inner_ty = self.infer_expr_inner(*expr, &expectation); |
365 | Ty::apply_one(TypeCtor::Ref(*mutability), inner_ty) | 370 | let ty = match rawness { |
371 | Rawness::RawPtr => TypeCtor::RawPtr(*mutability), | ||
372 | Rawness::Ref => TypeCtor::Ref(*mutability), | ||
373 | }; | ||
374 | Ty::apply_one(ty, inner_ty) | ||
366 | } | 375 | } |
367 | Expr::Box { expr } => { | 376 | Expr::Box { expr } => { |
368 | let inner_ty = self.infer_expr_inner(*expr, &Expectation::none()); | 377 | let inner_ty = self.infer_expr_inner(*expr, &Expectation::none()); |
diff --git a/crates/ra_hir_ty/src/lib.rs b/crates/ra_hir_ty/src/lib.rs index 93cb45a64..9fa8d3bdc 100644 --- a/crates/ra_hir_ty/src/lib.rs +++ b/crates/ra_hir_ty/src/lib.rs | |||
@@ -49,8 +49,10 @@ use std::sync::Arc; | |||
49 | use std::{iter, mem}; | 49 | use std::{iter, mem}; |
50 | 50 | ||
51 | use hir_def::{ | 51 | use hir_def::{ |
52 | expr::ExprId, type_ref::Mutability, AdtId, AssocContainerId, DefWithBodyId, GenericDefId, | 52 | expr::ExprId, |
53 | HasModule, Lookup, TraitId, TypeAliasId, TypeParamId, | 53 | type_ref::{Mutability, Rawness}, |
54 | AdtId, AssocContainerId, DefWithBodyId, GenericDefId, HasModule, Lookup, TraitId, TypeAliasId, | ||
55 | TypeParamId, | ||
54 | }; | 56 | }; |
55 | use ra_db::{impl_intern_key, salsa, CrateId}; | 57 | use ra_db::{impl_intern_key, salsa, CrateId}; |
56 | 58 | ||
@@ -709,6 +711,18 @@ impl Ty { | |||
709 | } | 711 | } |
710 | } | 712 | } |
711 | 713 | ||
714 | pub fn as_reference_or_ptr(&self) -> Option<(&Ty, Rawness, Mutability)> { | ||
715 | match self { | ||
716 | Ty::Apply(ApplicationTy { ctor: TypeCtor::Ref(mutability), parameters }) => { | ||
717 | Some((parameters.as_single(), Rawness::Ref, *mutability)) | ||
718 | } | ||
719 | Ty::Apply(ApplicationTy { ctor: TypeCtor::RawPtr(mutability), parameters }) => { | ||
720 | Some((parameters.as_single(), Rawness::RawPtr, *mutability)) | ||
721 | } | ||
722 | _ => None, | ||
723 | } | ||
724 | } | ||
725 | |||
712 | pub fn strip_references(&self) -> &Ty { | 726 | pub fn strip_references(&self) -> &Ty { |
713 | let mut t: &Ty = self; | 727 | let mut t: &Ty = self; |
714 | 728 | ||
diff --git a/crates/ra_hir_ty/src/tests/coercion.rs b/crates/ra_hir_ty/src/tests/coercion.rs index 2cc4f4bf9..6f777ed8c 100644 --- a/crates/ra_hir_ty/src/tests/coercion.rs +++ b/crates/ra_hir_ty/src/tests/coercion.rs | |||
@@ -116,15 +116,20 @@ fn infer_let_stmt_coerce() { | |||
116 | assert_snapshot!( | 116 | assert_snapshot!( |
117 | infer(r#" | 117 | infer(r#" |
118 | fn test() { | 118 | fn test() { |
119 | let x: &[i32] = &[1]; | 119 | let x: &[isize] = &[1]; |
120 | let x: *const [isize] = &[1]; | ||
120 | } | 121 | } |
121 | "#), | 122 | "#), |
122 | @r###" | 123 | @r###" |
123 | 11..40 '{ ...[1]; }': () | 124 | 11..76 '{ ...[1]; }': () |
124 | 21..22 'x': &[i32] | 125 | 21..22 'x': &[isize] |
125 | 33..37 '&[1]': &[i32; _] | 126 | 35..39 '&[1]': &[isize; _] |
126 | 34..37 '[1]': [i32; _] | 127 | 36..39 '[1]': [isize; _] |
127 | 35..36 '1': i32 | 128 | 37..38 '1': isize |
129 | 49..50 'x': *const [isize] | ||
130 | 69..73 '&[1]': &[isize; _] | ||
131 | 70..73 '[1]': [isize; _] | ||
132 | 71..72 '1': isize | ||
128 | "###); | 133 | "###); |
129 | } | 134 | } |
130 | 135 | ||
diff --git a/crates/ra_hir_ty/src/tests/simple.rs b/crates/ra_hir_ty/src/tests/simple.rs index daa9cc953..839491b9e 100644 --- a/crates/ra_hir_ty/src/tests/simple.rs +++ b/crates/ra_hir_ty/src/tests/simple.rs | |||
@@ -385,6 +385,26 @@ fn test(a: &u32, b: &mut u32, c: *const u32, d: *mut u32) { | |||
385 | } | 385 | } |
386 | 386 | ||
387 | #[test] | 387 | #[test] |
388 | fn infer_raw_ref() { | ||
389 | assert_snapshot!( | ||
390 | infer(r#" | ||
391 | fn test(a: i32) { | ||
392 | &raw mut a; | ||
393 | &raw const a; | ||
394 | } | ||
395 | "#), | ||
396 | @r###" | ||
397 | 9..10 'a': i32 | ||
398 | 17..54 '{ ...t a; }': () | ||
399 | 23..33 '&raw mut a': *mut i32 | ||
400 | 32..33 'a': i32 | ||
401 | 39..51 '&raw const a': *const i32 | ||
402 | 50..51 'a': i32 | ||
403 | "### | ||
404 | ); | ||
405 | } | ||
406 | |||
407 | #[test] | ||
388 | fn infer_literals() { | 408 | fn infer_literals() { |
389 | assert_snapshot!( | 409 | assert_snapshot!( |
390 | infer(r##" | 410 | infer(r##" |
diff --git a/crates/ra_hir_ty/src/tests/traits.rs b/crates/ra_hir_ty/src/tests/traits.rs index 0419bc751..e8778d419 100644 --- a/crates/ra_hir_ty/src/tests/traits.rs +++ b/crates/ra_hir_ty/src/tests/traits.rs | |||
@@ -2665,7 +2665,6 @@ fn test() { | |||
2665 | Enum::Variant.test(); | 2665 | Enum::Variant.test(); |
2666 | } | 2666 | } |
2667 | "#, true), | 2667 | "#, true), |
2668 | // wrong result, because the built-in Copy impl for fn defs doesn't exist in Chalk yet | ||
2669 | @r###" | 2668 | @r###" |
2670 | 42..44 '{}': () | 2669 | 42..44 '{}': () |
2671 | 61..62 'T': {unknown} | 2670 | 61..62 'T': {unknown} |
@@ -2674,13 +2673,13 @@ fn test() { | |||
2674 | 146..150 'self': &Self | 2673 | 146..150 'self': &Self |
2675 | 202..282 '{ ...t(); }': () | 2674 | 202..282 '{ ...t(); }': () |
2676 | 208..211 'foo': fn foo() | 2675 | 208..211 'foo': fn foo() |
2677 | 208..218 'foo.test()': {unknown} | 2676 | 208..218 'foo.test()': bool |
2678 | 224..227 'bar': fn bar<{unknown}>({unknown}) -> {unknown} | 2677 | 224..227 'bar': fn bar<{unknown}>({unknown}) -> {unknown} |
2679 | 224..234 'bar.test()': {unknown} | 2678 | 224..234 'bar.test()': bool |
2680 | 240..246 'Struct': Struct(usize) -> Struct | 2679 | 240..246 'Struct': Struct(usize) -> Struct |
2681 | 240..253 'Struct.test()': {unknown} | 2680 | 240..253 'Struct.test()': bool |
2682 | 259..272 'Enum::Variant': Variant(usize) -> Enum | 2681 | 259..272 'Enum::Variant': Variant(usize) -> Enum |
2683 | 259..279 'Enum::...test()': {unknown} | 2682 | 259..279 'Enum::...test()': bool |
2684 | "### | 2683 | "### |
2685 | ); | 2684 | ); |
2686 | } | 2685 | } |
@@ -2754,3 +2753,48 @@ fn test() { | |||
2754 | "### | 2753 | "### |
2755 | ); | 2754 | ); |
2756 | } | 2755 | } |
2756 | |||
2757 | #[test] | ||
2758 | fn integer_range_iterate() { | ||
2759 | let t = type_at( | ||
2760 | r#" | ||
2761 | //- /main.rs crate:main deps:std | ||
2762 | fn test() { | ||
2763 | for x in 0..100 { x<|>; } | ||
2764 | } | ||
2765 | |||
2766 | //- /std.rs crate:std | ||
2767 | pub mod ops { | ||
2768 | pub struct Range<Idx> { | ||
2769 | pub start: Idx, | ||
2770 | pub end: Idx, | ||
2771 | } | ||
2772 | } | ||
2773 | |||
2774 | pub mod iter { | ||
2775 | pub trait Iterator { | ||
2776 | type Item; | ||
2777 | } | ||
2778 | |||
2779 | pub trait IntoIterator { | ||
2780 | type Item; | ||
2781 | type IntoIter: Iterator<Item = Self::Item>; | ||
2782 | } | ||
2783 | |||
2784 | impl<T> IntoIterator for T where T: Iterator { | ||
2785 | type Item = <T as Iterator>::Item; | ||
2786 | type IntoIter = Self; | ||
2787 | } | ||
2788 | } | ||
2789 | |||
2790 | trait Step {} | ||
2791 | impl Step for i32 {} | ||
2792 | impl Step for i64 {} | ||
2793 | |||
2794 | impl<A: Step> iter::Iterator for ops::Range<A> { | ||
2795 | type Item = A; | ||
2796 | } | ||
2797 | "#, | ||
2798 | ); | ||
2799 | assert_eq!(t, "i32"); | ||
2800 | } | ||