From 837b550238aa671a591ccf282dddeab29cadb206 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sat, 18 May 2024 04:49:42 +0200 Subject: Merging upstream version 1.71.1+dfsg1. Signed-off-by: Daniel Baumann --- compiler/rustc_ast/src/ast.rs | 71 +++++++++++++++++++++--------- compiler/rustc_ast/src/attr/mod.rs | 42 +++--------------- compiler/rustc_ast/src/expand/allocator.rs | 22 ++++++--- compiler/rustc_ast/src/lib.rs | 1 - compiler/rustc_ast/src/mut_visit.rs | 13 +++++- compiler/rustc_ast/src/node_id.rs | 8 ++-- compiler/rustc_ast/src/ptr.rs | 3 +- compiler/rustc_ast/src/token.rs | 9 +++- compiler/rustc_ast/src/tokenstream.rs | 17 ++++--- compiler/rustc_ast/src/util/literal.rs | 66 +++++++++++++++++++++++++-- compiler/rustc_ast/src/util/parser.rs | 29 ++++++------ compiler/rustc_ast/src/visit.rs | 13 +++++- 12 files changed, 196 insertions(+), 98 deletions(-) (limited to 'compiler/rustc_ast') diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index df1a71675..4360fbeb9 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -120,6 +120,12 @@ impl Path { pub fn is_global(&self) -> bool { !self.segments.is_empty() && self.segments[0].ident.name == kw::PathRoot } + + /// If this path is a single identifier with no arguments, does not ensure + /// that the path resolves to a const param, the caller should check this. + pub fn is_potential_trivial_const_arg(&self) -> bool { + self.segments.len() == 1 && self.segments[0].args.is_none() + } } /// A segment of a path: an identifier, an optional lifetime, and a set of types. @@ -287,12 +293,20 @@ pub enum TraitBoundModifier { /// No modifiers None, + /// `!Trait` + Negative, + /// `?Trait` Maybe, /// `~const Trait` MaybeConst, + /// `~const !Trait` + // + // This parses but will be rejected during AST validation. + MaybeConstNegative, + /// `~const ?Trait` // // This parses but will be rejected during AST validation. @@ -1146,7 +1160,9 @@ impl Expr { /// /// If this is not the case, name resolution does not resolve `N` when using /// `min_const_generics` as more complex expressions are not supported. - pub fn is_potential_trivial_const_param(&self) -> bool { + /// + /// Does not ensure that the path resolves to a const param, the caller should check this. + pub fn is_potential_trivial_const_arg(&self) -> bool { let this = if let ExprKind::Block(block, None) = &self.kind && block.stmts.len() == 1 && let StmtKind::Expr(expr) = &block.stmts[0].kind @@ -1157,8 +1173,7 @@ impl Expr { }; if let ExprKind::Path(None, path) = &this.kind - && path.segments.len() == 1 - && path.segments[0].args.is_none() + && path.is_potential_trivial_const_arg() { true } else { @@ -1271,6 +1286,7 @@ impl Expr { ExprKind::Continue(..) => ExprPrecedence::Continue, ExprKind::Ret(..) => ExprPrecedence::Ret, ExprKind::InlineAsm(..) => ExprPrecedence::InlineAsm, + ExprKind::OffsetOf(..) => ExprPrecedence::OffsetOf, ExprKind::MacCall(..) => ExprPrecedence::Mac, ExprKind::Struct(..) => ExprPrecedence::Struct, ExprKind::Repeat(..) => ExprPrecedence::Repeat, @@ -1298,17 +1314,17 @@ impl Expr { /// To a first-order approximation, is this a pattern? pub fn is_approximately_pattern(&self) -> bool { - match &self.peel_parens().kind { + matches!( + &self.peel_parens().kind, ExprKind::Array(_) - | ExprKind::Call(_, _) - | ExprKind::Tup(_) - | ExprKind::Lit(_) - | ExprKind::Range(_, _, _) - | ExprKind::Underscore - | ExprKind::Path(_, _) - | ExprKind::Struct(_) => true, - _ => false, - } + | ExprKind::Call(_, _) + | ExprKind::Tup(_) + | ExprKind::Lit(_) + | ExprKind::Range(_, _, _) + | ExprKind::Underscore + | ExprKind::Path(_, _) + | ExprKind::Struct(_) + ) } } @@ -1429,8 +1445,8 @@ pub enum ExprKind { /// The async block used to have a `NodeId`, which was removed in favor of /// using the parent `NodeId` of the parent `Expr`. Async(CaptureBy, P), - /// An await expression (`my_future.await`). - Await(P), + /// An await expression (`my_future.await`). Span is of await keyword. + Await(P, Span), /// A try block (`try { ... }`). TryBlock(P), @@ -1469,6 +1485,9 @@ pub enum ExprKind { /// Output of the `asm!()` macro. InlineAsm(P), + /// Output of the `offset_of!()` macro. + OffsetOf(P, P<[Ident]>), + /// A macro invocation; pre-expansion. MacCall(P), @@ -1585,7 +1604,6 @@ pub enum ClosureBinder { pub struct MacCall { pub path: Path, pub args: P, - pub prior_type_ascription: Option<(Span, bool)>, } impl MacCall { @@ -1810,6 +1828,8 @@ pub enum LitKind { /// A byte string (`b"foo"`). Not stored as a symbol because it might be /// non-utf8, and symbols only allow utf8 strings. ByteStr(Lrc<[u8]>, StrStyle), + /// A C String (`c"foo"`). Guaranteed to only have `\0` at the end. + CStr(Lrc<[u8]>, StrStyle), /// A byte char (`b'f'`). Byte(u8), /// A character literal (`'a'`). @@ -1864,6 +1884,7 @@ impl LitKind { // unsuffixed variants LitKind::Str(..) | LitKind::ByteStr(..) + | LitKind::CStr(..) | LitKind::Byte(..) | LitKind::Char(..) | LitKind::Int(_, LitIntType::Unsuffixed) @@ -2370,10 +2391,10 @@ pub struct FnDecl { impl FnDecl { pub fn has_self(&self) -> bool { - self.inputs.get(0).map_or(false, Param::is_self) + self.inputs.get(0).is_some_and(Param::is_self) } pub fn c_variadic(&self) -> bool { - self.inputs.last().map_or(false, |arg| matches!(arg.ty.kind, TyKind::CVarArgs)) + self.inputs.last().is_some_and(|arg| matches!(arg.ty.kind, TyKind::CVarArgs)) } } @@ -2443,6 +2464,16 @@ impl fmt::Debug for ImplPolarity { } } +#[derive(Copy, Clone, PartialEq, Encodable, Decodable, HashStable_Generic)] +pub enum BoundPolarity { + /// `Type: Trait` + Positive, + /// `Type: !Trait` + Negative(Span), + /// `Type: ?Trait` + Maybe(Span), +} + #[derive(Clone, Encodable, Decodable, Debug)] pub enum FnRetTy { /// Returns type is not specified. @@ -2972,7 +3003,7 @@ pub enum ItemKind { } impl ItemKind { - pub fn article(&self) -> &str { + pub fn article(&self) -> &'static str { use ItemKind::*; match self { Use(..) | Static(..) | Const(..) | Fn(..) | Mod(..) | GlobalAsm(..) | TyAlias(..) @@ -2981,7 +3012,7 @@ impl ItemKind { } } - pub fn descr(&self) -> &str { + pub fn descr(&self) -> &'static str { match self { ItemKind::ExternCrate(..) => "extern crate", ItemKind::Use(..) => "`use` import", diff --git a/compiler/rustc_ast/src/attr/mod.rs b/compiler/rustc_ast/src/attr/mod.rs index c4771115c..15fe29580 100644 --- a/compiler/rustc_ast/src/attr/mod.rs +++ b/compiler/rustc_ast/src/attr/mod.rs @@ -10,15 +10,10 @@ use crate::tokenstream::{DelimSpan, Spacing, TokenTree}; use crate::tokenstream::{LazyAttrTokenStream, TokenStream}; use crate::util::comments; use crate::util::literal::escape_string_symbol; -use rustc_data_structures::sync::WorkerLocal; use rustc_index::bit_set::GrowableBitSet; use rustc_span::symbol::{sym, Ident, Symbol}; use rustc_span::Span; -use std::cell::Cell; use std::iter; -#[cfg(debug_assertions)] -use std::ops::BitXor; -#[cfg(debug_assertions)] use std::sync::atomic::{AtomicU32, Ordering}; use thin_vec::{thin_vec, ThinVec}; @@ -40,39 +35,16 @@ impl MarkedAttrs { } } -pub struct AttrIdGenerator(WorkerLocal>); - -#[cfg(debug_assertions)] -static MAX_ATTR_ID: AtomicU32 = AtomicU32::new(u32::MAX); +pub struct AttrIdGenerator(AtomicU32); impl AttrIdGenerator { pub fn new() -> Self { - // We use `(index as u32).reverse_bits()` to initialize the - // starting value of AttrId in each worker thread. - // The `index` is the index of the worker thread. - // This ensures that the AttrId generated in each thread is unique. - AttrIdGenerator(WorkerLocal::new(|index| { - let index: u32 = index.try_into().unwrap(); - - #[cfg(debug_assertions)] - { - let max_id = ((index + 1).next_power_of_two() - 1).bitxor(u32::MAX).reverse_bits(); - MAX_ATTR_ID.fetch_min(max_id, Ordering::Release); - } - - Cell::new(index.reverse_bits()) - })) + AttrIdGenerator(AtomicU32::new(0)) } pub fn mk_attr_id(&self) -> AttrId { - let id = self.0.get(); - - // Ensure the assigned attr_id does not overlap the bits - // representing the number of threads. - #[cfg(debug_assertions)] - assert!(id <= MAX_ATTR_ID.load(Ordering::Acquire)); - - self.0.set(id + 1); + let id = self.0.fetch_add(1, Ordering::Relaxed); + assert!(id != u32::MAX); AttrId::from_u32(id) } } @@ -177,7 +149,7 @@ impl Attribute { } pub fn may_have_doc_links(&self) -> bool { - self.doc_str().map_or(false, |s| comments::may_have_doc_links(s.as_str())) + self.doc_str().is_some_and(|s| comments::may_have_doc_links(s.as_str())) } pub fn is_proc_macro_attr(&self) -> bool { @@ -469,12 +441,12 @@ impl NestedMetaItem { /// Returns `true` if this list item is a MetaItem with a name of `name`. pub fn has_name(&self, name: Symbol) -> bool { - self.meta_item().map_or(false, |meta_item| meta_item.has_name(name)) + self.meta_item().is_some_and(|meta_item| meta_item.has_name(name)) } /// Returns `true` if `self` is a `MetaItem` and the meta item is a word. pub fn is_word(&self) -> bool { - self.meta_item().map_or(false, |meta_item| meta_item.is_word()) + self.meta_item().is_some_and(|meta_item| meta_item.is_word()) } /// Gets a list of inner meta items from a list `MetaItem` type. diff --git a/compiler/rustc_ast/src/expand/allocator.rs b/compiler/rustc_ast/src/expand/allocator.rs index 359394963..e87f6e820 100644 --- a/compiler/rustc_ast/src/expand/allocator.rs +++ b/compiler/rustc_ast/src/expand/allocator.rs @@ -1,20 +1,28 @@ use rustc_span::symbol::{sym, Symbol}; -#[derive(Clone, Debug, Copy, HashStable_Generic)] +#[derive(Clone, Debug, Copy, Eq, PartialEq, HashStable_Generic)] pub enum AllocatorKind { Global, Default, } -impl AllocatorKind { - pub fn fn_name(&self, base: Symbol) -> String { - match *self { - AllocatorKind::Global => format!("__rg_{base}"), - AllocatorKind::Default => format!("__rdl_{base}"), - } +pub fn global_fn_name(base: Symbol) -> String { + format!("__rust_{base}") +} + +pub fn default_fn_name(base: Symbol) -> String { + format!("__rdl_{base}") +} + +pub fn alloc_error_handler_name(alloc_error_handler_kind: AllocatorKind) -> &'static str { + match alloc_error_handler_kind { + AllocatorKind::Global => "__rg_oom", + AllocatorKind::Default => "__rdl_oom", } } +pub const NO_ALLOC_SHIM_IS_UNSTABLE: &str = "__rust_no_alloc_shim_is_unstable"; + pub enum AllocatorTy { Layout, Ptr, diff --git a/compiler/rustc_ast/src/lib.rs b/compiler/rustc_ast/src/lib.rs index 23c32fa96..b07ed1d1c 100644 --- a/compiler/rustc_ast/src/lib.rs +++ b/compiler/rustc_ast/src/lib.rs @@ -10,7 +10,6 @@ )] #![feature(associated_type_bounds)] #![feature(box_patterns)] -#![feature(const_default_impls)] #![feature(const_trait_impl)] #![feature(if_let_guard)] #![feature(let_chains)] diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs index 694d31d8f..66b94d12a 100644 --- a/compiler/rustc_ast/src/mut_visit.rs +++ b/compiler/rustc_ast/src/mut_visit.rs @@ -631,7 +631,7 @@ pub fn noop_visit_attribute(attr: &mut Attribute, vis: &mut T) { } pub fn noop_visit_mac(mac: &mut MacCall, vis: &mut T) { - let MacCall { path, args, prior_type_ascription: _ } = mac; + let MacCall { path, args } = mac; vis.visit_path(path); visit_delim_args(args, vis); } @@ -1415,7 +1415,10 @@ pub fn noop_visit_expr( ExprKind::Async(_capture_by, body) => { vis.visit_block(body); } - ExprKind::Await(expr) => vis.visit_expr(expr), + ExprKind::Await(expr, await_kw_span) => { + vis.visit_expr(expr); + vis.visit_span(await_kw_span); + } ExprKind::Assign(el, er, _) => { vis.visit_expr(el); vis.visit_expr(er); @@ -1456,6 +1459,12 @@ pub fn noop_visit_expr( } ExprKind::InlineAsm(asm) => vis.visit_inline_asm(asm), ExprKind::FormatArgs(fmt) => vis.visit_format_args(fmt), + ExprKind::OffsetOf(container, fields) => { + vis.visit_ty(container); + for field in fields.iter_mut() { + vis.visit_ident(field); + } + } ExprKind::MacCall(mac) => vis.visit_mac_call(mac), ExprKind::Struct(se) => { let StructExpr { qself, path, fields, rest } = se.deref_mut(); diff --git a/compiler/rustc_ast/src/node_id.rs b/compiler/rustc_ast/src/node_id.rs index daa82996b..d16741757 100644 --- a/compiler/rustc_ast/src/node_id.rs +++ b/compiler/rustc_ast/src/node_id.rs @@ -9,14 +9,14 @@ rustc_index::newtype_index! { /// /// [`DefId`]: rustc_span::def_id::DefId #[debug_format = "NodeId({})"] - pub struct NodeId {} + pub struct NodeId { + /// The [`NodeId`] used to represent the root of the crate. + const CRATE_NODE_ID = 0; + } } rustc_data_structures::define_id_collections!(NodeMap, NodeSet, NodeMapEntry, NodeId); -/// The [`NodeId`] used to represent the root of the crate. -pub const CRATE_NODE_ID: NodeId = NodeId::from_u32(0); - /// When parsing and at the beginning of doing expansions, we initially give all AST nodes /// this dummy AST [`NodeId`]. Then, during a later phase of expansion, we renumber them /// to have small, positive IDs. diff --git a/compiler/rustc_ast/src/ptr.rs b/compiler/rustc_ast/src/ptr.rs index 4b2850336..0140fb752 100644 --- a/compiler/rustc_ast/src/ptr.rs +++ b/compiler/rustc_ast/src/ptr.rs @@ -126,7 +126,8 @@ impl> Encodable for P { } impl P<[T]> { - pub const fn new() -> P<[T]> { + // FIXME(const-hack) make this const again + pub fn new() -> P<[T]> { P { ptr: Box::default() } } diff --git a/compiler/rustc_ast/src/token.rs b/compiler/rustc_ast/src/token.rs index f947ae4d0..7ef39f802 100644 --- a/compiler/rustc_ast/src/token.rs +++ b/compiler/rustc_ast/src/token.rs @@ -74,6 +74,8 @@ pub enum LitKind { StrRaw(u8), // raw string delimited by `n` hash symbols ByteStr, ByteStrRaw(u8), // raw byte string delimited by `n` hash symbols + CStr, + CStrRaw(u8), Err, } @@ -141,6 +143,10 @@ impl fmt::Display for Lit { delim = "#".repeat(n as usize), string = symbol )?, + CStr => write!(f, "c\"{symbol}\"")?, + CStrRaw(n) => { + write!(f, "cr{delim}\"{symbol}\"{delim}", delim = "#".repeat(n as usize))? + } Integer | Float | Bool | Err => write!(f, "{symbol}")?, } @@ -170,6 +176,7 @@ impl LitKind { Float => "float", Str | StrRaw(..) => "string", ByteStr | ByteStrRaw(..) => "byte string", + CStr | CStrRaw(..) => "C string", Err => "error", } } @@ -600,7 +607,7 @@ impl Token { /// Returns `true` if the token is an identifier whose name is the given /// string slice. pub fn is_ident_named(&self, name: Symbol) -> bool { - self.ident().map_or(false, |(ident, _)| ident.name == name) + self.ident().is_some_and(|(ident, _)| ident.name == name) } /// Returns `true` if the token is an interpolated path. diff --git a/compiler/rustc_ast/src/tokenstream.rs b/compiler/rustc_ast/src/tokenstream.rs index f0a6a5e07..db296aa44 100644 --- a/compiler/rustc_ast/src/tokenstream.rs +++ b/compiler/rustc_ast/src/tokenstream.rs @@ -48,14 +48,15 @@ pub enum TokenTree { Delimited(DelimSpan, Delimiter, TokenStream), } -// Ensure all fields of `TokenTree` is `Send` and `Sync`. +// Ensure all fields of `TokenTree` are `DynSend` and `DynSync`. #[cfg(parallel_compiler)] fn _dummy() where - Token: Send + Sync, - DelimSpan: Send + Sync, - Delimiter: Send + Sync, - TokenStream: Send + Sync, + Token: sync::DynSend + sync::DynSync, + Spacing: sync::DynSend + sync::DynSync, + DelimSpan: sync::DynSend + sync::DynSync, + Delimiter: sync::DynSend + sync::DynSync, + TokenStream: sync::DynSend + sync::DynSync, { } @@ -118,7 +119,7 @@ where } } -pub trait ToAttrTokenStream: sync::Send + sync::Sync { +pub trait ToAttrTokenStream: sync::DynSend + sync::DynSync { fn to_attr_token_stream(&self) -> AttrTokenStream; } @@ -550,6 +551,10 @@ impl TokenStream { vec_mut.extend(stream_iter); } } + + pub fn chunks(&self, chunk_size: usize) -> core::slice::Chunks<'_, TokenTree> { + self.0.chunks(chunk_size) + } } /// By-reference iterator over a [`TokenStream`], that produces `&TokenTree` diff --git a/compiler/rustc_ast/src/util/literal.rs b/compiler/rustc_ast/src/util/literal.rs index 74b842ac9..50eb92125 100644 --- a/compiler/rustc_ast/src/util/literal.rs +++ b/compiler/rustc_ast/src/util/literal.rs @@ -2,9 +2,13 @@ use crate::ast::{self, LitKind, MetaItemLit, StrStyle}; use crate::token::{self, Token}; -use rustc_lexer::unescape::{byte_from_char, unescape_byte, unescape_char, unescape_literal, Mode}; +use rustc_lexer::unescape::{ + byte_from_char, unescape_byte, unescape_c_string, unescape_char, unescape_literal, CStrUnit, + Mode, +}; use rustc_span::symbol::{kw, sym, Symbol}; use rustc_span::Span; +use std::ops::Range; use std::{ascii, fmt, str}; // Escapes a string, represented as a symbol. Reuses the original symbol, @@ -35,6 +39,7 @@ pub enum LitError { InvalidFloatSuffix, NonDecimalFloat(u32), IntTooLarge(u32), + NulInCStr(Range), } impl LitKind { @@ -158,6 +163,52 @@ impl LitKind { LitKind::ByteStr(bytes.into(), StrStyle::Raw(n)) } + token::CStr => { + let s = symbol.as_str(); + let mut buf = Vec::with_capacity(s.len()); + let mut error = Ok(()); + unescape_c_string(s, Mode::CStr, &mut |span, c| match c { + Ok(CStrUnit::Byte(0) | CStrUnit::Char('\0')) => { + error = Err(LitError::NulInCStr(span)); + } + Ok(CStrUnit::Byte(b)) => buf.push(b), + Ok(CStrUnit::Char(c)) if c.len_utf8() == 1 => buf.push(c as u8), + Ok(CStrUnit::Char(c)) => { + buf.extend_from_slice(c.encode_utf8(&mut [0; 4]).as_bytes()) + } + Err(err) => { + if err.is_fatal() { + error = Err(LitError::LexerError); + } + } + }); + error?; + buf.push(0); + LitKind::CStr(buf.into(), StrStyle::Cooked) + } + token::CStrRaw(n) => { + let s = symbol.as_str(); + let mut buf = Vec::with_capacity(s.len()); + let mut error = Ok(()); + unescape_c_string(s, Mode::RawCStr, &mut |span, c| match c { + Ok(CStrUnit::Byte(0) | CStrUnit::Char('\0')) => { + error = Err(LitError::NulInCStr(span)); + } + Ok(CStrUnit::Byte(b)) => buf.push(b), + Ok(CStrUnit::Char(c)) if c.len_utf8() == 1 => buf.push(c as u8), + Ok(CStrUnit::Char(c)) => { + buf.extend_from_slice(c.encode_utf8(&mut [0; 4]).as_bytes()) + } + Err(err) => { + if err.is_fatal() { + error = Err(LitError::LexerError); + } + } + }); + error?; + buf.push(0); + LitKind::CStr(buf.into(), StrStyle::Raw(n)) + } token::Err => LitKind::Err, }) } @@ -191,6 +242,14 @@ impl fmt::Display for LitKind { string = symbol )?; } + LitKind::CStr(ref bytes, StrStyle::Cooked) => { + write!(f, "c\"{}\"", escape_byte_str_symbol(bytes))? + } + LitKind::CStr(ref bytes, StrStyle::Raw(n)) => { + // This can only be valid UTF-8. + let symbol = str::from_utf8(bytes).unwrap(); + write!(f, "cr{delim}\"{symbol}\"{delim}", delim = "#".repeat(n as usize),)?; + } LitKind::Int(n, ty) => { write!(f, "{n}")?; match ty { @@ -237,6 +296,8 @@ impl MetaItemLit { LitKind::Str(_, ast::StrStyle::Raw(n)) => token::StrRaw(n), LitKind::ByteStr(_, ast::StrStyle::Cooked) => token::ByteStr, LitKind::ByteStr(_, ast::StrStyle::Raw(n)) => token::ByteStrRaw(n), + LitKind::CStr(_, ast::StrStyle::Cooked) => token::CStr, + LitKind::CStr(_, ast::StrStyle::Raw(n)) => token::CStrRaw(n), LitKind::Byte(_) => token::Byte, LitKind::Char(_) => token::Char, LitKind::Int(..) => token::Integer, @@ -331,8 +392,7 @@ fn integer_lit(symbol: Symbol, suffix: Option) -> Result= base)); + let from_lexer = base < 10 && s.chars().any(|c| c.to_digit(10).is_some_and(|d| d >= base)); if from_lexer { LitError::LexerError } else { LitError::IntTooLarge(base) } }) } diff --git a/compiler/rustc_ast/src/util/parser.rs b/compiler/rustc_ast/src/util/parser.rs index 3893875e9..35afd5423 100644 --- a/compiler/rustc_ast/src/util/parser.rs +++ b/compiler/rustc_ast/src/util/parser.rs @@ -53,8 +53,6 @@ pub enum AssocOp { DotDot, /// `..=` range DotDotEq, - /// `:` - Colon, } #[derive(PartialEq, Debug)] @@ -96,7 +94,6 @@ impl AssocOp { token::DotDotEq => Some(DotDotEq), // DotDotDot is no longer supported, but we need some way to display the error token::DotDotDot => Some(DotDotEq), - token::Colon => Some(Colon), // `<-` should probably be `< -` token::LArrow => Some(Less), _ if t.is_keyword(kw::As) => Some(As), @@ -133,7 +130,7 @@ impl AssocOp { pub fn precedence(&self) -> usize { use AssocOp::*; match *self { - As | Colon => 14, + As => 14, Multiply | Divide | Modulus => 13, Add | Subtract => 12, ShiftLeft | ShiftRight => 11, @@ -156,7 +153,7 @@ impl AssocOp { Assign | AssignOp(_) => Fixity::Right, As | Multiply | Divide | Modulus | Add | Subtract | ShiftLeft | ShiftRight | BitAnd | BitXor | BitOr | Less | Greater | LessEqual | GreaterEqual | Equal | NotEqual - | LAnd | LOr | Colon => Fixity::Left, + | LAnd | LOr => Fixity::Left, DotDot | DotDotEq => Fixity::None, } } @@ -166,8 +163,9 @@ impl AssocOp { match *self { Less | Greater | LessEqual | GreaterEqual | Equal | NotEqual => true, Assign | AssignOp(_) | As | Multiply | Divide | Modulus | Add | Subtract - | ShiftLeft | ShiftRight | BitAnd | BitXor | BitOr | LAnd | LOr | DotDot | DotDotEq - | Colon => false, + | ShiftLeft | ShiftRight | BitAnd | BitXor | BitOr | LAnd | LOr | DotDot | DotDotEq => { + false + } } } @@ -177,7 +175,7 @@ impl AssocOp { Assign | AssignOp(_) => true, Less | Greater | LessEqual | GreaterEqual | Equal | NotEqual | As | Multiply | Divide | Modulus | Add | Subtract | ShiftLeft | ShiftRight | BitAnd | BitXor - | BitOr | LAnd | LOr | DotDot | DotDotEq | Colon => false, + | BitOr | LAnd | LOr | DotDot | DotDotEq => false, } } @@ -202,7 +200,7 @@ impl AssocOp { BitOr => Some(BinOpKind::BitOr), LAnd => Some(BinOpKind::And), LOr => Some(BinOpKind::Or), - Assign | AssignOp(_) | As | DotDot | DotDotEq | Colon => None, + Assign | AssignOp(_) | As | DotDot | DotDotEq => None, } } @@ -223,10 +221,9 @@ impl AssocOp { Greater | // `{ 42 } > 3` GreaterEqual | // `{ 42 } >= 3` AssignOp(_) | // `{ 42 } +=` - As | // `{ 42 } as usize` // Equal | // `{ 42 } == { 42 }` Accepting these here would regress incorrect - // NotEqual | // `{ 42 } != { 42 }` struct literals parser recovery. - Colon, // `{ 42 }: usize` + // NotEqual | // `{ 42 } != { 42 } struct literals parser recovery. + As // `{ 42 } as usize` ) } } @@ -254,7 +251,6 @@ pub enum ExprPrecedence { Binary(BinOpKind), Cast, - Type, Assign, AssignOp, @@ -269,6 +265,7 @@ pub enum ExprPrecedence { Index, Try, InlineAsm, + OffsetOf, Mac, FormatArgs, @@ -312,7 +309,6 @@ impl ExprPrecedence { // Binop-like expr kinds, handled by `AssocOp`. ExprPrecedence::Binary(op) => AssocOp::from_ast_binop(op).precedence() as i8, ExprPrecedence::Cast => AssocOp::As.precedence() as i8, - ExprPrecedence::Type => AssocOp::Colon.precedence() as i8, ExprPrecedence::Assign | ExprPrecedence::AssignOp => AssocOp::Assign.precedence() as i8, @@ -335,7 +331,8 @@ impl ExprPrecedence { | ExprPrecedence::Try | ExprPrecedence::InlineAsm | ExprPrecedence::Mac - | ExprPrecedence::FormatArgs => PREC_POSTFIX, + | ExprPrecedence::FormatArgs + | ExprPrecedence::OffsetOf => PREC_POSTFIX, // Never need parens ExprPrecedence::Array @@ -386,7 +383,7 @@ pub fn contains_exterior_struct_lit(value: &ast::Expr) -> bool { // X { y: 1 } + X { y: 2 } contains_exterior_struct_lit(lhs) || contains_exterior_struct_lit(rhs) } - ast::ExprKind::Await(x) + ast::ExprKind::Await(x, _) | ast::ExprKind::Unary(_, x) | ast::ExprKind::Cast(x, _) | ast::ExprKind::Type(x, _) diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs index ac9b321b7..275692ad5 100644 --- a/compiler/rustc_ast/src/visit.rs +++ b/compiler/rustc_ast/src/visit.rs @@ -188,6 +188,9 @@ pub trait Visitor<'ast>: Sized { fn visit_variant(&mut self, v: &'ast Variant) { walk_variant(self, v) } + fn visit_variant_discr(&mut self, discr: &'ast AnonConst) { + self.visit_anon_const(discr); + } fn visit_label(&mut self, label: &'ast Label) { walk_label(self, label) } @@ -380,7 +383,7 @@ where visitor.visit_ident(variant.ident); visitor.visit_vis(&variant.vis); visitor.visit_variant_data(&variant.data); - walk_list!(visitor, visit_anon_const, &variant.disr_expr); + walk_list!(visitor, visit_variant_discr, &variant.disr_expr); walk_list!(visitor, visit_attribute, &variant.attrs); } @@ -864,7 +867,7 @@ pub fn walk_expr<'a, V: Visitor<'a>>(visitor: &mut V, expression: &'a Expr) { ExprKind::Async(_, body) => { visitor.visit_block(body); } - ExprKind::Await(expr) => visitor.visit_expr(expr), + ExprKind::Await(expr, _) => visitor.visit_expr(expr), ExprKind::Assign(lhs, rhs, _) => { visitor.visit_expr(lhs); visitor.visit_expr(rhs); @@ -909,6 +912,12 @@ pub fn walk_expr<'a, V: Visitor<'a>>(visitor: &mut V, expression: &'a Expr) { ExprKind::Paren(subexpression) => visitor.visit_expr(subexpression), ExprKind::InlineAsm(asm) => visitor.visit_inline_asm(asm), ExprKind::FormatArgs(f) => visitor.visit_format_args(f), + ExprKind::OffsetOf(container, fields) => { + visitor.visit_ty(container); + for &field in fields { + visitor.visit_ident(field); + } + } ExprKind::Yield(optional_expression) => { walk_list!(visitor, visit_expr, optional_expression); } -- cgit v1.2.3