Auto merge of #136776 - BoxyUwU:forbid_object_lifetime_casts, r=lcnr · rust-lang/rust@198328a (original) (raw)
`@@ -1113,15 +1113,23 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
`
1113
1113
`self.prove_predicate(
`
1114
1114
` ty::ClauseKind::WellFormed(src_ty.into()),
`
1115
1115
` location.to_locations(),
`
1116
``
`-
ConstraintCategory::Cast { is_implicit_coercion, unsize_to: None },
`
``
1116
`+
ConstraintCategory::Cast {
`
``
1117
`+
is_raw_ptr_dyn_type_cast: false,
`
``
1118
`+
is_implicit_coercion,
`
``
1119
`+
unsize_to: None,
`
``
1120
`+
},
`
1117
1121
`);
`
1118
1122
``
1119
1123
`let src_ty = self.normalize(src_ty, location);
`
1120
1124
`if let Err(terr) = self.sub_types(
`
1121
1125
` src_ty,
`
1122
1126
`*ty,
`
1123
1127
` location.to_locations(),
`
1124
``
`-
ConstraintCategory::Cast { is_implicit_coercion, unsize_to: None },
`
``
1128
`+
ConstraintCategory::Cast {
`
``
1129
`+
is_raw_ptr_dyn_type_cast: false,
`
``
1130
`+
is_implicit_coercion,
`
``
1131
`+
unsize_to: None,
`
``
1132
`+
},
`
1125
1133
`) {
`
1126
1134
`span_mirbug!(
`
1127
1135
`self,
`
`@@ -1142,7 +1150,11 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
`
1142
1150
`self.prove_predicate(
`
1143
1151
` ty::ClauseKind::WellFormed(src_ty.into()),
`
1144
1152
` location.to_locations(),
`
1145
``
`-
ConstraintCategory::Cast { is_implicit_coercion, unsize_to: None },
`
``
1153
`+
ConstraintCategory::Cast {
`
``
1154
`+
is_raw_ptr_dyn_type_cast: false,
`
``
1155
`+
is_implicit_coercion,
`
``
1156
`+
unsize_to: None,
`
``
1157
`+
},
`
1146
1158
`);
`
1147
1159
``
1148
1160
`// The type that we see in the fcx is like
`
`@@ -1155,7 +1167,11 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
`
1155
1167
` src_ty,
`
1156
1168
`*ty,
`
1157
1169
` location.to_locations(),
`
1158
``
`-
ConstraintCategory::Cast { is_implicit_coercion, unsize_to: None },
`
``
1170
`+
ConstraintCategory::Cast {
`
``
1171
`+
is_raw_ptr_dyn_type_cast: false,
`
``
1172
`+
is_implicit_coercion,
`
``
1173
`+
unsize_to: None,
`
``
1174
`+
},
`
1159
1175
`) {
`
1160
1176
`span_mirbug!(
`
1161
1177
`self,
`
`@@ -1184,7 +1200,11 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
`
1184
1200
` ty_fn_ptr_from,
`
1185
1201
`*ty,
`
1186
1202
` location.to_locations(),
`
1187
``
`-
ConstraintCategory::Cast { is_implicit_coercion, unsize_to: None },
`
``
1203
`+
ConstraintCategory::Cast {
`
``
1204
`+
is_raw_ptr_dyn_type_cast: false,
`
``
1205
`+
is_implicit_coercion,
`
``
1206
`+
unsize_to: None,
`
``
1207
`+
},
`
1188
1208
`) {
`
1189
1209
`span_mirbug!(
`
1190
1210
`self,
`
`@@ -1217,7 +1237,11 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
`
1217
1237
` ty_fn_ptr_from,
`
1218
1238
`*ty,
`
1219
1239
` location.to_locations(),
`
1220
``
`-
ConstraintCategory::Cast { is_implicit_coercion, unsize_to: None },
`
``
1240
`+
ConstraintCategory::Cast {
`
``
1241
`+
is_raw_ptr_dyn_type_cast: false,
`
``
1242
`+
is_implicit_coercion,
`
``
1243
`+
unsize_to: None,
`
``
1244
`+
},
`
1221
1245
`) {
`
1222
1246
`span_mirbug!(
`
1223
1247
`self,
`
`@@ -1246,6 +1270,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
`
1246
1270
` trait_ref,
`
1247
1271
` location.to_locations(),
`
1248
1272
`ConstraintCategory::Cast {
`
``
1273
`+
is_raw_ptr_dyn_type_cast: false,
`
1249
1274
` is_implicit_coercion,
`
1250
1275
`unsize_to: Some(unsize_to),
`
1251
1276
`},
`
`@@ -1271,7 +1296,11 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
`
1271
1296
`*ty_from,
`
1272
1297
`*ty_to,
`
1273
1298
` location.to_locations(),
`
1274
``
`-
ConstraintCategory::Cast { is_implicit_coercion, unsize_to: None },
`
``
1299
`+
ConstraintCategory::Cast {
`
``
1300
`+
is_raw_ptr_dyn_type_cast: false,
`
``
1301
`+
is_implicit_coercion,
`
``
1302
`+
unsize_to: None,
`
``
1303
`+
},
`
1275
1304
`) {
`
1276
1305
`span_mirbug!(
`
1277
1306
`self,
`
`@@ -1334,7 +1363,11 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
`
1334
1363
`*ty_elem,
`
1335
1364
`*ty_to,
`
1336
1365
` location.to_locations(),
`
1337
``
`-
ConstraintCategory::Cast { is_implicit_coercion, unsize_to: None },
`
``
1366
`+
ConstraintCategory::Cast {
`
``
1367
`+
is_raw_ptr_dyn_type_cast: false,
`
``
1368
`+
is_implicit_coercion,
`
``
1369
`+
unsize_to: None,
`
``
1370
`+
},
`
1338
1371
`) {
`
1339
1372
`span_mirbug!(
`
1340
1373
`self,
`
`@@ -1491,55 +1524,90 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
`
1491
1524
` trait_ref,
`
1492
1525
` location.to_locations(),
`
1493
1526
`ConstraintCategory::Cast {
`
``
1527
`+
is_raw_ptr_dyn_type_cast: false,
`
1494
1528
`is_implicit_coercion: true,
`
1495
1529
`unsize_to: None,
`
1496
1530
`},
`
1497
1531
`);
`
1498
``
`-
} else if let ty::Dynamic(src_tty, _src_lt) =
`
``
1532
`+
} else if let ty::Dynamic(src_tty, src_lt) =
`
1499
1533
`*self.struct_tail(src.ty, location).kind()
`
1500
1534
` && let ty::Dynamic(dst_tty, dst_lt) =
`
1501
1535
`*self.struct_tail(dst.ty, location).kind()
`
1502
``
`-
&& src_tty.principal().is_some()
`
1503
``
`-
&& dst_tty.principal().is_some()
`
1504
1536
`{
`
1505
``
`-
// This checks (lifetime part of) vtable validity for pointer casts,
`
1506
``
`-
// which is irrelevant when there are aren't principal traits on
`
1507
``
`-
// both sides (aka only auto traits).
`
1508
``
`-
//
`
1509
``
`` -
// Note that other checks (such as denying dyn Send -> `dyn
``
1510
``
`` -
// Debug) are in rustc_hir_typeck`.
``
1511
``
-
1512
``
`-
// Remove auto traits.
`
1513
``
`` -
// Auto trait checks are handled in rustc_hir_typeck as FCW.
``
1514
``
`-
let src_obj = Ty::new_dynamic(
`
1515
``
`-
tcx,
`
1516
``
`-
tcx.mk_poly_existential_predicates(
`
1517
``
`-
&src_tty.without_auto_traits().collect::<Vec<_>>(),
`
1518
``
`-
),
`
1519
``
`` -
// FIXME: Once we disallow casting *const dyn Trait + 'short
``
1520
``
`` -
// to *const dyn Trait + 'long, then this can just be src_lt.
``
1521
``
`-
dst_lt,
`
1522
``
`-
);
`
1523
``
`-
let dst_obj = Ty::new_dynamic(
`
1524
``
`-
tcx,
`
1525
``
`-
tcx.mk_poly_existential_predicates(
`
1526
``
`-
&dst_tty.without_auto_traits().collect::<Vec<_>>(),
`
``
1537
`+
match (src_tty.principal(), dst_tty.principal()) {
`
``
1538
`+
(Some(), Some()) => {
`
``
1539
`+
// This checks (lifetime part of) vtable validity for pointer casts,
`
``
1540
`+
// which is irrelevant when there are aren't principal traits on
`
``
1541
`+
// both sides (aka only auto traits).
`
``
1542
`+
//
`
``
1543
`` +
// Note that other checks (such as denying dyn Send -> `dyn
``
``
1544
`` +
// Debug) are in rustc_hir_typeck`.
``
``
1545
+
``
1546
`+
// Remove auto traits.
`
``
1547
`` +
// Auto trait checks are handled in rustc_hir_typeck.
``
``
1548
`+
let src_obj = Ty::new_dynamic(
`
``
1549
`+
tcx,
`
``
1550
`+
tcx.mk_poly_existential_predicates(
`
``
1551
`+
&src_tty.without_auto_traits().collect::<Vec<_>>(),
`
``
1552
`+
),
`
``
1553
`+
src_lt,
`
``
1554
`+
);
`
``
1555
`+
let dst_obj = Ty::new_dynamic(
`
``
1556
`+
tcx,
`
``
1557
`+
tcx.mk_poly_existential_predicates(
`
``
1558
`+
&dst_tty.without_auto_traits().collect::<Vec<_>>(),
`
``
1559
`+
),
`
``
1560
`+
dst_lt,
`
``
1561
`+
);
`
``
1562
+
``
1563
`+
debug!(?src_tty, ?dst_tty, ?src_obj, ?dst_obj);
`
``
1564
+
``
1565
`+
// Trait parameters are invariant, the only part that actually has
`
``
1566
`+
// subtyping here is the lifetime bound of the dyn-type.
`
``
1567
`+
//
`
``
1568
`` +
// For example in dyn Trait<'a> + 'b <: dyn Trait<'c> + 'd we would
``
``
1569
`` +
// require that 'a == 'c but only that 'b: 'd.
``
``
1570
`+
//
`
``
1571
`+
// We must not allow freely casting lifetime bounds of dyn-types as it
`
``
1572
`+
// may allow for inaccessible VTable methods being callable: #136702
`
``
1573
`+
self.sub_types(
`
``
1574
`+
src_obj,
`
``
1575
`+
dst_obj,
`
``
1576
`+
location.to_locations(),
`
``
1577
`+
ConstraintCategory::Cast {
`
``
1578
`+
is_raw_ptr_dyn_type_cast: true,
`
``
1579
`+
is_implicit_coercion: false,
`
``
1580
`+
unsize_to: None,
`
``
1581
`+
},
`
``
1582
`+
)
`
``
1583
`+
.unwrap();
`
``
1584
`+
}
`
``
1585
`+
(None, None) => {
`
``
1586
`+
// The principalless (no non-auto traits) case:
`
``
1587
`` +
// You can only cast dyn Send + 'long to dyn Send + 'short.
``
``
1588
`+
self.constraints.outlives_constraints.push(
`
``
1589
`+
OutlivesConstraint {
`
``
1590
`+
sup: src_lt.as_var(),
`
``
1591
`+
sub: dst_lt.as_var(),
`
``
1592
`+
locations: location.to_locations(),
`
``
1593
`+
span: location.to_locations().span(self.body),
`
``
1594
`+
category: ConstraintCategory::Cast {
`
``
1595
`+
is_raw_ptr_dyn_type_cast: true,
`
``
1596
`+
is_implicit_coercion: false,
`
``
1597
`+
unsize_to: None,
`
``
1598
`+
},
`
``
1599
`+
variance_info: ty::VarianceDiagInfo::default(),
`
``
1600
`+
from_closure: false,
`
``
1601
`+
},
`
``
1602
`+
);
`
``
1603
`+
}
`
``
1604
`+
(None, Some(_)) => bug!(
`
``
1605
`+
"introducing a principal should have errored in HIR typeck"
`
1527
1606
`),
`
1528
``
`-
dst_lt,
`
1529
``
`-
);
`
1530
``
-
1531
``
`-
debug!(?src_tty, ?dst_tty, ?src_obj, ?dst_obj);
`
1532
``
-
1533
``
`-
self.sub_types(
`
1534
``
`-
src_obj,
`
1535
``
`-
dst_obj,
`
1536
``
`-
location.to_locations(),
`
1537
``
`-
ConstraintCategory::Cast {
`
1538
``
`-
is_implicit_coercion: false,
`
1539
``
`-
unsize_to: None,
`
1540
``
`-
},
`
1541
``
`-
)
`
1542
``
`-
.unwrap();
`
``
1607
`+
(Some(_), None) => {
`
``
1608
`+
bug!("dropping the principal should have been an unsizing cast")
`
``
1609
`+
}
`
``
1610
`+
}
`
1543
1611
`}
`
1544
1612
`}
`
1545
1613
`CastKind::Transmute => {
`