diff options
Diffstat (limited to 'crates/hir_ty')
-rw-r--r-- | crates/hir_ty/src/diagnostics.rs | 10 | ||||
-rw-r--r-- | crates/hir_ty/src/display.rs | 25 | ||||
-rw-r--r-- | crates/hir_ty/src/infer/expr.rs | 30 | ||||
-rw-r--r-- | crates/hir_ty/src/lib.rs | 10 | ||||
-rw-r--r-- | crates/hir_ty/src/lower.rs | 74 | ||||
-rw-r--r-- | crates/hir_ty/src/tests/regression.rs | 37 | ||||
-rw-r--r-- | crates/hir_ty/src/tests/simple.rs | 56 | ||||
-rw-r--r-- | crates/hir_ty/src/utils.rs | 24 |
8 files changed, 220 insertions, 46 deletions
diff --git a/crates/hir_ty/src/diagnostics.rs b/crates/hir_ty/src/diagnostics.rs index e59487e54..1c72f766e 100644 --- a/crates/hir_ty/src/diagnostics.rs +++ b/crates/hir_ty/src/diagnostics.rs | |||
@@ -624,4 +624,14 @@ fn foo() { break; } | |||
624 | "#, | 624 | "#, |
625 | ); | 625 | ); |
626 | } | 626 | } |
627 | |||
628 | #[test] | ||
629 | fn missing_semicolon() { | ||
630 | check_diagnostics( | ||
631 | r#" | ||
632 | fn test() -> i32 { 123; } | ||
633 | //^^^ Remove this semicolon | ||
634 | "#, | ||
635 | ); | ||
636 | } | ||
627 | } | 637 | } |
diff --git a/crates/hir_ty/src/display.rs b/crates/hir_ty/src/display.rs index e77481906..0e827a29e 100644 --- a/crates/hir_ty/src/display.rs +++ b/crates/hir_ty/src/display.rs | |||
@@ -4,7 +4,7 @@ use std::fmt; | |||
4 | 4 | ||
5 | use crate::{ | 5 | use crate::{ |
6 | db::HirDatabase, utils::generics, ApplicationTy, CallableDefId, FnSig, GenericPredicate, | 6 | db::HirDatabase, utils::generics, ApplicationTy, CallableDefId, FnSig, GenericPredicate, |
7 | Obligation, OpaqueTyId, ProjectionTy, Substs, TraitRef, Ty, TypeCtor, | 7 | Lifetime, Obligation, OpaqueTyId, ProjectionTy, Substs, TraitRef, Ty, TypeCtor, |
8 | }; | 8 | }; |
9 | use hir_def::{ | 9 | use hir_def::{ |
10 | find_path, generics::TypeParamProvenance, item_scope::ItemInNs, AdtId, AssocContainerId, | 10 | find_path, generics::TypeParamProvenance, item_scope::ItemInNs, AdtId, AssocContainerId, |
@@ -178,6 +178,7 @@ impl DisplayTarget { | |||
178 | #[derive(Debug)] | 178 | #[derive(Debug)] |
179 | pub enum DisplaySourceCodeError { | 179 | pub enum DisplaySourceCodeError { |
180 | PathNotFound, | 180 | PathNotFound, |
181 | UnknownType, | ||
181 | } | 182 | } |
182 | 183 | ||
183 | pub enum HirDisplayError { | 184 | pub enum HirDisplayError { |
@@ -558,7 +559,14 @@ impl HirDisplay for Ty { | |||
558 | } | 559 | } |
559 | }; | 560 | }; |
560 | } | 561 | } |
561 | Ty::Unknown => write!(f, "{{unknown}}")?, | 562 | Ty::Unknown => { |
563 | if f.display_target.is_source_code() { | ||
564 | return Err(HirDisplayError::DisplaySourceCodeError( | ||
565 | DisplaySourceCodeError::UnknownType, | ||
566 | )); | ||
567 | } | ||
568 | write!(f, "{{unknown}}")?; | ||
569 | } | ||
562 | Ty::Infer(..) => write!(f, "_")?, | 570 | Ty::Infer(..) => write!(f, "_")?, |
563 | } | 571 | } |
564 | Ok(()) | 572 | Ok(()) |
@@ -710,6 +718,19 @@ impl HirDisplay for GenericPredicate { | |||
710 | } | 718 | } |
711 | } | 719 | } |
712 | 720 | ||
721 | impl HirDisplay for Lifetime { | ||
722 | fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { | ||
723 | match self { | ||
724 | Lifetime::Parameter(id) => { | ||
725 | let generics = generics(f.db.upcast(), id.parent); | ||
726 | let param_data = &generics.params.lifetimes[id.local_id]; | ||
727 | write!(f, "{}", ¶m_data.name) | ||
728 | } | ||
729 | Lifetime::Static => write!(f, "'static"), | ||
730 | } | ||
731 | } | ||
732 | } | ||
733 | |||
713 | impl HirDisplay for Obligation { | 734 | impl HirDisplay for Obligation { |
714 | fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { | 735 | fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { |
715 | match self { | 736 | match self { |
diff --git a/crates/hir_ty/src/infer/expr.rs b/crates/hir_ty/src/infer/expr.rs index 605951b10..2cdce2cef 100644 --- a/crates/hir_ty/src/infer/expr.rs +++ b/crates/hir_ty/src/infer/expr.rs | |||
@@ -137,10 +137,24 @@ impl<'a> InferenceContext<'a> { | |||
137 | 137 | ||
138 | self.coerce_merge_branch(&then_ty, &else_ty) | 138 | self.coerce_merge_branch(&then_ty, &else_ty) |
139 | } | 139 | } |
140 | Expr::Block { statements, tail, .. } => { | 140 | Expr::Block { statements, tail, label } => match label { |
141 | // FIXME: Breakable block inference | 141 | Some(_) => { |
142 | self.infer_block(statements, *tail, expected) | 142 | let break_ty = self.table.new_type_var(); |
143 | } | 143 | self.breakables.push(BreakableContext { |
144 | may_break: false, | ||
145 | break_ty: break_ty.clone(), | ||
146 | label: label.clone(), | ||
147 | }); | ||
148 | let ty = self.infer_block(statements, *tail, &Expectation::has_type(break_ty)); | ||
149 | let ctxt = self.breakables.pop().expect("breakable stack broken"); | ||
150 | if ctxt.may_break { | ||
151 | ctxt.break_ty | ||
152 | } else { | ||
153 | ty | ||
154 | } | ||
155 | } | ||
156 | None => self.infer_block(statements, *tail, expected), | ||
157 | }, | ||
144 | Expr::Unsafe { body } => self.infer_expr(*body, expected), | 158 | Expr::Unsafe { body } => self.infer_expr(*body, expected), |
145 | Expr::TryBlock { body } => { | 159 | Expr::TryBlock { body } => { |
146 | let _inner = self.infer_expr(*body, expected); | 160 | let _inner = self.infer_expr(*body, expected); |
@@ -842,12 +856,18 @@ impl<'a> InferenceContext<'a> { | |||
842 | // handle provided type arguments | 856 | // handle provided type arguments |
843 | if let Some(generic_args) = generic_args { | 857 | if let Some(generic_args) = generic_args { |
844 | // if args are provided, it should be all of them, but we can't rely on that | 858 | // if args are provided, it should be all of them, but we can't rely on that |
845 | for arg in generic_args.args.iter().take(type_params) { | 859 | for arg in generic_args |
860 | .args | ||
861 | .iter() | ||
862 | .filter(|arg| matches!(arg, GenericArg::Type(_))) | ||
863 | .take(type_params) | ||
864 | { | ||
846 | match arg { | 865 | match arg { |
847 | GenericArg::Type(type_ref) => { | 866 | GenericArg::Type(type_ref) => { |
848 | let ty = self.make_ty(type_ref); | 867 | let ty = self.make_ty(type_ref); |
849 | substs.push(ty); | 868 | substs.push(ty); |
850 | } | 869 | } |
870 | GenericArg::Lifetime(_) => {} | ||
851 | } | 871 | } |
852 | } | 872 | } |
853 | }; | 873 | }; |
diff --git a/crates/hir_ty/src/lib.rs b/crates/hir_ty/src/lib.rs index 5a8c97198..357bd92f9 100644 --- a/crates/hir_ty/src/lib.rs +++ b/crates/hir_ty/src/lib.rs | |||
@@ -29,8 +29,8 @@ use base_db::{salsa, CrateId}; | |||
29 | use hir_def::{ | 29 | use hir_def::{ |
30 | expr::ExprId, | 30 | expr::ExprId, |
31 | type_ref::{Mutability, Rawness}, | 31 | type_ref::{Mutability, Rawness}, |
32 | AdtId, AssocContainerId, DefWithBodyId, GenericDefId, HasModule, Lookup, TraitId, TypeAliasId, | 32 | AdtId, AssocContainerId, DefWithBodyId, GenericDefId, HasModule, LifetimeParamId, Lookup, |
33 | TypeParamId, | 33 | TraitId, TypeAliasId, TypeParamId, |
34 | }; | 34 | }; |
35 | use itertools::Itertools; | 35 | use itertools::Itertools; |
36 | 36 | ||
@@ -52,6 +52,12 @@ pub use traits::{InEnvironment, Obligation, ProjectionPredicate, TraitEnvironmen | |||
52 | 52 | ||
53 | pub use chalk_ir::{BoundVar, DebruijnIndex}; | 53 | pub use chalk_ir::{BoundVar, DebruijnIndex}; |
54 | 54 | ||
55 | #[derive(Clone, PartialEq, Eq, Debug, Hash)] | ||
56 | pub enum Lifetime { | ||
57 | Parameter(LifetimeParamId), | ||
58 | Static, | ||
59 | } | ||
60 | |||
55 | /// A type constructor or type name: this might be something like the primitive | 61 | /// A type constructor or type name: this might be something like the primitive |
56 | /// type `bool`, a struct like `Vec`, or things like function pointers or | 62 | /// type `bool`, a struct like `Vec`, or things like function pointers or |
57 | /// tuples. | 63 | /// tuples. |
diff --git a/crates/hir_ty/src/lower.rs b/crates/hir_ty/src/lower.rs index 708e2af0f..8392cb770 100644 --- a/crates/hir_ty/src/lower.rs +++ b/crates/hir_ty/src/lower.rs | |||
@@ -12,7 +12,7 @@ use base_db::CrateId; | |||
12 | use hir_def::{ | 12 | use hir_def::{ |
13 | adt::StructKind, | 13 | adt::StructKind, |
14 | builtin_type::BuiltinType, | 14 | builtin_type::BuiltinType, |
15 | generics::{TypeParamProvenance, WherePredicate, WherePredicateTarget}, | 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::{TypeBound, TypeRef}, |
@@ -171,7 +171,7 @@ impl Ty { | |||
171 | let inner_ty = Ty::from_hir(ctx, inner); | 171 | let inner_ty = Ty::from_hir(ctx, inner); |
172 | Ty::apply_one(TypeCtor::Slice, inner_ty) | 172 | Ty::apply_one(TypeCtor::Slice, inner_ty) |
173 | } | 173 | } |
174 | TypeRef::Reference(inner, mutability) => { | 174 | TypeRef::Reference(inner, _, mutability) => { |
175 | let inner_ty = Ty::from_hir(ctx, inner); | 175 | let inner_ty = Ty::from_hir(ctx, inner); |
176 | Ty::apply_one(TypeCtor::Ref(*mutability), inner_ty) | 176 | Ty::apply_one(TypeCtor::Ref(*mutability), inner_ty) |
177 | } | 177 | } |
@@ -555,7 +555,7 @@ fn substs_from_path_segment( | |||
555 | 555 | ||
556 | substs.extend(iter::repeat(Ty::Unknown).take(parent_params)); | 556 | substs.extend(iter::repeat(Ty::Unknown).take(parent_params)); |
557 | 557 | ||
558 | let mut had_explicit_args = false; | 558 | let mut had_explicit_type_args = false; |
559 | 559 | ||
560 | if let Some(generic_args) = &segment.args_and_bindings { | 560 | if let Some(generic_args) = &segment.args_and_bindings { |
561 | if !generic_args.has_self_type { | 561 | if !generic_args.has_self_type { |
@@ -565,13 +565,20 @@ fn substs_from_path_segment( | |||
565 | if generic_args.has_self_type { self_params + type_params } else { type_params }; | 565 | if generic_args.has_self_type { self_params + type_params } else { type_params }; |
566 | let skip = if generic_args.has_self_type && self_params == 0 { 1 } else { 0 }; | 566 | let skip = if generic_args.has_self_type && self_params == 0 { 1 } else { 0 }; |
567 | // if args are provided, it should be all of them, but we can't rely on that | 567 | // if args are provided, it should be all of them, but we can't rely on that |
568 | for arg in generic_args.args.iter().skip(skip).take(expected_num) { | 568 | for arg in generic_args |
569 | .args | ||
570 | .iter() | ||
571 | .filter(|arg| matches!(arg, GenericArg::Type(_))) | ||
572 | .skip(skip) | ||
573 | .take(expected_num) | ||
574 | { | ||
569 | match arg { | 575 | match arg { |
570 | GenericArg::Type(type_ref) => { | 576 | GenericArg::Type(type_ref) => { |
571 | had_explicit_args = true; | 577 | had_explicit_type_args = true; |
572 | let ty = Ty::from_hir(ctx, type_ref); | 578 | let ty = Ty::from_hir(ctx, type_ref); |
573 | substs.push(ty); | 579 | substs.push(ty); |
574 | } | 580 | } |
581 | GenericArg::Lifetime(_) => {} | ||
575 | } | 582 | } |
576 | } | 583 | } |
577 | } | 584 | } |
@@ -579,7 +586,7 @@ fn substs_from_path_segment( | |||
579 | // handle defaults. In expression or pattern path segments without | 586 | // handle defaults. In expression or pattern path segments without |
580 | // explicitly specified type arguments, missing type arguments are inferred | 587 | // explicitly specified type arguments, missing type arguments are inferred |
581 | // (i.e. defaults aren't used). | 588 | // (i.e. defaults aren't used). |
582 | if !infer_args || had_explicit_args { | 589 | if !infer_args || had_explicit_type_args { |
583 | if let Some(def_generic) = def_generic { | 590 | if let Some(def_generic) = def_generic { |
584 | let defaults = ctx.db.generic_defaults(def_generic); | 591 | let defaults = ctx.db.generic_defaults(def_generic); |
585 | assert_eq!(total_len, defaults.len()); | 592 | assert_eq!(total_len, defaults.len()); |
@@ -657,7 +664,7 @@ impl TraitRef { | |||
657 | ) -> Option<TraitRef> { | 664 | ) -> Option<TraitRef> { |
658 | match bound { | 665 | match bound { |
659 | TypeBound::Path(path) => TraitRef::from_path(ctx, path, Some(self_ty)), | 666 | TypeBound::Path(path) => TraitRef::from_path(ctx, path, Some(self_ty)), |
660 | TypeBound::Error => None, | 667 | TypeBound::Lifetime(_) | TypeBound::Error => None, |
661 | } | 668 | } |
662 | } | 669 | } |
663 | } | 670 | } |
@@ -667,22 +674,30 @@ impl GenericPredicate { | |||
667 | ctx: &'a TyLoweringContext<'a>, | 674 | ctx: &'a TyLoweringContext<'a>, |
668 | where_predicate: &'a WherePredicate, | 675 | where_predicate: &'a WherePredicate, |
669 | ) -> impl Iterator<Item = GenericPredicate> + 'a { | 676 | ) -> impl Iterator<Item = GenericPredicate> + 'a { |
670 | let self_ty = match &where_predicate.target { | 677 | match where_predicate { |
671 | WherePredicateTarget::TypeRef(type_ref) => Ty::from_hir(ctx, type_ref), | 678 | WherePredicate::TypeBound { target, bound } => { |
672 | WherePredicateTarget::TypeParam(param_id) => { | 679 | let self_ty = match target { |
673 | let generic_def = ctx.resolver.generic_def().expect("generics in scope"); | 680 | WherePredicateTypeTarget::TypeRef(type_ref) => Ty::from_hir(ctx, type_ref), |
674 | let generics = generics(ctx.db.upcast(), generic_def); | 681 | WherePredicateTypeTarget::TypeParam(param_id) => { |
675 | let param_id = hir_def::TypeParamId { parent: generic_def, local_id: *param_id }; | 682 | let generic_def = ctx.resolver.generic_def().expect("generics in scope"); |
676 | match ctx.type_param_mode { | 683 | let generics = generics(ctx.db.upcast(), generic_def); |
677 | TypeParamLoweringMode::Placeholder => Ty::Placeholder(param_id), | 684 | let param_id = |
678 | TypeParamLoweringMode::Variable => { | 685 | hir_def::TypeParamId { parent: generic_def, local_id: *param_id }; |
679 | let idx = generics.param_idx(param_id).expect("matching generics"); | 686 | match ctx.type_param_mode { |
680 | Ty::Bound(BoundVar::new(DebruijnIndex::INNERMOST, idx)) | 687 | TypeParamLoweringMode::Placeholder => Ty::Placeholder(param_id), |
688 | TypeParamLoweringMode::Variable => { | ||
689 | let idx = generics.param_idx(param_id).expect("matching generics"); | ||
690 | Ty::Bound(BoundVar::new(DebruijnIndex::INNERMOST, idx)) | ||
691 | } | ||
692 | } | ||
681 | } | 693 | } |
682 | } | 694 | }; |
695 | GenericPredicate::from_type_bound(ctx, bound, self_ty) | ||
696 | .collect::<Vec<_>>() | ||
697 | .into_iter() | ||
683 | } | 698 | } |
684 | }; | 699 | WherePredicate::Lifetime { .. } => vec![].into_iter(), |
685 | GenericPredicate::from_type_bound(ctx, &where_predicate.bound, self_ty) | 700 | } |
686 | } | 701 | } |
687 | 702 | ||
688 | pub(crate) fn from_type_bound<'a>( | 703 | pub(crate) fn from_type_bound<'a>( |
@@ -707,7 +722,7 @@ fn assoc_type_bindings_from_type_bound<'a>( | |||
707 | ) -> impl Iterator<Item = GenericPredicate> + 'a { | 722 | ) -> impl Iterator<Item = GenericPredicate> + 'a { |
708 | let last_segment = match bound { | 723 | let last_segment = match bound { |
709 | TypeBound::Path(path) => path.segments().last(), | 724 | TypeBound::Path(path) => path.segments().last(), |
710 | TypeBound::Error => None, | 725 | TypeBound::Error | TypeBound::Lifetime(_) => None, |
711 | }; | 726 | }; |
712 | last_segment | 727 | last_segment |
713 | .into_iter() | 728 | .into_iter() |
@@ -872,11 +887,16 @@ pub(crate) fn generic_predicates_for_param_query( | |||
872 | resolver | 887 | resolver |
873 | .where_predicates_in_scope() | 888 | .where_predicates_in_scope() |
874 | // we have to filter out all other predicates *first*, before attempting to lower them | 889 | // we have to filter out all other predicates *first*, before attempting to lower them |
875 | .filter(|pred| match &pred.target { | 890 | .filter(|pred| match pred { |
876 | WherePredicateTarget::TypeRef(type_ref) => { | 891 | WherePredicate::TypeBound { |
877 | Ty::from_hir_only_param(&ctx, type_ref) == Some(param_id) | 892 | target: WherePredicateTypeTarget::TypeRef(type_ref), |
878 | } | 893 | .. |
879 | WherePredicateTarget::TypeParam(local_id) => *local_id == param_id.local_id, | 894 | } => Ty::from_hir_only_param(&ctx, type_ref) == Some(param_id), |
895 | WherePredicate::TypeBound { | ||
896 | target: WherePredicateTypeTarget::TypeParam(local_id), | ||
897 | .. | ||
898 | } => *local_id == param_id.local_id, | ||
899 | WherePredicate::Lifetime { .. } => false, | ||
880 | }) | 900 | }) |
881 | .flat_map(|pred| { | 901 | .flat_map(|pred| { |
882 | GenericPredicate::from_where_predicate(&ctx, pred) | 902 | GenericPredicate::from_where_predicate(&ctx, pred) |
diff --git a/crates/hir_ty/src/tests/regression.rs b/crates/hir_ty/src/tests/regression.rs index 8cf4e7012..da8170417 100644 --- a/crates/hir_ty/src/tests/regression.rs +++ b/crates/hir_ty/src/tests/regression.rs | |||
@@ -883,3 +883,40 @@ fn issue_6628() { | |||
883 | "#]], | 883 | "#]], |
884 | ); | 884 | ); |
885 | } | 885 | } |
886 | |||
887 | #[test] | ||
888 | fn issue_6852() { | ||
889 | check_infer( | ||
890 | r#" | ||
891 | #[lang = "deref"] | ||
892 | pub trait Deref { | ||
893 | type Target; | ||
894 | } | ||
895 | |||
896 | struct BufWriter {} | ||
897 | |||
898 | struct Mutex<T> {} | ||
899 | struct MutexGuard<'a, T> {} | ||
900 | impl<T> Mutex<T> { | ||
901 | fn lock(&self) -> MutexGuard<'_, T> {} | ||
902 | } | ||
903 | impl<'a, T: 'a> Deref for MutexGuard<'a, T> { | ||
904 | type Target = T; | ||
905 | } | ||
906 | fn flush(&self) { | ||
907 | let w: &Mutex<BufWriter>; | ||
908 | *(w.lock()); | ||
909 | } | ||
910 | "#, | ||
911 | expect![[r#" | ||
912 | 156..160 'self': &Mutex<T> | ||
913 | 183..185 '{}': () | ||
914 | 267..271 'self': &{unknown} | ||
915 | 273..323 '{ ...()); }': () | ||
916 | 283..284 'w': &Mutex<BufWriter> | ||
917 | 309..320 '*(w.lock())': BufWriter | ||
918 | 311..312 'w': &Mutex<BufWriter> | ||
919 | 311..319 'w.lock()': MutexGuard<BufWriter> | ||
920 | "#]], | ||
921 | ); | ||
922 | } | ||
diff --git a/crates/hir_ty/src/tests/simple.rs b/crates/hir_ty/src/tests/simple.rs index 4f72582b6..a569223b4 100644 --- a/crates/hir_ty/src/tests/simple.rs +++ b/crates/hir_ty/src/tests/simple.rs | |||
@@ -2075,6 +2075,62 @@ fn infer_labelled_break_with_val() { | |||
2075 | } | 2075 | } |
2076 | 2076 | ||
2077 | #[test] | 2077 | #[test] |
2078 | fn infer_labelled_block_break_with_val() { | ||
2079 | check_infer( | ||
2080 | r#" | ||
2081 | fn default<T>() -> T { loop {} } | ||
2082 | fn foo() { | ||
2083 | let _x = 'outer: { | ||
2084 | let inner = 'inner: { | ||
2085 | let i = default(); | ||
2086 | if (break 'outer i) { | ||
2087 | break 'inner 5i8; | ||
2088 | } else if true { | ||
2089 | break 'inner 6; | ||
2090 | } | ||
2091 | break 'inner 'innermost: { 0 }; | ||
2092 | 42 | ||
2093 | }; | ||
2094 | break 'outer inner < 8; | ||
2095 | }; | ||
2096 | } | ||
2097 | "#, | ||
2098 | expect![[r#" | ||
2099 | 21..32 '{ loop {} }': T | ||
2100 | 23..30 'loop {}': ! | ||
2101 | 28..30 '{}': () | ||
2102 | 42..381 '{ ... }; }': () | ||
2103 | 52..54 '_x': bool | ||
2104 | 65..378 '{ ... }': bool | ||
2105 | 79..84 'inner': i8 | ||
2106 | 95..339 '{ ... }': i8 | ||
2107 | 113..114 'i': bool | ||
2108 | 117..124 'default': fn default<bool>() -> bool | ||
2109 | 117..126 'default()': bool | ||
2110 | 140..270 'if (br... }': () | ||
2111 | 144..158 'break 'outer i': ! | ||
2112 | 157..158 'i': bool | ||
2113 | 160..209 '{ ... }': () | ||
2114 | 178..194 'break ...er 5i8': ! | ||
2115 | 191..194 '5i8': i8 | ||
2116 | 215..270 'if tru... }': () | ||
2117 | 218..222 'true': bool | ||
2118 | 223..270 '{ ... }': () | ||
2119 | 241..255 'break 'inner 6': ! | ||
2120 | 254..255 '6': i8 | ||
2121 | 283..313 'break ... { 0 }': ! | ||
2122 | 308..313 '{ 0 }': i8 | ||
2123 | 310..311 '0': i8 | ||
2124 | 327..329 '42': i8 | ||
2125 | 349..371 'break ...er < 8': ! | ||
2126 | 362..367 'inner': i8 | ||
2127 | 362..371 'inner < 8': bool | ||
2128 | 370..371 '8': i8 | ||
2129 | "#]], | ||
2130 | ); | ||
2131 | } | ||
2132 | |||
2133 | #[test] | ||
2078 | fn generic_default() { | 2134 | fn generic_default() { |
2079 | check_infer( | 2135 | check_infer( |
2080 | r#" | 2136 | r#" |
diff --git a/crates/hir_ty/src/utils.rs b/crates/hir_ty/src/utils.rs index e3e244268..af880c065 100644 --- a/crates/hir_ty/src/utils.rs +++ b/crates/hir_ty/src/utils.rs | |||
@@ -2,11 +2,10 @@ | |||
2 | //! query, but can't be computed directly from `*Data` (ie, which need a `db`). | 2 | //! query, but can't be computed directly from `*Data` (ie, which need a `db`). |
3 | use std::sync::Arc; | 3 | use std::sync::Arc; |
4 | 4 | ||
5 | use hir_def::generics::WherePredicateTarget; | ||
6 | use hir_def::{ | 5 | use hir_def::{ |
7 | adt::VariantData, | 6 | adt::VariantData, |
8 | db::DefDatabase, | 7 | db::DefDatabase, |
9 | generics::{GenericParams, TypeParamData, TypeParamProvenance}, | 8 | generics::{GenericParams, TypeParamData, TypeParamProvenance, WherePredicateTypeTarget}, |
10 | path::Path, | 9 | path::Path, |
11 | resolver::{HasResolver, TypeNs}, | 10 | resolver::{HasResolver, TypeNs}, |
12 | type_ref::TypeRef, | 11 | type_ref::TypeRef, |
@@ -27,14 +26,19 @@ fn direct_super_traits(db: &dyn DefDatabase, trait_: TraitId) -> Vec<TraitId> { | |||
27 | generic_params | 26 | generic_params |
28 | .where_predicates | 27 | .where_predicates |
29 | .iter() | 28 | .iter() |
30 | .filter_map(|pred| match &pred.target { | 29 | .filter_map(|pred| match pred { |
31 | WherePredicateTarget::TypeRef(TypeRef::Path(p)) if p == &Path::from(name![Self]) => { | 30 | hir_def::generics::WherePredicate::TypeBound { target, bound } => match target { |
32 | pred.bound.as_path() | 31 | WherePredicateTypeTarget::TypeRef(TypeRef::Path(p)) |
33 | } | 32 | if p == &Path::from(name![Self]) => |
34 | WherePredicateTarget::TypeParam(local_id) if Some(*local_id) == trait_self => { | 33 | { |
35 | pred.bound.as_path() | 34 | bound.as_path() |
36 | } | 35 | } |
37 | _ => None, | 36 | WherePredicateTypeTarget::TypeParam(local_id) if Some(*local_id) == trait_self => { |
37 | bound.as_path() | ||
38 | } | ||
39 | _ => None, | ||
40 | }, | ||
41 | hir_def::generics::WherePredicate::Lifetime { .. } => None, | ||
38 | }) | 42 | }) |
39 | .filter_map(|path| match resolver.resolve_path_in_type_ns_fully(db, path.mod_path()) { | 43 | .filter_map(|path| match resolver.resolve_path_in_type_ns_fully(db, path.mod_path()) { |
40 | Some(TypeNs::TraitId(t)) => Some(t), | 44 | Some(TypeNs::TraitId(t)) => Some(t), |