-
-
Notifications
You must be signed in to change notification settings - Fork 14.9k
view-types: store borrows of view types in the AST #156016
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2480,6 +2480,23 @@ impl Ty { | |
| final_ty | ||
| } | ||
|
|
||
| pub fn extract_view(&self) -> Option<(Self, &[Ident])> { | ||
| match &self.kind { | ||
| TyKind::View(inner, fields) => Some((*inner.clone(), fields)), | ||
|
|
||
| TyKind::Ref(lifetime, MutTy { ty, mutbl }) => { | ||
| let (inner, fields) = ty.extract_view()?; | ||
| let kind = | ||
| TyKind::Ref(*lifetime, MutTy { ty: Box::new(inner.clone()), mutbl: *mutbl }); | ||
| let ty = Ty { id: self.id, kind, span: self.span, tokens: self.tokens.clone() }; | ||
|
|
||
| Some((ty, fields)) | ||
| } | ||
|
|
||
| _ => None, | ||
| } | ||
| } | ||
|
|
||
| pub fn is_maybe_parenthesised_infer(&self) -> bool { | ||
| match &self.kind { | ||
| TyKind::Infer => true, | ||
|
|
@@ -2565,6 +2582,8 @@ pub enum TyKind { | |
| /// Usually not written directly in user code but indirectly via the macro | ||
| /// `core::field::field_of!(...)`. | ||
| FieldOf(Box<Ty>, Option<Ident>, Ident), | ||
| /// A view of a type. `T.{ field_1, field_2 }`. | ||
| View(Box<Ty>, #[visitable(ignore)] ThinVec<Ident>), | ||
| /// Sometimes we need a dummy value when no error has occurred. | ||
| Dummy, | ||
| /// Placeholder for a kind that has failed to be defined. | ||
|
|
@@ -2660,6 +2679,20 @@ pub enum TraitObjectSyntax { | |
| None = 1, | ||
| } | ||
|
|
||
| /// Represents how a reference is viewed. | ||
| // FIXME(scrabsha): move this to a new variant of `Mutability` when viewing of non-reference types | ||
| // is implemented. | ||
| #[derive(Clone, Encodable, Decodable, Debug, Walkable)] | ||
| pub enum ViewKind { | ||
| /// `&mut T`. All the fields can be observed. | ||
| Full, | ||
| /// `&mut T.{ foo, bar }`. Only `foo` and `bar` can be observed. | ||
|
Comment on lines
+2687
to
+2689
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. the |
||
| Partial { | ||
| #[visitable(ignore)] | ||
| fields: ThinVec<Ident>, | ||
| }, | ||
| } | ||
|
|
||
| /// SAFETY: `TraitObjectSyntax` only has 3 data-less variants which means | ||
| /// it can be represented with a `u2`. We use `repr(u8)` to guarantee the | ||
| /// discriminants of the variants are no greater than `3`. | ||
|
|
@@ -2929,13 +2962,19 @@ pub struct Param { | |
| /// Alternative representation for `Arg`s describing `self` parameter of methods. | ||
| /// | ||
| /// E.g., `&mut self` as in `fn foo(&mut self)`. | ||
| #[derive(Clone, Encodable, Decodable, Debug)] | ||
| pub struct SelfParam { | ||
| pub kind: SelfKind, | ||
| pub view: ViewKind, | ||
| } | ||
|
|
||
| #[derive(Clone, Encodable, Decodable, Debug)] | ||
| pub enum SelfKind { | ||
| /// `self`, `mut self` | ||
| Value(Mutability), | ||
| /// `&'lt self`, `&'lt mut self` | ||
| /// `&'lt self`, `&'lt mut self`, `&'lt mut self.{ a, b }` | ||
| Region(Option<Lifetime>, Mutability), | ||
| /// `&'lt pin const self`, `&'lt pin mut self` | ||
| /// `&'lt pin const self`, `&'lt pin mut self`, `&'lt pin mut self.{ a, b }`. | ||
|
Comment on lines
+2975
to
+2977
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. the comments can be reverted, the view is not stored here anymore |
||
| Pinned(Option<Lifetime>, Mutability), | ||
| /// `self: TYPE`, `mut self: TYPE` | ||
| Explicit(Box<Ty>, Mutability), | ||
|
|
@@ -2955,28 +2994,35 @@ impl SelfKind { | |
| } | ||
| } | ||
|
|
||
| pub type ExplicitSelf = Spanned<SelfKind>; | ||
| pub type ExplicitSelf = Spanned<SelfParam>; | ||
|
|
||
| impl Param { | ||
| /// Attempts to cast parameter to `ExplicitSelf`. | ||
| pub fn to_self(&self) -> Option<ExplicitSelf> { | ||
| if let PatKind::Ident(BindingMode(ByRef::No, mutbl), ident, _) = self.pat.kind { | ||
| if ident.name == kw::SelfLower { | ||
| return match self.ty.kind { | ||
| TyKind::ImplicitSelf => Some(respan(self.pat.span, SelfKind::Value(mutbl))), | ||
| let (ty, view) = match self.ty.extract_view() { | ||
| Some((this, fields)) => { | ||
| (this, ViewKind::Partial { fields: ThinVec::from(fields) }) | ||
| } | ||
| None => (*self.ty.clone(), ViewKind::Full), | ||
| }; | ||
|
|
||
| let (kind, span) = match ty.kind { | ||
| TyKind::ImplicitSelf => (SelfKind::Value(mutbl), self.pat.span), | ||
| TyKind::Ref(lt, MutTy { ref ty, mutbl }) if ty.kind.is_implicit_self() => { | ||
| Some(respan(self.pat.span, SelfKind::Region(lt, mutbl))) | ||
| (SelfKind::Region(lt, mutbl), self.pat.span) | ||
| } | ||
| TyKind::PinnedRef(lt, MutTy { ref ty, mutbl }) | ||
| if ty.kind.is_implicit_self() => | ||
| { | ||
| Some(respan(self.pat.span, SelfKind::Pinned(lt, mutbl))) | ||
| (SelfKind::Pinned(lt, mutbl), self.pat.span) | ||
| } | ||
| _ => Some(respan( | ||
| self.pat.span.to(self.ty.span), | ||
| SelfKind::Explicit(self.ty.clone(), mutbl), | ||
| )), | ||
| _ => (SelfKind::Explicit(Box::new(ty), mutbl), self.ty.span), | ||
| }; | ||
|
|
||
| let param = respan(span, SelfParam { view, kind }); | ||
| return Some(param); | ||
| } | ||
| } | ||
| None | ||
|
|
@@ -3000,7 +3046,7 @@ impl Param { | |
| span: eself_ident.span, | ||
| tokens: None, | ||
| }); | ||
| let (mutbl, ty) = match eself.node { | ||
| let (mutbl, mut ty) = match eself.node.kind { | ||
| SelfKind::Explicit(ty, mutbl) => (mutbl, ty), | ||
| SelfKind::Value(mutbl) => (mutbl, infer_ty), | ||
| SelfKind::Region(lt, mutbl) => ( | ||
|
|
@@ -3022,6 +3068,14 @@ impl Param { | |
| }), | ||
| ), | ||
| }; | ||
| if let ViewKind::Partial { fields } = eself.node.view { | ||
| ty = Box::new(Ty { | ||
| id: DUMMY_NODE_ID, | ||
| kind: TyKind::View(ty, fields), | ||
| span, | ||
| tokens: None, | ||
| }); | ||
| } | ||
| Param { | ||
| attrs, | ||
| pat: Box::new(Pat { | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -17,7 +17,7 @@ use rustc_ast::util::comments::{Comment, CommentStyle}; | |
| use rustc_ast::{ | ||
| self as ast, AttrArgs, BindingMode, BlockCheckMode, ByRef, DelimArgs, GenericArg, GenericBound, | ||
| InlineAsmOperand, InlineAsmOptions, InlineAsmRegOrRegClass, InlineAsmTemplatePiece, PatKind, | ||
| RangeEnd, RangeSyntax, Safety, SelfKind, Term, attr, | ||
| RangeEnd, RangeSyntax, Safety, SelfKind, Term, ViewKind, attr, | ||
| }; | ||
| use rustc_span::edition::Edition; | ||
| use rustc_span::source_map::SourceMap; | ||
|
|
@@ -1255,6 +1255,14 @@ impl<'a> State<'a> { | |
| } | ||
| } | ||
|
|
||
| fn print_view(&mut self, fields: &[Ident]) { | ||
| self.word_space(".{"); | ||
| self.commasep(Breaks::Inconsistent, fields, |s, field| { | ||
| s.print_ident(*field); | ||
| }); | ||
| self.word_space(" }"); | ||
| } | ||
|
Comment on lines
+1258
to
+1264
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. i'm 99% sure this is wrong somehow as far as i know, there is no other node in the rust grammar that is only a list of identifiers separated by commas, so i don't have anything to draw inspiration from :/ i'll try to skim over the |
||
|
|
||
| pub fn print_assoc_item_constraint(&mut self, constraint: &ast::AssocItemConstraint) { | ||
| self.print_ident(constraint.ident); | ||
| if let Some(args) = constraint.gen_args.as_ref() { | ||
|
|
@@ -1437,6 +1445,10 @@ impl<'a> State<'a> { | |
| self.end(ib); | ||
| self.pclose(); | ||
| } | ||
| ast::TyKind::View(ty, fields) => { | ||
| self.print_type(ty); | ||
| self.print_view(fields); | ||
| } | ||
| } | ||
| self.end(ib); | ||
| } | ||
|
|
@@ -2053,31 +2065,35 @@ impl<'a> State<'a> { | |
| } | ||
|
|
||
| fn print_explicit_self(&mut self, explicit_self: &ast::ExplicitSelf) { | ||
| match &explicit_self.node { | ||
| match &explicit_self.node.kind { | ||
| SelfKind::Value(m) => { | ||
| self.print_mutability(*m, false); | ||
| self.word("self") | ||
| self.word("self"); | ||
| } | ||
| SelfKind::Region(lt, m) => { | ||
| self.word("&"); | ||
| self.print_opt_lifetime(lt); | ||
| self.print_mutability(*m, false); | ||
| self.word("self") | ||
| self.word("self"); | ||
| } | ||
| SelfKind::Pinned(lt, m) => { | ||
| self.word("&"); | ||
| self.print_opt_lifetime(lt); | ||
| self.word("pin "); | ||
| self.print_mutability(*m, true); | ||
| self.word("self") | ||
| self.word("self"); | ||
| } | ||
| SelfKind::Explicit(typ, m) => { | ||
| self.print_mutability(*m, false); | ||
| self.word("self"); | ||
| self.word_space(":"); | ||
| self.print_type(typ) | ||
| self.print_type(typ); | ||
|
Comment on lines
+2068
to
+2090
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. these edits come from an earlier version of this change, let's revert them |
||
| } | ||
| } | ||
|
|
||
| if let ViewKind::Partial { fields } = &explicit_self.node.view { | ||
| self.print_view(fields); | ||
| } | ||
| } | ||
|
|
||
| fn print_coroutine_kind(&mut self, coroutine_kind: ast::CoroutineKind) { | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is this still relevant?
View changes since the review