diff options
Diffstat (limited to 'compiler/rustc_ast/src')
| -rw-r--r-- | compiler/rustc_ast/src/ast.rs | 65 | ||||
| -rw-r--r-- | compiler/rustc_ast/src/attr/mod.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_ast/src/expand/autodiff_attrs.rs | 27 | ||||
| -rw-r--r-- | compiler/rustc_ast/src/mut_visit.rs | 69 | ||||
| -rw-r--r-- | compiler/rustc_ast/src/token.rs | 20 | ||||
| -rw-r--r-- | compiler/rustc_ast/src/tokenstream.rs | 25 | ||||
| -rw-r--r-- | compiler/rustc_ast/src/util/comments.rs | 4 | ||||
| -rw-r--r-- | compiler/rustc_ast/src/util/literal.rs | 4 | ||||
| -rw-r--r-- | compiler/rustc_ast/src/visit.rs | 40 | 
9 files changed, 157 insertions, 99 deletions
| diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index 8e73df63ef5..deee3a597ae 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -19,6 +19,7 @@ //! - [`UnOp`], [`BinOp`], and [`BinOpKind`]: Unary and binary operators. use std::borrow::Cow; +use std::sync::Arc; use std::{cmp, fmt}; pub use GenericArgs::*; @@ -27,7 +28,7 @@ pub use rustc_ast_ir::{Movability, Mutability, Pinnedness}; use rustc_data_structures::packed::Pu128; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_data_structures::stack::ensure_sufficient_stack; -use rustc_data_structures::sync::Lrc; +use rustc_data_structures::tagged_ptr::Tag; use rustc_macros::{Decodable, Encodable, HashStable_Generic}; pub use rustc_span::AttrId; use rustc_span::source_map::{Spanned, respan}; @@ -99,7 +100,7 @@ pub struct Path { impl PartialEq<Symbol> for Path { #[inline] fn eq(&self, symbol: &Symbol) -> bool { - self.segments.len() == 1 && { self.segments[0].ident.name == *symbol } + matches!(&self.segments[..], [segment] if segment.ident.name == *symbol) } } @@ -120,13 +121,13 @@ impl Path { } pub fn is_global(&self) -> bool { - !self.segments.is_empty() && self.segments[0].ident.name == kw::PathRoot + self.segments.first().is_some_and(|segment| segment.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() + matches!(self.segments[..], [PathSegment { args: None, .. }]) } } @@ -287,6 +288,7 @@ impl ParenthesizedArgs { } } +use crate::AstDeref; pub use crate::node_id::{CRATE_NODE_ID, DUMMY_NODE_ID, NodeId}; /// Modifiers on a trait bound like `~const`, `?` and `!`. @@ -1609,7 +1611,7 @@ pub enum ExprKind { /// Added for optimization purposes to avoid the need to escape /// large binary blobs - should always behave like [`ExprKind::Lit`] /// with a `ByteStr` literal. - IncludedBytes(Lrc<[u8]>), + IncludedBytes(Arc<[u8]>), /// A `format_args!()` expression. FormatArgs(P<FormatArgs>), @@ -1655,7 +1657,7 @@ impl GenBlockKind { } /// Whether we're unwrapping or wrapping an unsafe binder -#[derive(Copy, Clone, Debug, PartialEq, Eq)] +#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] #[derive(Encodable, Decodable, HashStable_Generic)] pub enum UnsafeBinderCastKind { // e.g. `&i32` -> `unsafe<'a> &'a i32` @@ -1902,9 +1904,9 @@ pub enum LitKind { Str(Symbol, StrStyle), /// 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), + ByteStr(Arc<[u8]>, StrStyle), /// A C String (`c"foo"`). Guaranteed to only have `\0` at the end. - CStr(Lrc<[u8]>, StrStyle), + CStr(Arc<[u8]>, StrStyle), /// A byte char (`b'f'`). Byte(u8), /// A character literal (`'a'`). @@ -2165,6 +2167,14 @@ impl Ty { } final_ty } + + pub fn is_maybe_parenthesised_infer(&self) -> bool { + match &self.kind { + TyKind::Infer => true, + TyKind::Paren(inner) => inner.ast_deref().is_maybe_parenthesised_infer(), + _ => false, + } + } } #[derive(Clone, Encodable, Decodable, Debug)] @@ -2269,10 +2279,32 @@ impl TyKind { /// Syntax used to declare a trait object. #[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug, HashStable_Generic)] +#[repr(u8)] pub enum TraitObjectSyntax { - Dyn, - DynStar, - None, + // SAFETY: When adding new variants make sure to update the `Tag` impl. + Dyn = 0, + DynStar = 1, + None = 2, +} + +/// 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`. +unsafe impl Tag for TraitObjectSyntax { + const BITS: u32 = 2; + + fn into_usize(self) -> usize { + self as u8 as usize + } + + unsafe fn from_usize(tag: usize) -> Self { + match tag { + 0 => TraitObjectSyntax::Dyn, + 1 => TraitObjectSyntax::DynStar, + 2 => TraitObjectSyntax::None, + _ => unreachable!(), + } + } } #[derive(Clone, Encodable, Decodable, Debug)] @@ -3193,7 +3225,7 @@ pub enum Extern { /// /// E.g. `extern fn foo() {}`. /// - /// This is just `extern "C"` (see `rustc_target::spec::abi::Abi::FALLBACK`). + /// This is just `extern "C"` (see `rustc_abi::ExternAbi::FALLBACK`). Implicit(Span), /// An explicit extern keyword was used with an explicit ABI. /// @@ -3316,11 +3348,18 @@ pub struct Impl { pub items: ThinVec<P<AssocItem>>, } +#[derive(Clone, Encodable, Decodable, Debug, Default)] +pub struct FnContract { + pub requires: Option<P<Expr>>, + pub ensures: Option<P<Expr>>, +} + #[derive(Clone, Encodable, Decodable, Debug)] pub struct Fn { pub defaultness: Defaultness, pub generics: Generics, pub sig: FnSig, + pub contract: Option<P<FnContract>>, pub body: Option<P<Block>>, } @@ -3618,7 +3657,7 @@ mod size_asserts { static_assert_size!(Block, 32); static_assert_size!(Expr, 72); static_assert_size!(ExprKind, 40); - static_assert_size!(Fn, 160); + static_assert_size!(Fn, 168); static_assert_size!(ForeignItem, 88); static_assert_size!(ForeignItemKind, 16); static_assert_size!(GenericArg, 24); diff --git a/compiler/rustc_ast/src/attr/mod.rs b/compiler/rustc_ast/src/attr/mod.rs index 51f18580013..df2f4b88712 100644 --- a/compiler/rustc_ast/src/attr/mod.rs +++ b/compiler/rustc_ast/src/attr/mod.rs @@ -302,7 +302,7 @@ impl AttrItem { impl MetaItem { /// For a single-segment meta item, returns its name; otherwise, returns `None`. pub fn ident(&self) -> Option<Ident> { - if self.path.segments.len() == 1 { Some(self.path.segments[0].ident) } else { None } + if let [PathSegment { ident, .. }] = self.path.segments[..] { Some(ident) } else { None } } pub fn name_or_empty(&self) -> Symbol { diff --git a/compiler/rustc_ast/src/expand/autodiff_attrs.rs b/compiler/rustc_ast/src/expand/autodiff_attrs.rs index 7ef8bc17973..70222f4acab 100644 --- a/compiler/rustc_ast/src/expand/autodiff_attrs.rs +++ b/compiler/rustc_ast/src/expand/autodiff_attrs.rs @@ -30,14 +30,6 @@ pub enum DiffMode { Forward, /// The target function, to be created using reverse mode AD. Reverse, - /// The target function, to be created using forward mode AD. - /// This target function will also be used as a source for higher order derivatives, - /// so compute it before all Forward/Reverse targets and optimize it through llvm. - ForwardFirst, - /// The target function, to be created using reverse mode AD. - /// This target function will also be used as a source for higher order derivatives, - /// so compute it before all Forward/Reverse targets and optimize it through llvm. - ReverseFirst, } /// Dual and Duplicated (and their Only variants) are getting lowered to the same Enzyme Activity. @@ -79,6 +71,7 @@ pub struct AutoDiffItem { pub target: String, pub attrs: AutoDiffAttrs, } + #[derive(Clone, Eq, PartialEq, Encodable, Decodable, Debug, HashStable_Generic)] pub struct AutoDiffAttrs { /// Conceptually either forward or reverse mode AD, as described in various autodiff papers and @@ -91,10 +84,10 @@ pub struct AutoDiffAttrs { impl DiffMode { pub fn is_rev(&self) -> bool { - matches!(self, DiffMode::Reverse | DiffMode::ReverseFirst) + matches!(self, DiffMode::Reverse) } pub fn is_fwd(&self) -> bool { - matches!(self, DiffMode::Forward | DiffMode::ForwardFirst) + matches!(self, DiffMode::Forward) } } @@ -105,8 +98,6 @@ impl Display for DiffMode { DiffMode::Source => write!(f, "Source"), DiffMode::Forward => write!(f, "Forward"), DiffMode::Reverse => write!(f, "Reverse"), - DiffMode::ForwardFirst => write!(f, "ForwardFirst"), - DiffMode::ReverseFirst => write!(f, "ReverseFirst"), } } } @@ -124,12 +115,12 @@ pub fn valid_ret_activity(mode: DiffMode, activity: DiffActivity) -> bool { match mode { DiffMode::Error => false, DiffMode::Source => false, - DiffMode::Forward | DiffMode::ForwardFirst => { + DiffMode::Forward => { activity == DiffActivity::Dual || activity == DiffActivity::DualOnly || activity == DiffActivity::Const } - DiffMode::Reverse | DiffMode::ReverseFirst => { + DiffMode::Reverse => { activity == DiffActivity::Const || activity == DiffActivity::Active || activity == DiffActivity::ActiveOnly @@ -165,10 +156,10 @@ pub fn valid_input_activity(mode: DiffMode, activity: DiffActivity) -> bool { return match mode { DiffMode::Error => false, DiffMode::Source => false, - DiffMode::Forward | DiffMode::ForwardFirst => { + DiffMode::Forward => { matches!(activity, Dual | DualOnly | Const) } - DiffMode::Reverse | DiffMode::ReverseFirst => { + DiffMode::Reverse => { matches!(activity, Active | ActiveOnly | Duplicated | DuplicatedOnly | Const) } }; @@ -199,8 +190,6 @@ impl FromStr for DiffMode { "Source" => Ok(DiffMode::Source), "Forward" => Ok(DiffMode::Forward), "Reverse" => Ok(DiffMode::Reverse), - "ForwardFirst" => Ok(DiffMode::ForwardFirst), - "ReverseFirst" => Ok(DiffMode::ReverseFirst), _ => Err(()), } } @@ -231,7 +220,7 @@ impl AutoDiffAttrs { self.ret_activity == DiffActivity::ActiveOnly } - pub fn error() -> Self { + pub const fn error() -> Self { AutoDiffAttrs { mode: DiffMode::Error, ret_activity: DiffActivity::None, diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs index aa88e8369d5..a9961cca583 100644 --- a/compiler/rustc_ast/src/mut_visit.rs +++ b/compiler/rustc_ast/src/mut_visit.rs @@ -9,10 +9,10 @@ use std::ops::DerefMut; use std::panic; +use std::sync::Arc; use rustc_data_structures::flat_map_in_place::FlatMapInPlace; use rustc_data_structures::stack::ensure_sufficient_stack; -use rustc_data_structures::sync::Lrc; use rustc_span::source_map::Spanned; use rustc_span::{Ident, Span}; use smallvec::{Array, SmallVec, smallvec}; @@ -143,6 +143,10 @@ pub trait MutVisitor: Sized { walk_flat_map_assoc_item(self, i, ctxt) } + fn visit_contract(&mut self, c: &mut P<FnContract>) { + walk_contract(self, c); + } + fn visit_fn_decl(&mut self, d: &mut P<FnDecl>) { walk_fn_decl(self, d); } @@ -789,14 +793,14 @@ fn visit_tt<T: MutVisitor>(vis: &mut T, tt: &mut TokenTree) { // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. fn visit_tts<T: MutVisitor>(vis: &mut T, TokenStream(tts): &mut TokenStream) { if T::VISIT_TOKENS && !tts.is_empty() { - let tts = Lrc::make_mut(tts); + let tts = Arc::make_mut(tts); visit_vec(tts, |tree| visit_tt(vis, tree)); } } fn visit_attr_tts<T: MutVisitor>(vis: &mut T, AttrTokenStream(tts): &mut AttrTokenStream) { if T::VISIT_TOKENS && !tts.is_empty() { - let tts = Lrc::make_mut(tts); + let tts = Arc::make_mut(tts); visit_vec(tts, |tree| visit_attr_tt(vis, tree)); } } @@ -836,7 +840,7 @@ pub fn visit_token<T: MutVisitor>(vis: &mut T, t: &mut Token) { vis.visit_ident(ident); } token::Interpolated(nt) => { - let nt = Lrc::make_mut(nt); + let nt = Arc::make_mut(nt); visit_nonterminal(vis, nt); } _ => {} @@ -954,11 +958,20 @@ fn walk_coroutine_kind<T: MutVisitor>(vis: &mut T, coroutine_kind: &mut Coroutin fn walk_fn<T: MutVisitor>(vis: &mut T, kind: FnKind<'_>) { match kind { - FnKind::Fn(_ctxt, _ident, FnSig { header, decl, span }, _visibility, generics, body) => { + FnKind::Fn( + _ctxt, + _ident, + _vis, + Fn { defaultness, generics, contract, body, sig: FnSig { header, decl, span } }, + ) => { // Identifier and visibility are visited as a part of the item. + visit_defaultness(vis, defaultness); vis.visit_fn_header(header); vis.visit_generics(generics); vis.visit_fn_decl(decl); + if let Some(contract) = contract { + vis.visit_contract(contract); + } if let Some(body) = body { vis.visit_block(body); } @@ -973,6 +986,16 @@ fn walk_fn<T: MutVisitor>(vis: &mut T, kind: FnKind<'_>) { } } +fn walk_contract<T: MutVisitor>(vis: &mut T, contract: &mut P<FnContract>) { + let FnContract { requires, ensures } = contract.deref_mut(); + if let Some(pred) = requires { + vis.visit_expr(pred); + } + if let Some(pred) = ensures { + vis.visit_expr(pred); + } +} + fn walk_fn_decl<T: MutVisitor>(vis: &mut T, decl: &mut P<FnDecl>) { let FnDecl { inputs, output } = decl.deref_mut(); inputs.flat_map_in_place(|param| vis.flat_map_param(param)); @@ -1205,13 +1228,8 @@ impl WalkItemKind for ItemKind { ItemKind::Const(item) => { visit_const_item(item, vis); } - ItemKind::Fn(box Fn { defaultness, generics, sig, body }) => { - visit_defaultness(vis, defaultness); - vis.visit_fn( - FnKind::Fn(FnCtxt::Free, ident, sig, visibility, generics, body), - span, - id, - ); + ItemKind::Fn(func) => { + vis.visit_fn(FnKind::Fn(FnCtxt::Free, ident, visibility, &mut *func), span, id); } ItemKind::Mod(safety, mod_kind) => { visit_safety(vis, safety); @@ -1329,10 +1347,9 @@ impl WalkItemKind for AssocItemKind { AssocItemKind::Const(item) => { visit_const_item(item, visitor); } - AssocItemKind::Fn(box Fn { defaultness, generics, sig, body }) => { - visit_defaultness(visitor, defaultness); + AssocItemKind::Fn(func) => { visitor.visit_fn( - FnKind::Fn(FnCtxt::Assoc(ctxt), ident, sig, visibility, generics, body), + FnKind::Fn(FnCtxt::Assoc(ctxt), ident, visibility, &mut *func), span, id, ); @@ -1476,10 +1493,9 @@ impl WalkItemKind for ForeignItemKind { visitor.visit_ty(ty); visit_opt(expr, |expr| visitor.visit_expr(expr)); } - ForeignItemKind::Fn(box Fn { defaultness, generics, sig, body }) => { - visit_defaultness(visitor, defaultness); + ForeignItemKind::Fn(func) => { visitor.visit_fn( - FnKind::Fn(FnCtxt::Foreign, ident, sig, visibility, generics, body), + FnKind::Fn(FnCtxt::Foreign, ident, visibility, &mut *func), span, id, ); @@ -1813,10 +1829,10 @@ pub fn walk_flat_map_stmt<T: MutVisitor>( .into_iter() .map(|kind| Stmt { id, kind, span }) .collect(); - match stmts.len() { - 0 => {} - 1 => vis.visit_span(&mut stmts[0].span), - 2.. => panic!( + match &mut stmts[..] { + [] => {} + [stmt] => vis.visit_span(&mut stmt.span), + _ => panic!( "cloning statement `NodeId`s is prohibited by default, \ the visitor should implement custom statement visiting" ), @@ -1965,14 +1981,7 @@ impl<N: DummyAstNode, T: DummyAstNode> DummyAstNode for crate::ast_traits::AstNo #[derive(Debug)] pub enum FnKind<'a> { /// E.g., `fn foo()`, `fn foo(&self)`, or `extern "Abi" fn foo()`. - Fn( - FnCtxt, - &'a mut Ident, - &'a mut FnSig, - &'a mut Visibility, - &'a mut Generics, - &'a mut Option<P<Block>>, - ), + Fn(FnCtxt, &'a mut Ident, &'a mut Visibility, &'a mut Fn), /// E.g., `|x, y| body`. Closure( diff --git a/compiler/rustc_ast/src/token.rs b/compiler/rustc_ast/src/token.rs index 3b7367d1ee2..36a7b7d8789 100644 --- a/compiler/rustc_ast/src/token.rs +++ b/compiler/rustc_ast/src/token.rs @@ -1,5 +1,6 @@ use std::borrow::Cow; use std::fmt; +use std::sync::Arc; pub use BinOpToken::*; pub use LitKind::*; @@ -8,7 +9,6 @@ pub use NtExprKind::*; pub use NtPatKind::*; pub use TokenKind::*; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; -use rustc_data_structures::sync::Lrc; use rustc_macros::{Decodable, Encodable, HashStable_Generic}; use rustc_span::edition::Edition; use rustc_span::{DUMMY_SP, ErrorGuaranteed, Span, kw, sym}; @@ -451,7 +451,7 @@ pub enum TokenKind { /// The span in the surrounding `Token` is that of the metavariable in the /// macro's RHS. The span within the Nonterminal is that of the fragment /// passed to the macro at the call site. - Interpolated(Lrc<Nonterminal>), + Interpolated(Arc<Nonterminal>), /// A doc comment token. /// `Symbol` is the doc comment's data excluding its "quotes" (`///`, `/**`, etc) @@ -469,7 +469,7 @@ impl Clone for TokenKind { // a copy. This is faster than the `derive(Clone)` version which has a // separate path for every variant. match self { - Interpolated(nt) => Interpolated(Lrc::clone(nt)), + Interpolated(nt) => Interpolated(Arc::clone(nt)), _ => unsafe { std::ptr::read(self) }, } } @@ -527,13 +527,13 @@ impl TokenKind { /// Returns tokens that are likely to be typed accidentally instead of the current token. /// Enables better error recovery when the wrong token is found. - pub fn similar_tokens(&self) -> Option<Vec<TokenKind>> { - match *self { - Comma => Some(vec![Dot, Lt, Semi]), - Semi => Some(vec![Colon, Comma]), - Colon => Some(vec![Semi]), - FatArrow => Some(vec![Eq, RArrow, Ge, Gt]), - _ => None, + pub fn similar_tokens(&self) -> &[TokenKind] { + match self { + Comma => &[Dot, Lt, Semi], + Semi => &[Colon, Comma], + Colon => &[Semi], + FatArrow => &[Eq, RArrow, Ge, Gt], + _ => &[], } } diff --git a/compiler/rustc_ast/src/tokenstream.rs b/compiler/rustc_ast/src/tokenstream.rs index e7b393d869d..50f10d083a0 100644 --- a/compiler/rustc_ast/src/tokenstream.rs +++ b/compiler/rustc_ast/src/tokenstream.rs @@ -14,10 +14,11 @@ //! ownership of the original. use std::borrow::Cow; +use std::sync::Arc; use std::{cmp, fmt, iter}; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; -use rustc_data_structures::sync::{self, Lrc}; +use rustc_data_structures::sync; use rustc_macros::{Decodable, Encodable, HashStable_Generic}; use rustc_serialize::{Decodable, Encodable}; use rustc_span::{DUMMY_SP, Span, SpanDecoder, SpanEncoder, Symbol, sym}; @@ -119,11 +120,11 @@ impl ToAttrTokenStream for AttrTokenStream { /// of an actual `TokenStream` until it is needed. /// `Box` is here only to reduce the structure size. #[derive(Clone)] -pub struct LazyAttrTokenStream(Lrc<Box<dyn ToAttrTokenStream>>); +pub struct LazyAttrTokenStream(Arc<Box<dyn ToAttrTokenStream>>); impl LazyAttrTokenStream { pub fn new(inner: impl ToAttrTokenStream + 'static) -> LazyAttrTokenStream { - LazyAttrTokenStream(Lrc::new(Box::new(inner))) + LazyAttrTokenStream(Arc::new(Box::new(inner))) } pub fn to_attr_token_stream(&self) -> AttrTokenStream { @@ -160,7 +161,7 @@ impl<CTX> HashStable<CTX> for LazyAttrTokenStream { /// during expansion to perform early cfg-expansion, and to process attributes /// during proc-macro invocations. #[derive(Clone, Debug, Default, Encodable, Decodable)] -pub struct AttrTokenStream(pub Lrc<Vec<AttrTokenTree>>); +pub struct AttrTokenStream(pub Arc<Vec<AttrTokenTree>>); /// Like `TokenTree`, but for `AttrTokenStream`. #[derive(Clone, Debug, Encodable, Decodable)] @@ -175,7 +176,7 @@ pub enum AttrTokenTree { impl AttrTokenStream { pub fn new(tokens: Vec<AttrTokenTree>) -> AttrTokenStream { - AttrTokenStream(Lrc::new(tokens)) + AttrTokenStream(Arc::new(tokens)) } /// Converts this `AttrTokenStream` to a plain `Vec<TokenTree>`. During @@ -293,7 +294,7 @@ pub struct AttrsTarget { /// Today's `TokenTree`s can still contain AST via `token::Interpolated` for /// backwards compatibility. #[derive(Clone, Debug, Default, Encodable, Decodable)] -pub struct TokenStream(pub(crate) Lrc<Vec<TokenTree>>); +pub struct TokenStream(pub(crate) Arc<Vec<TokenTree>>); /// Indicates whether a token can join with the following token to form a /// compound token. Used for conversions to `proc_macro::Spacing`. Also used to @@ -412,7 +413,7 @@ impl PartialEq<TokenStream> for TokenStream { impl TokenStream { pub fn new(tts: Vec<TokenTree>) -> TokenStream { - TokenStream(Lrc::new(tts)) + TokenStream(Arc::new(tts)) } pub fn is_empty(&self) -> bool { @@ -544,7 +545,7 @@ impl TokenStream { /// Push `tt` onto the end of the stream, possibly gluing it to the last /// token. Uses `make_mut` to maximize efficiency. pub fn push_tree(&mut self, tt: TokenTree) { - let vec_mut = Lrc::make_mut(&mut self.0); + let vec_mut = Arc::make_mut(&mut self.0); if Self::try_glue_to_last(vec_mut, &tt) { // nothing else to do @@ -557,7 +558,7 @@ impl TokenStream { /// token tree to the last token. (No other token trees will be glued.) /// Uses `make_mut` to maximize efficiency. pub fn push_stream(&mut self, stream: TokenStream) { - let vec_mut = Lrc::make_mut(&mut self.0); + let vec_mut = Arc::make_mut(&mut self.0); let stream_iter = stream.0.iter().cloned(); @@ -577,7 +578,7 @@ impl TokenStream { } /// Desugar doc comments like `/// foo` in the stream into `#[doc = - /// r"foo"]`. Modifies the `TokenStream` via `Lrc::make_mut`, but as little + /// r"foo"]`. Modifies the `TokenStream` via `Arc::make_mut`, but as little /// as possible. pub fn desugar_doc_comments(&mut self) { if let Some(desugared_stream) = desugar_inner(self.clone()) { @@ -596,7 +597,7 @@ impl TokenStream { ) => { let desugared = desugared_tts(attr_style, data, span); let desugared_len = desugared.len(); - Lrc::make_mut(&mut stream.0).splice(i..i + 1, desugared); + Arc::make_mut(&mut stream.0).splice(i..i + 1, desugared); modified = true; i += desugared_len; } @@ -607,7 +608,7 @@ impl TokenStream { if let Some(desugared_delim_stream) = desugar_inner(delim_stream.clone()) { let new_tt = TokenTree::Delimited(sp, spacing, delim, desugared_delim_stream); - Lrc::make_mut(&mut stream.0)[i] = new_tt; + Arc::make_mut(&mut stream.0)[i] = new_tt; modified = true; } i += 1; diff --git a/compiler/rustc_ast/src/util/comments.rs b/compiler/rustc_ast/src/util/comments.rs index f39142f08ba..e12818623d8 100644 --- a/compiler/rustc_ast/src/util/comments.rs +++ b/compiler/rustc_ast/src/util/comments.rs @@ -39,7 +39,7 @@ pub fn beautify_doc_string(data: Symbol, kind: CommentKind) -> Symbol { let mut i = 0; let mut j = lines.len(); // first line of all-stars should be omitted - if !lines.is_empty() && lines[0].chars().all(|c| c == '*') { + if lines.first().is_some_and(|line| line.chars().all(|c| c == '*')) { i += 1; } @@ -97,7 +97,7 @@ pub fn beautify_doc_string(data: Symbol, kind: CommentKind) -> Symbol { return None; } } - if lines.is_empty() { None } else { Some(lines[0][..i].into()) } + Some(lines.first()?[..i].to_string()) } let data_s = data.as_str(); diff --git a/compiler/rustc_ast/src/util/literal.rs b/compiler/rustc_ast/src/util/literal.rs index 4459cb962e8..6896ac723fa 100644 --- a/compiler/rustc_ast/src/util/literal.rs +++ b/compiler/rustc_ast/src/util/literal.rs @@ -121,7 +121,7 @@ impl LitKind { } token::ByteStrRaw(n) => { // Raw strings have no escapes so we can convert the symbol - // directly to a `Lrc<u8>`. + // directly to a `Arc<u8>`. let buf = symbol.as_str().to_owned().into_bytes(); LitKind::ByteStr(buf.into(), StrStyle::Raw(n)) } @@ -142,7 +142,7 @@ impl LitKind { } token::CStrRaw(n) => { // Raw strings have no escapes so we can convert the symbol - // directly to a `Lrc<u8>` after appending the terminating NUL + // directly to a `Arc<u8>` after appending the terminating NUL // char. let mut buf = symbol.as_str().to_owned().into_bytes(); buf.push(0); diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs index 1d6d7330757..714b074f930 100644 --- a/compiler/rustc_ast/src/visit.rs +++ b/compiler/rustc_ast/src/visit.rs @@ -65,7 +65,7 @@ impl BoundKind { #[derive(Copy, Clone, Debug)] pub enum FnKind<'a> { /// E.g., `fn foo()`, `fn foo(&self)`, or `extern "Abi" fn foo()`. - Fn(FnCtxt, &'a Ident, &'a FnSig, &'a Visibility, &'a Generics, &'a Option<P<Block>>), + Fn(FnCtxt, &'a Ident, &'a Visibility, &'a Fn), /// E.g., `|x, y| body`. Closure(&'a ClosureBinder, &'a Option<CoroutineKind>, &'a FnDecl, &'a Expr), @@ -74,7 +74,7 @@ pub enum FnKind<'a> { impl<'a> FnKind<'a> { pub fn header(&self) -> Option<&'a FnHeader> { match *self { - FnKind::Fn(_, _, sig, _, _, _) => Some(&sig.header), + FnKind::Fn(_, _, _, Fn { sig, .. }) => Some(&sig.header), FnKind::Closure(..) => None, } } @@ -88,7 +88,7 @@ impl<'a> FnKind<'a> { pub fn decl(&self) -> &'a FnDecl { match self { - FnKind::Fn(_, _, sig, _, _, _) => &sig.decl, + FnKind::Fn(_, _, _, Fn { sig, .. }) => &sig.decl, FnKind::Closure(_, _, decl, _) => decl, } } @@ -188,6 +188,9 @@ pub trait Visitor<'ast>: Sized { fn visit_closure_binder(&mut self, b: &'ast ClosureBinder) -> Self::Result { walk_closure_binder(self, b) } + fn visit_contract(&mut self, c: &'ast FnContract) -> Self::Result { + walk_contract(self, c) + } fn visit_where_predicate(&mut self, p: &'ast WherePredicate) -> Self::Result { walk_where_predicate(self, p) } @@ -374,8 +377,8 @@ impl WalkItemKind for ItemKind { try_visit!(visitor.visit_ty(ty)); visit_opt!(visitor, visit_expr, expr); } - ItemKind::Fn(box Fn { defaultness: _, generics, sig, body }) => { - let kind = FnKind::Fn(FnCtxt::Free, ident, sig, vis, generics, body); + ItemKind::Fn(func) => { + let kind = FnKind::Fn(FnCtxt::Free, ident, vis, &*func); try_visit!(visitor.visit_fn(kind, span, id)); } ItemKind::Mod(_unsafety, mod_kind) => match mod_kind { @@ -715,8 +718,8 @@ impl WalkItemKind for ForeignItemKind { try_visit!(visitor.visit_ty(ty)); visit_opt!(visitor, visit_expr, expr); } - ForeignItemKind::Fn(box Fn { defaultness: _, generics, sig, body }) => { - let kind = FnKind::Fn(FnCtxt::Foreign, ident, sig, vis, generics, body); + ForeignItemKind::Fn(func) => { + let kind = FnKind::Fn(FnCtxt::Foreign, ident, vis, &*func); try_visit!(visitor.visit_fn(kind, span, id)); } ForeignItemKind::TyAlias(box TyAlias { @@ -800,6 +803,17 @@ pub fn walk_closure_binder<'a, V: Visitor<'a>>( V::Result::output() } +pub fn walk_contract<'a, V: Visitor<'a>>(visitor: &mut V, c: &'a FnContract) -> V::Result { + let FnContract { requires, ensures } = c; + if let Some(pred) = requires { + visitor.visit_expr(pred); + } + if let Some(pred) = ensures { + visitor.visit_expr(pred); + } + V::Result::output() +} + pub fn walk_where_predicate<'a, V: Visitor<'a>>( visitor: &mut V, predicate: &'a WherePredicate, @@ -858,11 +872,17 @@ pub fn walk_fn_decl<'a, V: Visitor<'a>>( pub fn walk_fn<'a, V: Visitor<'a>>(visitor: &mut V, kind: FnKind<'a>) -> V::Result { match kind { - FnKind::Fn(_ctxt, _ident, FnSig { header, decl, span: _ }, _vis, generics, body) => { + FnKind::Fn( + _ctxt, + _ident, + _vis, + Fn { defaultness: _, sig: FnSig { header, decl, span: _ }, generics, contract, body }, + ) => { // Identifier and visibility are visited as a part of the item. try_visit!(visitor.visit_fn_header(header)); try_visit!(visitor.visit_generics(generics)); try_visit!(visitor.visit_fn_decl(decl)); + visit_opt!(visitor, visit_contract, contract); visit_opt!(visitor, visit_block, body); } FnKind::Closure(binder, coroutine_kind, decl, body) => { @@ -892,8 +912,8 @@ impl WalkItemKind for AssocItemKind { try_visit!(visitor.visit_ty(ty)); visit_opt!(visitor, visit_expr, expr); } - AssocItemKind::Fn(box Fn { defaultness: _, generics, sig, body }) => { - let kind = FnKind::Fn(FnCtxt::Assoc(ctxt), ident, sig, vis, generics, body); + AssocItemKind::Fn(func) => { + let kind = FnKind::Fn(FnCtxt::Assoc(ctxt), ident, vis, &*func); try_visit!(visitor.visit_fn(kind, span, id)); } AssocItemKind::Type(box TyAlias { | 
