Skip to content

Commit 7eee68f

Browse files
committed
Address CoerceShared field relation review
1 parent a6509ec commit 7eee68f

28 files changed

Lines changed: 485 additions & 411 deletions

compiler/rustc_borrowck/src/type_check/mod.rs

Lines changed: 29 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -25,14 +25,15 @@ use rustc_middle::mir::*;
2525
use rustc_middle::traits::query::NoSolution;
2626
use rustc_middle::ty::adjustment::PointerCoercion;
2727
use rustc_middle::ty::cast::CastTy;
28+
use rustc_middle::ty::reborrow::{self, CoerceSharedFieldPairError};
2829
use rustc_middle::ty::{
2930
self, CanonicalUserTypeAnnotation, CanonicalUserTypeAnnotations, CoroutineArgsExt,
3031
GenericArgsRef, Ty, TyCtxt, TypeVisitableExt, UserArgs, UserTypeAnnotationIndex, fold_regions,
3132
};
3233
use rustc_mir_dataflow::move_paths::MoveData;
3334
use rustc_mir_dataflow::points::DenseLocationMap;
3435
use rustc_span::def_id::CRATE_DEF_ID;
35-
use rustc_span::{Span, Spanned, Symbol, sym};
36+
use rustc_span::{Span, Spanned, sym};
3637
use rustc_trait_selection::infer::InferCtxtExt;
3738
use rustc_trait_selection::traits::query::type_op::custom::scrape_region_constraints;
3839
use rustc_trait_selection::traits::query::type_op::{TypeOp, TypeOpOutput};
@@ -65,42 +66,6 @@ macro_rules! span_mirbug {
6566
})
6667
}
6768

