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/diagnostics/match_check.rs40
-rw-r--r--crates/hir_ty/src/infer/expr.rs2
-rw-r--r--crates/hir_ty/src/lower.rs12
-rw-r--r--crates/hir_ty/src/tests/traits.rs43
4 files changed, 64 insertions, 33 deletions
diff --git a/crates/hir_ty/src/diagnostics/match_check.rs b/crates/hir_ty/src/diagnostics/match_check.rs
index 5a5cdcbf3..9cb472b51 100644
--- a/crates/hir_ty/src/diagnostics/match_check.rs
+++ b/crates/hir_ty/src/diagnostics/match_check.rs
@@ -539,7 +539,7 @@ impl Matrix {
539 if let Some(Pat::Or(pat_ids)) = row.get_head().map(|pat_id| pat_id.as_pat(cx)) { 539 if let Some(Pat::Or(pat_ids)) = row.get_head().map(|pat_id| pat_id.as_pat(cx)) {
540 // Or patterns are expanded here 540 // Or patterns are expanded here
541 for pat_id in pat_ids { 541 for pat_id in pat_ids {
542 self.0.push(PatStack::from_pattern(pat_id)); 542 self.0.push(row.replace_head_with([pat_id].iter()));
543 } 543 }
544 } else { 544 } else {
545 self.0.push(row); 545 self.0.push(row);
@@ -1085,6 +1085,20 @@ fn main() {
1085 } 1085 }
1086 1086
1087 #[test] 1087 #[test]
1088 fn or_pattern_no_diagnostic() {
1089 check_diagnostics(
1090 r#"
1091enum Either {A, B}
1092
1093fn main() {
1094 match (Either::A, Either::B) {
1095 (Either::A | Either::B, _) => (),
1096 }
1097}"#,
1098 )
1099 }
1100
1101 #[test]
1088 fn mismatched_types() { 1102 fn mismatched_types() {
1089 // Match statements with arms that don't match the 1103 // Match statements with arms that don't match the
1090 // expression pattern do not fire this diagnostic. 1104 // expression pattern do not fire this diagnostic.
@@ -1336,30 +1350,6 @@ fn bang(never: !) {
1336 } 1350 }
1337 1351
1338 #[test] 1352 #[test]
1339 fn or_pattern_panic() {
1340 check_diagnostics(
1341 r#"
1342pub enum Category { Infinity, Zero }
1343
1344fn panic(a: Category, b: Category) {
1345 match (a, b) {
1346 (Category::Zero | Category::Infinity, _) => (),
1347 (_, Category::Zero | Category::Infinity) => (),
1348 }
1349
1350 // FIXME: This is a false positive, but the code used to cause a panic in the match checker,
1351 // so this acts as a regression test for that.
1352 match (a, b) {
1353 //^^^^^^ Missing match arm
1354 (Category::Infinity, Category::Infinity) | (Category::Zero, Category::Zero) => (),
1355 (Category::Infinity | Category::Zero, _) => (),
1356 }
1357}
1358"#,
1359 );
1360 }
1361
1362 #[test]
1363 fn unknown_type() { 1353 fn unknown_type() {
1364 check_diagnostics( 1354 check_diagnostics(
1365 r#" 1355 r#"
diff --git a/crates/hir_ty/src/infer/expr.rs b/crates/hir_ty/src/infer/expr.rs
index e6ede05ca..6279aa572 100644
--- a/crates/hir_ty/src/infer/expr.rs
+++ b/crates/hir_ty/src/infer/expr.rs
@@ -119,6 +119,8 @@ impl<'a> InferenceContext<'a> {
119 } 119 }
120 120
121 fn infer_expr_inner(&mut self, tgt_expr: ExprId, expected: &Expectation) -> Ty { 121 fn infer_expr_inner(&mut self, tgt_expr: ExprId, expected: &Expectation) -> Ty {
122 self.db.check_canceled();
123
122 let body = Arc::clone(&self.body); // avoid borrow checker problem 124 let body = Arc::clone(&self.body); // avoid borrow checker problem
123 let ty = match &body[tgt_expr] { 125 let ty = match &body[tgt_expr] {
124 Expr::Missing => self.err_ty(), 126 Expr::Missing => self.err_ty(),
diff --git a/crates/hir_ty/src/lower.rs b/crates/hir_ty/src/lower.rs
index c87789d45..afbfa12d5 100644
--- a/crates/hir_ty/src/lower.rs
+++ b/crates/hir_ty/src/lower.rs
@@ -15,7 +15,7 @@ use hir_def::{
15 generics::{TypeParamProvenance, WherePredicate, WherePredicateTypeTarget}, 15 generics::{TypeParamProvenance, WherePredicate, WherePredicateTypeTarget},
16 path::{GenericArg, Path, PathSegment, PathSegments}, 16 path::{GenericArg, Path, PathSegment, PathSegments},
17 resolver::{HasResolver, Resolver, TypeNs}, 17 resolver::{HasResolver, Resolver, TypeNs},
18 type_ref::{TypeBound, TypeRef}, 18 type_ref::{TraitRef as HirTraitRef, TypeBound, TypeRef},
19 AdtId, AssocContainerId, AssocItemId, ConstId, ConstParamId, EnumId, EnumVariantId, FunctionId, 19 AdtId, AssocContainerId, AssocItemId, ConstId, ConstParamId, EnumId, EnumVariantId, FunctionId,
20 GenericDefId, HasModule, ImplId, LocalFieldId, Lookup, StaticId, StructId, TraitId, 20 GenericDefId, HasModule, ImplId, LocalFieldId, Lookup, StaticId, StructId, TraitId,
21 TypeAliasId, TypeParamId, UnionId, VariantId, 21 TypeAliasId, TypeParamId, UnionId, VariantId,
@@ -667,14 +667,10 @@ impl<'a> TyLoweringContext<'a> {
667 667
668 fn lower_trait_ref( 668 fn lower_trait_ref(
669 &self, 669 &self,
670 type_ref: &TypeRef, 670 trait_ref: &HirTraitRef,
671 explicit_self_ty: Option<Ty>, 671 explicit_self_ty: Option<Ty>,
672 ) -> Option<TraitRef> { 672 ) -> Option<TraitRef> {
673 let path = match type_ref { 673 self.lower_trait_ref_from_path(&trait_ref.path, explicit_self_ty)
674 TypeRef::Path(path) => path,
675 _ => return None,
676 };
677 self.lower_trait_ref_from_path(path, explicit_self_ty)
678 } 674 }
679 675
680 fn trait_ref_substs_from_path( 676 fn trait_ref_substs_from_path(
@@ -1253,7 +1249,7 @@ pub(crate) fn impl_self_ty_query(db: &dyn HirDatabase, impl_id: ImplId) -> Binde
1253 let generics = generics(db.upcast(), impl_id.into()); 1249 let generics = generics(db.upcast(), impl_id.into());
1254 let ctx = 1250 let ctx =
1255 TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable); 1251 TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable);
1256 Binders::new(generics.len(), ctx.lower_ty(&impl_data.target_type)) 1252 Binders::new(generics.len(), ctx.lower_ty(&impl_data.self_ty))
1257} 1253}
1258 1254
1259pub(crate) fn const_param_ty_query(db: &dyn HirDatabase, def: ConstParamId) -> Ty { 1255pub(crate) fn const_param_ty_query(db: &dyn HirDatabase, def: ConstParamId) -> Ty {
diff --git a/crates/hir_ty/src/tests/traits.rs b/crates/hir_ty/src/tests/traits.rs
index 2ba97f814..65b71fdfa 100644
--- a/crates/hir_ty/src/tests/traits.rs
+++ b/crates/hir_ty/src/tests/traits.rs
@@ -3370,3 +3370,46 @@ fn test() {
3370 "#]], 3370 "#]],
3371 ) 3371 )
3372} 3372}
3373
3374#[test]
3375fn qualified_path_as_qualified_trait() {
3376 check_infer(
3377 r#"
3378mod foo {
3379
3380 pub trait Foo {
3381 type Target;
3382 }
3383 pub trait Bar {
3384 type Output;
3385 fn boo() -> Self::Output {
3386 loop {}
3387 }
3388 }
3389}
3390
3391struct F;
3392impl foo::Foo for F {
3393 type Target = ();
3394}
3395impl foo::Bar for F {
3396 type Output = <F as foo::Foo>::Target;
3397}
3398
3399fn foo() {
3400 use foo::Bar;
3401 let x = <F as Bar>::boo();
3402}
3403
3404 "#,
3405 expect![[r#"
3406 132..163 '{ ... }': Bar::Output<Self>
3407 146..153 'loop {}': !
3408 151..153 '{}': ()
3409 306..358 '{ ...o(); }': ()
3410 334..335 'x': ()
3411 338..353 '<F as Bar>::boo': fn boo<F>() -> <F as Bar>::Output
3412 338..355 '<F as ...:boo()': ()
3413 "#]],
3414 );
3415}