@@ -2198,45 +2198,46 @@ impl ClashingExternDeclarations {
2198
2198
debug ! ( "structurally_same_type_impl(cx, a = {:?}, b = {:?})" , a, b) ;
2199
2199
match seen_types. get ( a, b) {
2200
2200
// If we've already computed the result, just return the memoized result.
2201
- SeenSetResult :: Computed ( result) => result,
2201
+ SeenSetResult :: Computed ( result) => return result,
2202
2202
// We are already in the process of computing structural sameness for this type,
2203
2203
// meaning we've found a cycle. The types are structurally same, then.
2204
- SeenSetResult :: Computing => true ,
2205
- // We haven't seen this combination of types at all -- compute their sameness.
2206
- SeenSetResult :: Unseen => {
2207
- seen_types. mark_computing ( a, b) ;
2208
- let tcx = cx. tcx ;
2209
- let result = if a == b || rustc_middle:: ty:: TyS :: same_type ( a, b) {
2210
- // All nominally-same types are structurally same, too.
2211
- true
2212
- } else {
2213
- // Do a full, depth-first comparison between the two.
2214
- use rustc_middle:: ty:: TyKind :: * ;
2215
- let a_kind = & a. kind ;
2216
- let b_kind = & b. kind ;
2217
-
2218
- let compare_layouts = |a, b| -> bool {
2219
- let a_layout = & cx. layout_of ( a) . unwrap ( ) . layout . abi ;
2220
- let b_layout = & cx. layout_of ( b) . unwrap ( ) . layout . abi ;
2221
- debug ! ( "{:?} == {:?} = {}" , a_layout, b_layout, a_layout == b_layout) ;
2222
- a_layout == b_layout
2223
- } ;
2204
+ SeenSetResult :: Computing => return true ,
2205
+ // We haven't seen this combination of types at all -- continue on to computing
2206
+ // their sameness.
2207
+ SeenSetResult :: Unseen => ( ) ,
2208
+ }
2209
+ seen_types. mark_computing ( a, b) ;
2210
+ let tcx = cx. tcx ;
2211
+ let result = if a == b || rustc_middle:: ty:: TyS :: same_type ( a, b) {
2212
+ // All nominally-same types are structurally same, too.
2213
+ true
2214
+ } else {
2215
+ // Do a full, depth-first comparison between the two.
2216
+ use rustc_middle:: ty:: TyKind :: * ;
2217
+ let a_kind = & a. kind ;
2218
+ let b_kind = & b. kind ;
2219
+
2220
+ let compare_layouts = |a, b| -> bool {
2221
+ let a_layout = & cx. layout_of ( a) . unwrap ( ) . layout . abi ;
2222
+ let b_layout = & cx. layout_of ( b) . unwrap ( ) . layout . abi ;
2223
+ debug ! ( "{:?} == {:?} = {}" , a_layout, b_layout, a_layout == b_layout) ;
2224
+ a_layout == b_layout
2225
+ } ;
2224
2226
2225
- #[ allow( rustc:: usage_of_ty_tykind) ]
2226
- let is_primitive_or_pointer = |kind : & ty:: TyKind < ' _ > | {
2227
- kind. is_primitive ( ) || matches ! ( kind, RawPtr ( ..) )
2228
- } ;
2227
+ #[ allow( rustc:: usage_of_ty_tykind) ]
2228
+ let is_primitive_or_pointer =
2229
+ |kind : & ty:: TyKind < ' _ > | kind. is_primitive ( ) || matches ! ( kind, RawPtr ( ..) ) ;
2229
2230
2230
- match ( a_kind, b_kind) {
2231
- ( Adt ( a_def, a_substs) , Adt ( b_def, b_substs) ) => {
2232
- let a = a. subst ( cx. tcx , a_substs) ;
2233
- let b = b. subst ( cx. tcx , b_substs) ;
2234
- debug ! ( "Comparing {:?} and {:?}" , a, b) ;
2231
+ match ( a_kind, b_kind) {
2232
+ ( Adt ( a_def, a_substs) , Adt ( b_def, b_substs) ) => {
2233
+ let a = a. subst ( cx. tcx , a_substs) ;
2234
+ let b = b. subst ( cx. tcx , b_substs) ;
2235
+ debug ! ( "Comparing {:?} and {:?}" , a, b) ;
2235
2236
2236
- // Grab a flattened representation of all fields.
2237
- let a_fields = a_def. variants . iter ( ) . flat_map ( |v| v. fields . iter ( ) ) ;
2238
- let b_fields = b_def. variants . iter ( ) . flat_map ( |v| v. fields . iter ( ) ) ;
2239
- compare_layouts ( a, b)
2237
+ // Grab a flattened representation of all fields.
2238
+ let a_fields = a_def. variants . iter ( ) . flat_map ( |v| v. fields . iter ( ) ) ;
2239
+ let b_fields = b_def. variants . iter ( ) . flat_map ( |v| v. fields . iter ( ) ) ;
2240
+ compare_layouts ( a, b)
2240
2241
&& a_fields. eq_by (
2241
2242
b_fields,
2242
2243
|& ty:: FieldDef { did : a_did, .. } ,
@@ -2250,99 +2251,91 @@ impl ClashingExternDeclarations {
2250
2251
)
2251
2252
} ,
2252
2253
)
2253
- }
2254
- ( Array ( a_ty, a_const) , Array ( b_ty, b_const) ) => {
2255
- // For arrays, we also check the constness of the type.
2256
- a_const. val == b_const. val
2257
- && structurally_same_type_impl (
2258
- seen_types, cx, a_ty, b_ty, ckind,
2259
- )
2260
- }
2261
- ( Slice ( a_ty) , Slice ( b_ty) ) => {
2262
- structurally_same_type_impl ( seen_types, cx, a_ty, b_ty, ckind)
2263
- }
2264
- ( RawPtr ( a_tymut) , RawPtr ( b_tymut) ) => {
2265
- a_tymut. mutbl == b_tymut. mutbl
2266
- && structurally_same_type_impl (
2267
- seen_types,
2268
- cx,
2269
- & a_tymut. ty ,
2270
- & b_tymut. ty ,
2271
- ckind,
2272
- )
2273
- }
2274
- ( Ref ( _a_region, a_ty, a_mut) , Ref ( _b_region, b_ty, b_mut) ) => {
2275
- // For structural sameness, we don't need the region to be same.
2276
- a_mut == b_mut
2277
- && structurally_same_type_impl (
2278
- seen_types, cx, a_ty, b_ty, ckind,
2279
- )
2280
- }
2281
- ( FnDef ( ..) , FnDef ( ..) ) => {
2282
- let a_poly_sig = a. fn_sig ( tcx) ;
2283
- let b_poly_sig = b. fn_sig ( tcx) ;
2284
-
2285
- // As we don't compare regions, skip_binder is fine.
2286
- let a_sig = a_poly_sig. skip_binder ( ) ;
2287
- let b_sig = b_poly_sig. skip_binder ( ) ;
2288
-
2289
- ( a_sig. abi , a_sig. unsafety , a_sig. c_variadic )
2290
- == ( b_sig. abi , b_sig. unsafety , b_sig. c_variadic )
2291
- && a_sig. inputs ( ) . iter ( ) . eq_by ( b_sig. inputs ( ) . iter ( ) , |a, b| {
2292
- structurally_same_type_impl ( seen_types, cx, a, b, ckind)
2293
- } )
2294
- && structurally_same_type_impl (
2295
- seen_types,
2296
- cx,
2297
- a_sig. output ( ) ,
2298
- b_sig. output ( ) ,
2299
- ckind,
2300
- )
2301
- }
2302
- ( Tuple ( a_substs) , Tuple ( b_substs) ) => {
2303
- a_substs. types ( ) . eq_by ( b_substs. types ( ) , |a_ty, b_ty| {
2304
- structurally_same_type_impl ( seen_types, cx, a_ty, b_ty, ckind)
2305
- } )
2306
- }
2307
- // For these, it's not quite as easy to define structural-sameness quite so easily.
2308
- // For the purposes of this lint, take the conservative approach and mark them as
2309
- // not structurally same.
2310
- ( Dynamic ( ..) , Dynamic ( ..) )
2311
- | ( Error ( ..) , Error ( ..) )
2312
- | ( Closure ( ..) , Closure ( ..) )
2313
- | ( Generator ( ..) , Generator ( ..) )
2314
- | ( GeneratorWitness ( ..) , GeneratorWitness ( ..) )
2315
- | ( Projection ( ..) , Projection ( ..) )
2316
- | ( Opaque ( ..) , Opaque ( ..) ) => false ,
2317
-
2318
- // These definitely should have been caught above.
2319
- ( Bool , Bool ) | ( Char , Char ) | ( Never , Never ) | ( Str , Str ) => {
2320
- unreachable ! ( )
2321
- }
2322
-
2323
- // An Adt and a primitive type. This can be FFI-safe is the ADT is an enum with a
2324
- // non-null field.
2325
- ( Adt ( ..) , other_kind) | ( other_kind, Adt ( ..) )
2326
- if is_primitive_or_pointer ( other_kind) =>
2327
- {
2328
- let ( primitive, adt) =
2329
- if is_primitive_or_pointer ( & a. kind ) { ( a, b) } else { ( b, a) } ;
2330
- if let Some ( ty) = crate :: types:: repr_nullable_ptr ( cx, adt, ckind) {
2331
- ty == primitive
2332
- } else {
2333
- compare_layouts ( a, b)
2334
- }
2335
- }
2336
- // Otherwise, just compare the layouts. This may fail to lint for some
2337
- // incompatible types, but at the very least, will stop reads into
2338
- // uninitialised memory.
2339
- _ => compare_layouts ( a, b) ,
2254
+ }
2255
+ ( Array ( a_ty, a_const) , Array ( b_ty, b_const) ) => {
2256
+ // For arrays, we also check the constness of the type.
2257
+ a_const. val == b_const. val
2258
+ && structurally_same_type_impl ( seen_types, cx, a_ty, b_ty, ckind)
2259
+ }
2260
+ ( Slice ( a_ty) , Slice ( b_ty) ) => {
2261
+ structurally_same_type_impl ( seen_types, cx, a_ty, b_ty, ckind)
2262
+ }
2263
+ ( RawPtr ( a_tymut) , RawPtr ( b_tymut) ) => {
2264
+ a_tymut. mutbl == b_tymut. mutbl
2265
+ && structurally_same_type_impl (
2266
+ seen_types,
2267
+ cx,
2268
+ & a_tymut. ty ,
2269
+ & b_tymut. ty ,
2270
+ ckind,
2271
+ )
2272
+ }
2273
+ ( Ref ( _a_region, a_ty, a_mut) , Ref ( _b_region, b_ty, b_mut) ) => {
2274
+ // For structural sameness, we don't need the region to be same.
2275
+ a_mut == b_mut
2276
+ && structurally_same_type_impl ( seen_types, cx, a_ty, b_ty, ckind)
2277
+ }
2278
+ ( FnDef ( ..) , FnDef ( ..) ) => {
2279
+ let a_poly_sig = a. fn_sig ( tcx) ;
2280
+ let b_poly_sig = b. fn_sig ( tcx) ;
2281
+
2282
+ // As we don't compare regions, skip_binder is fine.
2283
+ let a_sig = a_poly_sig. skip_binder ( ) ;
2284
+ let b_sig = b_poly_sig. skip_binder ( ) ;
2285
+
2286
+ ( a_sig. abi , a_sig. unsafety , a_sig. c_variadic )
2287
+ == ( b_sig. abi , b_sig. unsafety , b_sig. c_variadic )
2288
+ && a_sig. inputs ( ) . iter ( ) . eq_by ( b_sig. inputs ( ) . iter ( ) , |a, b| {
2289
+ structurally_same_type_impl ( seen_types, cx, a, b, ckind)
2290
+ } )
2291
+ && structurally_same_type_impl (
2292
+ seen_types,
2293
+ cx,
2294
+ a_sig. output ( ) ,
2295
+ b_sig. output ( ) ,
2296
+ ckind,
2297
+ )
2298
+ }
2299
+ ( Tuple ( a_substs) , Tuple ( b_substs) ) => {
2300
+ a_substs. types ( ) . eq_by ( b_substs. types ( ) , |a_ty, b_ty| {
2301
+ structurally_same_type_impl ( seen_types, cx, a_ty, b_ty, ckind)
2302
+ } )
2303
+ }
2304
+ // For these, it's not quite as easy to define structural-sameness quite so easily.
2305
+ // For the purposes of this lint, take the conservative approach and mark them as
2306
+ // not structurally same.
2307
+ ( Dynamic ( ..) , Dynamic ( ..) )
2308
+ | ( Error ( ..) , Error ( ..) )
2309
+ | ( Closure ( ..) , Closure ( ..) )
2310
+ | ( Generator ( ..) , Generator ( ..) )
2311
+ | ( GeneratorWitness ( ..) , GeneratorWitness ( ..) )
2312
+ | ( Projection ( ..) , Projection ( ..) )
2313
+ | ( Opaque ( ..) , Opaque ( ..) ) => false ,
2314
+
2315
+ // These definitely should have been caught above.
2316
+ ( Bool , Bool ) | ( Char , Char ) | ( Never , Never ) | ( Str , Str ) => unreachable ! ( ) ,
2317
+
2318
+ // An Adt and a primitive type. This can be FFI-safe is the ADT is an enum with a
2319
+ // non-null field.
2320
+ ( Adt ( ..) , other_kind) | ( other_kind, Adt ( ..) )
2321
+ if is_primitive_or_pointer ( other_kind) =>
2322
+ {
2323
+ let ( primitive, adt) =
2324
+ if is_primitive_or_pointer ( & a. kind ) { ( a, b) } else { ( b, a) } ;
2325
+ if let Some ( ty) = crate :: types:: repr_nullable_ptr ( cx, adt, ckind) {
2326
+ ty == primitive
2327
+ } else {
2328
+ compare_layouts ( a, b)
2340
2329
}
2341
- } ;
2342
- seen_types. mark_computed ( a, b, result) ;
2343
- result
2330
+ }
2331
+ // Otherwise, just compare the layouts. This may fail to lint for some
2332
+ // incompatible types, but at the very least, will stop reads into
2333
+ // uninitialised memory.
2334
+ _ => compare_layouts ( a, b) ,
2344
2335
}
2345
- }
2336
+ } ;
2337
+ seen_types. mark_computed ( a, b, result) ;
2338
+ result
2346
2339
}
2347
2340
let mut seen_types = SeenSet :: new ( ) ;
2348
2341
structurally_same_type_impl ( & mut seen_types, cx, a, b, ckind)
0 commit comments