Skip to content

Commit bd31e3e

Browse files
author
Lukas Markeffsky
committed
be even more precise about "cast" vs "coercion"
1 parent 5e60d1f commit bd31e3e

File tree

90 files changed

+289
-231
lines changed

Some content is hidden

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

90 files changed

+289
-231
lines changed

Diff for: 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
) => {

Diff for: 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 ",

Diff for: compiler/rustc_borrowck/src/type_check/mod.rs

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

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

19821983
// HACK: This shouldn't be necessary... We can remove this when we actually
@@ -2007,15 +2008,15 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
20072008
self.prove_predicate(
20082009
ty::ClauseKind::WellFormed(src_ty.into()),
20092010
location.to_locations(),
2010-
ConstraintCategory::Cast { is_coercion: true, unsize_to: None },
2011+
ConstraintCategory::Cast { is_implicit_coercion, unsize_to: None },
20112012
);
20122013

20132014
let src_ty = self.normalize(src_ty, location);
20142015
if let Err(terr) = self.sub_types(
20152016
src_ty,
20162017
*ty,
20172018
location.to_locations(),
2018-
ConstraintCategory::Cast { is_coercion: true, unsize_to: None },
2019+
ConstraintCategory::Cast { is_implicit_coercion, unsize_to: None },
20192020
) {
20202021
span_mirbug!(
20212022
self,
@@ -2036,7 +2037,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
20362037
self.prove_predicate(
20372038
ty::ClauseKind::WellFormed(src_ty.into()),
20382039
location.to_locations(),
2039-
ConstraintCategory::Cast { is_coercion: true, unsize_to: None },
2040+
ConstraintCategory::Cast { is_implicit_coercion, unsize_to: None },
20402041
);
20412042

20422043
// The type that we see in the fcx is like
@@ -2049,7 +2050,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
20492050
src_ty,
20502051
*ty,
20512052
location.to_locations(),
2052-
ConstraintCategory::Cast { is_coercion: true, unsize_to: None },
2053+
ConstraintCategory::Cast { is_implicit_coercion, unsize_to: None },
20532054
) {
20542055
span_mirbug!(
20552056
self,
@@ -2062,19 +2063,23 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
20622063
}
20632064
}
20642065

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

2077+
let is_implicit_coercion = coercion_source == CoercionSource::Implicit;
20732078
if let Err(terr) = self.sub_types(
20742079
ty_fn_ptr_from,
20752080
*ty,
20762081
location.to_locations(),
2077-
ConstraintCategory::Cast { is_coercion: true, unsize_to: None },
2082+
ConstraintCategory::Cast { is_implicit_coercion, unsize_to: None },
20782083
) {
20792084
span_mirbug!(
20802085
self,
@@ -2087,7 +2092,10 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
20872092
}
20882093
}
20892094

2090-
CastKind::PointerCoercion(PointerCoercion::UnsafeFnPointer) => {
2095+
CastKind::PointerCoercion(
2096+
PointerCoercion::UnsafeFnPointer,
2097+
coercion_source,
2098+
) => {
20912099
let fn_sig = op.ty(body, tcx).fn_sig(tcx);
20922100

20932101
// The type that we see in the fcx is like
@@ -2099,11 +2107,12 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
20992107

21002108
let ty_fn_ptr_from = tcx.safe_to_unsafe_fn_ty(fn_sig);
21012109

2110+
let is_implicit_coercion = coercion_source == CoercionSource::Implicit;
21022111
if let Err(terr) = self.sub_types(
21032112
ty_fn_ptr_from,
21042113
*ty,
21052114
location.to_locations(),
2106-
ConstraintCategory::Cast { is_coercion: true, unsize_to: None },
2115+
ConstraintCategory::Cast { is_implicit_coercion, unsize_to: None },
21072116
) {
21082117
span_mirbug!(
21092118
self,
@@ -2116,31 +2125,29 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
21162125
}
21172126
}
21182127

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

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+
});
21272140
self.prove_trait_ref(
21282141
trait_ref,
21292142
location.to_locations(),
21302143
ConstraintCategory::Cast {
2131-
is_coercion: true,
2132-
unsize_to: Some(tcx.fold_regions(ty, |r, _| {
2133-
if let ty::ReVar(_) = r.kind() {
2134-
tcx.lifetimes.re_erased
2135-
} else {
2136-
r
2137-
}
2138-
})),
2144+
is_implicit_coercion,
2145+
unsize_to: Some(unsize_to),
21392146
},
21402147
);
21412148
}
21422149

2143-
CastKind::PointerCoercion(PointerCoercion::DynStar) => {
2150+
CastKind::PointerCoercion(PointerCoercion::DynStar, coercion_source) => {
21442151
// get the constraints from the target type (`dyn* Clone`)
21452152
//
21462153
// apply them to prove that the source type `Foo` implements `Clone` etc
@@ -2151,12 +2158,13 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
21512158

21522159
let self_ty = op.ty(body, tcx);
21532160

2161+
let is_implicit_coercion = coercion_source == CoercionSource::Implicit;
21542162
self.prove_predicates(
21552163
existential_predicates
21562164
.iter()
21572165
.map(|predicate| predicate.with_self_ty(tcx, self_ty)),
21582166
location.to_locations(),
2159-
ConstraintCategory::Cast { is_coercion: true, unsize_to: None },
2167+
ConstraintCategory::Cast { is_implicit_coercion, unsize_to: None },
21602168
);
21612169

21622170
let outlives_predicate = tcx.mk_predicate(Binder::dummy(
@@ -2167,11 +2175,14 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
21672175
self.prove_predicate(
21682176
outlives_predicate,
21692177
location.to_locations(),
2170-
ConstraintCategory::Cast { is_coercion: true, unsize_to: None },
2178+
ConstraintCategory::Cast { is_implicit_coercion, unsize_to: None },
21712179
);
21722180
}
21732181

2174-
CastKind::PointerCoercion(PointerCoercion::MutToConstPointer) => {
2182+
CastKind::PointerCoercion(
2183+
PointerCoercion::MutToConstPointer,
2184+
coercion_source,
2185+
) => {
21752186
let ty::RawPtr(ty_from, hir::Mutability::Mut) = op.ty(body, tcx).kind()
21762187
else {
21772188
span_mirbug!(self, rvalue, "unexpected base type for cast {:?}", ty,);
@@ -2181,11 +2192,12 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
21812192
span_mirbug!(self, rvalue, "unexpected target type for cast {:?}", ty,);
21822193
return;
21832194
};
2195+
let is_implicit_coercion = coercion_source == CoercionSource::Implicit;
21842196
if let Err(terr) = self.sub_types(
21852197
*ty_from,
21862198
*ty_to,
21872199
location.to_locations(),
2188-
ConstraintCategory::Cast { is_coercion: true, unsize_to: None },
2200+
ConstraintCategory::Cast { is_implicit_coercion, unsize_to: None },
21892201
) {
21902202
span_mirbug!(
21912203
self,
@@ -2198,7 +2210,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
21982210
}
21992211
}
22002212

2201-
CastKind::PointerCoercion(PointerCoercion::ArrayToPointer) => {
2213+
CastKind::PointerCoercion(PointerCoercion::ArrayToPointer, coercion_source) => {
22022214
let ty_from = op.ty(body, tcx);
22032215

22042216
let opt_ty_elem_mut = match ty_from.kind() {
@@ -2243,11 +2255,12 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
22432255
return;
22442256
}
22452257

2258+
let is_implicit_coercion = coercion_source == CoercionSource::Implicit;
22462259
if let Err(terr) = self.sub_types(
22472260
*ty_elem,
22482261
*ty_to,
22492262
location.to_locations(),
2250-
ConstraintCategory::Cast { is_coercion: true, unsize_to: None },
2263+
ConstraintCategory::Cast { is_implicit_coercion, unsize_to: None },
22512264
) {
22522265
span_mirbug!(
22532266
self,
@@ -2429,7 +2442,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
24292442
dst_obj,
24302443
location.to_locations(),
24312444
ConstraintCategory::Cast {
2432-
is_coercion: false,
2445+
is_implicit_coercion: false,
24332446
unsize_to: None,
24342447
},
24352448
)

Diff for: 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
) => {

Diff for: 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
) => {
@@ -465,7 +465,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
465465
let lladdr = bx.ptrtoint(llptr, llcast_ty);
466466
OperandValue::Immediate(lladdr)
467467
}
468-
mir::CastKind::PointerCoercion(PointerCoercion::ReifyFnPointer) => {
468+
mir::CastKind::PointerCoercion(PointerCoercion::ReifyFnPointer, _) => {
469469
match *operand.layout.ty.kind() {
470470
ty::FnDef(def_id, args) => {
471471
let instance = ty::Instance::resolve_for_fn_ptr(
@@ -481,7 +481,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
481481
_ => bug!("{} cannot be reified to a fn ptr", operand.layout.ty),
482482
}
483483
}
484-
mir::CastKind::PointerCoercion(PointerCoercion::ClosureFnPointer(_)) => {
484+
mir::CastKind::PointerCoercion(PointerCoercion::ClosureFnPointer(_), _) => {
485485
match *operand.layout.ty.kind() {
486486
ty::Closure(def_id, args) => {
487487
let instance = Instance::resolve_closure(
@@ -496,19 +496,19 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
496496
_ => bug!("{} cannot be cast to a fn ptr", operand.layout.ty),
497497
}
498498
}
499-
mir::CastKind::PointerCoercion(PointerCoercion::UnsafeFnPointer) => {
499+
mir::CastKind::PointerCoercion(PointerCoercion::UnsafeFnPointer, _) => {
500500
// This is a no-op at the LLVM level.
501501
operand.val
502502
}
503-
mir::CastKind::PointerCoercion(PointerCoercion::Unsize) => {
503+
mir::CastKind::PointerCoercion(PointerCoercion::Unsize, _) => {
504504
assert!(bx.cx().is_backend_scalar_pair(cast));
505505
let (lldata, llextra) = operand.val.pointer_parts();
506506
let (lldata, llextra) =
507507
base::unsize_ptr(bx, lldata, operand.layout.ty, cast.ty, llextra);
508508
OperandValue::Pair(lldata, llextra)
509509
}
510510
mir::CastKind::PointerCoercion(
511-
PointerCoercion::MutToConstPointer | PointerCoercion::ArrayToPointer,
511+
PointerCoercion::MutToConstPointer | PointerCoercion::ArrayToPointer, _
512512
) => {
513513
bug!("{kind:?} is for borrowck, and should never appear in codegen");
514514
}
@@ -526,7 +526,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
526526
bug!("unexpected non-pair operand");
527527
}
528528
}
529-
mir::CastKind::PointerCoercion(PointerCoercion::DynStar) => {
529+
mir::CastKind::PointerCoercion(PointerCoercion::DynStar, _) => {
530530
let (lldata, llextra) = operand.val.pointer_parts();
531531
let (lldata, llextra) =
532532
base::cast_to_dyn_star(bx, lldata, operand.layout, cast.ty, llextra);

Diff for: 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)