@@ -1977,8 +1977,9 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
1977
1977
Rvalue :: Cast ( cast_kind, op, ty) => {
1978
1978
self . check_operand ( op, location) ;
1979
1979
1980
- match cast_kind {
1981
- CastKind :: PointerCoercion ( PointerCoercion :: ReifyFnPointer ) => {
1980
+ match * cast_kind {
1981
+ CastKind :: PointerCoercion ( PointerCoercion :: ReifyFnPointer , coercion_source) => {
1982
+ let is_implicit_coercion = coercion_source == CoercionSource :: Implicit ;
1982
1983
let src_sig = op. ty ( body, tcx) . fn_sig ( tcx) ;
1983
1984
1984
1985
// HACK: This shouldn't be necessary... We can remove this when we actually
@@ -2009,15 +2010,15 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
2009
2010
self . prove_predicate (
2010
2011
ty:: ClauseKind :: WellFormed ( src_ty. into ( ) ) ,
2011
2012
location. to_locations ( ) ,
2012
- ConstraintCategory :: Cast { is_coercion : true , unsize_to : None } ,
2013
+ ConstraintCategory :: Cast { is_implicit_coercion , unsize_to : None } ,
2013
2014
) ;
2014
2015
2015
2016
let src_ty = self . normalize ( src_ty, location) ;
2016
2017
if let Err ( terr) = self . sub_types (
2017
2018
src_ty,
2018
2019
* ty,
2019
2020
location. to_locations ( ) ,
2020
- ConstraintCategory :: Cast { is_coercion : true , unsize_to : None } ,
2021
+ ConstraintCategory :: Cast { is_implicit_coercion , unsize_to : None } ,
2021
2022
) {
2022
2023
span_mirbug ! (
2023
2024
self ,
@@ -2038,7 +2039,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
2038
2039
self . prove_predicate (
2039
2040
ty:: ClauseKind :: WellFormed ( src_ty. into ( ) ) ,
2040
2041
location. to_locations ( ) ,
2041
- ConstraintCategory :: Cast { is_coercion : true , unsize_to : None } ,
2042
+ ConstraintCategory :: Cast { is_implicit_coercion , unsize_to : None } ,
2042
2043
) ;
2043
2044
2044
2045
// The type that we see in the fcx is like
@@ -2051,7 +2052,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
2051
2052
src_ty,
2052
2053
* ty,
2053
2054
location. to_locations ( ) ,
2054
- ConstraintCategory :: Cast { is_coercion : true , unsize_to : None } ,
2055
+ ConstraintCategory :: Cast { is_implicit_coercion , unsize_to : None } ,
2055
2056
) {
2056
2057
span_mirbug ! (
2057
2058
self ,
@@ -2064,19 +2065,23 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
2064
2065
}
2065
2066
}
2066
2067
2067
- CastKind :: PointerCoercion ( PointerCoercion :: ClosureFnPointer ( safety) ) => {
2068
+ CastKind :: PointerCoercion (
2069
+ PointerCoercion :: ClosureFnPointer ( safety) ,
2070
+ coercion_source,
2071
+ ) => {
2068
2072
let sig = match op. ty ( body, tcx) . kind ( ) {
2069
2073
ty:: Closure ( _, args) => args. as_closure ( ) . sig ( ) ,
2070
2074
_ => bug ! ( ) ,
2071
2075
} ;
2072
2076
let ty_fn_ptr_from =
2073
- Ty :: new_fn_ptr ( tcx, tcx. signature_unclosure ( sig, * safety) ) ;
2077
+ Ty :: new_fn_ptr ( tcx, tcx. signature_unclosure ( sig, safety) ) ;
2074
2078
2079
+ let is_implicit_coercion = coercion_source == CoercionSource :: Implicit ;
2075
2080
if let Err ( terr) = self . sub_types (
2076
2081
ty_fn_ptr_from,
2077
2082
* ty,
2078
2083
location. to_locations ( ) ,
2079
- ConstraintCategory :: Cast { is_coercion : true , unsize_to : None } ,
2084
+ ConstraintCategory :: Cast { is_implicit_coercion , unsize_to : None } ,
2080
2085
) {
2081
2086
span_mirbug ! (
2082
2087
self ,
@@ -2089,7 +2094,10 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
2089
2094
}
2090
2095
}
2091
2096
2092
- CastKind :: PointerCoercion ( PointerCoercion :: UnsafeFnPointer ) => {
2097
+ CastKind :: PointerCoercion (
2098
+ PointerCoercion :: UnsafeFnPointer ,
2099
+ coercion_source,
2100
+ ) => {
2093
2101
let fn_sig = op. ty ( body, tcx) . fn_sig ( tcx) ;
2094
2102
2095
2103
// The type that we see in the fcx is like
@@ -2101,11 +2109,12 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
2101
2109
2102
2110
let ty_fn_ptr_from = tcx. safe_to_unsafe_fn_ty ( fn_sig) ;
2103
2111
2112
+ let is_implicit_coercion = coercion_source == CoercionSource :: Implicit ;
2104
2113
if let Err ( terr) = self . sub_types (
2105
2114
ty_fn_ptr_from,
2106
2115
* ty,
2107
2116
location. to_locations ( ) ,
2108
- ConstraintCategory :: Cast { is_coercion : true , unsize_to : None } ,
2117
+ ConstraintCategory :: Cast { is_implicit_coercion , unsize_to : None } ,
2109
2118
) {
2110
2119
span_mirbug ! (
2111
2120
self ,
@@ -2118,31 +2127,29 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
2118
2127
}
2119
2128
}
2120
2129
2121
- CastKind :: PointerCoercion ( PointerCoercion :: Unsize ) => {
2130
+ CastKind :: PointerCoercion ( PointerCoercion :: Unsize , coercion_source ) => {
2122
2131
let & ty = ty;
2123
2132
let trait_ref = ty:: TraitRef :: new (
2124
2133
tcx,
2125
2134
tcx. require_lang_item ( LangItem :: CoerceUnsized , Some ( span) ) ,
2126
2135
[ op. ty ( body, tcx) , ty] ,
2127
2136
) ;
2128
2137
2138
+ let is_implicit_coercion = coercion_source == CoercionSource :: Implicit ;
2139
+ let unsize_to = tcx. fold_regions ( ty, |r, _| {
2140
+ if let ty:: ReVar ( _) = r. kind ( ) { tcx. lifetimes . re_erased } else { r }
2141
+ } ) ;
2129
2142
self . prove_trait_ref (
2130
2143
trait_ref,
2131
2144
location. to_locations ( ) ,
2132
2145
ConstraintCategory :: Cast {
2133
- is_coercion : true ,
2134
- unsize_to : Some ( tcx. fold_regions ( ty, |r, _| {
2135
- if let ty:: ReVar ( _) = r. kind ( ) {
2136
- tcx. lifetimes . re_erased
2137
- } else {
2138
- r
2139
- }
2140
- } ) ) ,
2146
+ is_implicit_coercion,
2147
+ unsize_to : Some ( unsize_to) ,
2141
2148
} ,
2142
2149
) ;
2143
2150
}
2144
2151
2145
- CastKind :: PointerCoercion ( PointerCoercion :: DynStar ) => {
2152
+ CastKind :: PointerCoercion ( PointerCoercion :: DynStar , coercion_source ) => {
2146
2153
// get the constraints from the target type (`dyn* Clone`)
2147
2154
//
2148
2155
// apply them to prove that the source type `Foo` implements `Clone` etc
@@ -2153,12 +2160,13 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
2153
2160
2154
2161
let self_ty = op. ty ( body, tcx) ;
2155
2162
2163
+ let is_implicit_coercion = coercion_source == CoercionSource :: Implicit ;
2156
2164
self . prove_predicates (
2157
2165
existential_predicates
2158
2166
. iter ( )
2159
2167
. map ( |predicate| predicate. with_self_ty ( tcx, self_ty) ) ,
2160
2168
location. to_locations ( ) ,
2161
- ConstraintCategory :: Cast { is_coercion : true , unsize_to : None } ,
2169
+ ConstraintCategory :: Cast { is_implicit_coercion , unsize_to : None } ,
2162
2170
) ;
2163
2171
2164
2172
let outlives_predicate = tcx. mk_predicate ( Binder :: dummy (
@@ -2169,11 +2177,14 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
2169
2177
self . prove_predicate (
2170
2178
outlives_predicate,
2171
2179
location. to_locations ( ) ,
2172
- ConstraintCategory :: Cast { is_coercion : true , unsize_to : None } ,
2180
+ ConstraintCategory :: Cast { is_implicit_coercion , unsize_to : None } ,
2173
2181
) ;
2174
2182
}
2175
2183
2176
- CastKind :: PointerCoercion ( PointerCoercion :: MutToConstPointer ) => {
2184
+ CastKind :: PointerCoercion (
2185
+ PointerCoercion :: MutToConstPointer ,
2186
+ coercion_source,
2187
+ ) => {
2177
2188
let ty:: RawPtr ( ty_from, hir:: Mutability :: Mut ) = op. ty ( body, tcx) . kind ( )
2178
2189
else {
2179
2190
span_mirbug ! ( self , rvalue, "unexpected base type for cast {:?}" , ty, ) ;
@@ -2183,11 +2194,12 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
2183
2194
span_mirbug ! ( self , rvalue, "unexpected target type for cast {:?}" , ty, ) ;
2184
2195
return ;
2185
2196
} ;
2197
+ let is_implicit_coercion = coercion_source == CoercionSource :: Implicit ;
2186
2198
if let Err ( terr) = self . sub_types (
2187
2199
* ty_from,
2188
2200
* ty_to,
2189
2201
location. to_locations ( ) ,
2190
- ConstraintCategory :: Cast { is_coercion : true , unsize_to : None } ,
2202
+ ConstraintCategory :: Cast { is_implicit_coercion , unsize_to : None } ,
2191
2203
) {
2192
2204
span_mirbug ! (
2193
2205
self ,
@@ -2200,7 +2212,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
2200
2212
}
2201
2213
}
2202
2214
2203
- CastKind :: PointerCoercion ( PointerCoercion :: ArrayToPointer ) => {
2215
+ CastKind :: PointerCoercion ( PointerCoercion :: ArrayToPointer , coercion_source ) => {
2204
2216
let ty_from = op. ty ( body, tcx) ;
2205
2217
2206
2218
let opt_ty_elem_mut = match ty_from. kind ( ) {
@@ -2245,11 +2257,12 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
2245
2257
return ;
2246
2258
}
2247
2259
2260
+ let is_implicit_coercion = coercion_source == CoercionSource :: Implicit ;
2248
2261
if let Err ( terr) = self . sub_types (
2249
2262
* ty_elem,
2250
2263
* ty_to,
2251
2264
location. to_locations ( ) ,
2252
- ConstraintCategory :: Cast { is_coercion : true , unsize_to : None } ,
2265
+ ConstraintCategory :: Cast { is_implicit_coercion , unsize_to : None } ,
2253
2266
) {
2254
2267
span_mirbug ! (
2255
2268
self ,
@@ -2431,7 +2444,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
2431
2444
dst_obj,
2432
2445
location. to_locations ( ) ,
2433
2446
ConstraintCategory :: Cast {
2434
- is_coercion : false ,
2447
+ is_implicit_coercion : false ,
2435
2448
unsize_to : None ,
2436
2449
} ,
2437
2450
)
0 commit comments