Skip to content

Commit 59696de

Browse files
author
Lukas Markeffsky
committed
be even more precise about "cast" vs "coercion"
1 parent 85f4395 commit 59696de

File tree

89 files changed

+288
-230
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

89 files changed

+288
-230
lines changed

compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs

+5-3
Original file line numberDiff line numberDiff line change
@@ -333,8 +333,10 @@ impl<'tcx> BorrowExplanation<'tcx> {
333333
}
334334
}
335335

336-
if let ConstraintCategory::Cast { is_coercion: true, unsize_to: Some(unsize_ty) } =
337-
category
336+
if let ConstraintCategory::Cast {
337+
is_implicit_coercion: true,
338+
unsize_to: Some(unsize_ty),
339+
} = category
338340
{
339341
self.add_object_lifetime_default_note(tcx, err, unsize_ty);
340342
}
@@ -742,7 +744,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, 'tcx> {
742744
// If we see an unsized cast, then if it is our data we should check
743745
// whether it is being cast to a trait object.
744746
Rvalue::Cast(
745-
CastKind::PointerCoercion(PointerCoercion::Unsize),
747+
CastKind::PointerCoercion(PointerCoercion::Unsize, _),
746748
operand,
747749
ty,
748750
) => {

compiler/rustc_borrowck/src/diagnostics/region_errors.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,8 @@ impl<'tcx> ConstraintDescription for ConstraintCategory<'tcx> {
4747
ConstraintCategory::Yield => "yielding this value ",
4848
ConstraintCategory::UseAsConst => "using this value as a constant ",
4949
ConstraintCategory::UseAsStatic => "using this value as a static ",
50-
ConstraintCategory::Cast { is_coercion: false, .. } => "cast ",
51-
ConstraintCategory::Cast { is_coercion: true, .. } => "coercion ",
50+
ConstraintCategory::Cast { is_implicit_coercion: false, .. } => "cast ",
51+
ConstraintCategory::Cast { is_implicit_coercion: true, .. } => "coercion ",
5252
ConstraintCategory::CallArgument(_) => "argument ",
5353
ConstraintCategory::TypeAnnotation => "type annotation ",
5454
ConstraintCategory::ClosureBounds => "closure body ",

compiler/rustc_borrowck/src/type_check/mod.rs

+41-28
Original file line numberDiff line numberDiff line change
@@ -1977,8 +1977,9 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
19771977
Rvalue::Cast(cast_kind, op, ty) => {
19781978
self.check_operand(op, location);
19791979

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;
19821983
let src_sig = op.ty(body, tcx).fn_sig(tcx);
19831984

19841985
// HACK: This shouldn't be necessary... We can remove this when we actually
@@ -2009,15 +2010,15 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
20092010
self.prove_predicate(
20102011
ty::ClauseKind::WellFormed(src_ty.into()),
20112012
location.to_locations(),
2012-
ConstraintCategory::Cast { is_coercion: true, unsize_to: None },
2013+
ConstraintCategory::Cast { is_implicit_coercion, unsize_to: None },
20132014
);
20142015

20152016
let src_ty = self.normalize(src_ty, location);
20162017
if let Err(terr) = self.sub_types(
20172018
src_ty,
20182019
*ty,
20192020
location.to_locations(),
2020-
ConstraintCategory::Cast { is_coercion: true, unsize_to: None },
2021+
ConstraintCategory::Cast { is_implicit_coercion, unsize_to: None },
20212022
) {
20222023
span_mirbug!(
20232024
self,
@@ -2038,7 +2039,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
20382039
self.prove_predicate(
20392040
ty::ClauseKind::WellFormed(src_ty.into()),
20402041
location.to_locations(),
2041-
ConstraintCategory::Cast { is_coercion: true, unsize_to: None },
2042+
ConstraintCategory::Cast { is_implicit_coercion, unsize_to: None },
20422043
);
20432044

20442045
// The type that we see in the fcx is like
@@ -2051,7 +2052,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
20512052
src_ty,
20522053
*ty,
20532054
location.to_locations(),
2054-
ConstraintCategory::Cast { is_coercion: true, unsize_to: None },
2055+
ConstraintCategory::Cast { is_implicit_coercion, unsize_to: None },
20552056
) {
20562057
span_mirbug!(
20572058
self,
@@ -2064,19 +2065,23 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
20642065
}
20652066
}
20662067

2067-
CastKind::PointerCoercion(PointerCoercion::ClosureFnPointer(safety)) => {
2068+
CastKind::PointerCoercion(
2069+
PointerCoercion::ClosureFnPointer(safety),
2070+
coercion_source,
2071+
) => {
20682072
let sig = match op.ty(body, tcx).kind() {
20692073
ty::Closure(_, args) => args.as_closure().sig(),
20702074
_ => bug!(),
20712075
};
20722076
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));
20742078

2079+
let is_implicit_coercion = coercion_source == CoercionSource::Implicit;
20752080
if let Err(terr) = self.sub_types(
20762081
ty_fn_ptr_from,
20772082
*ty,
20782083
location.to_locations(),
2079-
ConstraintCategory::Cast { is_coercion: true, unsize_to: None },
2084+
ConstraintCategory::Cast { is_implicit_coercion, unsize_to: None },
20802085
) {
20812086
span_mirbug!(
20822087
self,
@@ -2089,7 +2094,10 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
20892094
}
20902095
}
20912096

2092-
CastKind::PointerCoercion(PointerCoercion::UnsafeFnPointer) => {
2097+
CastKind::PointerCoercion(
2098+
PointerCoercion::UnsafeFnPointer,
2099+
coercion_source,
2100+
) => {
20932101
let fn_sig = op.ty(body, tcx).fn_sig(tcx);
20942102

20952103
// The type that we see in the fcx is like
@@ -2101,11 +2109,12 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
21012109

21022110
let ty_fn_ptr_from = tcx.safe_to_unsafe_fn_ty(fn_sig);
21032111

2112+
let is_implicit_coercion = coercion_source == CoercionSource::Implicit;
21042113
if let Err(terr) = self.sub_types(
21052114
ty_fn_ptr_from,
21062115
*ty,
21072116
location.to_locations(),
2108-
ConstraintCategory::Cast { is_coercion: true, unsize_to: None },
2117+
ConstraintCategory::Cast { is_implicit_coercion, unsize_to: None },
21092118
) {
21102119
span_mirbug!(
21112120
self,
@@ -2118,31 +2127,29 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
21182127
}
21192128
}
21202129

2121-
CastKind::PointerCoercion(PointerCoercion::Unsize) => {
2130+
CastKind::PointerCoercion(PointerCoercion::Unsize, coercion_source) => {
21222131
let &ty = ty;
21232132
let trait_ref = ty::TraitRef::new(
21242133
tcx,
21252134
tcx.require_lang_item(LangItem::CoerceUnsized, Some(span)),
21262135
[op.ty(body, tcx), ty],
21272136
);
21282137

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+
});
21292142
self.prove_trait_ref(
21302143
trait_ref,
21312144
location.to_locations(),
21322145
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),
21412148
},
21422149
);
21432150
}
21442151

2145-
CastKind::PointerCoercion(PointerCoercion::DynStar) => {
2152+
CastKind::PointerCoercion(PointerCoercion::DynStar, coercion_source) => {
21462153
// get the constraints from the target type (`dyn* Clone`)
21472154
//
21482155
// apply them to prove that the source type `Foo` implements `Clone` etc
@@ -2153,12 +2160,13 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
21532160

21542161
let self_ty = op.ty(body, tcx);
21552162

2163+
let is_implicit_coercion = coercion_source == CoercionSource::Implicit;
21562164
self.prove_predicates(
21572165
existential_predicates
21582166
.iter()
21592167
.map(|predicate| predicate.with_self_ty(tcx, self_ty)),
21602168
location.to_locations(),
2161-
ConstraintCategory::Cast { is_coercion: true, unsize_to: None },
2169+
ConstraintCategory::Cast { is_implicit_coercion, unsize_to: None },
21622170
);
21632171

21642172
let outlives_predicate = tcx.mk_predicate(Binder::dummy(
@@ -2169,11 +2177,14 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
21692177
self.prove_predicate(
21702178
outlives_predicate,
21712179
location.to_locations(),
2172-
ConstraintCategory::Cast { is_coercion: true, unsize_to: None },
2180+
ConstraintCategory::Cast { is_implicit_coercion, unsize_to: None },
21732181
);
21742182
}
21752183

2176-
CastKind::PointerCoercion(PointerCoercion::MutToConstPointer) => {
2184+
CastKind::PointerCoercion(
2185+
PointerCoercion::MutToConstPointer,
2186+
coercion_source,
2187+
) => {
21772188
let ty::RawPtr(ty_from, hir::Mutability::Mut) = op.ty(body, tcx).kind()
21782189
else {
21792190
span_mirbug!(self, rvalue, "unexpected base type for cast {:?}", ty,);
@@ -2183,11 +2194,12 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
21832194
span_mirbug!(self, rvalue, "unexpected target type for cast {:?}", ty,);
21842195
return;
21852196
};
2197+
let is_implicit_coercion = coercion_source == CoercionSource::Implicit;
21862198
if let Err(terr) = self.sub_types(
21872199
*ty_from,
21882200
*ty_to,
21892201
location.to_locations(),
2190-
ConstraintCategory::Cast { is_coercion: true, unsize_to: None },
2202+
ConstraintCategory::Cast { is_implicit_coercion, unsize_to: None },
21912203
) {
21922204
span_mirbug!(
21932205
self,
@@ -2200,7 +2212,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
22002212
}
22012213
}
22022214

2203-
CastKind::PointerCoercion(PointerCoercion::ArrayToPointer) => {
2215+
CastKind::PointerCoercion(PointerCoercion::ArrayToPointer, coercion_source) => {
22042216
let ty_from = op.ty(body, tcx);
22052217

22062218
let opt_ty_elem_mut = match ty_from.kind() {
@@ -2245,11 +2257,12 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
22452257
return;
22462258
}
22472259

2260+
let is_implicit_coercion = coercion_source == CoercionSource::Implicit;
22482261
if let Err(terr) = self.sub_types(
22492262
*ty_elem,
22502263
*ty_to,
22512264
location.to_locations(),
2252-
ConstraintCategory::Cast { is_coercion: true, unsize_to: None },
2265+
ConstraintCategory::Cast { is_implicit_coercion, unsize_to: None },
22532266
) {
22542267
span_mirbug!(
22552268
self,
@@ -2431,7 +2444,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
24312444
dst_obj,
24322445
location.to_locations(),
24332446
ConstraintCategory::Cast {
2434-
is_coercion: false,
2447+
is_implicit_coercion: false,
24352448
unsize_to: None,
24362449
},
24372450
)

compiler/rustc_codegen_cranelift/src/base.rs

+6-5
Original file line numberDiff line numberDiff line change
@@ -652,7 +652,7 @@ fn codegen_stmt<'tcx>(
652652
lval.write_cvalue(fx, res);
653653
}
654654
Rvalue::Cast(
655-
CastKind::PointerCoercion(PointerCoercion::ReifyFnPointer),
655+
CastKind::PointerCoercion(PointerCoercion::ReifyFnPointer, _),
656656
ref operand,
657657
to_ty,
658658
) => {
@@ -677,7 +677,7 @@ fn codegen_stmt<'tcx>(
677677
}
678678
}
679679
Rvalue::Cast(
680-
CastKind::PointerCoercion(PointerCoercion::UnsafeFnPointer),
680+
CastKind::PointerCoercion(PointerCoercion::UnsafeFnPointer, _),
681681
ref operand,
682682
to_ty,
683683
) => {
@@ -688,6 +688,7 @@ fn codegen_stmt<'tcx>(
688688
Rvalue::Cast(
689689
CastKind::PointerCoercion(
690690
PointerCoercion::MutToConstPointer | PointerCoercion::ArrayToPointer,
691+
_,
691692
),
692693
..,
693694
) => {
@@ -741,7 +742,7 @@ fn codegen_stmt<'tcx>(
741742
}
742743
}
743744
Rvalue::Cast(
744-
CastKind::PointerCoercion(PointerCoercion::ClosureFnPointer(_)),
745+
CastKind::PointerCoercion(PointerCoercion::ClosureFnPointer(_), _),
745746
ref operand,
746747
_to_ty,
747748
) => {
@@ -763,15 +764,15 @@ fn codegen_stmt<'tcx>(
763764
}
764765
}
765766
Rvalue::Cast(
766-
CastKind::PointerCoercion(PointerCoercion::Unsize),
767+
CastKind::PointerCoercion(PointerCoercion::Unsize, _),
767768
ref operand,
768769
_to_ty,
769770
) => {
770771
let operand = codegen_operand(fx, operand);
771772
crate::unsize::coerce_unsized_into(fx, operand, lval);
772773
}
773774
Rvalue::Cast(
774-
CastKind::PointerCoercion(PointerCoercion::DynStar),
775+
CastKind::PointerCoercion(PointerCoercion::DynStar, _),
775776
ref operand,
776777
_,
777778
) => {

compiler/rustc_codegen_ssa/src/mir/rvalue.rs

+7-7
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
3434
}
3535

3636
mir::Rvalue::Cast(
37-
mir::CastKind::PointerCoercion(PointerCoercion::Unsize),
37+
mir::CastKind::PointerCoercion(PointerCoercion::Unsize, _),
3838
ref source,
3939
_,
4040
) => {
@@ -464,7 +464,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
464464
let lladdr = bx.ptrtoint(llptr, llcast_ty);
465465
OperandValue::Immediate(lladdr)
466466
}
467-
mir::CastKind::PointerCoercion(PointerCoercion::ReifyFnPointer) => {
467+
mir::CastKind::PointerCoercion(PointerCoercion::ReifyFnPointer, _) => {
468468
match *operand.layout.ty.kind() {
469469
ty::FnDef(def_id, args) => {
470470
let instance = ty::Instance::resolve_for_fn_ptr(
@@ -480,7 +480,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
480480
_ => bug!("{} cannot be reified to a fn ptr", operand.layout.ty),
481481
}
482482
}
483-
mir::CastKind::PointerCoercion(PointerCoercion::ClosureFnPointer(_)) => {
483+
mir::CastKind::PointerCoercion(PointerCoercion::ClosureFnPointer(_), _) => {
484484
match *operand.layout.ty.kind() {
485485
ty::Closure(def_id, args) => {
486486
let instance = Instance::resolve_closure(
@@ -495,19 +495,19 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
495495
_ => bug!("{} cannot be cast to a fn ptr", operand.layout.ty),
496496
}
497497
}
498-
mir::CastKind::PointerCoercion(PointerCoercion::UnsafeFnPointer) => {
498+
mir::CastKind::PointerCoercion(PointerCoercion::UnsafeFnPointer, _) => {
499499
// This is a no-op at the LLVM level.
500500
operand.val
501501
}
502-
mir::CastKind::PointerCoercion(PointerCoercion::Unsize) => {
502+
mir::CastKind::PointerCoercion(PointerCoercion::Unsize, _) => {
503503
assert!(bx.cx().is_backend_scalar_pair(cast));
504504
let (lldata, llextra) = operand.val.pointer_parts();
505505
let (lldata, llextra) =
506506
base::unsize_ptr(bx, lldata, operand.layout.ty, cast.ty, llextra);
507507
OperandValue::Pair(lldata, llextra)
508508
}
509509
mir::CastKind::PointerCoercion(
510-
PointerCoercion::MutToConstPointer | PointerCoercion::ArrayToPointer,
510+
PointerCoercion::MutToConstPointer | PointerCoercion::ArrayToPointer, _
511511
) => {
512512
bug!("{kind:?} is for borrowck, and should never appear in codegen");
513513
}
@@ -525,7 +525,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
525525
bug!("unexpected non-pair operand");
526526
}
527527
}
528-
mir::CastKind::PointerCoercion(PointerCoercion::DynStar) => {
528+
mir::CastKind::PointerCoercion(PointerCoercion::DynStar, _) => {
529529
let (lldata, llextra) = operand.val.pointer_parts();
530530
let (lldata, llextra) =
531531
base::cast_to_dyn_star(bx, lldata, operand.layout, cast.ty, llextra);

compiler/rustc_const_eval/src/check_consts/check.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -440,6 +440,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
440440
| PointerCoercion::UnsafeFnPointer
441441
| PointerCoercion::ClosureFnPointer(_)
442442
| PointerCoercion::ReifyFnPointer,
443+
_,
443444
),
444445
_,
445446
_,
@@ -448,7 +449,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
448449
}
449450

450451
Rvalue::Cast(
451-
CastKind::PointerCoercion(PointerCoercion::Unsize | PointerCoercion::DynStar),
452+
CastKind::PointerCoercion(PointerCoercion::Unsize | PointerCoercion::DynStar, _),
452453
_,
453454
_,
454455
) => {

0 commit comments

Comments
 (0)