Skip to content

Commit 9e4753b

Browse files
committed
do not impl Field for FRTs of repr(packed) types
1 parent b11f308 commit 9e4753b

7 files changed

Lines changed: 64 additions & 2 deletions

File tree

compiler/rustc_middle/src/ty/sty.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1157,6 +1157,10 @@ impl<'tcx> rustc_type_ir::inherent::Ty<TyCtxt<'tcx>> for Ty<'tcx> {
11571157
fn has_unsafe_fields(self) -> bool {
11581158
Ty::has_unsafe_fields(self)
11591159
}
1160+
1161+
fn is_packed(self) -> bool {
1162+
Ty::is_packed(self)
1163+
}
11601164
}
11611165

11621166
/// Type utilities
@@ -1211,6 +1215,11 @@ impl<'tcx> Ty<'tcx> {
12111215
matches!(self.kind(), Adt(..))
12121216
}
12131217

1218+
#[inline]
1219+
pub fn is_packed(self) -> bool {
1220+
matches!(self.kind(), Adt(def, _) if def.repr().packed())
1221+
}
1222+
12141223
#[inline]
12151224
pub fn is_ref(self) -> bool {
12161225
matches!(self.kind(), Ref(..))

compiler/rustc_next_trait_solver/src/solve/trait_goals.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -850,7 +850,9 @@ where
850850
if goal.predicate.polarity != ty::PredicatePolarity::Positive {
851851
return Err(NoSolution);
852852
}
853-
if let ty::FRT(..) = goal.predicate.self_ty().kind() {
853+
if let ty::FRT(ty, _) = goal.predicate.self_ty().kind()
854+
&& !ty.is_packed()
855+
{
854856
ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc)
855857
.enter(|ecx| ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes))
856858
} else {

compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1457,7 +1457,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
14571457
obligation: &PolyTraitObligation<'tcx>,
14581458
candidates: &mut SelectionCandidateSet<'tcx>,
14591459
) {
1460-
if let ty::FRT(..) = obligation.predicate.self_ty().skip_binder().kind() {
1460+
if let ty::FRT(ty, _) = obligation.predicate.self_ty().skip_binder().kind()
1461+
&& !ty.is_packed()
1462+
{
14611463
candidates.vec.push(BuiltinCandidate);
14621464
}
14631465
}

compiler/rustc_type_ir/src/inherent.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,9 @@ pub trait Ty<I: Interner<Ty = Self>>:
154154
/// Checks whether this type is an ADT that has unsafe fields.
155155
fn has_unsafe_fields(self) -> bool;
156156

157+
/// Checks whether this type is an ADT that is `repr(packed)`.
158+
fn is_packed(self) -> bool;
159+
157160
fn fn_sig(self, interner: I) -> ty::Binder<I, ty::FnSig<I>> {
158161
self.kind().fn_sig(interner)
159162
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
error[E0277]: the trait bound `field_of!(MyStruct, 0): Field` is not satisfied
2+
--> $DIR/not-field-if-packed.rs:14:20
3+
|
4+
LL | assert_field::<field_of!(MyStruct, 0)>();
5+
| ^^^^^^^^^^^^^^^^^^^^^^ the trait `Field` is not implemented for `field_of!(MyStruct, 0)`
6+
|
7+
note: required by a bound in `assert_field`
8+
--> $DIR/not-field-if-packed.rs:11:20
9+
|
10+
LL | fn assert_field<F: Field>() {}
11+
| ^^^^^ required by this bound in `assert_field`
12+
13+
error: aborting due to 1 previous error
14+
15+
For more information about this error, try `rustc --explain E0277`.
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
error[E0277]: the trait bound `field_of!(MyStruct, 0): Field` is not satisfied
2+
--> $DIR/not-field-if-packed.rs:14:20
3+
|
4+
LL | assert_field::<field_of!(MyStruct, 0)>();
5+
| ^^^^^^^^^^^^^^^^^^^^^^ the trait `Field` is not implemented for `field_of!(MyStruct, 0)`
6+
|
7+
note: required by a bound in `assert_field`
8+
--> $DIR/not-field-if-packed.rs:11:20
9+
|
10+
LL | fn assert_field<F: Field>() {}
11+
| ^^^^^ required by this bound in `assert_field`
12+
13+
error: aborting due to 1 previous error
14+
15+
For more information about this error, try `rustc --explain E0277`.
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
//@ revisions: old next
2+
//@ [next] compile-flags: -Znext-solver
3+
#![allow(incomplete_features)]
4+
#![feature(field_projections)]
5+
6+
use std::field::{Field, field_of};
7+
8+
#[repr(packed)]
9+
pub struct MyStruct(usize);
10+
11+
fn assert_field<F: Field>() {}
12+
13+
fn main() {
14+
assert_field::<field_of!(MyStruct, 0)>();
15+
//~^ ERROR: the trait bound `field_of!(MyStruct, 0): Field` is not satisfied [E0277]
16+
}

0 commit comments

Comments
 (0)