Skip to content

Commit aeca9e4

Browse files
ShaddyDCdingxiangfei2009
authored andcommitted
implement k# raw_handle and place handles
Co-authored-by: Xiangfei Ding <dingxiangfei2009protonmail.ch> Signed-off-by: Rasmus Piorr <piorr@google.com> Signed-off-by: Xiangfei Ding <dingxiangfei2009@protonmail.ch>
1 parent d6ac639 commit aeca9e4

55 files changed

Lines changed: 1126 additions & 148 deletions

File tree

Some content is hidden

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

‎compiler/rustc_ast/src/ast.rs‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1612,6 +1612,7 @@ impl Expr {
16121612
| ExprKind::Match(..)
16131613
| ExprKind::MethodCall(..)
16141614
| ExprKind::OffsetOf(..)
1615+
| ExprKind::RawHandle(..)
16151616
| ExprKind::Paren(..)
16161617
| ExprKind::Path(..)
16171618
| ExprKind::Repeat(..)
@@ -1871,6 +1872,9 @@ pub enum ExprKind {
18711872
/// indirectly via the macro `core::mem::offset_of!(...)`.
18721873
OffsetOf(Box<Ty>, ThinVec<Ident>),
18731874

1875+
/// A `raw_handle` expression (e.g., `k#raw_handle(expr)`).
1876+
RawHandle(Box<Expr>),
1877+
18741878
/// A macro invocation; pre-expansion.
18751879
MacCall(Box<MacCall>),
18761880

‎compiler/rustc_ast/src/util/classify.rs‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,7 @@ pub fn leading_labeled_expr(mut expr: &ast::Expr) -> bool {
144144
| MacCall(..)
145145
| Match(_, _, MatchKind::Prefix)
146146
| OffsetOf(..)
147+
| RawHandle(..)
147148
| Paren(..)
148149
| Path(..)
149150
| Range(None, _, _)
@@ -218,7 +219,7 @@ pub fn expr_trailing_brace(mut expr: &ast::Expr) -> Option<TrailingBrace<'_>> {
218219
break (mac.args.delim == Delimiter::Brace).then_some(TrailingBrace::MacCall(mac));
219220
}
220221

221-
InlineAsm(_) | OffsetOf(_, _) | IncludedBytes(_) | FormatArgs(_) => {
222+
InlineAsm(_) | OffsetOf(_, _) | RawHandle(_) | IncludedBytes(_) | FormatArgs(_) => {
222223
// These should have been denied pre-expansion.
223224
break None;
224225
}

‎compiler/rustc_ast/src/visit.rs‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1101,6 +1101,8 @@ macro_rules! common_visitor_and_walkers {
11011101
visit_visitable!(vis, f),
11021102
ExprKind::OffsetOf(container, fields) =>
11031103
visit_visitable!(vis, container, fields),
1104+
ExprKind::RawHandle(subexpression) =>
1105+
visit_visitable!(vis, subexpression),
11041106
ExprKind::Yield(kind) =>
11051107
visit_visitable!(vis, kind),
11061108
ExprKind::Try(subexpression) =>

‎compiler/rustc_ast_lowering/src/diagnostics.rs‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,14 @@ pub(crate) struct UnderscoreExprLhsAssign {
112112
pub span: Span,
113113
}
114114

115+
#[derive(Diagnostic)]
116+
#[diag("cannot take address of a temporary", code = E0745)]
117+
pub(crate) struct AddressOfTemporaryTaken {
118+
#[primary_span]
119+
#[label("temporary value")]
120+
pub span: Span,
121+
}
122+
115123
#[derive(Diagnostic)]
116124
#[diag("`await` is only allowed inside `async` functions and blocks", code = E0728)]
117125
pub(crate) struct AwaitOnlyInAsyncFnAndBlocks {

‎compiler/rustc_ast_lowering/src/expr.rs‎

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,14 @@ use rustc_hir::def::{DefKind, Res};
1414
use rustc_middle::ty::TyCtxt;
1515
use rustc_session::diagnostics::report_lit_error;
1616
use rustc_span::{
17-
ByteSymbol, DUMMY_SP, DesugaringKind, Ident, Span, Spanned, Symbol, respan, span_bug, sym,
17+
ByteSymbol, DUMMY_SP, DesugaringKind, ErrorGuaranteed, Ident, Span, Spanned, Symbol, respan,
18+
span_bug, sym,
1819
};
1920
use thin_vec::ThinVec;
2021
mod closure;
2122

2223
use crate::diagnostics::{
23-
AsyncCoroutinesNotSupported, AwaitOnlyInAsyncFnAndBlocks,
24+
AddressOfTemporaryTaken, AsyncCoroutinesNotSupported, AwaitOnlyInAsyncFnAndBlocks,
2425
FunctionalRecordUpdateDestructuringAssignment, InclusiveRangeWithNoEnd,
2526
InvalidLegacyConstGenericArg, MatchArmWithNoBody, MoveExprOnlyInSupportedContexts,
2627
NestedMoveExprWithoutEnclosingContext, NeverPatternWithBody, NeverPatternWithGuard,
@@ -500,6 +501,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
500501
),
501502
self.arena.alloc_from_iter(fields.iter().map(|&ident| self.lower_ident(ident))),
502503
),
504+
ExprKind::RawHandle(place) => match self.lower_field_project(place) {
505+
Ok(fp) => hir::ExprKind::RawHandle(fp),
506+
Err(guar) => hir::ExprKind::Err(guar),
507+
},
503508
ExprKind::Struct(se) => {
504509
let rest = match se.rest {
505510
StructRest::Base(ref e) => hir::StructTailExpr::Base(self.lower_expr(e)),
@@ -553,6 +558,35 @@ impl<'hir> LoweringContext<'_, 'hir> {
553558
hir::Expr { hir_id: expr_hir_id, kind, span }
554559
}
555560

561+
fn lower_field_project(
562+
&mut self,
563+
e: &Expr,
564+
) -> Result<&'hir hir::FieldProject<'hir>, ErrorGuaranteed> {
565+
let kind = match &e.kind {
566+
ExprKind::Paren(inner) => return self.lower_field_project(inner),
567+
ExprKind::Path(qself, path) => hir::FieldProjectKind::Path(self.lower_qpath(
568+
e.id,
569+
qself,
570+
path,
571+
ParamMode::Optional,
572+
AllowReturnTypeNotation::No,
573+
ImplTraitContext::Disallowed(ImplTraitPosition::Path),
574+
None,
575+
)),
576+
ExprKind::Field(base, ident) => {
577+
let base = self.lower_field_project(base)?;
578+
hir::FieldProjectKind::Field(base, self.lower_ident(*ident))
579+
}
580+
ExprKind::Unary(UnOp::Deref, base) => {
581+
hir::FieldProjectKind::Deref(self.lower_field_project(base)?)
582+
}
583+
ExprKind::Err(guar) => return Err(*guar),
584+
_ => return Err(self.dcx().emit_err(AddressOfTemporaryTaken { span: e.span })),
585+
};
586+
let hir_id = self.lower_node_id(e.id);
587+
Ok(self.arena.alloc(hir::FieldProject { hir_id, kind, span: self.lower_span(e.span) }))
588+
}
589+
556590
pub(crate) fn lower_const_block(&mut self, c: &AnonConst) -> hir::ConstBlock {
557591
self.with_new_scopes(c.value.span, |this| {
558592
let def_id = this.local_def_id(c.id);

‎compiler/rustc_ast_lowering/src/index.rs‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -286,6 +286,13 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
286286
});
287287
}
288288

289+
fn visit_field_project(&mut self, fp: &'hir FieldProject<'hir>) {
290+
self.insert(fp.span, fp.hir_id, Node::FieldProject(fp));
291+
self.with_parent(fp.hir_id, |this| {
292+
intravisit::walk_field_project(this, fp);
293+
});
294+
}
295+
289296
fn visit_const_arg_expr_field(&mut self, field: &'hir ConstArgExprField<'hir>) {
290297
self.insert(field.span, field.hir_id, Node::ConstArgExprField(field));
291298
self.with_parent(field.hir_id, |this| {

‎compiler/rustc_ast_pretty/src/pprust/state/expr.rs‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -813,6 +813,14 @@ impl<'a> State<'a> {
813813
self.end(ib);
814814
self.pclose();
815815
}
816+
ast::ExprKind::RawHandle(expr) => {
817+
self.word("k#raw_handle");
818+
self.popen();
819+
let ib = self.ibox(0);
820+
self.print_expr(expr, FixupContext::default());
821+
self.end(ib);
822+
self.pclose();
823+
}
816824
ast::ExprKind::MacCall(m) => self.print_mac(m),
817825
ast::ExprKind::Paren(e) => {
818826
self.popen();

‎compiler/rustc_attr_ir/src/lang_items.rs‎

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -466,6 +466,15 @@ language_item_table! {
466466
FieldType, sym::field_type, field_type, Target::AssocTy(AssocCtxt::Trait), GenericRequirement::Exact(0);
467467
FieldOffset, sym::field_offset, field_offset, Target::AssocConst(AssocCtxt::Trait), GenericRequirement::Exact(0);
468468

469+
// Place handles.
470+
LocalHandle, sym::local_handle, local_handle, Target::Struct, GenericRequirement::Exact(1);
471+
DerefPlace, sym::deref_place, deref_place_trait, Target::Trait, GenericRequirement::Exact(0);
472+
DerefPlacePointeeHandle, sym::deref_place_pointee_handle, deref_place_pointee_handle, Target::AssocTy(AssocCtxt::Trait), GenericRequirement::None;
473+
DerefPlaceDerefPlace, sym::deref_place_deref_place, deref_place_deref_place, Target::Method(MethodKind::Trait { body: false }), GenericRequirement::None;
474+
ProjectPlace, sym::project_place, project_place_trait, Target::Trait, GenericRequirement::Exact(1);
475+
ProjectPlaceProjected, sym::project_place_projected, project_place_projected, Target::AssocTy(AssocCtxt::Trait), GenericRequirement::None;
476+
ProjectPlaceProjectPlace, sym::project_place_project_place, project_place_project_place, Target::Method(MethodKind::Trait { body: false }), GenericRequirement::None;
477+
469478
// Used to fallback `{float}` to `f32` when `f32: From<{float}>`
470479
From, sym::From, from_trait, Target::Trait, GenericRequirement::Exact(1);
471480
FromFn, sym::from, from_fn, Target::Method(MethodKind::Trait { body: false }), GenericRequirement::None;

‎compiler/rustc_builtin_macros/src/assert/context.rs‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,7 @@ impl<'cx, 'a> Context<'cx, 'a> {
310310
| ExprKind::Loop(_, _, _)
311311
| ExprKind::MacCall(_)
312312
| ExprKind::OffsetOf(_, _)
313+
| ExprKind::RawHandle(..)
313314
| ExprKind::Path(_, _)
314315
| ExprKind::Ret(_)
315316
| ExprKind::Try(_)

‎compiler/rustc_hir/src/hir.rs‎

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2266,6 +2266,7 @@ impl Expr<'_> {
22662266
| ExprKind::Match(..)
22672267
| ExprKind::MethodCall(..)
22682268
| ExprKind::OffsetOf(..)
2269+
| ExprKind::RawHandle(..)
22692270
| ExprKind::Path(..)
22702271
| ExprKind::Repeat(..)
22712272
| ExprKind::Struct(..)
@@ -2338,6 +2339,7 @@ impl Expr<'_> {
23382339
| ExprKind::Assign(..)
23392340
| ExprKind::InlineAsm(..)
23402341
| ExprKind::OffsetOf(..)
2342+
| ExprKind::RawHandle(..)
23412343
| ExprKind::AssignOp(..)
23422344
| ExprKind::Lit(_)
23432345
| ExprKind::ConstBlock(..)
@@ -2429,6 +2431,7 @@ impl Expr<'_> {
24292431
| ExprKind::Become(_)
24302432
| ExprKind::InlineAsm(_)
24312433
| ExprKind::OffsetOf(..)
2434+
| ExprKind::RawHandle(..)
24322435
| ExprKind::Struct(..)
24332436
| ExprKind::Repeat(..)
24342437
| ExprKind::Yield(..)
@@ -2486,9 +2489,11 @@ impl Expr<'_> {
24862489

24872490
pub fn can_have_side_effects(&self) -> bool {
24882491
match self.peel_drop_temps().kind {
2489-
ExprKind::Path(_) | ExprKind::Lit(_) | ExprKind::OffsetOf(..) | ExprKind::Use(..) => {
2490-
false
2491-
}
2492+
ExprKind::Path(_)
2493+
| ExprKind::Lit(_)
2494+
| ExprKind::OffsetOf(..)
2495+
| ExprKind::RawHandle(..)
2496+
| ExprKind::Use(..) => false,
24922497
ExprKind::Type(base, _)
24932498
| ExprKind::Unary(_, base)
24942499
| ExprKind::Field(base, _)
@@ -2654,6 +2659,21 @@ pub fn expr_needs_parens(expr: &Expr<'_>) -> bool {
26542659
}
26552660
}
26562661

2662+
#[derive(Debug, Clone, Copy, StableHash)]
2663+
pub struct FieldProject<'hir> {
2664+
#[stable_hash(ignore)]
2665+
pub hir_id: HirId,
2666+
pub kind: FieldProjectKind<'hir>,
2667+
pub span: Span,
2668+
}
2669+
2670+
#[derive(Debug, Clone, Copy, StableHash)]
2671+
pub enum FieldProjectKind<'hir> {
2672+
Path(QPath<'hir>),
2673+
Field(&'hir FieldProject<'hir>, Ident),
2674+
Deref(&'hir FieldProject<'hir>),
2675+
}
2676+
26572677
#[derive(Debug, Clone, Copy, StableHash)]
26582678
pub enum ExprKind<'hir> {
26592679
/// Allow anonymous constants from an inline `const` block
@@ -2770,6 +2790,9 @@ pub enum ExprKind<'hir> {
27702790
/// Field offset (`offset_of!`)
27712791
OffsetOf(&'hir Ty<'hir>, &'hir [Ident]),
27722792

2793+
/// Raw place handle (`raw_handle!`)
2794+
RawHandle(&'hir FieldProject<'hir>),
2795+
27732796
/// A struct or struct-like variant literal expression.
27742797
///
27752798
/// E.g., `Foo {x: 1, y: 2}`, or `Foo {x: 1, .. base}`,
@@ -5050,6 +5073,7 @@ pub enum Node<'hir> {
50505073
ConstBlock(&'hir ConstBlock),
50515074
ConstArg(&'hir ConstArg<'hir>),
50525075
Expr(&'hir Expr<'hir>),
5076+
FieldProject(&'hir FieldProject<'hir>),
50535077
ExprField(&'hir ExprField<'hir>),
50545078
ConstArgExprField(&'hir ConstArgExprField<'hir>),
50555079
Stmt(&'hir Stmt<'hir>),
@@ -5122,6 +5146,7 @@ impl<'hir> Node<'hir> {
51225146
| Node::ConstBlock(..)
51235147
| Node::ConstArg(..)
51245148
| Node::Expr(..)
5149+
| Node::FieldProject(..)
51255150
| Node::Stmt(..)
51265151
| Node::Block(..)
51275152
| Node::Ctor(..)
@@ -5322,6 +5347,7 @@ impl<'hir> Node<'hir> {
53225347
match self {
53235348
Node::Ty(Ty { kind: TyKind::Path(path), .. })
53245349
| Node::Expr(Expr { kind: ExprKind::Path(path), .. })
5350+
| Node::FieldProject(FieldProject { kind: FieldProjectKind::Path(path), .. })
53255351
| Node::PatExpr(PatExpr { kind: PatExprKind::Path(path), .. }) => Some(path),
53265352
_ => None,
53275353
}
@@ -5338,6 +5364,7 @@ impl<'hir> Node<'hir> {
53385364
expect_anon_const, &'hir AnonConst, Node::AnonConst(n), n;
53395365
expect_inline_const, &'hir ConstBlock, Node::ConstBlock(n), n;
53405366
expect_expr, &'hir Expr<'hir>, Node::Expr(n), n;
5367+
expect_field_project, &'hir FieldProject<'hir>, Node::FieldProject(n), n;
53415368
expect_expr_field, &'hir ExprField<'hir>, Node::ExprField(n), n;
53425369
expect_stmt, &'hir Stmt<'hir>, Node::Stmt(n), n;
53435370
expect_path_segment, &'hir PathSegment<'hir>, Node::PathSegment(n), n;
@@ -5370,6 +5397,8 @@ mod size_asserts {
53705397
static_assert_size!(Body<'_>, 24);
53715398
static_assert_size!(Expr<'_>, 64);
53725399
static_assert_size!(ExprKind<'_>, 48);
5400+
static_assert_size!(FieldProject<'_>, 48);
5401+
static_assert_size!(FieldProjectKind<'_>, 32);
53735402
static_assert_size!(FnDecl<'_>, 40);
53745403
static_assert_size!(ForeignItem<'_>, 88);
53755404
static_assert_size!(ForeignItemKind<'_>, 56);

0 commit comments

Comments
 (0)