Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
0f25806
parse field representing types
BennoLossin Jan 1, 2026
2eadcf3
lower field representing types to HIR
BennoLossin Jan 1, 2026
f23a7e4
lower field representing types to MIR
BennoLossin Jan 1, 2026
6f61de1
add field representing types to rustc_public
BennoLossin Jan 1, 2026
d006af8
add `Field` trait, lang items and `field_offset` intrinsic
BennoLossin Jan 1, 2026
47a9976
add builtin impl of `Field` for field representing types
BennoLossin Jan 1, 2026
2a5e3a9
add feature gate test
BennoLossin Jan 1, 2026
e57556a
add run-pass tests
BennoLossin Jan 1, 2026
b072258
test incoherent impls
BennoLossin Jan 1, 2026
9519728
deny accessing FRTs of private fields
BennoLossin Jan 1, 2026
a90feec
deny manual impls of the `Field` trait
BennoLossin Jan 1, 2026
15e679c
deny auto trait and drop impls for FRTs
BennoLossin Jan 1, 2026
239c168
do not impl `Field` for FRTs of `repr(packed)` types
BennoLossin Jan 1, 2026
e9c9d0d
tests: fix ui output
BennoLossin Jan 16, 2026
d329a10
tests: check auto traits and `Copy` for FRTs
BennoLossin Jan 16, 2026
3f54f94
consolidate tests
BennoLossin Jan 16, 2026
267f9b0
tests: more nonexistent
BennoLossin Jan 16, 2026
75ef23a
tests: add invalid syntax
BennoLossin Jan 16, 2026
41d1c17
tests: fix symbol generation
BennoLossin Jan 16, 2026
a1047bb
tests: add nonexistent tuple fields
BennoLossin Jan 16, 2026
e335d2b
tests: expect(incomplete_features) instead of allow
BennoLossin Jan 16, 2026
162c3fb
tests: add offset function
BennoLossin Jan 16, 2026
fea9b95
tests: bad normalization case for next-solver
BennoLossin Jan 16, 2026
b7d6a10
tests: fix debuginfo
BennoLossin Jan 16, 2026
ba07bb0
replace `#[rustc_do_not_implement_via_object]` with `#[rustc_dyn_inco…
BennoLossin Jan 22, 2026
5d720bb
remove unresolved FieldId & fail on projections early
BennoLossin Jan 29, 2026
2484c00
prevent FRTs of enums and unions from implementing the `Field` trait
BennoLossin Jan 29, 2026
fba9554
add test for projections
BennoLossin Jan 29, 2026
c79d5ae
test that FRTs of unions and enums don't implement `Field`
BennoLossin Jan 29, 2026
f8d1caf
document ui tests
BennoLossin Jan 29, 2026
877e900
remove resolved FIXMEs
BennoLossin Jan 29, 2026
d95cb89
fix auto-trait handling
BennoLossin Jan 29, 2026
d9dab43
move `lower_field_of` to rustc_hir_analysis and improve diagnostics
BennoLossin Jan 29, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3431,6 +3431,7 @@ dependencies = [
"rustc_macros",
"rustc_serialize",
"rustc_span",
"serde",
"tracing",
]

Expand Down Expand Up @@ -4299,6 +4300,7 @@ dependencies = [
"rustc_target",
"rustc_thread_pool",
"rustc_type_ir",
"serde",
"smallvec",
"thin-vec",
"tracing",
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_abi/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ rustc_index = { path = "../rustc_index", default-features = false }
rustc_macros = { path = "../rustc_macros", optional = true }
rustc_serialize = { path = "../rustc_serialize", optional = true }
rustc_span = { path = "../rustc_span", optional = true }
serde = { version = "1.0.125", features = ["derive"] }
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if this is okay, but I need this in order for FieldId (which contains FieldIdx and VariantIdx) to implement serde::Serialize. This is because FieldId is needed in RigidTy, which derives serde::Serialize.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@oli-obk how do you feel about this addition?

tracing = "0.1"
# tidy-alphabetical-end

Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_abi/src/layout/ty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ rustc_index::newtype_index! {
/// `b` is `FieldIdx(1)` in `VariantIdx(0)`,
/// `d` is `FieldIdx(1)` in `VariantIdx(1)`, and
/// `f` is `FieldIdx(1)` in `VariantIdx(0)`.
#[derive(HashStable_Generic)]
#[derive(HashStable_Generic, serde::Serialize)]
#[encodable]
#[orderable]
pub struct FieldIdx {}
Expand All @@ -57,7 +57,7 @@ rustc_index::newtype_index! {
///
/// `struct`s, `tuples`, and `unions`s are considered to have a single variant
/// with variant index zero, aka [`FIRST_VARIANT`].
#[derive(HashStable_Generic)]
#[derive(HashStable_Generic, serde::Serialize)]
#[encodable]
#[orderable]
pub struct VariantIdx {
Expand Down
5 changes: 5 additions & 0 deletions compiler/rustc_ast/src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2557,6 +2557,11 @@ pub enum TyKind {
/// Pattern types like `pattern_type!(u32 is 1..=)`, which is the same as `NonZero<u32>`,
/// just as part of the type system.
Pat(Box<Ty>, Box<TyPat>),
/// A `field_of` expression (e.g., `builtin # field_of(Struct, field)`).
///
/// Usually not written directly in user code but indirectly via the macro
/// `core::field::field_of!(...)`.
FieldOf(Box<Ty>, Vec<Ident>),
/// Sometimes we need a dummy value when no error has occurred.
Dummy,
/// Placeholder for a kind that has failed to be defined.
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_ast/src/util/classify.rs
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,7 @@ fn type_trailing_braced_mac_call(mut ty: &ast::Ty) -> Option<&ast::MacCall> {
| ast::TyKind::ImplicitSelf
| ast::TyKind::CVarArgs
| ast::TyKind::Pat(..)
| ast::TyKind::FieldOf(..)
| ast::TyKind::Dummy
| ast::TyKind::Err(..) => break None,
}
Expand Down
4 changes: 4 additions & 0 deletions compiler/rustc_ast_lowering/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1499,6 +1499,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
TyKind::Pat(ty, pat) => {
hir::TyKind::Pat(self.lower_ty_alloc(ty, itctx), self.lower_ty_pat(pat, ty.span))
}
TyKind::FieldOf(ty, fields) => match self.lower_ty_field_path(fields, ty.span) {
Ok(field_path) => hir::TyKind::FieldOf(self.lower_ty_alloc(ty, itctx), field_path),
Err(err) => hir::TyKind::Err(err),
},
TyKind::MacCall(_) => {
span_bug!(t.span, "`TyKind::MacCall` should have been expanded by now")
}
Expand Down
29 changes: 28 additions & 1 deletion compiler/rustc_ast_lowering/src/pat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use rustc_hir::definitions::DefPathData;
use rustc_hir::{self as hir, LangItem, Target};
use rustc_middle::span_bug;
use rustc_span::source_map::{Spanned, respan};
use rustc_span::{DesugaringKind, Ident, Span};
use rustc_span::{DesugaringKind, ErrorGuaranteed, Ident, Span};

