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.rs6
-rw-r--r--crates/hir_ty/src/infer/pat.rs16
-rw-r--r--crates/hir_ty/src/tests/patterns.rs25
-rw-r--r--crates/hir_ty/src/traits/chalk.rs14
-rw-r--r--crates/hir_ty/src/traits/chalk/interner.rs18
-rw-r--r--crates/hir_ty/src/traits/chalk/mapping.rs12
6 files changed, 72 insertions, 19 deletions
diff --git a/crates/hir_ty/src/infer.rs b/crates/hir_ty/src/infer.rs
index 03b00b101..2b53b8297 100644
--- a/crates/hir_ty/src/infer.rs
+++ b/crates/hir_ty/src/infer.rs
@@ -125,7 +125,7 @@ pub struct InferenceResult {
125 field_resolutions: FxHashMap<ExprId, FieldId>, 125 field_resolutions: FxHashMap<ExprId, FieldId>,
126 /// For each field in record literal, records the field it resolves to. 126 /// For each field in record literal, records the field it resolves to.
127 record_field_resolutions: FxHashMap<ExprId, FieldId>, 127 record_field_resolutions: FxHashMap<ExprId, FieldId>,
128 record_field_pat_resolutions: FxHashMap<PatId, FieldId>, 128 record_pat_field_resolutions: FxHashMap<PatId, FieldId>,
129 /// For each struct literal, records the variant it resolves to. 129 /// For each struct literal, records the variant it resolves to.
130 variant_resolutions: FxHashMap<ExprOrPatId, VariantId>, 130 variant_resolutions: FxHashMap<ExprOrPatId, VariantId>,
131 /// For each associated item record what it resolves to 131 /// For each associated item record what it resolves to
@@ -146,8 +146,8 @@ impl InferenceResult {
146 pub fn record_field_resolution(&self, expr: ExprId) -> Option<FieldId> { 146 pub fn record_field_resolution(&self, expr: ExprId) -> Option<FieldId> {
147 self.record_field_resolutions.get(&expr).copied() 147 self.record_field_resolutions.get(&expr).copied()
148 } 148 }
149 pub fn record_field_pat_resolution(&self, pat: PatId) -> Option<FieldId> { 149 pub fn record_pat_field_resolution(&self, pat: PatId) -> Option<FieldId> {
150 self.record_field_pat_resolutions.get(&pat).copied() 150 self.record_pat_field_resolutions.get(&pat).copied()
151 } 151 }
152 pub fn variant_resolution_for_expr(&self, id: ExprId) -> Option<VariantId> { 152 pub fn variant_resolution_for_expr(&self, id: ExprId) -> Option<VariantId> {
153 self.variant_resolutions.get(&id.into()).copied() 153 self.variant_resolutions.get(&id.into()).copied()
diff --git a/crates/hir_ty/src/infer/pat.rs b/crates/hir_ty/src/infer/pat.rs
index 4dd4f9802..cde2ab82b 100644
--- a/crates/hir_ty/src/infer/pat.rs
+++ b/crates/hir_ty/src/infer/pat.rs
@@ -70,7 +70,7 @@ impl<'a> InferenceContext<'a> {
70 let matching_field = var_data.as_ref().and_then(|it| it.field(&subpat.name)); 70 let matching_field = var_data.as_ref().and_then(|it| it.field(&subpat.name));
71 if let Some(local_id) = matching_field { 71 if let Some(local_id) = matching_field {
72 let field_def = FieldId { parent: def.unwrap(), local_id }; 72 let field_def = FieldId { parent: def.unwrap(), local_id };
73 self.result.record_field_pat_resolutions.insert(subpat.pat, field_def); 73 self.result.record_pat_field_resolutions.insert(subpat.pat, field_def);
74 } 74 }
75 75
76 let expected_ty = 76 let expected_ty =
@@ -209,6 +209,18 @@ impl<'a> InferenceContext<'a> {
209 end_ty 209 end_ty
210 } 210 }
211 Pat::Lit(expr) => self.infer_expr(*expr, &Expectation::has_type(expected.clone())), 211 Pat::Lit(expr) => self.infer_expr(*expr, &Expectation::has_type(expected.clone())),
212 Pat::Box { inner } => match self.resolve_boxed_box() {
213 Some(box_adt) => {
214 let inner_expected = match expected.as_adt() {
215 Some((adt, substs)) if adt == box_adt => substs.as_single(),
216 _ => &Ty::Unknown,
217 };
218
219 let inner_ty = self.infer_pat(*inner, inner_expected, default_bm);
220 Ty::apply_one(TypeCtor::Adt(box_adt), inner_ty)
221 }
222 None => Ty::Unknown,
223 },
212 Pat::Missing => Ty::Unknown, 224 Pat::Missing => Ty::Unknown,
213 }; 225 };
214 // use a new type variable if we got Ty::Unknown here 226 // use a new type variable if we got Ty::Unknown here
@@ -236,6 +248,6 @@ fn is_non_ref_pat(body: &hir_def::body::Body, pat: PatId) -> bool {
236 Expr::Literal(Literal::String(..)) => false, 248 Expr::Literal(Literal::String(..)) => false,
237 _ => true, 249 _ => true,
238 }, 250 },
239 Pat::Wild | Pat::Bind { .. } | Pat::Ref { .. } | Pat::Missing => false, 251 Pat::Wild | Pat::Bind { .. } | Pat::Ref { .. } | Pat::Box { .. } | Pat::Missing => false,
240 } 252 }
241} 253}
diff --git a/crates/hir_ty/src/tests/patterns.rs b/crates/hir_ty/src/tests/patterns.rs
index aeb191c79..6a965ac4f 100644
--- a/crates/hir_ty/src/tests/patterns.rs
+++ b/crates/hir_ty/src/tests/patterns.rs
@@ -654,3 +654,28 @@ fn slice_tail_pattern() {
654 "#]], 654 "#]],
655 ); 655 );
656} 656}
657
658#[test]
659fn box_pattern() {
660 check_infer(
661 r#"
662 #[lang = "owned_box"]
663 pub struct Box<T>(T);
664
665 fn foo(params: Box<i32>) {
666 match params {
667 box integer => {}
668 }
669 }
670 "#,
671 expect![[r#"
672 52..58 'params': Box<i32>
673 70..124 '{ ... } }': ()
674 76..122 'match ... }': ()
675 82..88 'params': Box<i32>
676 99..110 'box integer': Box<i32>
677 103..110 'integer': i32
678 114..116 '{}': ()
679 "#]],
680 );
681}
diff --git a/crates/hir_ty/src/traits/chalk.rs b/crates/hir_ty/src/traits/chalk.rs
index ff364789e..57d0a32df 100644
--- a/crates/hir_ty/src/traits/chalk.rs
+++ b/crates/hir_ty/src/traits/chalk.rs
@@ -307,13 +307,17 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> {
307 let id = from_chalk(self.db, trait_id); 307 let id = from_chalk(self.db, trait_id);
308 self.db.trait_data(id).name.to_string() 308 self.db.trait_data(id).name.to_string()
309 } 309 }
310 // FIXME: lookup names 310 fn adt_name(&self, adt_id: chalk_ir::AdtId<Interner>) -> String {
311 fn adt_name(&self, struct_id: chalk_ir::AdtId<Interner>) -> String { 311 let id = from_chalk(self.db, adt_id);
312 let datum = self.db.struct_datum(self.krate, struct_id); 312 match id {
313 format!("{:?}", datum.name(&Interner)) 313 hir_def::AdtId::StructId(id) => self.db.struct_data(id).name.to_string(),
314 hir_def::AdtId::EnumId(id) => self.db.enum_data(id).name.to_string(),
315 hir_def::AdtId::UnionId(id) => self.db.union_data(id).name.to_string(),
316 }
314 } 317 }
315 fn assoc_type_name(&self, assoc_ty_id: chalk_ir::AssocTypeId<Interner>) -> String { 318 fn assoc_type_name(&self, assoc_ty_id: chalk_ir::AssocTypeId<Interner>) -> String {
316 format!("Assoc_{}", assoc_ty_id.0) 319 let id = self.db.associated_ty_data(assoc_ty_id).name;
320 self.db.type_alias_data(id).name.to_string()
317 } 321 }
318 fn opaque_type_name(&self, opaque_ty_id: chalk_ir::OpaqueTyId<Interner>) -> String { 322 fn opaque_type_name(&self, opaque_ty_id: chalk_ir::OpaqueTyId<Interner>) -> String {
319 format!("Opaque_{}", opaque_ty_id.0) 323 format!("Opaque_{}", opaque_ty_id.0)
diff --git a/crates/hir_ty/src/traits/chalk/interner.rs b/crates/hir_ty/src/traits/chalk/interner.rs
index fc0f9c201..eb35db3ff 100644
--- a/crates/hir_ty/src/traits/chalk/interner.rs
+++ b/crates/hir_ty/src/traits/chalk/interner.rs
@@ -26,7 +26,7 @@ pub type OpaqueTyId = chalk_ir::OpaqueTyId<Interner>;
26pub type OpaqueTyDatum = chalk_solve::rust_ir::OpaqueTyDatum<Interner>; 26pub type OpaqueTyDatum = chalk_solve::rust_ir::OpaqueTyDatum<Interner>;
27 27
28impl chalk_ir::interner::Interner for Interner { 28impl chalk_ir::interner::Interner for Interner {
29 type InternedType = Box<chalk_ir::TyData<Self>>; // FIXME use Arc? 29 type InternedType = Arc<chalk_ir::TyData<Self>>;
30 type InternedLifetime = chalk_ir::LifetimeData<Self>; 30 type InternedLifetime = chalk_ir::LifetimeData<Self>;
31 type InternedConst = Arc<chalk_ir::ConstData<Self>>; 31 type InternedConst = Arc<chalk_ir::ConstData<Self>>;
32 type InternedConcreteConst = (); 32 type InternedConcreteConst = ();
@@ -34,7 +34,7 @@ impl chalk_ir::interner::Interner for Interner {
34 type InternedGoal = Arc<GoalData<Self>>; 34 type InternedGoal = Arc<GoalData<Self>>;
35 type InternedGoals = Vec<Goal<Self>>; 35 type InternedGoals = Vec<Goal<Self>>;
36 type InternedSubstitution = Vec<GenericArg<Self>>; 36 type InternedSubstitution = Vec<GenericArg<Self>>;
37 type InternedProgramClause = chalk_ir::ProgramClauseData<Self>; 37 type InternedProgramClause = Arc<chalk_ir::ProgramClauseData<Self>>;
38 type InternedProgramClauses = Arc<[chalk_ir::ProgramClause<Self>]>; 38 type InternedProgramClauses = Arc<[chalk_ir::ProgramClause<Self>]>;
39 type InternedQuantifiedWhereClauses = Vec<chalk_ir::QuantifiedWhereClause<Self>>; 39 type InternedQuantifiedWhereClauses = Vec<chalk_ir::QuantifiedWhereClause<Self>>;
40 type InternedVariableKinds = Vec<chalk_ir::VariableKind<Self>>; 40 type InternedVariableKinds = Vec<chalk_ir::VariableKind<Self>>;
@@ -197,11 +197,11 @@ impl chalk_ir::interner::Interner for Interner {
197 tls::with_current_program(|prog| Some(prog?.debug_quantified_where_clauses(clauses, fmt))) 197 tls::with_current_program(|prog| Some(prog?.debug_quantified_where_clauses(clauses, fmt)))
198 } 198 }
199 199
200 fn intern_ty(&self, ty: chalk_ir::TyData<Self>) -> Box<chalk_ir::TyData<Self>> { 200 fn intern_ty(&self, ty: chalk_ir::TyData<Self>) -> Arc<chalk_ir::TyData<Self>> {
201 Box::new(ty) 201 Arc::new(ty)
202 } 202 }
203 203
204 fn ty_data<'a>(&self, ty: &'a Box<chalk_ir::TyData<Self>>) -> &'a chalk_ir::TyData<Self> { 204 fn ty_data<'a>(&self, ty: &'a Arc<chalk_ir::TyData<Self>>) -> &'a chalk_ir::TyData<Self> {
205 ty 205 ty
206 } 206 }
207 207
@@ -230,7 +230,7 @@ impl chalk_ir::interner::Interner for Interner {
230 constant 230 constant
231 } 231 }
232 232
233 fn const_eq(&self, _ty: &Box<chalk_ir::TyData<Self>>, _c1: &(), _c2: &()) -> bool { 233 fn const_eq(&self, _ty: &Arc<chalk_ir::TyData<Self>>, _c1: &(), _c2: &()) -> bool {
234 true 234 true
235 } 235 }
236 236
@@ -284,13 +284,13 @@ impl chalk_ir::interner::Interner for Interner {
284 fn intern_program_clause( 284 fn intern_program_clause(
285 &self, 285 &self,
286 data: chalk_ir::ProgramClauseData<Self>, 286 data: chalk_ir::ProgramClauseData<Self>,
287 ) -> chalk_ir::ProgramClauseData<Self> { 287 ) -> Arc<chalk_ir::ProgramClauseData<Self>> {
288 data 288 Arc::new(data)
289 } 289 }
290 290
291 fn program_clause_data<'a>( 291 fn program_clause_data<'a>(
292 &self, 292 &self,
293 clause: &'a chalk_ir::ProgramClauseData<Self>, 293 clause: &'a Arc<chalk_ir::ProgramClauseData<Self>>,
294 ) -> &'a chalk_ir::ProgramClauseData<Self> { 294 ) -> &'a chalk_ir::ProgramClauseData<Self> {
295 clause 295 clause
296 } 296 }
diff --git a/crates/hir_ty/src/traits/chalk/mapping.rs b/crates/hir_ty/src/traits/chalk/mapping.rs
index fe62f3fa7..d6bacba1d 100644
--- a/crates/hir_ty/src/traits/chalk/mapping.rs
+++ b/crates/hir_ty/src/traits/chalk/mapping.rs
@@ -464,6 +464,18 @@ impl ToChalk for hir_def::ImplId {
464 } 464 }
465} 465}
466 466
467impl ToChalk for hir_def::AdtId {
468 type Chalk = AdtId;
469
470 fn to_chalk(self, _db: &dyn HirDatabase) -> Self::Chalk {
471 chalk_ir::AdtId(self.into())
472 }
473
474 fn from_chalk(_db: &dyn HirDatabase, id: AdtId) -> Self {
475 id.0
476 }
477}
478
467impl ToChalk for CallableDefId { 479impl ToChalk for CallableDefId {
468 type Chalk = FnDefId; 480 type Chalk = FnDefId;
469 481