@@ -27,6 +27,7 @@ use rustc::hir::def_id::DefId;
27
27
use rustc:: infer:: canonical:: QueryRegionConstraint ;
28
28
use rustc:: infer:: outlives:: env:: RegionBoundPairs ;
29
29
use rustc:: infer:: { InferCtxt , InferOk , LateBoundRegionConversionTime , NLLRegionVariableOrigin } ;
30
+ use rustc:: infer:: type_variable:: TypeVariableOrigin ;
30
31
use rustc:: mir:: interpret:: EvalErrorKind :: BoundsCheck ;
31
32
use rustc:: mir:: tcx:: PlaceTy ;
32
33
use rustc:: mir:: visit:: { PlaceContext , Visitor , MutatingUseContext , NonMutatingUseContext } ;
@@ -2074,15 +2075,163 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
2074
2075
) ;
2075
2076
}
2076
2077
2077
- CastKind :: Misc => { }
2078
+ CastKind :: MutToConstPointer => {
2079
+ let ty_from = match op. ty ( mir, tcx) . sty {
2080
+ ty:: RawPtr ( ty:: TypeAndMut {
2081
+ ty : ty_from,
2082
+ mutbl : hir:: MutMutable ,
2083
+ } ) => ty_from,
2084
+ _ => {
2085
+ span_mirbug ! (
2086
+ self ,
2087
+ rvalue,
2088
+ "unexpected base type for cast {:?}" ,
2089
+ ty,
2090
+ ) ;
2091
+ return ;
2092
+ }
2093
+ } ;
2094
+ let ty_to = match ty. sty {
2095
+ ty:: RawPtr ( ty:: TypeAndMut {
2096
+ ty : ty_to,
2097
+ mutbl : hir:: MutImmutable ,
2098
+ } ) => ty_to,
2099
+ _ => {
2100
+ span_mirbug ! (
2101
+ self ,
2102
+ rvalue,
2103
+ "unexpected target type for cast {:?}" ,
2104
+ ty,
2105
+ ) ;
2106
+ return ;
2107
+ }
2108
+ } ;
2109
+ if let Err ( terr) = self . sub_types (
2110
+ ty_from,
2111
+ ty_to,
2112
+ location. to_locations ( ) ,
2113
+ ConstraintCategory :: Cast ,
2114
+ ) {
2115
+ span_mirbug ! (
2116
+ self ,
2117
+ rvalue,
2118
+ "relating {:?} with {:?} yields {:?}" ,
2119
+ ty_from,
2120
+ ty_to,
2121
+ terr
2122
+ )
2123
+ }
2124
+ }
2125
+
2126
+ CastKind :: Misc => {
2127
+ if let ty:: Ref ( _, mut ty_from, _) = op. ty ( mir, tcx) . sty {
2128
+ let ( mut ty_to, mutability) = if let ty:: RawPtr ( ty:: TypeAndMut {
2129
+ ty : ty_to,
2130
+ mutbl,
2131
+ } ) = ty. sty {
2132
+ ( ty_to, mutbl)
2133
+ } else {
2134
+ span_mirbug ! (
2135
+ self ,
2136
+ rvalue,
2137
+ "invalid cast types {:?} -> {:?}" ,
2138
+ op. ty( mir, tcx) ,
2139
+ ty,
2140
+ ) ;
2141
+ return ;
2142
+ } ;
2143
+
2144
+ // Handle the direct cast from `&[T; N]` to `*const T` by unwrapping
2145
+ // any array we find.
2146
+ while let ty:: Array ( ty_elem_from, _) = ty_from. sty {
2147
+ ty_from = ty_elem_from;
2148
+ if let ty:: Array ( ty_elem_to, _) = ty_to. sty {
2149
+ ty_to = ty_elem_to;
2150
+ } else {
2151
+ break ;
2152
+ }
2153
+ }
2154
+
2155
+ if let hir:: MutMutable = mutability {
2156
+ if let Err ( terr) = self . eq_types (
2157
+ ty_from,
2158
+ ty_to,
2159
+ location. to_locations ( ) ,
2160
+ ConstraintCategory :: Cast ,
2161
+ ) {
2162
+ span_mirbug ! (
2163
+ self ,
2164
+ rvalue,
2165
+ "equating {:?} with {:?} yields {:?}" ,
2166
+ ty_from,
2167
+ ty_to,
2168
+ terr
2169
+ )
2170
+ }
2171
+ } else {
2172
+ if let Err ( terr) = self . sub_types (
2173
+ ty_from,
2174
+ ty_to,
2175
+ location. to_locations ( ) ,
2176
+ ConstraintCategory :: Cast ,
2177
+ ) {
2178
+ span_mirbug ! (
2179
+ self ,
2180
+ rvalue,
2181
+ "relating {:?} with {:?} yields {:?}" ,
2182
+ ty_from,
2183
+ ty_to,
2184
+ terr
2185
+ )
2186
+ }
2187
+ }
2188
+ }
2189
+ }
2078
2190
}
2079
2191
}
2080
2192
2081
2193
Rvalue :: Ref ( region, _borrow_kind, borrowed_place) => {
2082
2194
self . add_reborrow_constraint ( mir, location, region, borrowed_place) ;
2083
2195
}
2084
2196
2085
- // FIXME: These other cases have to be implemented in future PRs
2197
+ Rvalue :: BinaryOp ( BinOp :: Eq , left, right)
2198
+ | Rvalue :: BinaryOp ( BinOp :: Ne , left, right)
2199
+ | Rvalue :: BinaryOp ( BinOp :: Lt , left, right)
2200
+ | Rvalue :: BinaryOp ( BinOp :: Le , left, right)
2201
+ | Rvalue :: BinaryOp ( BinOp :: Gt , left, right)
2202
+ | Rvalue :: BinaryOp ( BinOp :: Ge , left, right) => {
2203
+ let ty_left = left. ty ( mir, tcx) ;
2204
+ if let ty:: RawPtr ( _) | ty:: FnPtr ( _) = ty_left. sty {
2205
+ let ty_right = right. ty ( mir, tcx) ;
2206
+ let common_ty = self . infcx . next_ty_var (
2207
+ TypeVariableOrigin :: MiscVariable ( mir. source_info ( location) . span ) ,
2208
+ ) ;
2209
+ self . sub_types (
2210
+ common_ty,
2211
+ ty_left,
2212
+ location. to_locations ( ) ,
2213
+ ConstraintCategory :: Boring
2214
+ ) . unwrap_or_else ( |err| {
2215
+ bug ! ( "Could not equate type variable with {:?}: {:?}" , ty_left, err)
2216
+ } ) ;
2217
+ if let Err ( terr) = self . sub_types (
2218
+ common_ty,
2219
+ ty_right,
2220
+ location. to_locations ( ) ,
2221
+ ConstraintCategory :: Boring
2222
+ ) {
2223
+ span_mirbug ! (
2224
+ self ,
2225
+ rvalue,
2226
+ "unexpected comparison types {:?} and {:?} yields {:?}" ,
2227
+ ty_left,
2228
+ ty_right,
2229
+ terr
2230
+ )
2231
+ }
2232
+ }
2233
+ }
2234
+
2086
2235
Rvalue :: Use ( ..)
2087
2236
| Rvalue :: Len ( ..)
2088
2237
| Rvalue :: BinaryOp ( ..)
0 commit comments