use super::errors::{
ArbitraryExpressionInPattern, ExtraDoubleDot, MisplacedDoubleDot, SubTupleBinding,
Expand Down Expand Up @@ -478,6 +478,33 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
hir::TyPat { hir_id: pat_hir_id, kind: node, span: self.lower_span(pattern.span) }
}

pub(crate) fn lower_ty_field_path(
&mut self,
fields: &[Ident],
ty_span: Span,
) -> Result<&'hir hir::TyFieldPath, ErrorGuaranteed> {
Ok(self.arena.alloc(self.lower_ty_field_path_mut(fields, ty_span)?))
}

fn lower_ty_field_path_mut(
&mut self,
fields: &[Ident],
ty_span: Span,
) -> Result<hir::TyFieldPath, ErrorGuaranteed> {
match fields.len() {
0 => span_bug!(ty_span, "expected at least one field ident parsed in `field_of!`"),
1 => Ok(hir::TyFieldPath { variant: None, field: self.lower_ident(fields[0]) }),
2 => Ok(hir::TyFieldPath {
variant: Some(self.lower_ident(fields[0])),
field: self.lower_ident(fields[1]),
}),
_ => Err(self.dcx().span_err(
fields.iter().map(|f| f.span).collect::<Vec<_>>(),
"`field_of!` only supports a single field or a variant with a field",
)),
}
}

