Skip to content

Commit 7f6749b

Browse files
committed
view types: actually store view types in the AST
1 parent 0b5cef2 commit 7f6749b

26 files changed

Lines changed: 291 additions & 168 deletions

File tree

compiler/rustc_ast/src/ast.rs

Lines changed: 47 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -646,8 +646,10 @@ impl Pat {
646646
PatKind::MacCall(mac) => TyKind::MacCall(mac.clone()),
647647
// `&mut? P` can be reinterpreted as `&mut? T` where `T` is `P` reparsed as a type.
648648
PatKind::Ref(pat, pinned, mutbl) => pat.to_ty().map(|ty| match pinned {
649-
Pinnedness::Not => TyKind::Ref(None, MutTy { ty, mutbl: *mutbl }),
650-
Pinnedness::Pinned => TyKind::PinnedRef(None, MutTy { ty, mutbl: *mutbl }),
649+
Pinnedness::Not => TyKind::Ref(None, MutTy { ty, mutbl: *mutbl }, ViewKind::Full),
650+
Pinnedness::Pinned => {
651+
TyKind::PinnedRef(None, MutTy { ty, mutbl: *mutbl }, ViewKind::Full)
652+
}
651653
})?,
652654
// A slice/array pattern `[P]` can be reparsed as `[T]`, an unsized array,
653655
// when `P` can be reparsed as a type `T`.
@@ -1510,9 +1512,9 @@ impl Expr {
15101512

15111513
ExprKind::Paren(expr) => expr.to_ty().map(TyKind::Paren)?,
15121514

1513-
ExprKind::AddrOf(BorrowKind::Ref, mutbl, expr) => {
1514-
expr.to_ty().map(|ty| TyKind::Ref(None, MutTy { ty, mutbl: *mutbl }))?
1515-
}
1515+
ExprKind::AddrOf(BorrowKind::Ref, mutbl, expr) => expr
1516+
.to_ty()
1517+
.map(|ty| TyKind::Ref(None, MutTy { ty, mutbl: *mutbl }, ViewKind::Full))?,
15161518

15171519
ExprKind::Repeat(expr, expr_len) => {
15181520
expr.to_ty().map(|ty| TyKind::Array(ty, expr_len.clone()))?
@@ -2473,7 +2475,8 @@ impl From<Box<Ty>> for Ty {
24732475
impl Ty {
24742476
pub fn peel_refs(&self) -> &Self {
24752477
let mut final_ty = self;
2476-
while let TyKind::Ref(_, MutTy { ty, .. }) | TyKind::Ptr(MutTy { ty, .. }) = &final_ty.kind
2478+
while let TyKind::Ref(_, MutTy { ty, .. }, _) | TyKind::Ptr(MutTy { ty, .. }) =
2479+
&final_ty.kind
24772480
{
24782481
final_ty = ty;
24792482
}
@@ -2518,11 +2521,11 @@ pub enum TyKind {
25182521
/// A raw pointer (`*const T` or `*mut T`).
25192522
Ptr(MutTy),
25202523
/// A reference (`&'a T` or `&'a mut T`).
2521-
Ref(#[visitable(extra = LifetimeCtxt::Ref)] Option<Lifetime>, MutTy),
2524+
Ref(#[visitable(extra = LifetimeCtxt::Ref)] Option<Lifetime>, MutTy, ViewKind),
25222525
/// A pinned reference (`&'a pin const T` or `&'a pin mut T`).
25232526
///
25242527
/// Desugars into `Pin<&'a T>` or `Pin<&'a mut T>`.
2525-
PinnedRef(#[visitable(extra = LifetimeCtxt::Ref)] Option<Lifetime>, MutTy),
2528+
PinnedRef(#[visitable(extra = LifetimeCtxt::Ref)] Option<Lifetime>, MutTy, ViewKind),
25262529
/// A function pointer type (e.g., `fn(usize) -> bool`).
25272530
FnPtr(Box<FnPtrTy>),
25282531
/// An unsafe existential lifetime binder (e.g., `unsafe<'a> &'a ()`).
@@ -2660,6 +2663,19 @@ pub enum TraitObjectSyntax {
26602663
None = 1,
26612664
}
26622665

2666+
/// Represents how a reference is viewed.
2667+
#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
2668+
pub enum ViewKind {
2669+
/// `&mut T`. All the fields can be observed.
2670+
Full,
2671+
/// `&mut T.{ foo, bar }`. Only `foo` and `bar` can be observed.
2672+
Partial {
2673+
span: Span,
2674+
#[visitable(ignore)]
2675+
fields: ThinVec<Ident>,
2676+
},
2677+
}
2678+
26632679
/// SAFETY: `TraitObjectSyntax` only has 3 data-less variants which means
26642680
/// it can be represented with a `u2`. We use `repr(u8)` to guarantee the
26652681
/// discriminants of the variants are no greater than `3`.
@@ -2933,21 +2949,21 @@ pub struct Param {
29332949
pub enum SelfKind {
29342950
/// `self`, `mut self`
29352951
Value(Mutability),
2936-
/// `&'lt self`, `&'lt mut self`
2937-
Region(Option<Lifetime>, Mutability),
2938-
/// `&'lt pin const self`, `&'lt pin mut self`
2939-
Pinned(Option<Lifetime>, Mutability),
2952+
/// `&'lt self`, `&'lt mut self`, `&'lt mut self.{ a, b }`
2953+
Region(Option<Lifetime>, Mutability, ViewKind),
2954+
/// `&'lt pin const self`, `&'lt pin mut self`, `&'lt pin mut self.{ a, b }`.
2955+
Pinned(Option<Lifetime>, Mutability, ViewKind),
29402956
/// `self: TYPE`, `mut self: TYPE`
29412957
Explicit(Box<Ty>, Mutability),
29422958
}
29432959

29442960
impl SelfKind {
29452961
pub fn to_ref_suggestion(&self) -> String {
29462962
match self {
2947-
SelfKind::Region(None, mutbl) => mutbl.ref_prefix_str().to_string(),
2948-
SelfKind::Region(Some(lt), mutbl) => format!("&{lt} {}", mutbl.prefix_str()),
2949-
SelfKind::Pinned(None, mutbl) => format!("&pin {}", mutbl.ptr_str()),
2950-
SelfKind::Pinned(Some(lt), mutbl) => format!("&{lt} pin {}", mutbl.ptr_str()),
2963+
SelfKind::Region(None, mutbl, _) => mutbl.ref_prefix_str().to_string(),
2964+
SelfKind::Region(Some(lt), mutbl, _) => format!("&{lt} {}", mutbl.prefix_str()),
2965+
SelfKind::Pinned(None, mutbl, _) => format!("&pin {}", mutbl.ptr_str()),
2966+
SelfKind::Pinned(Some(lt), mutbl, _) => format!("&{lt} pin {}", mutbl.ptr_str()),
29512967
SelfKind::Value(_) | SelfKind::Explicit(_, _) => {
29522968
unreachable!("if we had an explicit self, we wouldn't be here")
29532969
}
@@ -2964,13 +2980,18 @@ impl Param {
29642980
if ident.name == kw::SelfLower {
29652981
return match self.ty.kind {
29662982
TyKind::ImplicitSelf => Some(respan(self.pat.span, SelfKind::Value(mutbl))),
2967-
TyKind::Ref(lt, MutTy { ref ty, mutbl }) if ty.kind.is_implicit_self() => {
2968-
Some(respan(self.pat.span, SelfKind::Region(lt, mutbl)))
2983+
TyKind::Ref(lt, MutTy { ref ty, mutbl }, ref view_fields)
2984+
if ty.kind.is_implicit_self() =>
2985+
{
2986+
Some(respan(
2987+
self.pat.span,
2988+
SelfKind::Region(lt, mutbl, view_fields.clone()),
2989+
))
29692990
}
2970-
TyKind::PinnedRef(lt, MutTy { ref ty, mutbl })
2991+
TyKind::PinnedRef(lt, MutTy { ref ty, mutbl }, ref view)
29712992
if ty.kind.is_implicit_self() =>
29722993
{
2973-
Some(respan(self.pat.span, SelfKind::Pinned(lt, mutbl)))
2994+
Some(respan(self.pat.span, SelfKind::Pinned(lt, mutbl, view.clone())))
29742995
}
29752996
_ => Some(respan(
29762997
self.pat.span.to(self.ty.span),
@@ -3003,20 +3024,20 @@ impl Param {
30033024
let (mutbl, ty) = match eself.node {
30043025
SelfKind::Explicit(ty, mutbl) => (mutbl, ty),
30053026
SelfKind::Value(mutbl) => (mutbl, infer_ty),
3006-
SelfKind::Region(lt, mutbl) => (
3027+
SelfKind::Region(lt, mutbl, views) => (
30073028
Mutability::Not,
30083029
Box::new(Ty {
30093030
id: DUMMY_NODE_ID,
3010-
kind: TyKind::Ref(lt, MutTy { ty: infer_ty, mutbl }),
3031+
kind: TyKind::Ref(lt, MutTy { ty: infer_ty, mutbl }, views),
30113032
span,
30123033
tokens: None,
30133034
}),
30143035
),
3015-
SelfKind::Pinned(lt, mutbl) => (
3036+
SelfKind::Pinned(lt, mutbl, view) => (
30163037
mutbl,
30173038
Box::new(Ty {
30183039
id: DUMMY_NODE_ID,
3019-
kind: TyKind::PinnedRef(lt, MutTy { ty: infer_ty, mutbl }),
3040+
kind: TyKind::PinnedRef(lt, MutTy { ty: infer_ty, mutbl }, view),
30203041
span,
30213042
tokens: None,
30223043
}),
@@ -4340,7 +4361,7 @@ mod size_asserts {
43404361
static_assert_size!(Stmt, 32);
43414362
static_assert_size!(StmtKind, 16);
43424363
static_assert_size!(TraitImplHeader, 72);
4343-
static_assert_size!(Ty, 64);
4344-
static_assert_size!(TyKind, 40);
4364+
static_assert_size!(Ty, 80);
4365+
static_assert_size!(TyKind, 56);
43454366
// tidy-alphabetical-end
43464367
}

compiler/rustc_ast/src/util/classify.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
//! Routines the parser and pretty-printer use to classify AST nodes.
22
3+
use crate::ViewKind;
34
use crate::ast::ExprKind::*;
45
use crate::ast::{self, MatchKind};
56
use crate::token::Delimiter;
@@ -252,15 +253,18 @@ fn type_trailing_braced_mac_call(mut ty: &ast::Ty) -> Option<&ast::MacCall> {
252253
loop {
253254
match &ty.kind {
254255
ast::TyKind::MacCall(mac) => {
255-
break (mac.args.delim == Delimiter::Brace).then_some(mac);
256+
break (mac.args.delim == Delimiter::Brace).then_some(mac.as_ref());
256257
}
257258

258259
ast::TyKind::Ptr(mut_ty)
259-
| ast::TyKind::Ref(_, mut_ty)
260-
| ast::TyKind::PinnedRef(_, mut_ty) => {
260+
| ast::TyKind::Ref(_, mut_ty, ViewKind::Full)
261+
| ast::TyKind::PinnedRef(_, mut_ty, ViewKind::Full) => {
261262
ty = &mut_ty.ty;
262263
}
263264

265+
ast::TyKind::Ref(_, _, ViewKind::Partial { .. })
266+
| ast::TyKind::PinnedRef(_, _, ViewKind::Partial { .. }) => break None,
267+
264268
ast::TyKind::UnsafeBinder(binder) => {
265269
ty = &binder.inner_ty;
266270
}

compiler/rustc_ast/src/visit.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -486,6 +486,7 @@ macro_rules! common_visitor_and_walkers {
486486
UnsafeBinderTy,
487487
UnsafeSource,
488488
UseTreeKind,
489+
ViewKind,
489490
VisibilityKind,
490491
WhereBoundPredicate,
491492
WhereClause,

compiler/rustc_ast_lowering/src/lib.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1413,11 +1413,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
14131413
TyKind::Err(guar) => hir::TyKind::Err(*guar),
14141414
TyKind::Slice(ty) => hir::TyKind::Slice(self.lower_ty_alloc(ty, itctx)),
14151415
TyKind::Ptr(mt) => hir::TyKind::Ptr(self.lower_mt(mt, itctx)),
1416-
TyKind::Ref(region, mt) => {
1416+
TyKind::Ref(region, mt, _) => {
14171417
let lifetime = self.lower_ty_direct_lifetime(t, *region);
14181418
hir::TyKind::Ref(lifetime, self.lower_mt(mt, itctx))
14191419
}
1420-
TyKind::PinnedRef(region, mt) => {
1420+
TyKind::PinnedRef(region, mt, _) => {
14211421
let lifetime = self.lower_ty_direct_lifetime(t, *region);
14221422
let kind = hir::TyKind::Ref(lifetime, self.lower_mt(mt, itctx));
14231423
let span = self.lower_span(t.span);
@@ -1841,7 +1841,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
18411841
// Given we are only considering `ImplicitSelf` types, we needn't consider
18421842
// the case where we have a mutable pattern to a reference as that would
18431843
// no longer be an `ImplicitSelf`.
1844-
TyKind::Ref(_, mt) | TyKind::PinnedRef(_, mt)
1844+
TyKind::Ref(_, mt, _) | TyKind::PinnedRef(_, mt, _)
18451845
if mt.ty.kind.is_implicit_self() =>
18461846
{
18471847
match mt.mutbl {

compiler/rustc_ast_pretty/src/pprust/state.rs

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ use rustc_ast::util::comments::{Comment, CommentStyle};
1717
use rustc_ast::{
1818
self as ast, AttrArgs, BindingMode, BlockCheckMode, ByRef, DelimArgs, GenericArg, GenericBound,
1919
InlineAsmOperand, InlineAsmOptions, InlineAsmRegOrRegClass, InlineAsmTemplatePiece, PatKind,
20-
RangeEnd, RangeSyntax, Safety, SelfKind, Term, attr,
20+
RangeEnd, RangeSyntax, Safety, SelfKind, Term, ViewKind, attr,
2121
};
2222
use rustc_span::edition::Edition;
2323
use rustc_span::source_map::SourceMap;
@@ -1255,6 +1255,15 @@ impl<'a> State<'a> {
12551255
}
12561256
}
12571257

1258+
fn print_view(&mut self, view: &ViewKind) {
1259+
if let ViewKind::Partial { fields, .. } = view {
1260+
self.word_space(".{");
1261+
self.commasep(Breaks::Inconsistent, fields, |s, field| {
1262+
s.print_ident(*field);
1263+
});
1264+
}
1265+
}
1266+
12581267
pub fn print_assoc_item_constraint(&mut self, constraint: &ast::AssocItemConstraint) {
12591268
self.print_ident(constraint.ident);
12601269
if let Some(args) = constraint.gen_args.as_ref() {
@@ -1333,16 +1342,18 @@ impl<'a> State<'a> {
13331342
self.word("*");
13341343
self.print_mt(mt, true);
13351344
}
1336-
ast::TyKind::Ref(lifetime, mt) => {
1345+
ast::TyKind::Ref(lifetime, mt, view) => {
13371346
self.word("&");
13381347
self.print_opt_lifetime(lifetime);
13391348
self.print_mt(mt, false);
1349+
self.print_view(view);
13401350
}
1341-
ast::TyKind::PinnedRef(lifetime, mt) => {
1351+
ast::TyKind::PinnedRef(lifetime, mt, view) => {
13421352
self.word("&");
13431353
self.print_opt_lifetime(lifetime);
13441354
self.word("pin ");
13451355
self.print_mt(mt, true);
1356+
self.print_view(view);
13461357
}
13471358
ast::TyKind::Never => {
13481359
self.word("!");
@@ -2056,26 +2067,28 @@ impl<'a> State<'a> {
20562067
match &explicit_self.node {
20572068
SelfKind::Value(m) => {
20582069
self.print_mutability(*m, false);
2059-
self.word("self")
2070+
self.word("self");
20602071
}
2061-
SelfKind::Region(lt, m) => {
2072+
SelfKind::Region(lt, m, view) => {
20622073
self.word("&");
20632074
self.print_opt_lifetime(lt);
20642075
self.print_mutability(*m, false);
2065-
self.word("self")
2076+
self.word("self");
2077+
self.print_view(view);
20662078
}
2067-
SelfKind::Pinned(lt, m) => {
2079+
SelfKind::Pinned(lt, m, view) => {
20682080
self.word("&");
20692081
self.print_opt_lifetime(lt);
20702082
self.word("pin ");
20712083
self.print_mutability(*m, true);
2072-
self.word("self")
2084+
self.word("self");
2085+
self.print_view(view);
20732086
}
20742087
SelfKind::Explicit(typ, m) => {
20752088
self.print_mutability(*m, false);
20762089
self.word("self");
20772090
self.word_space(":");
2078-
self.print_type(typ)
2091+
self.print_type(typ);
20792092
}
20802093
}
20812094
}

compiler/rustc_builtin_macros/src/autodiff.rs

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -487,7 +487,7 @@ mod llvm_enzyme {
487487
TyKind::Ptr(ref mut mut_ty) => {
488488
mut_ty.mutbl = ast::Mutability::Mut;
489489
}
490-
TyKind::Ref(_, ref mut mut_ty) => {
490+
TyKind::Ref(_, ref mut mut_ty, _) => {
491491
mut_ty.mutbl = ast::Mutability::Mut;
492492
}
493493
_ => {
@@ -521,10 +521,15 @@ mod llvm_enzyme {
521521
.map(|param| {
522522
let ty = match &param.ty.kind {
523523
TyKind::ImplicitSelf => self_ty(),
524-
TyKind::Ref(lt, mt) if matches!(mt.ty.kind, TyKind::ImplicitSelf) => ecx.ty(
525-
span,
526-
TyKind::Ref(lt.clone(), ast::MutTy { ty: self_ty(), mutbl: mt.mutbl }),
527-
),
524+
TyKind::Ref(lt, mt, view) if matches!(mt.ty.kind, TyKind::ImplicitSelf) => ecx
525+
.ty(
526+
span,
527+
TyKind::Ref(
528+
lt.clone(),
529+
ast::MutTy { ty: self_ty(), mutbl: mt.mutbl },
530+
view.clone(),
531+
),
532+
),
528533
TyKind::Ptr(mt) if matches!(mt.ty.kind, TyKind::ImplicitSelf) => {
529534
ecx.ty(span, TyKind::Ptr(ast::MutTy { ty: self_ty(), mutbl: mt.mutbl }))
530535
}

compiler/rustc_builtin_macros/src/deriving/debug.rs

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use rustc_ast::{self as ast, EnumDef, MetaItem, Safety};
1+
use rustc_ast::{self as ast, EnumDef, MetaItem, Safety, ViewKind};
22
use rustc_expand::base::{Annotatable, ExtCtxt};
33
use rustc_session::config::FmtDebug;
44
use rustc_span::{Ident, Span, Symbol, sym};
@@ -152,7 +152,8 @@ fn show_substructure(cx: &ExtCtxt<'_>, span: Span, substr: &Substructure<'_>) ->
152152
// `let names: &'static _ = &["field1", "field2"];`
153153
let names_let = is_struct.then(|| {
154154
let lt_static = Some(cx.lifetime_static(span));
155-
let ty_static_ref = cx.ty_ref(span, cx.ty_infer(span), lt_static, ast::Mutability::Not);
155+
let ty_static_ref =
156+
cx.ty_ref(span, cx.ty_infer(span), lt_static, ast::Mutability::Not, ViewKind::Full);
156157
cx.stmt_let_ty(
157158
span,
158159
false,
@@ -173,13 +174,19 @@ fn show_substructure(cx: &ExtCtxt<'_>, span: Span, substr: &Substructure<'_>) ->
173174
);
174175
let ty_slice = cx.ty(
175176
span,
176-
ast::TyKind::Slice(cx.ty_ref(span, ty_dyn_debug, None, ast::Mutability::Not)),
177+
ast::TyKind::Slice(cx.ty_ref(
178+
span,
179+
ty_dyn_debug,
180+
None,
181+
ast::Mutability::Not,
182+
ViewKind::Full,
183+
)),
177184
);
178185
let values_let = cx.stmt_let_ty(
179186
span,
180187
false,
181188
Ident::new(sym::values, span),
182-
Some(cx.ty_ref(span, ty_slice, None, ast::Mutability::Not)),
189+
Some(cx.ty_ref(span, ty_slice, None, ast::Mutability::Not, ViewKind::Full)),
183190
cx.expr_array_ref(span, value_exprs),
184191
);
185192

compiler/rustc_builtin_macros/src/deriving/generic/ty.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@
22
//! when specifying impls to be derived.
33
44
pub(crate) use Ty::*;
5-
use rustc_ast::{self as ast, Expr, GenericArg, GenericParamKind, Generics, SelfKind, TyKind};
5+
use rustc_ast::{
6+
self as ast, Expr, GenericArg, GenericParamKind, Generics, SelfKind, TyKind, ViewKind,
7+
};
68
use rustc_expand::base::ExtCtxt;
79
use rustc_span::{DUMMY_SP, Ident, Span, Symbol, kw, respan};
810
use thin_vec::ThinVec;
@@ -94,7 +96,7 @@ impl Ty {
9496
match self {
9597
Ref(ty, mutbl) => {
9698
let raw_ty = ty.to_ty(cx, span, self_ty, self_generics);
97-
cx.ty_ref(span, raw_ty, None, *mutbl)
99+
cx.ty_ref(span, raw_ty, None, *mutbl, ViewKind::Full)
98100
}
99101
Path(p) => p.to_ty(cx, span, self_ty, self_generics),
100102
Self_ => cx.ty_path(self.to_path(cx, span, self_ty, self_generics)),
@@ -200,6 +202,6 @@ impl Bounds {
200202
pub(crate) fn get_explicit_self(cx: &ExtCtxt<'_>, span: Span) -> (Box<Expr>, ast::ExplicitSelf) {
201203
// This constructs a fresh `self` path.
202204
let self_path = cx.expr_self(span);
203-
let self_ty = respan(span, SelfKind::Region(None, ast::Mutability::Not));
205+
let self_ty = respan(span, SelfKind::Region(None, ast::Mutability::Not, ViewKind::Full));
204206
(self_path, self_ty)
205207
}

0 commit comments

Comments
 (0)