Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit b20dd1d

Browse files
committed
Allow unsizing pattern types with pointer base
1 parent e5c8b26 commit b20dd1d

File tree

17 files changed

+142
-5
lines changed

17 files changed

+142
-5
lines changed

‎compiler/rustc_codegen_cranelift/src/unsize.rs‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,11 @@ pub(crate) fn coerce_unsized_into<'tcx>(
133133
dst.write_cvalue(fx, CValue::by_val_pair(base, info, dst.layout()));
134134
};
135135
match (&src_ty.kind(), &dst_ty.kind()) {
136+
(ty::Pat(a, _), ty::Pat(b, _)) => {
137+
let src = src.cast_pat_ty_to_base(fx.layout_of(*a));
138+
let dst = dst.place_transmute_type(fx, *b);
139+
return coerce_unsized_into(fx, src, dst);
140+
}
136141
(&ty::Ref(..), &ty::Ref(..))
137142
| (&ty::Ref(..), &ty::RawPtr(..))
138143
| (&ty::RawPtr(..), &ty::RawPtr(..)) => coerce_ptr(),

‎compiler/rustc_codegen_cranelift/src/value_and_place.rs‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -342,6 +342,14 @@ impl<'tcx> CValue<'tcx> {
342342
assert_eq!(self.layout().backend_repr, layout.backend_repr);
343343
CValue(self.0, layout)
344344
}
345+
346+
pub(crate) fn cast_pat_ty_to_base(self, layout: TyAndLayout<'tcx>) -> Self {
347+
let ty::Pat(base, _) = *self.layout().ty.kind() else {
348+
panic!("not a pattern type: {:#?}", self.layout())
349+
};
350+
assert_eq!(layout.ty, base);
351+
CValue(self.0, layout)
352+
}
345353
}
346354

347355
/// A place where you can write a value to or read a value from