/// Lowers the range end of an exclusive range (`2..5`) to an inclusive range 2..=(5 - 1).
/// This way the type system doesn't have to handle the distinction between inclusive/exclusive ranges.
fn lower_excluded_range_end(&mut self, e: &AnonConst) -> &'hir hir::ConstArg<'hir> {
Expand Down
19 changes: 19 additions & 0 deletions compiler/rustc_ast_pretty/src/pprust/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1377,6 +1377,25 @@ impl<'a> State<'a> {
self.word(" is ");
self.print_ty_pat(pat);
}
ast::TyKind::FieldOf(ty, fields) => {
self.word("builtin # field_of");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we can print this as field_of!(?

self.popen();
let ib = self.ibox(0);
self.print_type(ty);
self.word(",");
self.space();

if let Some((&first, rest)) = fields.split_first() {
self.print_ident(first);

for &field in rest {
self.word(".");
self.print_ident(field);
}
}
self.end(ib);
self.pclose();
}
}
self.end(ib);
}
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_borrowck/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1875,6 +1875,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
| ty::Str
| ty::Array(_, _)
| ty::Pat(_, _)
| ty::FRT(..)
| ty::Slice(_)
| ty::FnDef(_, _)
| ty::FnPtr(..)
Expand Down Expand Up @@ -1919,6 +1920,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
| ty::Str
| ty::Array(_, _)
| ty::Pat(_, _)
| ty::FRT(..)
| ty::Slice(_)
| ty::RawPtr(_, _)
| ty::Ref(_, _, _)
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,8 @@ fn push_debuginfo_type_name<'tcx>(
write!(output, "{:?}", t).unwrap();
}
}
// FIXME(FRTs): implement debuginfo for field representing types
ty::FRT(..) => todo!(),
ty::Slice(inner_type) => {
if cpp_like_debuginfo {
output.push_str("slice2$<");
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_const_eval/src/const_eval/type_info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ impl<'tcx> InterpCx<'tcx, CompileTimeMachine<'tcx>> {
variant
}
ty::Adt(_, _)
| ty::FRT(_, _)
| ty::Foreign(_)
| ty::Pat(_, _)
| ty::FnDef(..)
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_const_eval/src/const_eval/valtrees.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ fn const_to_valtree_inner<'tcx>(
}