68-
#[derive(Clone, Copy)]
69-
struct ReborrowField<'tcx> {
70-
index: FieldIdx,
71-
name: Symbol,
72-
ty: Ty<'tcx>,
73-
}
74-
75-
fn reborrow_data_fields<'tcx>(
76-
tcx: TyCtxt<'tcx>,
77-
def: ty::AdtDef<'tcx>,
78-
args: GenericArgsRef<'tcx>,
79-
) -> Vec<ReborrowField<'tcx>> {
80-
def.non_enum_variant()
81-
.fields
82-
.iter_enumerated()
83-
.filter_map(|(index, field)| {
84-
let ty = field.ty(tcx, args).skip_norm_wip();
85-
(!ty.is_phantom_data()).then_some(ReborrowField { index, name: field.name, ty })
86-
})
87-
.collect()
88-
}
89-
90-
fn reborrow_field_styles_match(a: ty::AdtDef<'_>, b: ty::AdtDef<'_>) -> bool {
91-
a.non_enum_variant().ctor_kind() == b.non_enum_variant().ctor_kind()
92-
}
93-
94-
fn find_corresponding_reborrow_field<'a, 'tcx>(
95-
source_fields: &'a [ReborrowField<'tcx>],
96-
target: ReborrowField<'tcx>,
97-
by_index: bool,
98-
) -> Option<&'a ReborrowField<'tcx>> {
99-
source_fields.iter().find(|source| {
100-
if by_index { source.index == target.index } else { source.name == target.name }
101-
})
102-
}
103-
10469
pub(crate) mod canonical;
10570
pub(crate) mod constraint_conversion;
10671
pub(crate) mod free_region_relations;
@@ -2607,13 +2572,15 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
26072572
category: ConstraintCategory<'tcx>,
26082573
) -> Result<(), ()> {
26092574
let tcx = self.tcx();
2575+
let borrowed_ty = self.normalize(ty::Unnormalized::new_wip(borrowed_ty), location);
2576+
let dest_ty = self.normalize(ty::Unnormalized::new_wip(dest_ty), location);
26102577

26112578
if let (
26122579
ty::Ref(borrow_region, _, Mutability::Mut),
26132580
ty::Ref(ref_region, _, Mutability::Not),
26142581
) = (borrowed_ty.kind(), dest_ty.kind())
26152582
{
2616-
if let Err(terr) = self.relate_types(
2583+
if let Err(terr) = self.relate_types_structurally_relating_aliases(
26172584
borrowed_ty.peel_refs(),
26182585
ty::Variance::Covariant,
26192586
dest_ty.peel_refs(),
@@ -2647,48 +2614,48 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
26472614
(ty::Adt(borrowed_adt, borrowed_args), ty::Adt(dest_adt, dest_args))
26482615
if borrowed_adt.did() != dest_adt.did() =>
26492616
{
2650-
let borrowed_fields = reborrow_data_fields(tcx, *borrowed_adt, *borrowed_args);
2651-
let dest_fields = reborrow_data_fields(tcx, *dest_adt, *dest_args);
2652-
2653-
if !reborrow_field_styles_match(*borrowed_adt, *dest_adt) {
2654-
span_mirbug!(
2655-
self,
2656-
borrowed_place,
2657-
"generic shared reborrow has unsupported field structure: \
2658-
{borrowed_ty:?} -> {dest_ty:?}"
2659-
);
2660-
return Err(());
2661-
}
2662-
2663-
let by_index =
2664-
matches!(dest_adt.non_enum_variant().ctor_kind(), Some(hir::def::CtorKind::Fn));
2665-
2666-
for dest_field in dest_fields {
2667-
let Some(borrowed_field) =
2668-
find_corresponding_reborrow_field(&borrowed_fields, dest_field, by_index)
2669-
else {
2617+
let field_pairs = match reborrow::coerce_shared_field_pairs(
2618+
tcx,
2619+
*borrowed_adt,
2620+
*borrowed_args,
2621+
*dest_adt,
2622+
*dest_args,
2623+
) {
2624+
Ok(field_pairs) => field_pairs,
2625+
Err(CoerceSharedFieldPairError::FieldStyleMismatch) => {
2626+
span_mirbug!(
2627+
self,
2628+
borrowed_place,
2629+
"generic shared reborrow has unsupported field structure: \
2630+
{borrowed_ty:?} -> {dest_ty:?}"
2631+
);
2632+
return Err(());
2633+
}
2634+
Err(CoerceSharedFieldPairError::MissingSourceField { .. }) => {
26702635
span_mirbug!(
26712636
self,
26722637
borrowed_place,
26732638
"generic shared reborrow is missing a source field: \
26742639
{borrowed_ty:?} -> {dest_ty:?}"
26752640
);
26762641
return Err(());
2677-
};
2642+
}
2643+
};
26782644

2645+
for field_pair in field_pairs {
26792646
self.add_generic_shared_reborrow_constraints(
26802647
location,
26812648
borrowed_place,
2682-
borrowed_field.ty,
2683-
dest_field.ty,
2649+
field_pair.source.ty,
2650+
field_pair.target.ty,
26842651
category,
26852652
)?;
26862653
}
26872654

26882655
Ok(())
26892656
}
26902657
_ => {
2691-
if let Err(terr) = self.relate_types(
2658+
if let Err(terr) = self.relate_types_structurally_relating_aliases(
26922659
borrowed_ty,
26932660
ty::Variance::Covariant,
26942661
dest_ty,

compiler/rustc_borrowck/src/type_check/relate_tys.rs

Lines changed: 43 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,35 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
4040
locations: Locations,
4141
category: ConstraintCategory<'tcx>,
4242
) -> Result<(), NoSolution> {
43-
NllTypeRelating::new(self, locations, category, UniverseInfo::relate(a, b), v)
44-
.relate(a, b)?;
43+
NllTypeRelating::new(
44+
self,
45+
locations,
46+
category,
47+
UniverseInfo::relate(a, b),
48+
v,
49+
StructurallyRelateAliases::No,
50+
)
51+
.relate(a, b)?;
52+
Ok(())
53+
}
54+
55+
pub(super) fn relate_types_structurally_relating_aliases(
56+
&mut self,
57+
a: Ty<'tcx>,
58+
v: ty::Variance,
59+
b: Ty<'tcx>,
60+
locations: Locations,
61+
category: ConstraintCategory<'tcx>,
62+
) -> Result<(), NoSolution> {
63+
NllTypeRelating::new(
64+
self,
65+
locations,
66+
category,
67+
UniverseInfo::relate(a, b),
68+
v,
69+
StructurallyRelateAliases::Yes,
70+
)
71+
.relate(a, b)?;
4572
Ok(())
4673
}
4774

@@ -53,8 +80,15 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
5380
locations: Locations,
5481
category: ConstraintCategory<'tcx>,
5582
) -> Result<(), NoSolution> {
56-
NllTypeRelating::new(self, locations, category, UniverseInfo::other(), ty::Invariant)
57-
.relate(a, b)?;
83+
NllTypeRelating::new(
84+
self,
85+
locations,
86+
category,
87+
UniverseInfo::other(),
88+
ty::Invariant,
89+
StructurallyRelateAliases::No,
90+
)
91+
.relate(a, b)?;
5892
Ok(())
5993
}
6094
}
@@ -81,6 +115,8 @@ struct NllTypeRelating<'a, 'b, 'tcx> {
81115
ambient_variance: ty::Variance,
82116

83117
ambient_variance_info: ty::VarianceDiagInfo<TyCtxt<'tcx>>,
118+
119+
structurally_relate_aliases: StructurallyRelateAliases,
84120
}
85121

86122
impl<'a, 'b, 'tcx> NllTypeRelating<'a, 'b, 'tcx> {
@@ -90,6 +126,7 @@ impl<'a, 'b, 'tcx> NllTypeRelating<'a, 'b, 'tcx> {
90126
category: ConstraintCategory<'tcx>,
91127
universe_info: UniverseInfo<'tcx>,
92128
ambient_variance: ty::Variance,
129+
structurally_relate_aliases: StructurallyRelateAliases,
93130
) -> Self {
94131
Self {
95132
type_checker,
@@ -98,6 +135,7 @@ impl<'a, 'b, 'tcx> NllTypeRelating<'a, 'b, 'tcx> {
98135
universe_info,
99136
ambient_variance,
100137
ambient_variance_info: ty::VarianceDiagInfo::default(),
138+
structurally_relate_aliases,
101139
}
102140
}
103141

@@ -553,7 +591,7 @@ impl<'b, 'tcx> PredicateEmittingRelation<InferCtxt<'tcx>> for NllTypeRelating<'_
553591
}
554592

555593
fn structurally_relate_aliases(&self) -> StructurallyRelateAliases {
556-
StructurallyRelateAliases::No
594+
self.structurally_relate_aliases
557595
}
558596

559597
fn param_env(&self) -> ty::ParamEnv<'tcx> {

compiler/rustc_codegen_cranelift/src/base.rs

Lines changed: 22 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,12 @@ use cranelift_module::ModuleError;
77
use rustc_ast::InlineAsmOptions;
88
use rustc_codegen_ssa::base::is_call_from_compiler_builtins_to_upstream_monomorphization;
99
use rustc_data_structures::profiling::SelfProfilerRef;
10-
use rustc_hir::def::CtorKind;
1110
use rustc_index::IndexVec;
1211
use rustc_middle::ty::TypeVisitableExt;
1312
use rustc_middle::ty::adjustment::PointerCoercion;
1413
use rustc_middle::ty::layout::{FnAbiOf, HasTypingEnv as _};
1514
use rustc_middle::ty::print::with_no_trimmed_paths;
15+
use rustc_middle::ty::reborrow::{self, CoerceSharedFieldPairError};
1616
use rustc_session::config::OutputFilenames;
1717
use rustc_span::Symbol;
1818

@@ -959,7 +959,8 @@ fn codegen_reborrow_into<'tcx>(
959959
source_place: Place<'tcx>,
960960
dest: CPlace<'tcx>,
961961
) {
962-
let source_ty = source_place.ty(fx.mir, fx.tcx).ty;
962+
let source_ty = fx.monomorphize(source_place.ty(fx.mir, fx.tcx).ty);
963+
let target_ty = fx.monomorphize(target_ty);
963964
let (ty::Adt(source_def, source_args), ty::Adt(target_def, target_args)) =
964965
(source_ty.kind(), target_ty.kind())
965966
else {
@@ -974,41 +975,28 @@ fn codegen_reborrow_into<'tcx>(
974975
return;
975976
}
976977

977-
let source_variant = source_def.non_enum_variant();
978-
let target_variant = target_def.non_enum_variant();
979-
if source_variant.ctor_kind() != target_variant.ctor_kind() {
980-
bug!("generic shared reborrow has mismatched field styles");
981-
}
982-
983-
let by_index = matches!(target_variant.ctor_kind(), Some(CtorKind::Fn));
984-
for (target_index, target_field) in target_variant.fields.iter_enumerated() {
985-
let target_field_ty = target_field.ty(fx.tcx, target_args).skip_norm_wip();
986-
if target_field_ty.is_phantom_data() {
987-
continue;
978+
let field_pairs = match reborrow::coerce_shared_field_pairs(
979+
fx.tcx,
980+
*source_def,
981+
*source_args,
982+
*target_def,
983+
*target_args,
984+
) {
985+
Ok(field_pairs) => field_pairs,
986+
Err(CoerceSharedFieldPairError::FieldStyleMismatch) => {
987+
bug!("generic shared reborrow has mismatched field styles");
988988
}
989-
990-
let source = source_variant
991-
.fields
992-
.iter_enumerated()
993-
.find(|(source_index, source_field)| {
994-
if by_index {
995-
*source_index == target_index
996-
} else {
997-
source_field.name == target_field.name
998-
}
999-
})
1000-
.unwrap_or_else(|| bug!("generic shared reborrow is missing a source field"));
1001-
1002-
let source_index = source.0;
1003-
let source_field = source.1;
1004-
let source_field_ty = source_field.ty(fx.tcx, source_args).skip_norm_wip();
1005-
if source_field_ty.is_phantom_data() {
1006-
bug!("generic shared reborrow source field is PhantomData");
989+
Err(CoerceSharedFieldPairError::MissingSourceField { .. }) => {
990+
bug!("generic shared reborrow is missing a source field");
1007991
}
992+
};
1008993

1009-
let source_field_place =
1010-
source_place.project_deeper(&[PlaceElem::Field(source_index, source_field_ty)], fx.tcx);
1011-
let field_dest = dest.place_field(fx, target_index);
994+
for field_pair in field_pairs {
995+
let source_field_ty = fx.monomorphize(field_pair.source.ty);
996+
let target_field_ty = fx.monomorphize(field_pair.target.ty);
997+
let source_field_place = source_place
998+
.project_deeper(&[PlaceElem::Field(field_pair.source.index, source_field_ty)], fx.tcx);
999+
let field_dest = dest.place_field(fx, field_pair.target.index);
10121000
codegen_reborrow_into(fx, target_field_ty, source_field_place, field_dest);
10131001
}
10141002

0 commit comments

Comments
 (0)