@@ -8,8 +8,8 @@ use std::collections::HashSet;
8
8
#[ derive( Copy , Clone ) ]
9
9
enum Subtyping {
10
10
No ,
11
- Yes ,
12
- Once ,
11
+ Relaxed ,
12
+ Strict ,
13
13
}
14
14
15
15
#[ derive( Copy , Clone ) ]
@@ -75,7 +75,7 @@ impl Rules {
75
75
}
76
76
77
77
fn without_subtyping ( mut self ) -> Rules {
78
- if let Subtyping :: Yes = self . subtyping {
78
+ if let Subtyping :: Relaxed = self . subtyping {
79
79
self . subtyping = Subtyping :: No
80
80
}
81
81
@@ -97,13 +97,13 @@ impl Rules {
97
97
self
98
98
}
99
99
100
- fn with_one_time_subtyping ( mut self ) -> Rules {
101
- self . subtyping = Subtyping :: Once ;
100
+ fn with_strict_subtyping ( mut self ) -> Rules {
101
+ self . subtyping = Subtyping :: Strict ;
102
102
self
103
103
}
104
104
105
- fn with_subtyping ( mut self ) -> Rules {
106
- self . subtyping = Subtyping :: Yes ;
105
+ fn with_relaxed_subtyping ( mut self ) -> Rules {
106
+ self . subtyping = Subtyping :: Relaxed ;
107
107
self
108
108
}
109
109
@@ -214,8 +214,7 @@ impl<'a> TypeChecker<'a> {
214
214
let mut env =
215
215
Environment :: new ( left. type_arguments ( db) , right. type_arguments ( db) ) ;
216
216
217
- let rules =
218
- Rules :: new ( ) . with_kind ( Kind :: Cast ) . with_one_time_subtyping ( ) ;
217
+ let rules = Rules :: new ( ) . with_kind ( Kind :: Cast ) . with_strict_subtyping ( ) ;
219
218
220
219
TypeChecker :: new ( db) . check_type_ref ( left, right, & mut env, rules)
221
220
}
@@ -321,7 +320,7 @@ impl<'a> TypeChecker<'a> {
321
320
lhs. return_type ,
322
321
rhs. return_type ,
323
322
env,
324
- rules. with_subtyping ( ) ,
323
+ rules. with_strict_subtyping ( ) ,
325
324
)
326
325
}
327
326
@@ -348,7 +347,7 @@ impl<'a> TypeChecker<'a> {
348
347
env. left . assign ( bound, val) ;
349
348
350
349
let mut env = env. with_left_as_right ( ) ;
351
- let rules = Rules :: new ( ) . with_subtyping ( ) ;
350
+ let rules = Rules :: new ( ) . with_relaxed_subtyping ( ) ;
352
351
353
352
if bound. is_mutable ( self . db ) && !val. allow_mutating ( self . db ) {
354
353
return false ;
@@ -703,7 +702,7 @@ impl<'a> TypeChecker<'a> {
703
702
) -> bool {
704
703
let trait_rules = rules;
705
704
706
- if let Subtyping :: Once = rules. subtyping {
705
+ if let Subtyping :: Strict = rules. subtyping {
707
706
rules. subtyping = Subtyping :: No ;
708
707
}
709
708
@@ -772,7 +771,7 @@ impl<'a> TypeChecker<'a> {
772
771
lhs,
773
772
req,
774
773
env,
775
- rules. with_one_time_subtyping ( ) ,
774
+ rules. with_relaxed_subtyping ( ) ,
776
775
)
777
776
} )
778
777
}
@@ -963,7 +962,7 @@ impl<'a> TypeChecker<'a> {
963
962
964
963
// At this point no value is assigned yet, so it's safe to allow
965
964
// sub-typing through traits.
966
- let rules = rules. with_one_time_subtyping ( ) ;
965
+ let rules = rules. with_relaxed_subtyping ( ) ;
967
966
let res = match left_id {
968
967
TypeEnum :: TypeInstance ( lhs) => reqs
969
968
. into_iter ( )
@@ -1000,7 +999,7 @@ impl<'a> TypeChecker<'a> {
1000
999
TypeArguments :: for_trait ( self . db , right) ,
1001
1000
) ;
1002
1001
1003
- let rules = Rules :: new ( ) . with_one_time_subtyping ( ) ;
1002
+ let rules = Rules :: new ( ) . with_relaxed_subtyping ( ) ;
1004
1003
1005
1004
self . check_type_with_trait ( left, right, & mut env, rules)
1006
1005
}
@@ -1037,8 +1036,12 @@ impl<'a> TypeChecker<'a> {
1037
1036
// result in a `Dog` being added to the Array.
1038
1037
match rules. subtyping {
1039
1038
Subtyping :: No => return false ,
1040
- Subtyping :: Yes => { }
1041
- Subtyping :: Once => {
1039
+ Subtyping :: Relaxed => rules. subtyping = Subtyping :: No ,
1040
+ Subtyping :: Strict => {
1041
+ if !left. instance_of . allow_cast_to_trait ( self . db ) {
1042
+ return false ;
1043
+ }
1044
+
1042
1045
rules. subtyping = Subtyping :: No ;
1043
1046
}
1044
1047
}
0 commit comments