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.rs10
-rw-r--r--crates/hir_ty/src/infer/pat.rs6
-rw-r--r--crates/hir_ty/src/lower.rs18
-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
-rw-r--r--crates/hir_ty/src/utils.rs9
7 files changed, 73 insertions, 24 deletions
diff --git a/crates/hir_ty/src/infer/expr.rs b/crates/hir_ty/src/infer/expr.rs
index 2cdce2cef..70a3f3075 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());
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/lower.rs b/crates/hir_ty/src/lower.rs
index 8392cb770..8da56cd11 100644
--- a/crates/hir_ty/src/lower.rs
+++ b/crates/hir_ty/src/lower.rs
@@ -675,7 +675,8 @@ impl GenericPredicate {
675 where_predicate: &'a WherePredicate, 675 where_predicate: &'a WherePredicate,
676 ) -> impl Iterator<Item = GenericPredicate> + 'a { 676 ) -> impl Iterator<Item = GenericPredicate> + 'a {
677 match where_predicate { 677 match where_predicate {
678 WherePredicate::TypeBound { target, bound } => { 678 WherePredicate::ForLifetime { target, bound, .. }
679 | WherePredicate::TypeBound { target, bound } => {
679 let self_ty = match target { 680 let self_ty = match target {
680 WherePredicateTypeTarget::TypeRef(type_ref) => Ty::from_hir(ctx, type_ref), 681 WherePredicateTypeTarget::TypeRef(type_ref) => Ty::from_hir(ctx, type_ref),
681 WherePredicateTypeTarget::TypeParam(param_id) => { 682 WherePredicateTypeTarget::TypeParam(param_id) => {
@@ -888,14 +889,13 @@ pub(crate) fn generic_predicates_for_param_query(
888 .where_predicates_in_scope() 889 .where_predicates_in_scope()
889 // we have to filter out all other predicates *first*, before attempting to lower them 890 // we have to filter out all other predicates *first*, before attempting to lower them
890 .filter(|pred| match pred { 891 .filter(|pred| match pred {
891 WherePredicate::TypeBound { 892 WherePredicate::ForLifetime { target, .. }
892 target: WherePredicateTypeTarget::TypeRef(type_ref), 893 | WherePredicate::TypeBound { target, .. } => match target {
893 .. 894 WherePredicateTypeTarget::TypeRef(type_ref) => {
894 } => Ty::from_hir_only_param(&ctx, type_ref) == Some(param_id), 895 Ty::from_hir_only_param(&ctx, type_ref) == Some(param_id)
895 WherePredicate::TypeBound { 896 }
896 target: WherePredicateTypeTarget::TypeParam(local_id), 897 WherePredicateTypeTarget::TypeParam(local_id) => *local_id == param_id.local_id,
897 .. 898 },
898 } => *local_id == param_id.local_id,
899 WherePredicate::Lifetime { .. } => false, 899 WherePredicate::Lifetime { .. } => false,
900 }) 900 })
901 .flat_map(|pred| { 901 .flat_map(|pred| {
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
diff --git a/crates/hir_ty/src/utils.rs b/crates/hir_ty/src/utils.rs
index af880c065..65b79df0d 100644
--- a/crates/hir_ty/src/utils.rs
+++ b/crates/hir_ty/src/utils.rs
@@ -5,7 +5,9 @@ use std::sync::Arc;
5use hir_def::{ 5use hir_def::{
6 adt::VariantData, 6 adt::VariantData,
7 db::DefDatabase, 7 db::DefDatabase,
8 generics::{GenericParams, TypeParamData, TypeParamProvenance, WherePredicateTypeTarget}, 8 generics::{
9 GenericParams, TypeParamData, TypeParamProvenance, WherePredicate, WherePredicateTypeTarget,
10 },
9 path::Path, 11 path::Path,
10 resolver::{HasResolver, TypeNs}, 12 resolver::{HasResolver, TypeNs},
11 type_ref::TypeRef, 13 type_ref::TypeRef,
@@ -27,7 +29,8 @@ fn direct_super_traits(db: &dyn DefDatabase, trait_: TraitId) -> Vec<TraitId> {
27 .where_predicates 29 .where_predicates
28 .iter() 30 .iter()
29 .filter_map(|pred| match pred { 31 .filter_map(|pred| match pred {
30 hir_def::generics::WherePredicate::TypeBound { target, bound } => match target { 32 WherePredicate::ForLifetime { target, bound, .. }
33 | WherePredicate::TypeBound { target, bound } => match target {
31 WherePredicateTypeTarget::TypeRef(TypeRef::Path(p)) 34 WherePredicateTypeTarget::TypeRef(TypeRef::Path(p))
32 if p == &Path::from(name![Self]) => 35 if p == &Path::from(name![Self]) =>
33 { 36 {
@@ -38,7 +41,7 @@ fn direct_super_traits(db: &dyn DefDatabase, trait_: TraitId) -> Vec<TraitId> {
38 } 41 }
39 _ => None, 42 _ => None,
40 }, 43 },
41 hir_def::generics::WherePredicate::Lifetime { .. } => None, 44 WherePredicate::Lifetime { .. } => None,
42 }) 45 })
43 .filter_map(|path| match resolver.resolve_path_in_type_ns_fully(db, path.mod_path()) { 46 .filter_map(|path| match resolver.resolve_path_in_type_ns_fully(db, path.mod_path()) {
44 Some(TypeNs::TraitId(t)) => Some(t), 47 Some(TypeNs::TraitId(t)) => Some(t),