aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_ty/src
diff options
context:
space:
mode:
Diffstat (limited to 'crates/hir_ty/src')
-rw-r--r--crates/hir_ty/src/infer/expr.rs12
-rw-r--r--crates/hir_ty/src/infer/pat.rs6
-rw-r--r--crates/hir_ty/src/tests/patterns.rs30
-rw-r--r--crates/hir_ty/src/tests/simple.rs13
-rw-r--r--crates/hir_ty/src/traits/chalk.rs11
5 files changed, 60 insertions, 12 deletions
diff --git a/crates/hir_ty/src/infer/expr.rs b/crates/hir_ty/src/infer/expr.rs
index 2cdce2cef..f2fc69b2f 100644
--- a/crates/hir_ty/src/infer/expr.rs
+++ b/crates/hir_ty/src/infer/expr.rs
@@ -143,7 +143,7 @@ impl<'a> InferenceContext<'a> {
143 self.breakables.push(BreakableContext { 143 self.breakables.push(BreakableContext {
144 may_break: false, 144 may_break: false,
145 break_ty: break_ty.clone(), 145 break_ty: break_ty.clone(),
146 label: label.clone(), 146 label: label.map(|label| self.body[label].name.clone()),
147 }); 147 });
148 let ty = self.infer_block(statements, *tail, &Expectation::has_type(break_ty)); 148 let ty = self.infer_block(statements, *tail, &Expectation::has_type(break_ty));
149 let ctxt = self.breakables.pop().expect("breakable stack broken"); 149 let ctxt = self.breakables.pop().expect("breakable stack broken");
@@ -155,7 +155,7 @@ impl<'a> InferenceContext<'a> {
155 } 155 }
156 None => self.infer_block(statements, *tail, expected), 156 None => self.infer_block(statements, *tail, expected),
157 }, 157 },
158 Expr::Unsafe { body } => self.infer_expr(*body, expected), 158 Expr::Unsafe { body } | Expr::Const { body } => self.infer_expr(*body, expected),
159 Expr::TryBlock { body } => { 159 Expr::TryBlock { body } => {
160 let _inner = self.infer_expr(*body, expected); 160 let _inner = self.infer_expr(*body, expected);
161 // FIXME should be std::result::Result<{inner}, _> 161 // FIXME should be std::result::Result<{inner}, _>
@@ -172,7 +172,7 @@ impl<'a> InferenceContext<'a> {
172 self.breakables.push(BreakableContext { 172 self.breakables.push(BreakableContext {
173 may_break: false, 173 may_break: false,
174 break_ty: self.table.new_type_var(), 174 break_ty: self.table.new_type_var(),
175 label: label.clone(), 175 label: label.map(|label| self.body[label].name.clone()),
176 }); 176 });
177 self.infer_expr(*body, &Expectation::has_type(Ty::unit())); 177 self.infer_expr(*body, &Expectation::has_type(Ty::unit()));
178 178
@@ -191,7 +191,7 @@ impl<'a> InferenceContext<'a> {
191 self.breakables.push(BreakableContext { 191 self.breakables.push(BreakableContext {
192 may_break: false, 192 may_break: false,
193 break_ty: Ty::Unknown, 193 break_ty: Ty::Unknown,
194 label: label.clone(), 194 label: label.map(|label| self.body[label].name.clone()),
195 }); 195 });
196 // while let is desugared to a match loop, so this is always simple while 196 // while let is desugared to a match loop, so this is always simple while
197 self.infer_expr(*condition, &Expectation::has_type(Ty::simple(TypeCtor::Bool))); 197 self.infer_expr(*condition, &Expectation::has_type(Ty::simple(TypeCtor::Bool)));
@@ -207,7 +207,7 @@ impl<'a> InferenceContext<'a> {
207 self.breakables.push(BreakableContext { 207 self.breakables.push(BreakableContext {
208 may_break: false, 208 may_break: false,
209 break_ty: Ty::Unknown, 209 break_ty: Ty::Unknown,
210 label: label.clone(), 210 label: label.map(|label| self.body[label].name.clone()),
211 }); 211 });
212 let pat_ty = 212 let pat_ty =
213 self.resolve_associated_type(iterable_ty, self.resolve_into_iter_item()); 213 self.resolve_associated_type(iterable_ty, self.resolve_into_iter_item());
@@ -648,6 +648,8 @@ impl<'a> InferenceContext<'a> {
648 } 648 }
649 Expr::Array(array) => { 649 Expr::Array(array) => {
650 let elem_ty = match &expected.ty { 650 let elem_ty = match &expected.ty {
651 // FIXME: remove when https://github.com/rust-lang/rust/issues/80501 is fixed
652 #[allow(unreachable_patterns)]
651 ty_app!(TypeCtor::Array, st) | ty_app!(TypeCtor::Slice, st) => { 653 ty_app!(TypeCtor::Array, st) | ty_app!(TypeCtor::Slice, st) => {
652 st.as_single().clone() 654 st.as_single().clone()
653 } 655 }
diff --git a/crates/hir_ty/src/infer/pat.rs b/crates/hir_ty/src/infer/pat.rs
index b70ec55eb..d974f805b 100644
--- a/crates/hir_ty/src/infer/pat.rs
+++ b/crates/hir_ty/src/infer/pat.rs
@@ -243,6 +243,9 @@ impl<'a> InferenceContext<'a> {
243 } 243 }
244 None => Ty::Unknown, 244 None => Ty::Unknown,
245 }, 245 },
246 Pat::ConstBlock(expr) => {
247 self.infer_expr(*expr, &Expectation::has_type(expected.clone()))
248 }
246 Pat::Missing => Ty::Unknown, 249 Pat::Missing => Ty::Unknown,
247 }; 250 };
248 // use a new type variable if we got Ty::Unknown here 251 // use a new type variable if we got Ty::Unknown here
@@ -264,8 +267,9 @@ fn is_non_ref_pat(body: &hir_def::body::Body, pat: PatId) -> bool {
264 | Pat::Range { .. } 267 | Pat::Range { .. }
265 | Pat::Slice { .. } => true, 268 | Pat::Slice { .. } => true,
266 Pat::Or(pats) => pats.iter().all(|p| is_non_ref_pat(body, *p)), 269 Pat::Or(pats) => pats.iter().all(|p| is_non_ref_pat(body, *p)),
267 // FIXME: Path/Lit might actually evaluate to ref, but inference is unimplemented. 270 // FIXME: ConstBlock/Path/Lit might actually evaluate to ref, but inference is unimplemented.
268 Pat::Path(..) => true, 271 Pat::Path(..) => true,
272 Pat::ConstBlock(..) => true,
269 Pat::Lit(expr) => match body[*expr] { 273 Pat::Lit(expr) => match body[*expr] {
270 Expr::Literal(Literal::String(..)) => false, 274 Expr::Literal(Literal::String(..)) => false,
271 _ => true, 275 _ => true,
diff --git a/crates/hir_ty/src/tests/patterns.rs b/crates/hir_ty/src/tests/patterns.rs
index 5a5f48fd0..2053d8f56 100644
--- a/crates/hir_ty/src/tests/patterns.rs
+++ b/crates/hir_ty/src/tests/patterns.rs
@@ -774,3 +774,33 @@ fn foo(tuple: Tuple) {
774 "#]], 774 "#]],
775 ); 775 );
776} 776}
777
778#[test]
779fn const_block_pattern() {
780 check_infer(
781 r#"
782struct Foo(usize);
783fn foo(foo: Foo) {
784 match foo {
785 const { Foo(15 + 32) } => {},
786 _ => {}
787 }
788}"#,
789 expect![[r#"
790 26..29 'foo': Foo
791 36..115 '{ ... } }': ()
792 42..113 'match ... }': ()
793 48..51 'foo': Foo
794 62..84 'const ... 32) }': Foo
795 68..84 '{ Foo(... 32) }': Foo
796 70..73 'Foo': Foo(usize) -> Foo
797 70..82 'Foo(15 + 32)': Foo
798 74..76 '15': usize
799 74..81 '15 + 32': usize
800 79..81 '32': usize
801 88..90 '{}': ()
802 100..101 '_': Foo
803 105..107 '{}': ()
804 "#]],
805 );
806}
diff --git a/crates/hir_ty/src/tests/simple.rs b/crates/hir_ty/src/tests/simple.rs
index a569223b4..a61282d5a 100644
--- a/crates/hir_ty/src/tests/simple.rs
+++ b/crates/hir_ty/src/tests/simple.rs
@@ -1894,6 +1894,7 @@ fn effects_smoke_test() {
1894 let x = unsafe { 92 }; 1894 let x = unsafe { 92 };
1895 let y = async { async { () }.await }; 1895 let y = async { async { () }.await };
1896 let z = try { () }; 1896 let z = try { () };
1897 let w = const { 92 };
1897 let t = 'a: { 92 }; 1898 let t = 'a: { 92 };
1898 } 1899 }
1899 1900
@@ -1905,7 +1906,7 @@ fn effects_smoke_test() {
1905 } 1906 }
1906 "#, 1907 "#,
1907 expect![[r#" 1908 expect![[r#"
1908 16..136 '{ ...2 }; }': () 1909 16..162 '{ ...2 }; }': ()
1909 26..27 'x': i32 1910 26..27 'x': i32
1910 30..43 'unsafe { 92 }': i32 1911 30..43 'unsafe { 92 }': i32
1911 37..43 '{ 92 }': i32 1912 37..43 '{ 92 }': i32
@@ -1921,9 +1922,13 @@ fn effects_smoke_test() {
1921 99..109 'try { () }': {unknown} 1922 99..109 'try { () }': {unknown}
1922 103..109 '{ () }': () 1923 103..109 '{ () }': ()
1923 105..107 '()': () 1924 105..107 '()': ()
1924 119..120 't': i32 1925 119..120 'w': i32
1925 127..133 '{ 92 }': i32 1926 123..135 'const { 92 }': i32
1926 129..131 '92': i32 1927 129..135 '{ 92 }': i32
1928 131..133 '92': i32
1929 145..146 't': i32
1930 153..159 '{ 92 }': i32
1931 155..157 '92': i32
1927 "#]], 1932 "#]],
1928 ) 1933 )
1929} 1934}
diff --git a/crates/hir_ty/src/traits/chalk.rs b/crates/hir_ty/src/traits/chalk.rs
index 69eae6f79..2196af677 100644
--- a/crates/hir_ty/src/traits/chalk.rs
+++ b/crates/hir_ty/src/traits/chalk.rs
@@ -56,8 +56,13 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> {
56 fn adt_datum(&self, struct_id: AdtId) -> Arc<StructDatum> { 56 fn adt_datum(&self, struct_id: AdtId) -> Arc<StructDatum> {
57 self.db.struct_datum(self.krate, struct_id) 57 self.db.struct_datum(self.krate, struct_id)
58 } 58 }
59 fn adt_repr(&self, _struct_id: AdtId) -> rust_ir::AdtRepr { 59 fn adt_repr(&self, _struct_id: AdtId) -> Arc<rust_ir::AdtRepr<Interner>> {
60 rust_ir::AdtRepr { repr_c: false, repr_packed: false } 60 // FIXME: keep track of these
61 Arc::new(rust_ir::AdtRepr { c: false, packed: false, int: None })
62 }
63 fn discriminant_type(&self, _ty: chalk_ir::Ty<Interner>) -> chalk_ir::Ty<Interner> {
64 // FIXME: keep track of this
65 chalk_ir::TyKind::Scalar(chalk_ir::Scalar::Uint(chalk_ir::UintTy::U32)).intern(&Interner)
61 } 66 }
62 fn impl_datum(&self, impl_id: ImplId) -> Arc<ImplDatum> { 67 fn impl_datum(&self, impl_id: ImplId) -> Arc<ImplDatum> {
63 self.db.impl_datum(self.krate, impl_id) 68 self.db.impl_datum(self.krate, impl_id)
@@ -457,6 +462,7 @@ fn well_known_trait_from_lang_attr(name: &str) -> Option<WellKnownTrait> {
457 "fn" => WellKnownTrait::Fn, 462 "fn" => WellKnownTrait::Fn,
458 "unsize" => WellKnownTrait::Unsize, 463 "unsize" => WellKnownTrait::Unsize,
459 "coerce_unsized" => WellKnownTrait::CoerceUnsized, 464 "coerce_unsized" => WellKnownTrait::CoerceUnsized,
465 "discriminant_kind" => WellKnownTrait::DiscriminantKind,
460 _ => return None, 466 _ => return None,
461 }) 467 })
462} 468}
@@ -473,6 +479,7 @@ fn lang_attr_from_well_known_trait(attr: WellKnownTrait) -> &'static str {
473 WellKnownTrait::Unsize => "unsize", 479 WellKnownTrait::Unsize => "unsize",
474 WellKnownTrait::Unpin => "unpin", 480 WellKnownTrait::Unpin => "unpin",
475 WellKnownTrait::CoerceUnsized => "coerce_unsized", 481 WellKnownTrait::CoerceUnsized => "coerce_unsized",
482 WellKnownTrait::DiscriminantKind => "discriminant_kind",
476 } 483 }
477} 484}
478 485