match ty.kind() {
ty::FnDef(..) => {
ty::FnDef(..) | ty::FRT(..) => {
*num_nodes += 1;
Ok(ty::ValTree::zst(tcx))
}
Expand Down Expand Up @@ -273,7 +273,7 @@ pub fn valtree_to_const_value<'tcx>(
// create inner `MPlace`s which are filled recursively.
// FIXME: Does this need an example?
match *cv.ty.kind() {
ty::FnDef(..) => {
ty::FnDef(..) | ty::FRT(..) => {
assert!(cv.valtree.is_zst());
mir::ConstValue::ZeroSized
}
Expand Down
22 changes: 22 additions & 0 deletions compiler/rustc_const_eval/src/interpret/intrinsics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,27 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {

self.write_scalar(Scalar::from_target_usize(offset, self), dest)?;
}
sym::field_offset => {
let frt_ty = instance.args.type_at(0);

let (ty, field) = match frt_ty.kind() {
&ty::FRT(ty, field) => (ty, field),
ty::Alias(..) | ty::Param(..) | ty::Placeholder(..) | ty::Infer(..) => {
// This can happen in code which is generic over the field type.
throw_inval!(TooGeneric)
}
_ => {
span_bug!(self.cur_span(), "expected field representing type, got {frt_ty}")
}
};
let layout = self.layout_of(ty)?;
let cx = ty::layout::LayoutCx::new(*self.tcx, self.typing_env);

let layout = layout.for_variant(&cx, field.variant);
let offset = layout.fields.offset(field.field.index()).bytes();

self.write_scalar(Scalar::from_target_usize(offset, self), dest)?;
}
sym::vtable_for => {
let tp_ty = instance.args.type_at(0);
let result_ty = instance.args.type_at(1);
Expand Down Expand Up @@ -300,6 +321,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
| ty::UnsafeBinder(_)
| ty::Never
| ty::Tuple(_)
| ty::FRT(..)
| ty::Error(_) => ConstValue::from_target_usize(0u64, &tcx),
};
let val = self.const_val_to_op(val, dest.layout.ty, Some(dest.layout))?;
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_const_eval/src/interpret/stack.rs
Original file line number Diff line number Diff line change
Expand Up @@ -507,6 +507,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
| ty::Closure(..)
| ty::CoroutineClosure(..)
| ty::Never
| ty::FRT(..)
| ty::Error(_) => true,

ty::Str | ty::Slice(_) | ty::Dynamic(_, _) | ty::Foreign(..) => false,
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_const_eval/src/interpret/validity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -785,6 +785,7 @@ impl<'rt, 'tcx, M: Machine<'tcx>> ValidityVisitor<'rt, 'tcx, M> {
| ty::Dynamic(..)
| ty::Closure(..)
| ty::Pat(..)
| ty::FRT(..)
| ty::CoroutineClosure(..)
| ty::Coroutine(..) => interp_ok(false),
// Some types only occur during typechecking, they have no layout.
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_const_eval/src/util/type_name.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ impl<'tcx> Printer<'tcx> for TypeNamePrinter<'tcx> {
| ty::Float(_)
| ty::Str
| ty::Pat(_, _)
| ty::FRT(..)
| ty::Array(_, _)
| ty::Slice(_)
| ty::RawPtr(_, _)
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_feature/src/unstable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -490,6 +490,8 @@ declare_features! (
(unstable, ffi_const, "1.45.0", Some(58328)),
/// Allows the use of `#[ffi_pure]` on foreign functions.
(unstable, ffi_pure, "1.45.0", Some(58329)),
/// Experimental field projections.
(incomplete, field_projections, "CURRENT_RUSTC_VERSION", Some(145383)),
/// Controlling the behavior of fmt::Debug
(unstable, fmt_debug, "1.82.0", Some(129709)),
/// Allows using `#[align(...)]` on function items
Expand Down
10 changes: 10 additions & 0 deletions compiler/rustc_hir/src/hir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1729,6 +1729,12 @@ impl<'hir> Block<'hir> {
}
}

#[derive(Debug, Clone, Copy, HashStable_Generic)]
pub struct TyFieldPath {
pub variant: Option<Ident>,
pub field: Ident,
}

#[derive(Debug, Clone, Copy, HashStable_Generic)]
pub struct TyPat<'hir> {
#[stable_hasher(ignore)]
Expand Down Expand Up @@ -3773,6 +3779,10 @@ pub enum TyKind<'hir, Unambig = ()> {
Err(rustc_span::ErrorGuaranteed),
/// Pattern types (`pattern_type!(u32 is 1..)`)
Pat(&'hir Ty<'hir>, &'hir TyPat<'hir>),
/// Field representing type (`field_of!(Struct, field)`).
///
/// The optional ident is the variant when an enum is passed `field_of!(Enum, Variant.field)`.
FieldOf(&'hir Ty<'hir>, &'hir TyFieldPath),
/// `TyKind::Infer` means the type should be inferred instead of it having been
/// specified. This can appear anywhere in a type.
///
Expand Down
7 changes: 7 additions & 0 deletions compiler/rustc_hir/src/intravisit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1047,6 +1047,13 @@ pub fn walk_ty<'v, V: Visitor<'v>>(visitor: &mut V, typ: &'v Ty<'v, AmbigArg>) -
try_visit!(visitor.visit_ty_unambig(ty));
try_visit!(visitor.visit_pattern_type_pattern(pat));
}
TyKind::FieldOf(ty, TyFieldPath { variant, field }) => {
try_visit!(visitor.visit_ty_unambig(ty));
if let Some(variant) = *variant {
try_visit!(visitor.visit_ident(variant));
}
try_visit!(visitor.visit_ident(*field));
}
}
V::Result::output()
}
Expand Down
6 changes: 6 additions & 0 deletions compiler/rustc_hir/src/lang_items.rs
Original file line number Diff line number Diff line change
Expand Up @@ -448,6 +448,12 @@ language_item_table! {
// Reborrowing related lang-items
Reborrow, sym::reborrow, reborrow, Target::Trait, GenericRequirement::Exact(0);
CoerceShared, sym::coerce_shared, coerce_shared, Target::Trait, GenericRequirement::Exact(0);

// Field projection related lang-items
Field, sym::field, field, Target::Trait, GenericRequirement::Exact(0);
FieldBase, sym::field_base, field_base, Target::AssocTy, GenericRequirement::Exact(0);
FieldType, sym::field_type, field_type, Target::AssocTy, GenericRequirement::Exact(0);
FieldOffset, sym::field_offset, field_offset, Target::AssocConst, GenericRequirement::Exact(0);
}

/// The requirement imposed on the generics of a lang item
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_hir_analysis/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -376,6 +376,8 @@ hir_analysis_missing_trait_item_unstable = not all trait items implemented, miss
.some_note = use of unstable library feature `{$feature}`: {$reason}
.none_note = use of unstable library feature `{$feature}`

hir_analysis_no_field_on_type = no field `{$field}` on type `{$ty}`

hir_analysis_no_variant_named = no variant named `{$ident}` found for enum `{$ty}`

hir_analysis_not_supported_delegation = {$descr}
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_hir_analysis/src/check/intrinsic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ fn intrinsic_operation_unsafety(tcx: TyCtxt<'_>, intrinsic_id: LocalDefId) -> hi
| sym::fabsf128
| sym::fadd_algebraic
| sym::fdiv_algebraic
| sym::field_offset
| sym::floorf16
| sym::floorf32
| sym::floorf64
Expand Down Expand Up @@ -296,6 +297,7 @@ pub(crate) fn check_intrinsic_type(
(1, 0, vec![Ty::new_imm_ptr(tcx, param(0))], tcx.types.usize)
}
sym::offset_of => (1, 0, vec![tcx.types.u32, tcx.types.u32], tcx.types.usize),
sym::field_offset => (1, 0, vec![], tcx.types.usize),
sym::rustc_peek => (1, 0, vec![param(0)], param(0)),
sym::caller_location => (0, 0, vec![], tcx.caller_location_ty()),
sym::assert_inhabited | sym::assert_zero_valid | sym::assert_mem_uninitialized_valid => {
Expand Down
23 changes: 15 additions & 8 deletions compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use rustc_hir::find_attr;
use rustc_middle::bug;
use rustc_middle::ty::fast_reject::{SimplifiedType, TreatParams, simplify_type};
use rustc_middle::ty::{self, CrateInherentImpls, Ty, TyCtxt};
use rustc_span::ErrorGuaranteed;
use rustc_span::{ErrorGuaranteed, Span};

use crate::errors;

Expand Down Expand Up @@ -160,12 +160,16 @@ impl<'tcx> InherentCollect<'tcx> {
let id = id.owner_id.def_id;
let item_span = self.tcx.def_span(id);
let self_ty = self.tcx.type_of(id).instantiate_identity();
let mut self_ty = self.tcx.peel_off_free_alias_tys(self_ty);
// We allow impls on pattern types exactly when we allow impls on the base type.
// FIXME(pattern_types): Figure out the exact coherence rules we want here.
while let ty::Pat(base, _) = *self_ty.kind() {
self_ty = base;
}
let self_ty = self.tcx.peel_off_free_alias_tys(self_ty);
self.check_impl_self_ty(self_ty, id, item_span)
}

fn check_impl_self_ty(
&mut self,
self_ty: Ty<'tcx>,
id: LocalDefId,
item_span: Span,
) -> Result<(), ErrorGuaranteed> {
match *self_ty.kind() {
ty::Adt(def, _) => self.check_def_id(id, self_ty, def.did()),
ty::Foreign(did) => self.check_def_id(id, self_ty, did),
Expand All @@ -175,7 +179,10 @@ impl<'tcx> InherentCollect<'tcx> {
ty::Dynamic(..) => {
Err(self.tcx.dcx().emit_err(errors::InherentDyn { span: item_span }))
}
ty::Pat(_, _) => unreachable!(),
// We allow impls on pattern types exactly when we allow impls on the base type.
// FIXME(pattern_types): Figure out the exact coherence rules we want here.
ty::Pat(base, _) => self.check_impl_self_ty(base, id, item_span),
ty::FRT(ty, _) => self.check_impl_self_ty(ty, id, item_span),
ty::Bool
| ty::Char
| ty::Int(_)
Expand Down
4 changes: 4 additions & 0 deletions compiler/rustc_hir_analysis/src/coherence/orphan.rs
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,10 @@ pub(crate) fn orphan_check_impl(
NonlocalImpl::DisallowBecauseNonlocal
},
),
ty::FRT(..) => (
LocalImpl::Disallow { problematic_kind: "field representing type" },
NonlocalImpl::DisallowOther,
),

// extern { type OpaqueType; }
// impl AutoTrait for OpaqueType {}
Expand Down
Loading
Loading