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