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 => {

`