‎compiler/rustc_codegen_ssa/src/base.rs‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,7 @@ pub(crate) fn unsize_ptr<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
227227
) -> (Bx::Value, Bx::Value) {
228228
debug!("unsize_ptr: {:?} => {:?}", src_ty, dst_ty);
229229
match (src_ty.kind(), dst_ty.kind()) {
230+
(&ty::Pat(a, _), &ty::Pat(b, _)) => unsize_ptr(bx, src, a, b, old_info),
230231
(&ty::Ref(_, a, _), &ty::Ref(_, b, _) | &ty::RawPtr(b, _))
231232
| (&ty::RawPtr(a, _), &ty::RawPtr(b, _)) => {
232233
assert_eq!(bx.cx().type_is_sized(a), old_info.is_none());

‎compiler/rustc_const_eval/src/interpret/cast.rs‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -459,6 +459,12 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
459459
) -> InterpResult<'tcx> {
460460
trace!("Unsizing {:?} of type {} into {}", *src, src.layout.ty, cast_ty.ty);
461461
match (src.layout.ty.kind(), cast_ty.ty.kind()) {
462+
(&ty::Pat(_, s_pat), &ty::Pat(cast_ty, c_pat)) if s_pat == c_pat => {
463+
let src = self.project_field(src, FieldIdx::ZERO)?;
464+
let dest = self.project_field(dest, FieldIdx::ZERO)?;
465+
let cast_ty = self.layout_of(cast_ty)?;
466+
self.unsize_into(&src, cast_ty, &dest)
467+
}
462468
(&ty::Ref(_, s, _), &ty::Ref(_, c, _) | &ty::RawPtr(c, _))
463469
| (&ty::RawPtr(s, _), &ty::RawPtr(c, _)) => self.unsize_into_ptr(src, dest, s, c),
464470
(&ty::Adt(def_a, _), &ty::Adt(def_b, _)) => {

‎compiler/rustc_hir_analysis/messages.ftl‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,8 @@ hir_analysis_coerce_pointee_not_struct = `derive(CoercePointee)` is only applica
106106
107107
hir_analysis_coerce_pointee_not_transparent = `derive(CoercePointee)` is only applicable to `struct` with `repr(transparent)` layout
108108
109+
hir_analysis_coerce_same_pat_kind = only pattern types with the same pattern can be coerced between each other
110+
109111
hir_analysis_coerce_unsized_field_validity = for `{$ty}` to have a valid implementation of `{$trait_name}`, it must be possible to coerce the field of type `{$field_ty}`
110112
.label = `{$field_ty}` must be a pointer, reference, or smart pointer that is allowed to be unsized
111113

‎compiler/rustc_hir_analysis/src/coherence/builtin.rs‎

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,18 @@ fn visit_implementation_of_dispatch_from_dyn(checker: &Checker<'_>) -> Result<()
248248
// in the compiler (in particular, all the call ABI logic) will treat them as repr(transparent)
249249
// even if they do not carry that attribute.
250250
match (source.kind(), target.kind()) {
251+
(&ty::Pat(_, pat_a), &ty::Pat(_, pat_b)) => {
252+
if pat_a != pat_b {
253+
return Err(tcx.dcx().emit_err(errors::CoerceSamePatKind {
254+
span,
255+
trait_name,
256+
pat_a: pat_a.to_string(),
257+
pat_b: pat_b.to_string(),
258+
}));
259+
}
260+
Ok(())
261+
}
262+
251263
(&ty::Ref(r_a, _, mutbl_a), ty::Ref(r_b, _, mutbl_b))
252264
if r_a == *r_b && mutbl_a == *mutbl_b =>
253265
{
@@ -413,6 +425,18 @@ pub(crate) fn coerce_unsized_info<'tcx>(
413425
(mt_a.ty, mt_b.ty, unsize_trait, None, span)
414426
};
415427
let (source, target, trait_def_id, kind, field_span) = match (source.kind(), target.kind()) {
428+
(&ty::Pat(ty_a, pat_a), &ty::Pat(ty_b, pat_b)) => {
429+
if pat_a != pat_b {
430+
return Err(tcx.dcx().emit_err(errors::CoerceSamePatKind {
431+
span,
432+
trait_name,
433+
pat_a: pat_a.to_string(),
434+
pat_b: pat_b.to_string(),
435+
}));
436+
}
437+
(ty_a, ty_b, coerce_unsized_trait, None, span)
438+
}
439+
416440
(&ty::Ref(r_a, ty_a, mutbl_a), &ty::Ref(r_b, ty_b, mutbl_b)) => {
417441
infcx.sub_regions(SubregionOrigin::RelateObjectBound(span), r_b, r_a);
418442
let mt_a = ty::TypeAndMut { ty: ty_a, mutbl: mutbl_a };

‎compiler/rustc_hir_analysis/src/coherence/orphan.rs‎

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -206,12 +206,8 @@ pub(crate) fn orphan_check_impl(
206206
(LocalImpl::Disallow { problematic_kind }, NonlocalImpl::DisallowOther)
207207
}
208208

209-
ty::Pat(..) => (
210-
LocalImpl::Disallow { problematic_kind: "pattern type" },
211-
NonlocalImpl::DisallowOther,
212-
),
213-
214209
ty::Bool
210+
| ty::Pat(..)
215211
| ty::Char
216212
| ty::Int(..)
217213
| ty::Uint(..)

‎compiler/rustc_hir_analysis/src/errors.rs‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1279,6 +1279,16 @@ pub(crate) struct CoerceUnsizedNonStruct {
12791279
pub trait_name: &'static str,
12801280
}
12811281

1282+
#[derive(Diagnostic)]
1283+
#[diag(hir_analysis_coerce_same_pat_kind)]
1284+
pub(crate) struct CoerceSamePatKind {
1285+
#[primary_span]
1286+
pub span: Span,
1287+
pub trait_name: &'static str,
1288+
pub pat_a: String,
1289+
pub pat_b: String,
1290+
}
1291+
12821292
#[derive(Diagnostic)]
12831293
#[diag(hir_analysis_coerce_unsized_may, code = E0377)]
12841294
pub(crate) struct CoerceSameStruct {

‎compiler/rustc_middle/src/traits/select.rs‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,9 @@ pub enum SelectionCandidate<'tcx> {
159159
/// types generated for a fn pointer type (e.g., `fn(int) -> int`)
160160
FnPointerCandidate,
161161

162+
/// Builtin impl of the `PointerLike` trait.
163+
PointerLikeCandidate,
164+
162165
TraitAliasCandidate,
163166

164167
/// Matching `dyn Trait` with a supertrait of `Trait`. The index is the

‎compiler/rustc_mir_transform/src/validate.rs‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -707,6 +707,8 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
707707
};
708708
check_equal(self, location, *f_ty);
709709
}
710+
// Debug info is allowed to project into pattern types
711+
ty::Pat(base, _) => check_equal(self, location, *base),
710712
ty::Adt(adt_def, args) => {
711713
// see <https://github.com/rust-lang/rust/blob/7601adcc764d42c9f2984082b49948af652df986/compiler/rustc_middle/src/ty/layout.rs#L861-L864>
712714
if self.tcx.is_lang_item(adt_def.did(), LangItem::DynMetadata) {

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /