diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index 3f4911c4ecfcf..5e4288c344be2 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -24,7 +24,7 @@ pub use UnsafeSource::*; use crate::ptr::P; use crate::token::{self, CommentKind, Delimiter}; -use crate::tokenstream::{DelimSpan, LazyTokenStream, TokenStream}; +use crate::tokenstream::{DelimSpan, LazyAttrTokenStream, TokenStream}; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_data_structures::sync::Lrc; @@ -91,7 +91,7 @@ pub struct Path { /// The segments in the path: the things separated by `::`. /// Global paths begin with `kw::PathRoot`. pub segments: Vec, - pub tokens: Option, + pub tokens: Option, } impl PartialEq for Path { @@ -534,7 +534,7 @@ pub struct Block { /// Distinguishes between `unsafe { ... }` and `{ ... }`. pub rules: BlockCheckMode, pub span: Span, - pub tokens: Option, + pub tokens: Option, /// The following *isn't* a parse error, but will cause multiple errors in following stages. /// ```compile_fail /// let x = { @@ -553,7 +553,7 @@ pub struct Pat { pub id: NodeId, pub kind: PatKind, pub span: Span, - pub tokens: Option, + pub tokens: Option, } impl Pat { @@ -937,8 +937,8 @@ impl Stmt { /// a trailing semicolon. /// /// This only modifies the parsed AST struct, not the attached - /// `LazyTokenStream`. The parser is responsible for calling - /// `CreateTokenStream::add_trailing_semi` when there is actually + /// `LazyAttrTokenStream`. The parser is responsible for calling + /// `ToAttrTokenStream::add_trailing_semi` when there is actually /// a semicolon in the tokenstream. pub fn add_trailing_semicolon(mut self) -> Self { self.kind = match self.kind { @@ -984,7 +984,7 @@ pub struct MacCallStmt { pub mac: P, pub style: MacStmtStyle, pub attrs: AttrVec, - pub tokens: Option, + pub tokens: Option, } #[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug)] @@ -1009,7 +1009,7 @@ pub struct Local { pub kind: LocalKind, pub span: Span, pub attrs: AttrVec, - pub tokens: Option, + pub tokens: Option, } #[derive(Clone, Encodable, Decodable, Debug)] @@ -1108,7 +1108,7 @@ pub struct Expr { pub kind: ExprKind, pub span: Span, pub attrs: AttrVec, - pub tokens: Option, + pub tokens: Option, } impl Expr { @@ -1967,7 +1967,7 @@ pub struct Ty { pub id: NodeId, pub kind: TyKind, pub span: Span, - pub tokens: Option, + pub tokens: Option, } impl Clone for Ty { @@ -2532,7 +2532,7 @@ impl Decodable for AttrId { pub struct AttrItem { pub path: Path, pub args: MacArgs, - pub tokens: Option, + pub tokens: Option, } /// A list of attributes. @@ -2552,7 +2552,7 @@ pub struct Attribute { #[derive(Clone, Encodable, Decodable, Debug)] pub struct NormalAttr { pub item: AttrItem, - pub tokens: Option, + pub tokens: Option, } #[derive(Clone, Encodable, Decodable, Debug)] @@ -2603,7 +2603,7 @@ impl PolyTraitRef { pub struct Visibility { pub kind: VisibilityKind, pub span: Span, - pub tokens: Option, + pub tokens: Option, } #[derive(Clone, Encodable, Decodable, Debug)] @@ -2689,7 +2689,7 @@ pub struct Item { /// /// Note that the tokens here do not include the outer attributes, but will /// include inner attributes. - pub tokens: Option, + pub tokens: Option, } impl Item { diff --git a/compiler/rustc_ast/src/ast_traits.rs b/compiler/rustc_ast/src/ast_traits.rs index 79f5820230ed6..1b31be07f7ad1 100644 --- a/compiler/rustc_ast/src/ast_traits.rs +++ b/compiler/rustc_ast/src/ast_traits.rs @@ -4,7 +4,7 @@ use crate::ptr::P; use crate::token::Nonterminal; -use crate::tokenstream::LazyTokenStream; +use crate::tokenstream::LazyAttrTokenStream; use crate::{Arm, Crate, ExprField, FieldDef, GenericParam, Param, PatField, Variant}; use crate::{AssocItem, Expr, ForeignItem, Item, NodeId}; use crate::{AttrItem, AttrKind, Block, Pat, Path, Ty, Visibility}; @@ -124,18 +124,18 @@ impl HasSpan for AttrItem { /// A trait for AST nodes having (or not having) collected tokens. pub trait HasTokens { - fn tokens(&self) -> Option<&LazyTokenStream>; - fn tokens_mut(&mut self) -> Option<&mut Option>; + fn tokens(&self) -> Option<&LazyAttrTokenStream>; + fn tokens_mut(&mut self) -> Option<&mut Option>; } macro_rules! impl_has_tokens { ($($T:ty),+ $(,)?) => { $( impl HasTokens for $T { - fn tokens(&self) -> Option<&LazyTokenStream> { + fn tokens(&self) -> Option<&LazyAttrTokenStream> { self.tokens.as_ref() } - fn tokens_mut(&mut self) -> Option<&mut Option> { + fn tokens_mut(&mut self) -> Option<&mut Option> { Some(&mut self.tokens) } } @@ -147,10 +147,10 @@ macro_rules! impl_has_tokens_none { ($($T:ty),+ $(,)?) => { $( impl HasTokens for $T { - fn tokens(&self) -> Option<&LazyTokenStream> { + fn tokens(&self) -> Option<&LazyAttrTokenStream> { None } - fn tokens_mut(&mut self) -> Option<&mut Option> { + fn tokens_mut(&mut self) -> Option<&mut Option> { None } } @@ -162,25 +162,25 @@ impl_has_tokens!(AssocItem, AttrItem, Block, Expr, ForeignItem, Item, Pat, Path, impl_has_tokens_none!(Arm, ExprField, FieldDef, GenericParam, Param, PatField, Variant); impl> HasTokens for T { - fn tokens(&self) -> Option<&LazyTokenStream> { + fn tokens(&self) -> Option<&LazyAttrTokenStream> { self.ast_deref().tokens() } - fn tokens_mut(&mut self) -> Option<&mut Option> { + fn tokens_mut(&mut self) -> Option<&mut Option> { self.ast_deref_mut().tokens_mut() } } impl HasTokens for Option { - fn tokens(&self) -> Option<&LazyTokenStream> { + fn tokens(&self) -> Option<&LazyAttrTokenStream> { self.as_ref().and_then(|inner| inner.tokens()) } - fn tokens_mut(&mut self) -> Option<&mut Option> { + fn tokens_mut(&mut self) -> Option<&mut Option> { self.as_mut().and_then(|inner| inner.tokens_mut()) } } impl HasTokens for StmtKind { - fn tokens(&self) -> Option<&LazyTokenStream> { + fn tokens(&self) -> Option<&LazyAttrTokenStream> { match self { StmtKind::Local(local) => local.tokens.as_ref(), StmtKind::Item(item) => item.tokens(), @@ -189,7 +189,7 @@ impl HasTokens for StmtKind { StmtKind::MacCall(mac) => mac.tokens.as_ref(), } } - fn tokens_mut(&mut self) -> Option<&mut Option> { + fn tokens_mut(&mut self) -> Option<&mut Option> { match self { StmtKind::Local(local) => Some(&mut local.tokens), StmtKind::Item(item) => item.tokens_mut(), @@ -201,16 +201,16 @@ impl HasTokens for StmtKind { } impl HasTokens for Stmt { - fn tokens(&self) -> Option<&LazyTokenStream> { + fn tokens(&self) -> Option<&LazyAttrTokenStream> { self.kind.tokens() } - fn tokens_mut(&mut self) -> Option<&mut Option> { + fn tokens_mut(&mut self) -> Option<&mut Option> { self.kind.tokens_mut() } } impl HasTokens for Attribute { - fn tokens(&self) -> Option<&LazyTokenStream> { + fn tokens(&self) -> Option<&LazyAttrTokenStream> { match &self.kind { AttrKind::Normal(normal) => normal.tokens.as_ref(), kind @ AttrKind::DocComment(..) => { @@ -218,7 +218,7 @@ impl HasTokens for Attribute { } } } - fn tokens_mut(&mut self) -> Option<&mut Option> { + fn tokens_mut(&mut self) -> Option<&mut Option> { Some(match &mut self.kind { AttrKind::Normal(normal) => &mut normal.tokens, kind @ AttrKind::DocComment(..) => { @@ -229,7 +229,7 @@ impl HasTokens for Attribute { } impl HasTokens for Nonterminal { - fn tokens(&self) -> Option<&LazyTokenStream> { + fn tokens(&self) -> Option<&LazyAttrTokenStream> { match self { Nonterminal::NtItem(item) => item.tokens(), Nonterminal::NtStmt(stmt) => stmt.tokens(), @@ -243,7 +243,7 @@ impl HasTokens for Nonterminal { Nonterminal::NtIdent(..) | Nonterminal::NtLifetime(..) => None, } } - fn tokens_mut(&mut self) -> Option<&mut Option> { + fn tokens_mut(&mut self) -> Option<&mut Option> { match self { Nonterminal::NtItem(item) => item.tokens_mut(), Nonterminal::NtStmt(stmt) => stmt.tokens_mut(), diff --git a/compiler/rustc_ast/src/attr/mod.rs b/compiler/rustc_ast/src/attr/mod.rs index 6b0dac7c2f0b8..a40508494cdc1 100644 --- a/compiler/rustc_ast/src/attr/mod.rs +++ b/compiler/rustc_ast/src/attr/mod.rs @@ -7,9 +7,8 @@ use crate::ast::{MacArgs, MacArgsEq, MacDelimiter, MetaItem, MetaItemKind, Neste use crate::ast::{Path, PathSegment}; use crate::ptr::P; use crate::token::{self, CommentKind, Delimiter, Token}; -use crate::tokenstream::{AttrAnnotatedTokenStream, AttrAnnotatedTokenTree}; use crate::tokenstream::{DelimSpan, Spacing, TokenTree}; -use crate::tokenstream::{LazyTokenStream, TokenStream}; +use crate::tokenstream::{LazyAttrTokenStream, TokenStream}; use crate::util::comments; use rustc_index::bit_set::GrowableBitSet; @@ -296,20 +295,18 @@ impl Attribute { } } - pub fn tokens(&self) -> AttrAnnotatedTokenStream { + pub fn tokens(&self) -> TokenStream { match self.kind { AttrKind::Normal(ref normal) => normal .tokens .as_ref() .unwrap_or_else(|| panic!("attribute is missing tokens: {:?}", self)) - .create_token_stream(), - AttrKind::DocComment(comment_kind, data) => AttrAnnotatedTokenStream::from(( - AttrAnnotatedTokenTree::Token(Token::new( - token::DocComment(comment_kind, self.style, data), - self.span, - )), + .to_attr_token_stream() + .to_tokenstream(), + AttrKind::DocComment(comment_kind, data) => TokenStream::new(vec![TokenTree::Token( + Token::new(token::DocComment(comment_kind, self.style, data), self.span), Spacing::Alone, - )), + )]), } } } @@ -356,7 +353,7 @@ pub fn mk_attr(style: AttrStyle, path: Path, args: MacArgs, span: Span) -> Attri pub fn mk_attr_from_item( item: AttrItem, - tokens: Option, + tokens: Option, style: AttrStyle, span: Span, ) -> Attribute { diff --git a/compiler/rustc_ast/src/lib.rs b/compiler/rustc_ast/src/lib.rs index e5435e3a3d4fa..4d3620ee8b0f0 100644 --- a/compiler/rustc_ast/src/lib.rs +++ b/compiler/rustc_ast/src/lib.rs @@ -15,6 +15,7 @@ #![feature(if_let_guard)] #![cfg_attr(bootstrap, feature(label_break_value))] #![feature(let_chains)] +#![feature(let_else)] #![feature(min_specialization)] #![feature(negative_impls)] #![feature(slice_internals)] diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs index 458d1156ec251..ad68d6e755e02 100644 --- a/compiler/rustc_ast/src/mut_visit.rs +++ b/compiler/rustc_ast/src/mut_visit.rs @@ -642,17 +642,17 @@ pub fn noop_flat_map_param(mut param: Param, vis: &mut T) -> Smal } // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. -pub fn visit_attr_annotated_tt(tt: &mut AttrAnnotatedTokenTree, vis: &mut T) { +pub fn visit_attr_tt(tt: &mut AttrTokenTree, vis: &mut T) { match tt { - AttrAnnotatedTokenTree::Token(token) => { + AttrTokenTree::Token(token, _) => { visit_token(token, vis); } - AttrAnnotatedTokenTree::Delimited(DelimSpan { open, close }, _delim, tts) => { + AttrTokenTree::Delimited(DelimSpan { open, close }, _delim, tts) => { vis.visit_span(open); vis.visit_span(close); - visit_attr_annotated_tts(tts, vis); + visit_attr_tts(tts, vis); } - AttrAnnotatedTokenTree::Attributes(data) => { + AttrTokenTree::Attributes(data) => { for attr in &mut *data.attrs { match &mut attr.kind { AttrKind::Normal(normal) => { @@ -690,27 +690,27 @@ pub fn visit_tts(TokenStream(tts): &mut TokenStream, vis: &mut T) } } -pub fn visit_attr_annotated_tts( - AttrAnnotatedTokenStream(tts): &mut AttrAnnotatedTokenStream, - vis: &mut T, -) { +pub fn visit_attr_tts(AttrTokenStream(tts): &mut AttrTokenStream, vis: &mut T) { if T::VISIT_TOKENS && !tts.is_empty() { let tts = Lrc::make_mut(tts); - visit_vec(tts, |(tree, _is_joint)| visit_attr_annotated_tt(tree, vis)); + visit_vec(tts, |tree| visit_attr_tt(tree, vis)); } } -pub fn visit_lazy_tts_opt_mut(lazy_tts: Option<&mut LazyTokenStream>, vis: &mut T) { +pub fn visit_lazy_tts_opt_mut( + lazy_tts: Option<&mut LazyAttrTokenStream>, + vis: &mut T, +) { if T::VISIT_TOKENS { if let Some(lazy_tts) = lazy_tts { - let mut tts = lazy_tts.create_token_stream(); - visit_attr_annotated_tts(&mut tts, vis); - *lazy_tts = LazyTokenStream::new(tts); + let mut tts = lazy_tts.to_attr_token_stream(); + visit_attr_tts(&mut tts, vis); + *lazy_tts = LazyAttrTokenStream::new(tts); } } } -pub fn visit_lazy_tts(lazy_tts: &mut Option, vis: &mut T) { +pub fn visit_lazy_tts(lazy_tts: &mut Option, vis: &mut T) { visit_lazy_tts_opt_mut(lazy_tts.as_mut(), vis); } diff --git a/compiler/rustc_ast/src/tokenstream.rs b/compiler/rustc_ast/src/tokenstream.rs index b6684c0669b4c..875cd620dfc6c 100644 --- a/compiler/rustc_ast/src/tokenstream.rs +++ b/compiler/rustc_ast/src/tokenstream.rs @@ -121,12 +121,12 @@ where } } -pub trait CreateTokenStream: sync::Send + sync::Sync { - fn create_token_stream(&self) -> AttrAnnotatedTokenStream; +pub trait ToAttrTokenStream: sync::Send + sync::Sync { + fn to_attr_token_stream(&self) -> AttrTokenStream; } -impl CreateTokenStream for AttrAnnotatedTokenStream { - fn create_token_stream(&self) -> AttrAnnotatedTokenStream { +impl ToAttrTokenStream for AttrTokenStream { + fn to_attr_token_stream(&self) -> AttrTokenStream { self.clone() } } @@ -135,68 +135,68 @@ impl CreateTokenStream for AttrAnnotatedTokenStream { /// of an actual `TokenStream` until it is needed. /// `Box` is here only to reduce the structure size. #[derive(Clone)] -pub struct LazyTokenStream(Lrc>); +pub struct LazyAttrTokenStream(Lrc>); -impl LazyTokenStream { - pub fn new(inner: impl CreateTokenStream + 'static) -> LazyTokenStream { - LazyTokenStream(Lrc::new(Box::new(inner))) +impl LazyAttrTokenStream { + pub fn new(inner: impl ToAttrTokenStream + 'static) -> LazyAttrTokenStream { + LazyAttrTokenStream(Lrc::new(Box::new(inner))) } - pub fn create_token_stream(&self) -> AttrAnnotatedTokenStream { - self.0.create_token_stream() + pub fn to_attr_token_stream(&self) -> AttrTokenStream { + self.0.to_attr_token_stream() } } -impl fmt::Debug for LazyTokenStream { +impl fmt::Debug for LazyAttrTokenStream { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "LazyTokenStream({:?})", self.create_token_stream()) + write!(f, "LazyAttrTokenStream({:?})", self.to_attr_token_stream()) } } -impl Encodable for LazyTokenStream { +impl Encodable for LazyAttrTokenStream { fn encode(&self, s: &mut S) { // Used by AST json printing. - Encodable::encode(&self.create_token_stream(), s); + Encodable::encode(&self.to_attr_token_stream(), s); } } -impl Decodable for LazyTokenStream { +impl Decodable for LazyAttrTokenStream { fn decode(_d: &mut D) -> Self { - panic!("Attempted to decode LazyTokenStream"); + panic!("Attempted to decode LazyAttrTokenStream"); } } -impl HashStable for LazyTokenStream { +impl HashStable for LazyAttrTokenStream { fn hash_stable(&self, _hcx: &mut CTX, _hasher: &mut StableHasher) { - panic!("Attempted to compute stable hash for LazyTokenStream"); + panic!("Attempted to compute stable hash for LazyAttrTokenStream"); } } -/// A `AttrAnnotatedTokenStream` is similar to a `TokenStream`, but with extra +/// An `AttrTokenStream` is similar to a `TokenStream`, but with extra /// information about the tokens for attribute targets. This is used /// during expansion to perform early cfg-expansion, and to process attributes /// during proc-macro invocations. #[derive(Clone, Debug, Default, Encodable, Decodable)] -pub struct AttrAnnotatedTokenStream(pub Lrc>); +pub struct AttrTokenStream(pub Lrc>); -/// Like `TokenTree`, but for `AttrAnnotatedTokenStream` +/// Like `TokenTree`, but for `AttrTokenStream`. #[derive(Clone, Debug, Encodable, Decodable)] -pub enum AttrAnnotatedTokenTree { - Token(Token), - Delimited(DelimSpan, Delimiter, AttrAnnotatedTokenStream), +pub enum AttrTokenTree { + Token(Token, Spacing), + Delimited(DelimSpan, Delimiter, AttrTokenStream), /// Stores the attributes for an attribute target, /// along with the tokens for that attribute target. /// See `AttributesData` for more information Attributes(AttributesData), } -impl AttrAnnotatedTokenStream { - pub fn new(tokens: Vec<(AttrAnnotatedTokenTree, Spacing)>) -> AttrAnnotatedTokenStream { - AttrAnnotatedTokenStream(Lrc::new(tokens)) +impl AttrTokenStream { + pub fn new(tokens: Vec) -> AttrTokenStream { + AttrTokenStream(Lrc::new(tokens)) } - /// Converts this `AttrAnnotatedTokenStream` to a plain `TokenStream - /// During conversion, `AttrAnnotatedTokenTree::Attributes` get 'flattened' + /// Converts this `AttrTokenStream` to a plain `TokenStream`. + /// During conversion, `AttrTokenTree::Attributes` get 'flattened' /// back to a `TokenStream` of the form `outer_attr attr_target`. /// If there are inner attributes, they are inserted into the proper /// place in the attribute target tokens. @@ -204,31 +204,27 @@ impl AttrAnnotatedTokenStream { let trees: Vec<_> = self .0 .iter() - .flat_map(|tree| match &tree.0 { - AttrAnnotatedTokenTree::Token(inner) => { - smallvec![TokenTree::Token(inner.clone(), tree.1)].into_iter() + .flat_map(|tree| match &tree { + AttrTokenTree::Token(inner, spacing) => { + smallvec![TokenTree::Token(inner.clone(), *spacing)].into_iter() } - AttrAnnotatedTokenTree::Delimited(span, delim, stream) => { + AttrTokenTree::Delimited(span, delim, stream) => { smallvec![TokenTree::Delimited(*span, *delim, stream.to_tokenstream()),] .into_iter() } - AttrAnnotatedTokenTree::Attributes(data) => { + AttrTokenTree::Attributes(data) => { let mut outer_attrs = Vec::new(); let mut inner_attrs = Vec::new(); for attr in &data.attrs { match attr.style { - crate::AttrStyle::Outer => { - outer_attrs.push(attr); - } - crate::AttrStyle::Inner => { - inner_attrs.push(attr); - } + crate::AttrStyle::Outer => outer_attrs.push(attr), + crate::AttrStyle::Inner => inner_attrs.push(attr), } } let mut target_tokens: Vec<_> = data .tokens - .create_token_stream() + .to_attr_token_stream() .to_tokenstream() .0 .iter() @@ -239,9 +235,9 @@ impl AttrAnnotatedTokenStream { // Check the last two trees (to account for a trailing semi) for tree in target_tokens.iter_mut().rev().take(2) { if let TokenTree::Delimited(span, delim, delim_tokens) = tree { - // Inner attributes are only supported on extern blocks, functions, impls, - // and modules. All of these have their inner attributes placed at - // the beginning of the rightmost outermost braced group: + // Inner attributes are only supported on extern blocks, functions, + // impls, and modules. All of these have their inner attributes + // placed at the beginning of the rightmost outermost braced group: // e.g. fn foo() { #![my_attr} } // // Therefore, we can insert them back into the right location @@ -255,7 +251,7 @@ impl AttrAnnotatedTokenStream { let mut builder = TokenStreamBuilder::new(); for inner_attr in inner_attrs { - builder.push(inner_attr.tokens().to_tokenstream()); + builder.push(inner_attr.tokens()); } builder.push(delim_tokens.clone()); *tree = TokenTree::Delimited(*span, *delim, builder.build()); @@ -273,7 +269,7 @@ impl AttrAnnotatedTokenStream { let mut flat: SmallVec<[_; 1]> = SmallVec::new(); for attr in outer_attrs { // FIXME: Make this more efficient - flat.extend(attr.tokens().to_tokenstream().0.clone().iter().cloned()); + flat.extend(attr.tokens().0.clone().iter().cloned()); } flat.extend(target_tokens); flat.into_iter() @@ -300,7 +296,7 @@ pub struct AttributesData { pub attrs: AttrVec, /// The underlying tokens for the attribute target that `attrs` /// are applied to - pub tokens: LazyTokenStream, + pub tokens: LazyAttrTokenStream, } /// A `TokenStream` is an abstract sequence of tokens, organized into [`TokenTree`]s. @@ -363,12 +359,6 @@ impl TokenStream { } } -impl From<(AttrAnnotatedTokenTree, Spacing)> for AttrAnnotatedTokenStream { - fn from((tree, spacing): (AttrAnnotatedTokenTree, Spacing)) -> AttrAnnotatedTokenStream { - AttrAnnotatedTokenStream::new(vec![(tree, spacing)]) - } -} - impl iter::FromIterator for TokenStream { fn from_iter>(iter: I) -> Self { TokenStream::new(iter.into_iter().collect::>()) @@ -420,22 +410,6 @@ impl TokenStream { TokenStream(Lrc::new(self.0.iter().enumerate().map(|(i, tree)| f(i, tree)).collect())) } - fn opt_from_ast(node: &(impl HasAttrs + HasTokens)) -> Option { - let tokens = node.tokens()?; - let attrs = node.attrs(); - let attr_annotated = if attrs.is_empty() { - tokens.create_token_stream() - } else { - let attr_data = - AttributesData { attrs: attrs.iter().cloned().collect(), tokens: tokens.clone() }; - AttrAnnotatedTokenStream::new(vec![( - AttrAnnotatedTokenTree::Attributes(attr_data), - Spacing::Alone, - )]) - }; - Some(attr_annotated.to_tokenstream()) - } - // Create a token stream containing a single token with alone spacing. pub fn token_alone(kind: TokenKind, span: Span) -> TokenStream { TokenStream::new(vec![TokenTree::token_alone(kind, span)]) @@ -452,8 +426,18 @@ impl TokenStream { } pub fn from_ast(node: &(impl HasAttrs + HasSpan + HasTokens + fmt::Debug)) -> TokenStream { - TokenStream::opt_from_ast(node) - .unwrap_or_else(|| panic!("missing tokens for node at {:?}: {:?}", node.span(), node)) + let Some(tokens) = node.tokens() else { + panic!("missing tokens for node at {:?}: {:?}", node.span(), node); + }; + let attrs = node.attrs(); + let attr_stream = if attrs.is_empty() { + tokens.to_attr_token_stream() + } else { + let attr_data = + AttributesData { attrs: attrs.iter().cloned().collect(), tokens: tokens.clone() }; + AttrTokenStream::new(vec![AttrTokenTree::Attributes(attr_data)]) + }; + attr_stream.to_tokenstream() } pub fn from_nonterminal_ast(nt: &Nonterminal) -> TokenStream { diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs index f929549d70448..cd03e3fb4572d 100644 --- a/compiler/rustc_ast_lowering/src/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs @@ -146,13 +146,19 @@ impl<'hir> LoweringContext<'_, 'hir> { |this| this.with_new_scopes(|this| this.lower_block_expr(block)), ), ExprKind::Await(ref expr) => { - let span = if expr.span.hi() < e.span.hi() { - expr.span.shrink_to_hi().with_hi(e.span.hi()) + let dot_await_span = if expr.span.hi() < e.span.hi() { + let span_with_whitespace = self + .tcx + .sess + .source_map() + .span_extend_while(expr.span, char::is_whitespace) + .unwrap_or(expr.span); + span_with_whitespace.shrink_to_hi().with_hi(e.span.hi()) } else { // this is a recovered `await expr` e.span }; - self.lower_expr_await(span, expr) + self.lower_expr_await(dot_await_span, expr) } ExprKind::Closure( ref binder, diff --git a/compiler/rustc_builtin_macros/src/cfg_eval.rs b/compiler/rustc_builtin_macros/src/cfg_eval.rs index 89b2c329236d4..e673dff0dea8e 100644 --- a/compiler/rustc_builtin_macros/src/cfg_eval.rs +++ b/compiler/rustc_builtin_macros/src/cfg_eval.rs @@ -188,14 +188,14 @@ impl CfgEval<'_, '_> { let orig_tokens = annotatable.to_tokens().flattened(); // Re-parse the tokens, setting the `capture_cfg` flag to save extra information - // to the captured `AttrAnnotatedTokenStream` (specifically, we capture - // `AttrAnnotatedTokenTree::AttributesData` for all occurrences of `#[cfg]` and `#[cfg_attr]`) + // to the captured `AttrTokenStream` (specifically, we capture + // `AttrTokenTree::AttributesData` for all occurrences of `#[cfg]` and `#[cfg_attr]`) let mut parser = rustc_parse::stream_to_parser(&self.cfg.sess.parse_sess, orig_tokens, None); parser.capture_cfg = true; annotatable = parse_annotatable_with(&mut parser); - // Now that we have our re-parsed `AttrAnnotatedTokenStream`, recursively configuring + // Now that we have our re-parsed `AttrTokenStream`, recursively configuring // our attribute target will correctly the tokens as well. flat_map_annotatable(self, annotatable) } diff --git a/compiler/rustc_errors/src/emitter.rs b/compiler/rustc_errors/src/emitter.rs index 1d260f7cafccd..016404c5f6737 100644 --- a/compiler/rustc_errors/src/emitter.rs +++ b/compiler/rustc_errors/src/emitter.rs @@ -268,7 +268,10 @@ pub trait Emitter: Translate { SuggestionStyle::ShowAlways, ].contains(&sugg.style) { - let substitution = &sugg.substitutions[0].parts[0].snippet.trim(); + // Don't trim the substitution if it's only whitespace changes + let substitution = &sugg.substitutions[0].parts[0].snippet; + let substitution = + if substitution.trim().is_empty() { substitution } else { substitution.trim() }; let msg = if substitution.is_empty() || sugg.style.hide_inline() { // This substitution is only removal OR we explicitly don't want to show the // code inline (`hide_inline`). Therefore, we don't show the substitution. @@ -1704,7 +1707,7 @@ impl EmitterWriter { { notice_capitalization |= only_capitalization; - let has_deletion = parts.iter().any(|p| p.is_deletion()); + let has_deletion = parts.iter().any(|p| p.is_deletion(sm)); let is_multiline = complete.lines().count() > 1; if let Some(span) = span.primary_span() { @@ -1880,16 +1883,23 @@ impl EmitterWriter { let span_start_pos = sm.lookup_char_pos(part.span.lo()).col_display; let span_end_pos = sm.lookup_char_pos(part.span.hi()).col_display; + // If this addition is _only_ whitespace, then don't trim it, + // or else we're just not rendering anything. + let is_whitespace_addition = part.snippet.trim().is_empty(); + // Do not underline the leading... - let start = part.snippet.len().saturating_sub(part.snippet.trim_start().len()); + let start = if is_whitespace_addition { + 0 + } else { + part.snippet.len().saturating_sub(part.snippet.trim_start().len()) + }; // ...or trailing spaces. Account for substitutions containing unicode // characters. - let sub_len: usize = part - .snippet - .trim() - .chars() - .map(|ch| unicode_width::UnicodeWidthChar::width(ch).unwrap_or(1)) - .sum(); + let sub_len: usize = + if is_whitespace_addition { &part.snippet } else { part.snippet.trim() } + .chars() + .map(|ch| unicode_width::UnicodeWidthChar::width(ch).unwrap_or(1)) + .sum(); let offset: isize = offsets .iter() @@ -2130,7 +2140,7 @@ impl EmitterWriter { } } -#[derive(Clone, Copy)] +#[derive(Clone, Copy, Debug)] enum DisplaySuggestion { Underline, Diff, diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index fb7ae6f99cf5a..888128f3f74e7 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -150,21 +150,20 @@ pub struct SubstitutionHighlight { impl SubstitutionPart { pub fn is_addition(&self, sm: &SourceMap) -> bool { - !self.snippet.is_empty() - && sm - .span_to_snippet(self.span) - .map_or(self.span.is_empty(), |snippet| snippet.trim().is_empty()) + !self.snippet.is_empty() && !self.replaces_meaningful_content(sm) } - pub fn is_deletion(&self) -> bool { - self.snippet.trim().is_empty() + pub fn is_deletion(&self, sm: &SourceMap) -> bool { + self.snippet.trim().is_empty() && self.replaces_meaningful_content(sm) } pub fn is_replacement(&self, sm: &SourceMap) -> bool { - !self.snippet.is_empty() - && sm - .span_to_snippet(self.span) - .map_or(!self.span.is_empty(), |snippet| !snippet.trim().is_empty()) + !self.snippet.is_empty() && self.replaces_meaningful_content(sm) + } + + fn replaces_meaningful_content(&self, sm: &SourceMap) -> bool { + sm.span_to_snippet(self.span) + .map_or(!self.span.is_empty(), |snippet| !snippet.trim().is_empty()) } } diff --git a/compiler/rustc_expand/src/config.rs b/compiler/rustc_expand/src/config.rs index 48ee23d2c3d18..7d30596a936f9 100644 --- a/compiler/rustc_expand/src/config.rs +++ b/compiler/rustc_expand/src/config.rs @@ -2,9 +2,9 @@ use rustc_ast::ptr::P; use rustc_ast::token::{Delimiter, Token, TokenKind}; -use rustc_ast::tokenstream::{AttrAnnotatedTokenStream, AttrAnnotatedTokenTree}; +use rustc_ast::tokenstream::{AttrTokenStream, AttrTokenTree}; use rustc_ast::tokenstream::{DelimSpan, Spacing}; -use rustc_ast::tokenstream::{LazyTokenStream, TokenTree}; +use rustc_ast::tokenstream::{LazyAttrTokenStream, TokenTree}; use rustc_ast::NodeId; use rustc_ast::{self as ast, AttrStyle, Attribute, HasAttrs, HasTokens, MetaItem}; use rustc_attr as attr; @@ -259,8 +259,8 @@ impl<'a> StripUnconfigured<'a> { fn try_configure_tokens(&self, node: &mut T) { if self.config_tokens { if let Some(Some(tokens)) = node.tokens_mut() { - let attr_annotated_tokens = tokens.create_token_stream(); - *tokens = LazyTokenStream::new(self.configure_tokens(&attr_annotated_tokens)); + let attr_stream = tokens.to_attr_token_stream(); + *tokens = LazyAttrTokenStream::new(self.configure_tokens(&attr_stream)); } } } @@ -270,16 +270,16 @@ impl<'a> StripUnconfigured<'a> { if self.in_cfg(&attrs) { Some(attrs) } else { None } } - /// Performs cfg-expansion on `stream`, producing a new `AttrAnnotatedTokenStream`. + /// Performs cfg-expansion on `stream`, producing a new `AttrTokenStream`. /// This is only used during the invocation of `derive` proc-macros, /// which require that we cfg-expand their entire input. /// Normal cfg-expansion operates on parsed AST nodes via the `configure` method - fn configure_tokens(&self, stream: &AttrAnnotatedTokenStream) -> AttrAnnotatedTokenStream { - fn can_skip(stream: &AttrAnnotatedTokenStream) -> bool { - stream.0.iter().all(|(tree, _spacing)| match tree { - AttrAnnotatedTokenTree::Attributes(_) => false, - AttrAnnotatedTokenTree::Token(_) => true, - AttrAnnotatedTokenTree::Delimited(_, _, inner) => can_skip(inner), + fn configure_tokens(&self, stream: &AttrTokenStream) -> AttrTokenStream { + fn can_skip(stream: &AttrTokenStream) -> bool { + stream.0.iter().all(|tree| match tree { + AttrTokenTree::Attributes(_) => false, + AttrTokenTree::Token(..) => true, + AttrTokenTree::Delimited(_, _, inner) => can_skip(inner), }) } @@ -290,36 +290,36 @@ impl<'a> StripUnconfigured<'a> { let trees: Vec<_> = stream .0 .iter() - .flat_map(|(tree, spacing)| match tree.clone() { - AttrAnnotatedTokenTree::Attributes(mut data) => { + .flat_map(|tree| match tree.clone() { + AttrTokenTree::Attributes(mut data) => { data.attrs.flat_map_in_place(|attr| self.process_cfg_attr(attr)); if self.in_cfg(&data.attrs) { - data.tokens = LazyTokenStream::new( - self.configure_tokens(&data.tokens.create_token_stream()), + data.tokens = LazyAttrTokenStream::new( + self.configure_tokens(&data.tokens.to_attr_token_stream()), ); - Some((AttrAnnotatedTokenTree::Attributes(data), *spacing)).into_iter() + Some(AttrTokenTree::Attributes(data)).into_iter() } else { None.into_iter() } } - AttrAnnotatedTokenTree::Delimited(sp, delim, mut inner) => { + AttrTokenTree::Delimited(sp, delim, mut inner) => { inner = self.configure_tokens(&inner); - Some((AttrAnnotatedTokenTree::Delimited(sp, delim, inner), *spacing)) + Some(AttrTokenTree::Delimited(sp, delim, inner)) .into_iter() } - AttrAnnotatedTokenTree::Token(ref token) if let TokenKind::Interpolated(ref nt) = token.kind => { + AttrTokenTree::Token(ref token, _) if let TokenKind::Interpolated(ref nt) = token.kind => { panic!( "Nonterminal should have been flattened at {:?}: {:?}", token.span, nt ); } - AttrAnnotatedTokenTree::Token(token) => { - Some((AttrAnnotatedTokenTree::Token(token), *spacing)).into_iter() + AttrTokenTree::Token(token, spacing) => { + Some(AttrTokenTree::Token(token, spacing)).into_iter() } }) .collect(); - AttrAnnotatedTokenStream::new(trees) + AttrTokenStream::new(trees) } /// Parse and expand all `cfg_attr` attributes into a list of attributes @@ -388,7 +388,7 @@ impl<'a> StripUnconfigured<'a> { attr: &Attribute, (item, item_span): (ast::AttrItem, Span), ) -> Attribute { - let orig_tokens = attr.tokens().to_tokenstream(); + let orig_tokens = attr.tokens(); // We are taking an attribute of the form `#[cfg_attr(pred, attr)]` // and producing an attribute of the form `#[attr]`. We @@ -404,26 +404,26 @@ impl<'a> StripUnconfigured<'a> { }; let pound_span = pound_token.span; - let mut trees = vec![(AttrAnnotatedTokenTree::Token(pound_token), Spacing::Alone)]; + let mut trees = vec![AttrTokenTree::Token(pound_token, Spacing::Alone)]; if attr.style == AttrStyle::Inner { // For inner attributes, we do the same thing for the `!` in `#![some_attr]` let TokenTree::Token(bang_token @ Token { kind: TokenKind::Not, .. }, _) = orig_trees.next().unwrap() else { panic!("Bad tokens for attribute {:?}", attr); }; - trees.push((AttrAnnotatedTokenTree::Token(bang_token), Spacing::Alone)); + trees.push(AttrTokenTree::Token(bang_token, Spacing::Alone)); } // We don't really have a good span to use for the synthesized `[]` // in `#[attr]`, so just use the span of the `#` token. - let bracket_group = AttrAnnotatedTokenTree::Delimited( + let bracket_group = AttrTokenTree::Delimited( DelimSpan::from_single(pound_span), Delimiter::Bracket, item.tokens .as_ref() .unwrap_or_else(|| panic!("Missing tokens for {:?}", item)) - .create_token_stream(), + .to_attr_token_stream(), ); - trees.push((bracket_group, Spacing::Alone)); - let tokens = Some(LazyTokenStream::new(AttrAnnotatedTokenStream::new(trees))); + trees.push(bracket_group); + let tokens = Some(LazyAttrTokenStream::new(AttrTokenStream::new(trees))); let attr = attr::mk_attr_from_item(item, tokens, attr.style, item_span); if attr.has_name(sym::crate_type) { self.sess.parse_sess.buffer_lint( diff --git a/compiler/rustc_parse/src/parser/attr.rs b/compiler/rustc_parse/src/parser/attr.rs index 77a6bde1c164e..a37f828eafb9b 100644 --- a/compiler/rustc_parse/src/parser/attr.rs +++ b/compiler/rustc_parse/src/parser/attr.rs @@ -301,9 +301,9 @@ impl<'a> Parser<'a> { if let Some(attr) = attr { let end_pos: u32 = self.token_cursor.num_next_calls.try_into().unwrap(); // If we are currently capturing tokens, mark the location of this inner attribute. - // If capturing ends up creating a `LazyTokenStream`, we will include + // If capturing ends up creating a `LazyAttrTokenStream`, we will include // this replace range with it, removing the inner attribute from the final - // `AttrAnnotatedTokenStream`. Inner attributes are stored in the parsed AST note. + // `AttrTokenStream`. Inner attributes are stored in the parsed AST note. // During macro expansion, they are selectively inserted back into the // token stream (the first inner attribute is removed each time we invoke the // corresponding macro). diff --git a/compiler/rustc_parse/src/parser/attr_wrapper.rs b/compiler/rustc_parse/src/parser/attr_wrapper.rs index 2e58605cf19b0..5fdafd187c660 100644 --- a/compiler/rustc_parse/src/parser/attr_wrapper.rs +++ b/compiler/rustc_parse/src/parser/attr_wrapper.rs @@ -1,7 +1,7 @@ use super::{Capturing, FlatToken, ForceCollect, Parser, ReplaceRange, TokenCursor, TrailingToken}; use rustc_ast::token::{self, Delimiter, Token, TokenKind}; -use rustc_ast::tokenstream::{AttrAnnotatedTokenStream, AttributesData, CreateTokenStream}; -use rustc_ast::tokenstream::{AttrAnnotatedTokenTree, DelimSpan, LazyTokenStream, Spacing}; +use rustc_ast::tokenstream::{AttrTokenStream, AttributesData, ToAttrTokenStream}; +use rustc_ast::tokenstream::{AttrTokenTree, DelimSpan, LazyAttrTokenStream, Spacing}; use rustc_ast::{self as ast}; use rustc_ast::{AttrVec, Attribute, HasAttrs, HasTokens}; use rustc_errors::PResult; @@ -88,7 +88,7 @@ fn has_cfg_or_cfg_attr(attrs: &[Attribute]) -> bool { // This also makes `Parser` very cheap to clone, since // there is no intermediate collection buffer to clone. #[derive(Clone)] -struct LazyTokenStreamImpl { +struct LazyAttrTokenStreamImpl { start_token: (Token, Spacing), cursor_snapshot: TokenCursor, num_calls: usize, @@ -97,10 +97,10 @@ struct LazyTokenStreamImpl { } #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))] -rustc_data_structures::static_assert_size!(LazyTokenStreamImpl, 144); +rustc_data_structures::static_assert_size!(LazyAttrTokenStreamImpl, 144); -impl CreateTokenStream for LazyTokenStreamImpl { - fn create_token_stream(&self) -> AttrAnnotatedTokenStream { +impl ToAttrTokenStream for LazyAttrTokenStreamImpl { + fn to_attr_token_stream(&self) -> AttrTokenStream { // The token produced by the final call to `{,inlined_}next` was not // actually consumed by the callback. The combination of chaining the // initial token and using `take` produces the desired result - we @@ -179,7 +179,7 @@ impl CreateTokenStream for LazyTokenStreamImpl { impl<'a> Parser<'a> { /// Records all tokens consumed by the provided callback, /// including the current token. These tokens are collected - /// into a `LazyTokenStream`, and returned along with the result + /// into a `LazyAttrTokenStream`, and returned along with the result /// of the callback. /// /// Note: If your callback consumes an opening delimiter @@ -297,8 +297,8 @@ impl<'a> Parser<'a> { // If we 'broke' the last token (e.g. breaking a '>>' token to two '>' tokens), // then extend the range of captured tokens to include it, since the parser - // was not actually bumped past it. When the `LazyTokenStream` gets converted - // into an `AttrAnnotatedTokenStream`, we will create the proper token. + // was not actually bumped past it. When the `LazyAttrTokenStream` gets converted + // into an `AttrTokenStream`, we will create the proper token. if self.token_cursor.break_last_token { assert_eq!( trailing, @@ -316,8 +316,8 @@ impl<'a> Parser<'a> { Box::new([]) } else { // Grab any replace ranges that occur *inside* the current AST node. - // We will perform the actual replacement when we convert the `LazyTokenStream` - // to an `AttrAnnotatedTokenStream` + // We will perform the actual replacement when we convert the `LazyAttrTokenStream` + // to an `AttrTokenStream`. let start_calls: u32 = cursor_snapshot_next_calls.try_into().unwrap(); self.capture_state.replace_ranges[replace_ranges_start..replace_ranges_end] .iter() @@ -329,7 +329,7 @@ impl<'a> Parser<'a> { .collect() }; - let tokens = LazyTokenStream::new(LazyTokenStreamImpl { + let tokens = LazyAttrTokenStream::new(LazyAttrTokenStreamImpl { start_token, num_calls, cursor_snapshot, @@ -392,12 +392,12 @@ impl<'a> Parser<'a> { fn make_token_stream( mut iter: impl Iterator, break_last_token: bool, -) -> AttrAnnotatedTokenStream { +) -> AttrTokenStream { #[derive(Debug)] struct FrameData { // This is `None` for the first frame, `Some` for all others. open_delim_sp: Option<(Delimiter, Span)>, - inner: Vec<(AttrAnnotatedTokenTree, Spacing)>, + inner: Vec, } let mut stack = vec![FrameData { open_delim_sp: None, inner: vec![] }]; let mut token_and_spacing = iter.next(); @@ -418,48 +418,47 @@ fn make_token_stream( open_delim, span ); let dspan = DelimSpan::from_pair(open_sp, span); - let stream = AttrAnnotatedTokenStream::new(frame_data.inner); - let delimited = AttrAnnotatedTokenTree::Delimited(dspan, delim, stream); + let stream = AttrTokenStream::new(frame_data.inner); + let delimited = AttrTokenTree::Delimited(dspan, delim, stream); stack .last_mut() .unwrap_or_else(|| { panic!("Bottom token frame is missing for token: {:?}", token) }) .inner - .push((delimited, Spacing::Alone)); + .push(delimited); } FlatToken::Token(token) => stack .last_mut() .expect("Bottom token frame is missing!") .inner - .push((AttrAnnotatedTokenTree::Token(token), spacing)), + .push(AttrTokenTree::Token(token, spacing)), FlatToken::AttrTarget(data) => stack .last_mut() .expect("Bottom token frame is missing!") .inner - .push((AttrAnnotatedTokenTree::Attributes(data), spacing)), + .push(AttrTokenTree::Attributes(data)), FlatToken::Empty => {} } token_and_spacing = iter.next(); } let mut final_buf = stack.pop().expect("Missing final buf!"); if break_last_token { - let (last_token, spacing) = final_buf.inner.pop().unwrap(); - if let AttrAnnotatedTokenTree::Token(last_token) = last_token { + let last_token = final_buf.inner.pop().unwrap(); + if let AttrTokenTree::Token(last_token, spacing) = last_token { let unglued_first = last_token.kind.break_two_token_op().unwrap().0; // An 'unglued' token is always two ASCII characters let mut first_span = last_token.span.shrink_to_lo(); first_span = first_span.with_hi(first_span.lo() + rustc_span::BytePos(1)); - final_buf.inner.push(( - AttrAnnotatedTokenTree::Token(Token::new(unglued_first, first_span)), - spacing, - )); + final_buf + .inner + .push(AttrTokenTree::Token(Token::new(unglued_first, first_span), spacing)); } else { panic!("Unexpected last token {:?}", last_token) } } assert!(stack.is_empty(), "Stack should be empty: final_buf={:?} stack={:?}", final_buf, stack); - AttrAnnotatedTokenStream::new(final_buf.inner) + AttrTokenStream::new(final_buf.inner) } diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs index 5c8f374255c7f..4cb198561e0ad 100644 --- a/compiler/rustc_parse/src/parser/mod.rs +++ b/compiler/rustc_parse/src/parser/mod.rs @@ -170,7 +170,7 @@ pub struct ClosureSpans { /// attribute, we parse a nested AST node that has `#[cfg]` or `#[cfg_attr]` /// In this case, we use a `ReplaceRange` to replace the entire inner AST node /// with `FlatToken::AttrTarget`, allowing us to perform eager cfg-expansion -/// on an `AttrAnnotatedTokenStream` +/// on an `AttrTokenStream`. /// /// 2. When we parse an inner attribute while collecting tokens. We /// remove inner attributes from the token stream entirely, and @@ -183,7 +183,7 @@ pub type ReplaceRange = (Range, Vec<(FlatToken, Spacing)>); /// Controls how we capture tokens. Capturing can be expensive, /// so we try to avoid performing capturing in cases where -/// we will never need an `AttrAnnotatedTokenStream` +/// we will never need an `AttrTokenStream`. #[derive(Copy, Clone)] pub enum Capturing { /// We aren't performing any capturing - this is the default mode. @@ -237,7 +237,7 @@ struct TokenCursor { // the trailing `>>` token. The `break_last_token` // field is used to track this token - it gets // appended to the captured stream when - // we evaluate a `LazyTokenStream` + // we evaluate a `LazyAttrTokenStream`. break_last_token: bool, } @@ -1464,11 +1464,11 @@ pub fn emit_unclosed_delims(unclosed_delims: &mut Vec, sess: &Pa } } -/// A helper struct used when building an `AttrAnnotatedTokenStream` from -/// a `LazyTokenStream`. Both delimiter and non-delimited tokens +/// A helper struct used when building an `AttrTokenStream` from +/// a `LazyAttrTokenStream`. Both delimiter and non-delimited tokens /// are stored as `FlatToken::Token`. A vector of `FlatToken`s -/// is then 'parsed' to build up an `AttrAnnotatedTokenStream` with nested -/// `AttrAnnotatedTokenTree::Delimited` tokens +/// is then 'parsed' to build up an `AttrTokenStream` with nested +/// `AttrTokenTree::Delimited` tokens. #[derive(Debug, Clone)] pub enum FlatToken { /// A token - this holds both delimiter (e.g. '{' and '}') @@ -1476,11 +1476,11 @@ pub enum FlatToken { Token(Token), /// Holds the `AttributesData` for an AST node. The /// `AttributesData` is inserted directly into the - /// constructed `AttrAnnotatedTokenStream` as - /// an `AttrAnnotatedTokenTree::Attributes` + /// constructed `AttrTokenStream` as + /// an `AttrTokenTree::Attributes`. AttrTarget(AttributesData), /// A special 'empty' token that is ignored during the conversion - /// to an `AttrAnnotatedTokenStream`. This is used to simplify the + /// to an `AttrTokenStream`. This is used to simplify the /// handling of replace ranges. Empty, } diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index ecbeb9d79b118..cb605cacc9c98 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -1160,8 +1160,8 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { // and if not maybe suggest doing something else? If we kept the expression around we // could also check if it is an fn call (very likely) and suggest changing *that*, if // it is from the local crate. - err.span_suggestion_verbose( - expr.span.shrink_to_hi().with_hi(span.hi()), + err.span_suggestion( + span, "remove the `.await`", "", Applicability::MachineApplicable, diff --git a/compiler/rustc_typeck/src/astconv/mod.rs b/compiler/rustc_typeck/src/astconv/mod.rs index d9789d5aaf031..95c7e3e39aa12 100644 --- a/compiler/rustc_typeck/src/astconv/mod.rs +++ b/compiler/rustc_typeck/src/astconv/mod.rs @@ -2672,7 +2672,10 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { self.normalize_ty(ast_ty.span, array_ty) } hir::TyKind::Typeof(ref e) => { - let ty = tcx.type_of(tcx.hir().local_def_id(e.hir_id)); + let ty_erased = tcx.type_of(tcx.hir().local_def_id(e.hir_id)); + let ty = tcx.fold_regions(ty_erased, |r, _| { + if r.is_erased() { tcx.lifetimes.re_static } else { r } + }); let span = ast_ty.span; tcx.sess.emit_err(TypeofReservedKeywordUsed { span, diff --git a/library/core/src/ffi/c_str.rs b/library/core/src/ffi/c_str.rs index 970830045b812..21f80ec025a81 100644 --- a/library/core/src/ffi/c_str.rs +++ b/library/core/src/ffi/c_str.rs @@ -120,10 +120,10 @@ enum FromBytesWithNulErrorKind { } impl FromBytesWithNulError { - fn interior_nul(pos: usize) -> FromBytesWithNulError { + const fn interior_nul(pos: usize) -> FromBytesWithNulError { FromBytesWithNulError { kind: FromBytesWithNulErrorKind::InteriorNul(pos) } } - fn not_nul_terminated() -> FromBytesWithNulError { + const fn not_nul_terminated() -> FromBytesWithNulError { FromBytesWithNulError { kind: FromBytesWithNulErrorKind::NotNulTerminated } } @@ -294,7 +294,8 @@ impl CStr { /// ``` /// #[unstable(feature = "cstr_from_bytes_until_nul", issue = "95027")] - pub fn from_bytes_until_nul(bytes: &[u8]) -> Result<&CStr, FromBytesUntilNulError> { + #[rustc_const_unstable(feature = "cstr_from_bytes_until_nul", issue = "95027")] + pub const fn from_bytes_until_nul(bytes: &[u8]) -> Result<&CStr, FromBytesUntilNulError> { let nul_pos = memchr::memchr(0, bytes); match nul_pos { Some(nul_pos) => { @@ -343,7 +344,8 @@ impl CStr { /// assert!(cstr.is_err()); /// ``` #[stable(feature = "cstr_from_bytes", since = "1.10.0")] - pub fn from_bytes_with_nul(bytes: &[u8]) -> Result<&Self, FromBytesWithNulError> { + #[rustc_const_unstable(feature = "const_cstr_methods", issue = "101719")] + pub const fn from_bytes_with_nul(bytes: &[u8]) -> Result<&Self, FromBytesWithNulError> { let nul_pos = memchr::memchr(0, bytes); match nul_pos { Some(nul_pos) if nul_pos + 1 == bytes.len() => { @@ -493,7 +495,8 @@ impl CStr { #[must_use = "this returns the result of the operation, \ without modifying the original"] #[stable(feature = "rust1", since = "1.0.0")] - pub fn to_bytes(&self) -> &[u8] { + #[rustc_const_unstable(feature = "const_cstr_methods", issue = "101719")] + pub const fn to_bytes(&self) -> &[u8] { let bytes = self.to_bytes_with_nul(); // SAFETY: to_bytes_with_nul returns slice with length at least 1 unsafe { bytes.get_unchecked(..bytes.len() - 1) } @@ -520,7 +523,8 @@ impl CStr { #[must_use = "this returns the result of the operation, \ without modifying the original"] #[stable(feature = "rust1", since = "1.0.0")] - pub fn to_bytes_with_nul(&self) -> &[u8] { + #[rustc_const_unstable(feature = "const_cstr_methods", issue = "101719")] + pub const fn to_bytes_with_nul(&self) -> &[u8] { // SAFETY: Transmuting a slice of `c_char`s to a slice of `u8`s // is safe on all supported targets. unsafe { &*(&self.inner as *const [c_char] as *const [u8]) } @@ -543,7 +547,8 @@ impl CStr { /// assert_eq!(cstr.to_str(), Ok("foo")); /// ``` #[stable(feature = "cstr_to_str", since = "1.4.0")] - pub fn to_str(&self) -> Result<&str, str::Utf8Error> { + #[rustc_const_unstable(feature = "const_cstr_methods", issue = "101719")] + pub const fn to_str(&self) -> Result<&str, str::Utf8Error> { // N.B., when `CStr` is changed to perform the length check in `.to_bytes()` // instead of in `from_ptr()`, it may be worth considering if this should // be rewritten to do the UTF-8 check inline with the length calculation diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index 5b1e2045fff63..5621d15c1cd6f 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -159,6 +159,7 @@ #![feature(const_slice_from_ref)] #![feature(const_slice_index)] #![feature(const_is_char_boundary)] +#![feature(const_cstr_methods)] // // Language features: #![feature(abi_unadjusted)] diff --git a/library/core/src/slice/memchr.rs b/library/core/src/slice/memchr.rs index dffeaf6a834e7..e0419f0ffdbac 100644 --- a/library/core/src/slice/memchr.rs +++ b/library/core/src/slice/memchr.rs @@ -2,6 +2,7 @@ // Copyright 2015 Andrew Gallant, bluss and Nicolas Koch use crate::cmp; +use crate::intrinsics; use crate::mem; const LO_USIZE: usize = usize::repeat_u8(0x01); @@ -35,13 +36,31 @@ fn repeat_byte(b: u8) -> usize { /// Returns the first index matching the byte `x` in `text`. #[must_use] #[inline] -pub fn memchr(x: u8, text: &[u8]) -> Option { - // Fast path for small slices - if text.len() < 2 * USIZE_BYTES { - return text.iter().position(|elt| *elt == x); +pub const fn memchr(x: u8, text: &[u8]) -> Option { + #[inline] + fn rt_impl(x: u8, text: &[u8]) -> Option { + // Fast path for small slices + if text.len() < 2 * USIZE_BYTES { + return text.iter().position(|elt| *elt == x); + } + + memchr_general_case(x, text) + } + + const fn const_impl(x: u8, bytes: &[u8]) -> Option { + let mut i = 0; + while i < bytes.len() { + if bytes[i] == x { + return Some(i); + } + i += 1; + } + + None } - memchr_general_case(x, text) + // SAFETY: The const and runtime versions have identical behavior + unsafe { intrinsics::const_eval_select((x, text), const_impl, rt_impl) } } fn memchr_general_case(x: u8, text: &[u8]) -> Option { diff --git a/src/librustdoc/passes/html_tags.rs b/src/librustdoc/passes/html_tags.rs index f3a3c853caca6..1bce24b0ad3e8 100644 --- a/src/librustdoc/passes/html_tags.rs +++ b/src/librustdoc/passes/html_tags.rs @@ -94,6 +94,34 @@ fn extract_path_backwards(text: &str, end_pos: usize) -> Option { if current_pos == end_pos { None } else { Some(current_pos) } } +fn extract_path_forward(text: &str, start_pos: usize) -> Option { + use rustc_lexer::{is_id_continue, is_id_start}; + let mut current_pos = start_pos; + loop { + if current_pos < text.len() && text[current_pos..].starts_with("::") { + current_pos += 2; + } else { + break; + } + let mut chars = text[current_pos..].chars(); + if let Some(c) = chars.next() { + if is_id_start(c) { + current_pos += c.len_utf8(); + } else { + break; + } + } + while let Some(c) = chars.next() { + if is_id_continue(c) { + current_pos += c.len_utf8(); + } else { + break; + } + } + } + if current_pos == start_pos { None } else { Some(current_pos) } +} + fn is_valid_for_html_tag_name(c: char, is_empty: bool) -> bool { // https://spec.commonmark.org/0.30/#raw-html // @@ -218,19 +246,68 @@ impl<'a, 'tcx> DocVisitor for InvalidHtmlTagsLinter<'a, 'tcx> { // If a tag looks like ``, it might actually be a generic. // We don't try to detect stuff `` because that's not valid HTML, // and we don't try to detect stuff `` because that's not valid Rust. - if let Some(Some(generics_start)) = (is_open_tag - && dox[..range.end].ends_with('>')) + let mut generics_end = range.end; + if let Some(Some(mut generics_start)) = (is_open_tag + && dox[..generics_end].ends_with('>')) .then(|| extract_path_backwards(&dox, range.start)) { + while generics_start != 0 + && generics_end < dox.len() + && dox.as_bytes()[generics_start - 1] == b'<' + && dox.as_bytes()[generics_end] == b'>' + { + generics_end += 1; + generics_start -= 1; + if let Some(new_start) = extract_path_backwards(&dox, generics_start) { + generics_start = new_start; + } + if let Some(new_end) = extract_path_forward(&dox, generics_end) { + generics_end = new_end; + } + } + if let Some(new_end) = extract_path_forward(&dox, generics_end) { + generics_end = new_end; + } let generics_sp = match super::source_span_for_markdown_range( tcx, &dox, - &(generics_start..range.end), + &(generics_start..generics_end), &item.attrs, ) { Some(sp) => sp, None => item.attr_span(tcx), }; + // Sometimes, we only extract part of a path. For example, consider this: + // + // <[u32] as IntoIter>::Item + // ^^^^^ unclosed HTML tag `u32` + // + // We don't have any code for parsing fully-qualified trait paths. + // In theory, we could add it, but doing it correctly would require + // parsing the entire path grammar, which is problematic because of + // overlap between the path grammar and Markdown. + // + // The example above shows that ambiguity. Is `[u32]` intended to be an + // intra-doc link to the u32 primitive, or is it intended to be a slice? + // + // If the below conditional were removed, we would suggest this, which is + // not what the user probably wants. + // + // <[u32] as `IntoIter`>::Item + // + // We know that the user actually wants to wrap the whole thing in a code + // block, but the only reason we know that is because `u32` does not, in + // fact, implement IntoIter. If the example looks like this: + // + // <[Vec] as IntoIter::Item + // + // The ideal fix would be significantly different. + if (generics_start > 0 && dox.as_bytes()[generics_start - 1] == b'<') + || (generics_end < dox.len() && dox.as_bytes()[generics_end] == b'>') + { + diag.emit(); + return; + } // multipart form is chosen here because ``Vec`` would be confusing. diag.multipart_suggestion( "try marking as source code", diff --git a/src/test/rustdoc-ui/suggestions/html-as-generics-no-suggestions.rs b/src/test/rustdoc-ui/suggestions/html-as-generics-no-suggestions.rs index 744b3071f1b81..476e3b2d43e4a 100644 --- a/src/test/rustdoc-ui/suggestions/html-as-generics-no-suggestions.rs +++ b/src/test/rustdoc-ui/suggestions/html-as-generics-no-suggestions.rs @@ -8,6 +8,48 @@ pub struct ConstGeneric; // HTML tags cannot contain commas, so no error. pub struct MultipleGenerics; +/// This <[u32] as Iterator> thing! +//~^ERROR unclosed HTML tag `Item` +// Some forms of fully-qualified path are simultaneously valid HTML tags +// with attributes. They produce an error, but no suggestion, because figuring +// out if this is valid would require parsing the entire path grammar. +// +// The important part is that we don't produce any *wrong* suggestions. +// While several other examples below are added to make sure we don't +// produce suggestions when given complex paths, this example is the actual +// reason behind not just using the real path parser. It's ambiguous: there's +// no way to locally reason out whether that `[u32]` is intended to be a slice +// or an intra-doc link. +pub struct FullyQualifiedPathsDoNotCount; + +/// This ::Iter thing! +//~^ERROR unclosed HTML tag `Vec` +// Some forms of fully-qualified path are simultaneously valid HTML tags +// with attributes. They produce an error, but no suggestion, because figuring +// out if this is valid would require parsing the entire path grammar. +pub struct FullyQualifiedPathsDoNotCount1; + +/// This Vec::Iter thing! +//~^ERROR unclosed HTML tag `Vec` +// Some forms of fully-qualified path are simultaneously valid HTML tags +// with attributes. They produce an error, but no suggestion, because figuring +// out if this is valid would require parsing the entire path grammar. +pub struct FullyQualifiedPathsDoNotCount2; + +/// This Vec thing! +//~^ERROR unclosed HTML tag `Vec` +// Some forms of fully-qualified path are simultaneously valid HTML tags +// with attributes. They produce an error, but no suggestion, because figuring +// out if this is valid would require parsing the entire path grammar. +pub struct FullyQualifiedPathsDoNotCount3; + +/// This Vec as IntoIter> thing! +//~^ERROR unclosed HTML tag `i32` +// Some forms of fully-qualified path are simultaneously valid HTML tags +// with attributes. They produce an error, but no suggestion, because figuring +// out if this is valid would require parsing the entire path grammar. +pub struct FullyQualifiedPathsDoNotCount4; + /// This Vec thing! //~^ERROR unclosed HTML tag `i32` // HTML attributes shouldn't be treated as Rust syntax, so no suggestions. diff --git a/src/test/rustdoc-ui/suggestions/html-as-generics-no-suggestions.stderr b/src/test/rustdoc-ui/suggestions/html-as-generics-no-suggestions.stderr index 832b8b2cac79a..3856a251321b2 100644 --- a/src/test/rustdoc-ui/suggestions/html-as-generics-no-suggestions.stderr +++ b/src/test/rustdoc-ui/suggestions/html-as-generics-no-suggestions.stderr @@ -1,8 +1,8 @@ -error: unclosed HTML tag `i32` - --> $DIR/html-as-generics-no-suggestions.rs:11:13 +error: unclosed HTML tag `Item` + --> $DIR/html-as-generics-no-suggestions.rs:11:28 | -LL | /// This Vec thing! - | ^^^^ +LL | /// This <[u32] as Iterator> thing! + | ^^^^^^ | note: the lint level is defined here --> $DIR/html-as-generics-no-suggestions.rs:1:9 @@ -10,29 +10,59 @@ note: the lint level is defined here LL | #![deny(rustdoc::invalid_html_tags)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ +error: unclosed HTML tag `Vec` + --> $DIR/html-as-generics-no-suggestions.rs:25:10 + | +LL | /// This ::Iter thing! + | ^^^^ + +error: unclosed HTML tag `Vec` + --> $DIR/html-as-generics-no-suggestions.rs:32:13 + | +LL | /// This Vec::Iter thing! + | ^^^^ + +error: unclosed HTML tag `Vec` + --> $DIR/html-as-generics-no-suggestions.rs:39:13 + | +LL | /// This Vec thing! + | ^^^^ + +error: unclosed HTML tag `i32` + --> $DIR/html-as-generics-no-suggestions.rs:46:17 + | +LL | /// This Vec as IntoIter> thing! + | ^^^^^ + +error: unclosed HTML tag `i32` + --> $DIR/html-as-generics-no-suggestions.rs:53:13 + | +LL | /// This Vec thing! + | ^^^^ + error: unopened HTML tag `i32` - --> $DIR/html-as-generics-no-suggestions.rs:20:13 + --> $DIR/html-as-generics-no-suggestions.rs:62:13 | LL | /// This Vec thing! | ^^^^^^ error: unclosed HTML tag `i32` - --> $DIR/html-as-generics-no-suggestions.rs:25:13 + --> $DIR/html-as-generics-no-suggestions.rs:67:13 | LL | /// This 123 thing! | ^^^^^ error: unclosed HTML tag `i32` - --> $DIR/html-as-generics-no-suggestions.rs:30:14 + --> $DIR/html-as-generics-no-suggestions.rs:72:14 | LL | /// This Vec: thing! | ^^^^^ error: unclosed HTML tag `i32` - --> $DIR/html-as-generics-no-suggestions.rs:35:39 + --> $DIR/html-as-generics-no-suggestions.rs:77:39 | LL | /// This [link](https://rust-lang.org) thing! | ^^^^^ -error: aborting due to 5 previous errors +error: aborting due to 10 previous errors diff --git a/src/test/rustdoc-ui/suggestions/html-as-generics.fixed b/src/test/rustdoc-ui/suggestions/html-as-generics.fixed index c0a0de24c5263..07c8c9ff254bc 100644 --- a/src/test/rustdoc-ui/suggestions/html-as-generics.fixed +++ b/src/test/rustdoc-ui/suggestions/html-as-generics.fixed @@ -30,3 +30,43 @@ pub struct BareTurbofish; //~^ERROR unclosed HTML tag `i32` //~|HELP try marking as source pub struct Nested; + +/// Nested generics `Vec>` +//~^ ERROR unclosed HTML tag `u32` +//~|HELP try marking as source +pub struct NestedGenerics; + +/// Generics with path `Vec::Iter` +//~^ ERROR unclosed HTML tag `i32` +//~|HELP try marking as source +pub struct GenericsWithPath; + +/// Generics with path `>::Iter` +//~^ ERROR unclosed HTML tag `i32` +//~|HELP try marking as source +pub struct NestedGenericsWithPath; + +/// Generics with path `Vec>::Iter` +//~^ ERROR unclosed HTML tag `i32` +//~|HELP try marking as source +pub struct NestedGenericsWithPath2; + +/// Generics with bump `>`s +//~^ ERROR unclosed HTML tag `i32` +//~|HELP try marking as source +pub struct NestedGenericsWithBump; + +/// Generics with bump `Vec>`s +//~^ ERROR unclosed HTML tag `i32` +//~|HELP try marking as source +pub struct NestedGenericsWithBump2; + +/// Generics with punct `>`! +//~^ ERROR unclosed HTML tag `i32` +//~|HELP try marking as source +pub struct NestedGenericsWithPunct; + +/// Generics with punct `Vec>`! +//~^ ERROR unclosed HTML tag `i32` +//~|HELP try marking as source +pub struct NestedGenericsWithPunct2; diff --git a/src/test/rustdoc-ui/suggestions/html-as-generics.rs b/src/test/rustdoc-ui/suggestions/html-as-generics.rs index 0b6009b0e59c3..cdd652f397ec4 100644 --- a/src/test/rustdoc-ui/suggestions/html-as-generics.rs +++ b/src/test/rustdoc-ui/suggestions/html-as-generics.rs @@ -30,3 +30,43 @@ pub struct BareTurbofish; //~^ERROR unclosed HTML tag `i32` //~|HELP try marking as source pub struct Nested; + +/// Nested generics Vec> +//~^ ERROR unclosed HTML tag `u32` +//~|HELP try marking as source +pub struct NestedGenerics; + +/// Generics with path Vec::Iter +//~^ ERROR unclosed HTML tag `i32` +//~|HELP try marking as source +pub struct GenericsWithPath; + +/// Generics with path >::Iter +//~^ ERROR unclosed HTML tag `i32` +//~|HELP try marking as source +pub struct NestedGenericsWithPath; + +/// Generics with path Vec>::Iter +//~^ ERROR unclosed HTML tag `i32` +//~|HELP try marking as source +pub struct NestedGenericsWithPath2; + +/// Generics with bump >s +//~^ ERROR unclosed HTML tag `i32` +//~|HELP try marking as source +pub struct NestedGenericsWithBump; + +/// Generics with bump Vec>s +//~^ ERROR unclosed HTML tag `i32` +//~|HELP try marking as source +pub struct NestedGenericsWithBump2; + +/// Generics with punct >! +//~^ ERROR unclosed HTML tag `i32` +//~|HELP try marking as source +pub struct NestedGenericsWithPunct; + +/// Generics with punct Vec>! +//~^ ERROR unclosed HTML tag `i32` +//~|HELP try marking as source +pub struct NestedGenericsWithPunct2; diff --git a/src/test/rustdoc-ui/suggestions/html-as-generics.stderr b/src/test/rustdoc-ui/suggestions/html-as-generics.stderr index df54b71264ebc..211dd4210d50c 100644 --- a/src/test/rustdoc-ui/suggestions/html-as-generics.stderr +++ b/src/test/rustdoc-ui/suggestions/html-as-generics.stderr @@ -69,5 +69,93 @@ help: try marking as source code LL | /// This `Vec::` thing! | + + -error: aborting due to 6 previous errors +error: unclosed HTML tag `u32` + --> $DIR/html-as-generics.rs:34:28 + | +LL | /// Nested generics Vec> + | ^^^^^ + | +help: try marking as source code + | +LL | /// Nested generics `Vec>` + | + + + +error: unclosed HTML tag `i32` + --> $DIR/html-as-generics.rs:39:27 + | +LL | /// Generics with path Vec::Iter + | ^^^^^ + | +help: try marking as source code + | +LL | /// Generics with path `Vec::Iter` + | + + + +error: unclosed HTML tag `i32` + --> $DIR/html-as-generics.rs:44:28 + | +LL | /// Generics with path >::Iter + | ^^^^^ + | +help: try marking as source code + | +LL | /// Generics with path `>::Iter` + | + + + +error: unclosed HTML tag `i32` + --> $DIR/html-as-generics.rs:49:31 + | +LL | /// Generics with path Vec>::Iter + | ^^^^^ + | +help: try marking as source code + | +LL | /// Generics with path `Vec>::Iter` + | + + + +error: unclosed HTML tag `i32` + --> $DIR/html-as-generics.rs:54:28 + | +LL | /// Generics with bump >s + | ^^^^^ + | +help: try marking as source code + | +LL | /// Generics with bump `>`s + | + + + +error: unclosed HTML tag `i32` + --> $DIR/html-as-generics.rs:59:31 + | +LL | /// Generics with bump Vec>s + | ^^^^^ + | +help: try marking as source code + | +LL | /// Generics with bump `Vec>`s + | + + + +error: unclosed HTML tag `i32` + --> $DIR/html-as-generics.rs:64:29 + | +LL | /// Generics with punct >! + | ^^^^^ + | +help: try marking as source code + | +LL | /// Generics with punct `>`! + | + + + +error: unclosed HTML tag `i32` + --> $DIR/html-as-generics.rs:69:32 + | +LL | /// Generics with punct Vec>! + | ^^^^^ + | +help: try marking as source code + | +LL | /// Generics with punct `Vec>`! + | + + + +error: aborting due to 14 previous errors diff --git a/src/test/ui/async-await/issue-101715.rs b/src/test/ui/async-await/issue-101715.rs new file mode 100644 index 0000000000000..1be5d02482e84 --- /dev/null +++ b/src/test/ui/async-await/issue-101715.rs @@ -0,0 +1,17 @@ +// edition:2018 + +struct S; + +impl S { + fn very_long_method_name_the_longest_method_name_in_the_whole_universe(self) {} +} + +async fn foo() { + S.very_long_method_name_the_longest_method_name_in_the_whole_universe() + .await + //~^ error: `()` is not a future + //~| help: remove the `.await` + //~| help: the trait `Future` is not implemented for `()` +} + +fn main() {} diff --git a/src/test/ui/async-await/issue-101715.stderr b/src/test/ui/async-await/issue-101715.stderr new file mode 100644 index 0000000000000..a0e8d2a894371 --- /dev/null +++ b/src/test/ui/async-await/issue-101715.stderr @@ -0,0 +1,16 @@ +error[E0277]: `()` is not a future + --> $DIR/issue-101715.rs:11:9 + | +LL | .await + | ^^^^^^ + | | + | `()` is not a future + | help: remove the `.await` + | + = help: the trait `Future` is not implemented for `()` + = note: () must be a future or must implement `IntoFuture` to be awaited + = note: required for `()` to implement `IntoFuture` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/async-await/issue-70594.stderr b/src/test/ui/async-await/issue-70594.stderr index f6ff52a5fd29f..d3cf57d3b1402 100644 --- a/src/test/ui/async-await/issue-70594.stderr +++ b/src/test/ui/async-await/issue-70594.stderr @@ -22,16 +22,14 @@ error[E0277]: `()` is not a future --> $DIR/issue-70594.rs:4:11 | LL | [1; ().await]; - | ^^^^^^ `()` is not a future + | ^^^^^^ + | | + | `()` is not a future + | help: remove the `.await` | = help: the trait `Future` is not implemented for `()` = note: () must be a future or must implement `IntoFuture` to be awaited = note: required for `()` to implement `IntoFuture` -help: remove the `.await` - | -LL - [1; ().await]; -LL + [1; ()]; - | error: aborting due to 4 previous errors diff --git a/src/test/ui/async-await/issues/issue-62009-1.stderr b/src/test/ui/async-await/issues/issue-62009-1.stderr index 0e323443ae8b3..222afb2c7b2bb 100644 --- a/src/test/ui/async-await/issues/issue-62009-1.stderr +++ b/src/test/ui/async-await/issues/issue-62009-1.stderr @@ -28,16 +28,14 @@ error[E0277]: `[closure@$DIR/issue-62009-1.rs:12:6: 12:9]` is not a future --> $DIR/issue-62009-1.rs:12:15 | LL | (|_| 2333).await; - | ^^^^^^ `[closure@$DIR/issue-62009-1.rs:12:6: 12:9]` is not a future + | ^^^^^^ + | | + | `[closure@$DIR/issue-62009-1.rs:12:6: 12:9]` is not a future + | help: remove the `.await` | = help: the trait `Future` is not implemented for closure `[closure@$DIR/issue-62009-1.rs:12:6: 12:9]` = note: [closure@$DIR/issue-62009-1.rs:12:6: 12:9] must be a future or must implement `IntoFuture` to be awaited = note: required for `[closure@$DIR/issue-62009-1.rs:12:6: 12:9]` to implement `IntoFuture` -help: remove the `.await` - | -LL - (|_| 2333).await; -LL + (|_| 2333); - | error: aborting due to 4 previous errors diff --git a/src/test/ui/dyn-keyword/dyn-2018-edition-lint.stderr b/src/test/ui/dyn-keyword/dyn-2018-edition-lint.stderr index 34699bb26582e..e7db68693c068 100644 --- a/src/test/ui/dyn-keyword/dyn-2018-edition-lint.stderr +++ b/src/test/ui/dyn-keyword/dyn-2018-edition-lint.stderr @@ -13,9 +13,8 @@ LL | #[deny(bare_trait_objects)] = note: for more information, see help: use `dyn` | -LL - fn function(x: &SomeTrait, y: Box) { -LL + fn function(x: &dyn SomeTrait, y: Box) { - | +LL | fn function(x: &dyn SomeTrait, y: Box) { + | +++ error: trait objects without an explicit `dyn` are deprecated --> $DIR/dyn-2018-edition-lint.rs:4:35 @@ -27,9 +26,8 @@ LL | fn function(x: &SomeTrait, y: Box) { = note: for more information, see help: use `dyn` | -LL - fn function(x: &SomeTrait, y: Box) { -LL + fn function(x: &SomeTrait, y: Box) { - | +LL | fn function(x: &SomeTrait, y: Box) { + | +++ error: trait objects without an explicit `dyn` are deprecated --> $DIR/dyn-2018-edition-lint.rs:17:14 @@ -41,9 +39,8 @@ LL | let _x: &SomeTrait = todo!(); = note: for more information, see help: use `dyn` | -LL - let _x: &SomeTrait = todo!(); -LL + let _x: &dyn SomeTrait = todo!(); - | +LL | let _x: &dyn SomeTrait = todo!(); + | +++ error: trait objects without an explicit `dyn` are deprecated --> $DIR/dyn-2018-edition-lint.rs:4:17 @@ -55,9 +52,8 @@ LL | fn function(x: &SomeTrait, y: Box) { = note: for more information, see help: use `dyn` | -LL - fn function(x: &SomeTrait, y: Box) { -LL + fn function(x: &dyn SomeTrait, y: Box) { - | +LL | fn function(x: &dyn SomeTrait, y: Box) { + | +++ error: trait objects without an explicit `dyn` are deprecated --> $DIR/dyn-2018-edition-lint.rs:4:17 @@ -69,9 +65,8 @@ LL | fn function(x: &SomeTrait, y: Box) { = note: for more information, see help: use `dyn` | -LL - fn function(x: &SomeTrait, y: Box) { -LL + fn function(x: &dyn SomeTrait, y: Box) { - | +LL | fn function(x: &dyn SomeTrait, y: Box) { + | +++ error: trait objects without an explicit `dyn` are deprecated --> $DIR/dyn-2018-edition-lint.rs:4:35 @@ -83,9 +78,8 @@ LL | fn function(x: &SomeTrait, y: Box) { = note: for more information, see help: use `dyn` | -LL - fn function(x: &SomeTrait, y: Box) { -LL + fn function(x: &SomeTrait, y: Box) { - | +LL | fn function(x: &SomeTrait, y: Box) { + | +++ error: trait objects without an explicit `dyn` are deprecated --> $DIR/dyn-2018-edition-lint.rs:4:35 @@ -97,9 +91,8 @@ LL | fn function(x: &SomeTrait, y: Box) { = note: for more information, see help: use `dyn` | -LL - fn function(x: &SomeTrait, y: Box) { -LL + fn function(x: &SomeTrait, y: Box) { - | +LL | fn function(x: &SomeTrait, y: Box) { + | +++ error: aborting due to 7 previous errors diff --git a/src/test/ui/dyn-keyword/dyn-2021-edition-error.stderr b/src/test/ui/dyn-keyword/dyn-2021-edition-error.stderr index 9e212c77dc77c..08ee77116f0b8 100644 --- a/src/test/ui/dyn-keyword/dyn-2021-edition-error.stderr +++ b/src/test/ui/dyn-keyword/dyn-2021-edition-error.stderr @@ -6,9 +6,8 @@ LL | fn function(x: &SomeTrait, y: Box) { | help: add `dyn` keyword before this trait | -LL - fn function(x: &SomeTrait, y: Box) { -LL + fn function(x: &dyn SomeTrait, y: Box) { - | +LL | fn function(x: &dyn SomeTrait, y: Box) { + | +++ error[E0782]: trait objects must include the `dyn` keyword --> $DIR/dyn-2021-edition-error.rs:3:35 @@ -18,9 +17,8 @@ LL | fn function(x: &SomeTrait, y: Box) { | help: add `dyn` keyword before this trait | -LL - fn function(x: &SomeTrait, y: Box) { -LL + fn function(x: &SomeTrait, y: Box) { - | +LL | fn function(x: &SomeTrait, y: Box) { + | +++ error: aborting due to 2 previous errors diff --git a/src/test/ui/dyn-keyword/dyn-angle-brackets.stderr b/src/test/ui/dyn-keyword/dyn-angle-brackets.stderr index 9bc603fba5466..261c2d5742f40 100644 --- a/src/test/ui/dyn-keyword/dyn-angle-brackets.stderr +++ b/src/test/ui/dyn-keyword/dyn-angle-brackets.stderr @@ -13,9 +13,8 @@ LL | #![deny(bare_trait_objects)] = note: for more information, see help: use `dyn` | -LL - ::fmt(self, f) -LL + ::fmt(self, f) - | +LL | ::fmt(self, f) + | +++ error: aborting due to previous error diff --git a/src/test/ui/impl-trait/generic-with-implicit-hrtb-without-dyn.edition2021.stderr b/src/test/ui/impl-trait/generic-with-implicit-hrtb-without-dyn.edition2021.stderr index c01c33a893124..8f40922732486 100644 --- a/src/test/ui/impl-trait/generic-with-implicit-hrtb-without-dyn.edition2021.stderr +++ b/src/test/ui/impl-trait/generic-with-implicit-hrtb-without-dyn.edition2021.stderr @@ -6,9 +6,8 @@ LL | fn ice() -> impl AsRef { | help: add `dyn` keyword before this trait | -LL - fn ice() -> impl AsRef { -LL + fn ice() -> impl AsRef { - | +LL | fn ice() -> impl AsRef { + | +++ error[E0277]: the trait bound `(): AsRef<(dyn for<'r> Fn(&'r ()) + 'static)>` is not satisfied --> $DIR/generic-with-implicit-hrtb-without-dyn.rs:6:13 diff --git a/src/test/ui/issues/issue-86756.stderr b/src/test/ui/issues/issue-86756.stderr index 399c940ca195c..b26c1834d84a3 100644 --- a/src/test/ui/issues/issue-86756.stderr +++ b/src/test/ui/issues/issue-86756.stderr @@ -25,9 +25,8 @@ LL | eq:: = note: for more information, see help: use `dyn` | -LL - eq:: -LL + eq:: - | +LL | eq:: + | +++ error[E0107]: missing generics for trait `Foo` --> $DIR/issue-86756.rs:5:15 diff --git a/src/test/ui/lint/force-warn/allowed-group-warn-by-default-lint.stderr b/src/test/ui/lint/force-warn/allowed-group-warn-by-default-lint.stderr index 8d826bd145762..94d81c3aa71b5 100644 --- a/src/test/ui/lint/force-warn/allowed-group-warn-by-default-lint.stderr +++ b/src/test/ui/lint/force-warn/allowed-group-warn-by-default-lint.stderr @@ -9,9 +9,8 @@ LL | pub fn function(_x: Box) {} = note: for more information, see help: use `dyn` | -LL - pub fn function(_x: Box) {} -LL + pub fn function(_x: Box) {} - | +LL | pub fn function(_x: Box) {} + | +++ warning: trait objects without an explicit `dyn` are deprecated --> $DIR/allowed-group-warn-by-default-lint.rs:10:25 @@ -23,9 +22,8 @@ LL | pub fn function(_x: Box) {} = note: for more information, see help: use `dyn` | -LL - pub fn function(_x: Box) {} -LL + pub fn function(_x: Box) {} - | +LL | pub fn function(_x: Box) {} + | +++ warning: trait objects without an explicit `dyn` are deprecated --> $DIR/allowed-group-warn-by-default-lint.rs:10:25 @@ -37,9 +35,8 @@ LL | pub fn function(_x: Box) {} = note: for more information, see help: use `dyn` | -LL - pub fn function(_x: Box) {} -LL + pub fn function(_x: Box) {} - | +LL | pub fn function(_x: Box) {} + | +++ warning: 3 warnings emitted diff --git a/src/test/ui/lint/force-warn/cap-lints-allow.stderr b/src/test/ui/lint/force-warn/cap-lints-allow.stderr index 978270872c45c..7f0fd8530e2cc 100644 --- a/src/test/ui/lint/force-warn/cap-lints-allow.stderr +++ b/src/test/ui/lint/force-warn/cap-lints-allow.stderr @@ -9,9 +9,8 @@ LL | pub fn function(_x: Box) {} = note: for more information, see help: use `dyn` | -LL - pub fn function(_x: Box) {} -LL + pub fn function(_x: Box) {} - | +LL | pub fn function(_x: Box) {} + | +++ warning: trait objects without an explicit `dyn` are deprecated --> $DIR/cap-lints-allow.rs:8:25 @@ -23,9 +22,8 @@ LL | pub fn function(_x: Box) {} = note: for more information, see help: use `dyn` | -LL - pub fn function(_x: Box) {} -LL + pub fn function(_x: Box) {} - | +LL | pub fn function(_x: Box) {} + | +++ warning: trait objects without an explicit `dyn` are deprecated --> $DIR/cap-lints-allow.rs:8:25 @@ -37,9 +35,8 @@ LL | pub fn function(_x: Box) {} = note: for more information, see help: use `dyn` | -LL - pub fn function(_x: Box) {} -LL + pub fn function(_x: Box) {} - | +LL | pub fn function(_x: Box) {} + | +++ warning: 3 warnings emitted diff --git a/src/test/ui/lint/force-warn/lint-group-allowed-cli-warn-by-default-lint.stderr b/src/test/ui/lint/force-warn/lint-group-allowed-cli-warn-by-default-lint.stderr index 6e67ebf274733..eb2bca7b84d71 100644 --- a/src/test/ui/lint/force-warn/lint-group-allowed-cli-warn-by-default-lint.stderr +++ b/src/test/ui/lint/force-warn/lint-group-allowed-cli-warn-by-default-lint.stderr @@ -9,9 +9,8 @@ LL | pub fn function(_x: Box) {} = note: for more information, see help: use `dyn` | -LL - pub fn function(_x: Box) {} -LL + pub fn function(_x: Box) {} - | +LL | pub fn function(_x: Box) {} + | +++ warning: trait objects without an explicit `dyn` are deprecated --> $DIR/lint-group-allowed-cli-warn-by-default-lint.rs:8:25 @@ -23,9 +22,8 @@ LL | pub fn function(_x: Box) {} = note: for more information, see help: use `dyn` | -LL - pub fn function(_x: Box) {} -LL + pub fn function(_x: Box) {} - | +LL | pub fn function(_x: Box) {} + | +++ warning: trait objects without an explicit `dyn` are deprecated --> $DIR/lint-group-allowed-cli-warn-by-default-lint.rs:8:25 @@ -37,9 +35,8 @@ LL | pub fn function(_x: Box) {} = note: for more information, see help: use `dyn` | -LL - pub fn function(_x: Box) {} -LL + pub fn function(_x: Box) {} - | +LL | pub fn function(_x: Box) {} + | +++ warning: 3 warnings emitted diff --git a/src/test/ui/lint/force-warn/lint-group-allowed-lint-group.stderr b/src/test/ui/lint/force-warn/lint-group-allowed-lint-group.stderr index c5dea84b8f358..ed01937a57b15 100644 --- a/src/test/ui/lint/force-warn/lint-group-allowed-lint-group.stderr +++ b/src/test/ui/lint/force-warn/lint-group-allowed-lint-group.stderr @@ -9,9 +9,8 @@ LL | pub fn function(_x: Box) {} = note: for more information, see help: use `dyn` | -LL - pub fn function(_x: Box) {} -LL + pub fn function(_x: Box) {} - | +LL | pub fn function(_x: Box) {} + | +++ warning: trait objects without an explicit `dyn` are deprecated --> $DIR/lint-group-allowed-lint-group.rs:10:25 @@ -23,9 +22,8 @@ LL | pub fn function(_x: Box) {} = note: for more information, see help: use `dyn` | -LL - pub fn function(_x: Box) {} -LL + pub fn function(_x: Box) {} - | +LL | pub fn function(_x: Box) {} + | +++ warning: trait objects without an explicit `dyn` are deprecated --> $DIR/lint-group-allowed-lint-group.rs:10:25 @@ -37,9 +35,8 @@ LL | pub fn function(_x: Box) {} = note: for more information, see help: use `dyn` | -LL - pub fn function(_x: Box) {} -LL + pub fn function(_x: Box) {} - | +LL | pub fn function(_x: Box) {} + | +++ warning: 3 warnings emitted diff --git a/src/test/ui/lint/force-warn/lint-group-allowed-warn-by-default-lint.stderr b/src/test/ui/lint/force-warn/lint-group-allowed-warn-by-default-lint.stderr index acd0c503d9c02..8db7c12757b03 100644 --- a/src/test/ui/lint/force-warn/lint-group-allowed-warn-by-default-lint.stderr +++ b/src/test/ui/lint/force-warn/lint-group-allowed-warn-by-default-lint.stderr @@ -9,9 +9,8 @@ LL | pub fn function(_x: Box) {} = note: for more information, see help: use `dyn` | -LL - pub fn function(_x: Box) {} -LL + pub fn function(_x: Box) {} - | +LL | pub fn function(_x: Box) {} + | +++ warning: trait objects without an explicit `dyn` are deprecated --> $DIR/lint-group-allowed-warn-by-default-lint.rs:10:25 @@ -23,9 +22,8 @@ LL | pub fn function(_x: Box) {} = note: for more information, see help: use `dyn` | -LL - pub fn function(_x: Box) {} -LL + pub fn function(_x: Box) {} - | +LL | pub fn function(_x: Box) {} + | +++ warning: trait objects without an explicit `dyn` are deprecated --> $DIR/lint-group-allowed-warn-by-default-lint.rs:10:25 @@ -37,9 +35,8 @@ LL | pub fn function(_x: Box) {} = note: for more information, see help: use `dyn` | -LL - pub fn function(_x: Box) {} -LL + pub fn function(_x: Box) {} - | +LL | pub fn function(_x: Box) {} + | +++ warning: 3 warnings emitted diff --git a/src/test/ui/parser/increment-notfixed.stderr b/src/test/ui/parser/increment-notfixed.stderr index 352d98cf82ec7..ae55ae0671431 100644 --- a/src/test/ui/parser/increment-notfixed.stderr +++ b/src/test/ui/parser/increment-notfixed.stderr @@ -8,9 +8,8 @@ help: use `+= 1` instead | LL | { let tmp = i; i += 1; tmp }; | +++++++++++ ~~~~~~~~~~~~~~~ -LL - i++; -LL + i += 1; - | +LL | i += 1; + | ~~~~ error: Rust has no postfix increment operator --> $DIR/increment-notfixed.rs:17:12 @@ -24,9 +23,8 @@ help: use `+= 1` instead | LL | while { let tmp = i; i += 1; tmp } < 5 { | +++++++++++ ~~~~~~~~~~~~~~~ -LL - while i++ < 5 { -LL + while i += 1 < 5 { - | +LL | while i += 1 < 5 { + | ~~~~ error: Rust has no postfix increment operator --> $DIR/increment-notfixed.rs:25:8 @@ -38,9 +36,8 @@ help: use `+= 1` instead | LL | { let tmp_ = tmp; tmp += 1; tmp_ }; | ++++++++++++ ~~~~~~~~~~~~~~~~~~ -LL - tmp++; -LL + tmp += 1; - | +LL | tmp += 1; + | ~~~~ error: Rust has no postfix increment operator --> $DIR/increment-notfixed.rs:31:14 @@ -54,9 +51,8 @@ help: use `+= 1` instead | LL | while { let tmp_ = tmp; tmp += 1; tmp_ } < 5 { | ++++++++++++ ~~~~~~~~~~~~~~~~~~ -LL - while tmp++ < 5 { -LL + while tmp += 1 < 5 { - | +LL | while tmp += 1 < 5 { + | ~~~~ error: Rust has no postfix increment operator --> $DIR/increment-notfixed.rs:39:16 @@ -68,9 +64,8 @@ help: use `+= 1` instead | LL | { let tmp = foo.bar.qux; foo.bar.qux += 1; tmp }; | +++++++++++ ~~~~~~~~~~~~~~~~~~~~~~~~~ -LL - foo.bar.qux++; -LL + foo.bar.qux += 1; - | +LL | foo.bar.qux += 1; + | ~~~~ error: Rust has no postfix increment operator --> $DIR/increment-notfixed.rs:49:10 @@ -82,9 +77,8 @@ help: use `+= 1` instead | LL | { let tmp = s.tmp; s.tmp += 1; tmp }; | +++++++++++ ~~~~~~~~~~~~~~~~~~~ -LL - s.tmp++; -LL + s.tmp += 1; - | +LL | s.tmp += 1; + | ~~~~ error: Rust has no prefix increment operator --> $DIR/increment-notfixed.rs:56:5 diff --git a/src/test/ui/parser/trait-object-trait-parens.stderr b/src/test/ui/parser/trait-object-trait-parens.stderr index 7ee965bd2babd..823f75bfac86f 100644 --- a/src/test/ui/parser/trait-object-trait-parens.stderr +++ b/src/test/ui/parser/trait-object-trait-parens.stderr @@ -27,9 +27,8 @@ LL | let _: Box<(Obj) + (?Sized) + (for<'a> Trait<'a>)>; = note: for more information, see help: use `dyn` | -LL - let _: Box<(Obj) + (?Sized) + (for<'a> Trait<'a>)>; -LL + let _: Box Trait<'a>)>; - | +LL | let _: Box Trait<'a>)>; + | +++ error[E0225]: only auto traits can be used as additional traits in a trait object --> $DIR/trait-object-trait-parens.rs:8:35 @@ -52,9 +51,8 @@ LL | let _: Box Trait<'a>) + (Obj)>; = note: for more information, see help: use `dyn` | -LL - let _: Box Trait<'a>) + (Obj)>; -LL + let _: Box Trait<'a>) + (Obj)>; - | +LL | let _: Box Trait<'a>) + (Obj)>; + | +++ error[E0225]: only auto traits can be used as additional traits in a trait object --> $DIR/trait-object-trait-parens.rs:13:47 @@ -77,9 +75,8 @@ LL | let _: Box Trait<'a> + (Obj) + (?Sized)>; = note: for more information, see help: use `dyn` | -LL - let _: Box Trait<'a> + (Obj) + (?Sized)>; -LL + let _: Box Trait<'a> + (Obj) + (?Sized)>; - | +LL | let _: Box Trait<'a> + (Obj) + (?Sized)>; + | +++ error[E0225]: only auto traits can be used as additional traits in a trait object --> $DIR/trait-object-trait-parens.rs:18:36 diff --git a/src/test/ui/proc-macro/dollar-crate-issue-101211.rs b/src/test/ui/proc-macro/dollar-crate-issue-101211.rs new file mode 100644 index 0000000000000..fc1acfd32d2fc --- /dev/null +++ b/src/test/ui/proc-macro/dollar-crate-issue-101211.rs @@ -0,0 +1,29 @@ +// check-pass +// edition:2021 +// aux-build:test-macros.rs + +#![no_std] // Don't load unnecessary hygiene information from std +extern crate std; + +#[macro_use] +extern crate test_macros; + +macro_rules! foo { + ($($path:ident)::*) => ( + test_macros::recollect!( + $($path)::* + ) + ) +} + +macro_rules! baz { + () => ( + foo!($crate::BAR) + ) +} + +pub const BAR: u32 = 19; + +fn main(){ + std::println!("{}", baz!()); +} diff --git a/src/test/ui/rust-2021/reserved-prefixes-migration.stderr b/src/test/ui/rust-2021/reserved-prefixes-migration.stderr index 647a9f3931254..c6bc082cf18db 100644 --- a/src/test/ui/rust-2021/reserved-prefixes-migration.stderr +++ b/src/test/ui/rust-2021/reserved-prefixes-migration.stderr @@ -13,9 +13,8 @@ LL | #![warn(rust_2021_prefixes_incompatible_syntax)] = note: for more information, see help: insert whitespace here to avoid this being parsed as a prefix in Rust 2021 | -LL - m2!(z"hey"); -LL + m2!(z "hey"); - | +LL | m2!(z "hey"); + | + warning: prefix `prefix` is unknown --> $DIR/reserved-prefixes-migration.rs:19:9 @@ -27,9 +26,8 @@ LL | m2!(prefix"hey"); = note: for more information, see help: insert whitespace here to avoid this being parsed as a prefix in Rust 2021 | -LL - m2!(prefix"hey"); -LL + m2!(prefix "hey"); - | +LL | m2!(prefix "hey"); + | + warning: prefix `hey` is unknown --> $DIR/reserved-prefixes-migration.rs:22:9 @@ -41,9 +39,8 @@ LL | m3!(hey#123); = note: for more information, see help: insert whitespace here to avoid this being parsed as a prefix in Rust 2021 | -LL - m3!(hey#123); -LL + m3!(hey #123); - | +LL | m3!(hey #123); + | + warning: prefix `hey` is unknown --> $DIR/reserved-prefixes-migration.rs:25:9 @@ -55,9 +52,8 @@ LL | m3!(hey#hey); = note: for more information, see help: insert whitespace here to avoid this being parsed as a prefix in Rust 2021 | -LL - m3!(hey#hey); -LL + m3!(hey #hey); - | +LL | m3!(hey #hey); + | + warning: prefix `kind` is unknown --> $DIR/reserved-prefixes-migration.rs:35:14 @@ -69,9 +65,8 @@ LL | #name = #kind#value = note: for more information, see help: insert whitespace here to avoid this being parsed as a prefix in Rust 2021 | -LL - #name = #kind#value -LL + #name = #kind #value - | +LL | #name = #kind #value + | + warning: 5 warnings emitted diff --git a/src/test/ui/rust-2021/reserved-prefixes.stderr b/src/test/ui/rust-2021/reserved-prefixes.stderr index df31aee66fea7..807d6d98bd3c3 100644 --- a/src/test/ui/rust-2021/reserved-prefixes.stderr +++ b/src/test/ui/rust-2021/reserved-prefixes.stderr @@ -7,9 +7,8 @@ LL | demo3!(foo#bar); = note: prefixed identifiers and literals are reserved since Rust 2021 help: consider inserting whitespace here | -LL - demo3!(foo#bar); -LL + demo3!(foo #bar); - | +LL | demo3!(foo #bar); + | + error: prefix `foo` is unknown --> $DIR/reserved-prefixes.rs:17:12 @@ -20,9 +19,8 @@ LL | demo2!(foo"bar"); = note: prefixed identifiers and literals are reserved since Rust 2021 help: consider inserting whitespace here | -LL - demo2!(foo"bar"); -LL + demo2!(foo "bar"); - | +LL | demo2!(foo "bar"); + | + error: prefix `foo` is unknown --> $DIR/reserved-prefixes.rs:18:12 @@ -33,9 +31,8 @@ LL | demo2!(foo'b'); = note: prefixed identifiers and literals are reserved since Rust 2021 help: consider inserting whitespace here | -LL - demo2!(foo'b'); -LL + demo2!(foo 'b'); - | +LL | demo2!(foo 'b'); + | + error: prefix `foo` is unknown --> $DIR/reserved-prefixes.rs:20:12 @@ -46,9 +43,8 @@ LL | demo2!(foo'b); = note: prefixed identifiers and literals are reserved since Rust 2021 help: consider inserting whitespace here | -LL - demo2!(foo'b); -LL + demo2!(foo 'b); - | +LL | demo2!(foo 'b); + | + error: prefix `foo` is unknown --> $DIR/reserved-prefixes.rs:21:12 @@ -59,9 +55,8 @@ LL | demo3!(foo# bar); = note: prefixed identifiers and literals are reserved since Rust 2021 help: consider inserting whitespace here | -LL - demo3!(foo# bar); -LL + demo3!(foo # bar); - | +LL | demo3!(foo # bar); + | + error: prefix `foo` is unknown --> $DIR/reserved-prefixes.rs:22:12 @@ -72,9 +67,8 @@ LL | demo4!(foo#! bar); = note: prefixed identifiers and literals are reserved since Rust 2021 help: consider inserting whitespace here | -LL - demo4!(foo#! bar); -LL + demo4!(foo #! bar); - | +LL | demo4!(foo #! bar); + | + error: prefix `foo` is unknown --> $DIR/reserved-prefixes.rs:23:12 @@ -85,9 +79,8 @@ LL | demo4!(foo## bar); = note: prefixed identifiers and literals are reserved since Rust 2021 help: consider inserting whitespace here | -LL - demo4!(foo## bar); -LL + demo4!(foo ## bar); - | +LL | demo4!(foo ## bar); + | + error: prefix `foo` is unknown --> $DIR/reserved-prefixes.rs:25:12 @@ -98,9 +91,8 @@ LL | demo4!(foo#bar#); = note: prefixed identifiers and literals are reserved since Rust 2021 help: consider inserting whitespace here | -LL - demo4!(foo#bar#); -LL + demo4!(foo #bar#); - | +LL | demo4!(foo #bar#); + | + error: prefix `bar` is unknown --> $DIR/reserved-prefixes.rs:25:16 @@ -111,9 +103,8 @@ LL | demo4!(foo#bar#); = note: prefixed identifiers and literals are reserved since Rust 2021 help: consider inserting whitespace here | -LL - demo4!(foo#bar#); -LL + demo4!(foo#bar #); - | +LL | demo4!(foo#bar #); + | + error: aborting due to 9 previous errors diff --git a/src/test/ui/suggestions/issue-61963.stderr b/src/test/ui/suggestions/issue-61963.stderr index c0d776e59ab8d..a788cab6e4e8e 100644 --- a/src/test/ui/suggestions/issue-61963.stderr +++ b/src/test/ui/suggestions/issue-61963.stderr @@ -13,9 +13,8 @@ LL | #![deny(bare_trait_objects)] = note: for more information, see help: use `dyn` | -LL - bar: Box, -LL + bar: Box, - | +LL | bar: Box, + | +++ error: trait objects without an explicit `dyn` are deprecated --> $DIR/issue-61963.rs:18:1 @@ -27,9 +26,8 @@ LL | pub struct Foo { = note: for more information, see help: use `dyn` | -LL - pub struct Foo { -LL + dyn pub struct Foo { - | +LL | dyn pub struct Foo { + | +++ error: trait objects without an explicit `dyn` are deprecated --> $DIR/issue-61963.rs:28:14 @@ -41,9 +39,8 @@ LL | bar: Box, = note: for more information, see help: use `dyn` | -LL - bar: Box, -LL + bar: Box, - | +LL | bar: Box, + | +++ error: trait objects without an explicit `dyn` are deprecated --> $DIR/issue-61963.rs:28:14 @@ -55,9 +52,8 @@ LL | bar: Box, = note: for more information, see help: use `dyn` | -LL - bar: Box, -LL + bar: Box, - | +LL | bar: Box, + | +++ error: trait objects without an explicit `dyn` are deprecated --> $DIR/issue-61963.rs:18:1 @@ -69,9 +65,8 @@ LL | pub struct Foo { = note: for more information, see help: use `dyn` | -LL - pub struct Foo { -LL + dyn pub struct Foo { - | +LL | dyn pub struct Foo { + | +++ error: trait objects without an explicit `dyn` are deprecated --> $DIR/issue-61963.rs:18:1 @@ -83,9 +78,8 @@ LL | pub struct Foo { = note: for more information, see help: use `dyn` | -LL - pub struct Foo { -LL + dyn pub struct Foo { - | +LL | dyn pub struct Foo { + | +++ error: trait objects without an explicit `dyn` are deprecated --> $DIR/issue-61963.rs:18:1 @@ -97,9 +91,8 @@ LL | pub struct Foo { = note: for more information, see help: use `dyn` | -LL - pub struct Foo { -LL + dyn pub struct Foo { - | +LL | dyn pub struct Foo { + | +++ error: aborting due to 7 previous errors diff --git a/src/test/ui/suggestions/suggest-blanket-impl-local-trait.stderr b/src/test/ui/suggestions/suggest-blanket-impl-local-trait.stderr index d739a8272f152..398caa98b84db 100644 --- a/src/test/ui/suggestions/suggest-blanket-impl-local-trait.stderr +++ b/src/test/ui/suggestions/suggest-blanket-impl-local-trait.stderr @@ -6,9 +6,8 @@ LL | impl LocalTraitTwo for LocalTraitOne {} | help: add `dyn` keyword before this trait | -LL - impl LocalTraitTwo for LocalTraitOne {} -LL + impl LocalTraitTwo for dyn LocalTraitOne {} - | +LL | impl LocalTraitTwo for dyn LocalTraitOne {} + | +++ help: alternatively use a blanket implementation to implement `LocalTraitTwo` for all types that also implement `LocalTraitOne` | LL | impl LocalTraitTwo for T {} @@ -22,9 +21,8 @@ LL | impl fmt::Display for LocalTraitOne { | help: add `dyn` keyword before this trait | -LL - impl fmt::Display for LocalTraitOne { -LL + impl fmt::Display for dyn LocalTraitOne { - | +LL | impl fmt::Display for dyn LocalTraitOne { + | +++ error[E0782]: trait objects must include the `dyn` keyword --> $DIR/suggest-blanket-impl-local-trait.rs:26:23 @@ -34,9 +32,8 @@ LL | impl fmt::Display for LocalTraitTwo + Send { | help: add `dyn` keyword before this trait | -LL - impl fmt::Display for LocalTraitTwo + Send { -LL + impl fmt::Display for dyn LocalTraitTwo + Send { - | +LL | impl fmt::Display for dyn LocalTraitTwo + Send { + | +++ error[E0782]: trait objects must include the `dyn` keyword --> $DIR/suggest-blanket-impl-local-trait.rs:34:24 @@ -46,9 +43,8 @@ LL | impl LocalTraitOne for fmt::Display {} | help: add `dyn` keyword before this trait | -LL - impl LocalTraitOne for fmt::Display {} -LL + impl LocalTraitOne for dyn fmt::Display {} - | +LL | impl LocalTraitOne for dyn fmt::Display {} + | +++ help: alternatively use a blanket implementation to implement `LocalTraitOne` for all types that also implement `fmt::Display` | LL | impl LocalTraitOne for T {} @@ -62,9 +58,8 @@ LL | impl LocalTraitOne for fmt::Display + Send {} | help: add `dyn` keyword before this trait | -LL - impl LocalTraitOne for fmt::Display + Send {} -LL + impl LocalTraitOne for dyn fmt::Display + Send {} - | +LL | impl LocalTraitOne for dyn fmt::Display + Send {} + | +++ help: alternatively use a blanket implementation to implement `LocalTraitOne` for all types that also implement `fmt::Display + Send` | LL | impl LocalTraitOne for T {} @@ -78,9 +73,8 @@ LL | impl GenericTrait for LocalTraitOne {} | help: add `dyn` keyword before this trait | -LL - impl GenericTrait for LocalTraitOne {} -LL + impl GenericTrait for dyn LocalTraitOne {} - | +LL | impl GenericTrait for dyn LocalTraitOne {} + | +++ help: alternatively use a blanket implementation to implement `GenericTrait` for all types that also implement `LocalTraitOne` | LL | impl GenericTrait for T {} @@ -94,9 +88,8 @@ LL | impl GenericTraitTwo for GenericTrait {} | help: add `dyn` keyword before this trait | -LL - impl GenericTraitTwo for GenericTrait {} -LL + impl GenericTraitTwo for dyn GenericTrait {} - | +LL | impl GenericTraitTwo for dyn GenericTrait {} + | +++ help: alternatively use a blanket implementation to implement `GenericTraitTwo` for all types that also implement `GenericTrait` | LL | impl> GenericTraitTwo for U {} diff --git a/src/test/ui/suggestions/suggest-swapping-self-ty-and-trait-edition-2021.stderr b/src/test/ui/suggestions/suggest-swapping-self-ty-and-trait-edition-2021.stderr index fc880d6b86a71..87e7164362091 100644 --- a/src/test/ui/suggestions/suggest-swapping-self-ty-and-trait-edition-2021.stderr +++ b/src/test/ui/suggestions/suggest-swapping-self-ty-and-trait-edition-2021.stderr @@ -39,9 +39,8 @@ LL | impl<'a, T> Struct for Trait<'a, T> {} | help: add `dyn` keyword before this trait | -LL - impl<'a, T> Struct for Trait<'a, T> {} -LL + impl<'a, T> Struct for dyn Trait<'a, T> {} - | +LL | impl<'a, T> Struct for dyn Trait<'a, T> {} + | +++ error: aborting due to 4 previous errors diff --git a/src/test/ui/suggestions/suggest-swapping-self-ty-and-trait.stderr b/src/test/ui/suggestions/suggest-swapping-self-ty-and-trait.stderr index f5143762da8e5..f716e6c17e22d 100644 --- a/src/test/ui/suggestions/suggest-swapping-self-ty-and-trait.stderr +++ b/src/test/ui/suggestions/suggest-swapping-self-ty-and-trait.stderr @@ -42,9 +42,8 @@ LL | impl<'a, T> Struct for Trait<'a, T> {} = note: for more information, see help: use `dyn` | -LL - impl<'a, T> Struct for Trait<'a, T> {} -LL + impl<'a, T> Struct for dyn Trait<'a, T> {} - | +LL | impl<'a, T> Struct for dyn Trait<'a, T> {} + | +++ error: aborting due to 3 previous errors; 1 warning emitted diff --git a/src/test/ui/traits/bound/not-on-bare-trait.stderr b/src/test/ui/traits/bound/not-on-bare-trait.stderr index 8a92dd11872c4..1c52629daa483 100644 --- a/src/test/ui/traits/bound/not-on-bare-trait.stderr +++ b/src/test/ui/traits/bound/not-on-bare-trait.stderr @@ -9,9 +9,8 @@ LL | fn foo(_x: Foo + Send) { = note: for more information, see help: use `dyn` | -LL - fn foo(_x: Foo + Send) { -LL + fn foo(_x: dyn Foo + Send) { - | +LL | fn foo(_x: dyn Foo + Send) { + | +++ error[E0277]: the size for values of type `(dyn Foo + Send + 'static)` cannot be known at compilation time --> $DIR/not-on-bare-trait.rs:7:8 diff --git a/src/test/ui/typeof/issue-100183.rs b/src/test/ui/typeof/issue-100183.rs new file mode 100644 index 0000000000000..13e9493eaa59b --- /dev/null +++ b/src/test/ui/typeof/issue-100183.rs @@ -0,0 +1,6 @@ +struct Struct { + y: (typeof("hey"),), + //~^ ERROR `typeof` is a reserved keyword but unimplemented +} + +fn main() {} diff --git a/src/test/ui/typeof/issue-100183.stderr b/src/test/ui/typeof/issue-100183.stderr new file mode 100644 index 0000000000000..01d3079b246d1 --- /dev/null +++ b/src/test/ui/typeof/issue-100183.stderr @@ -0,0 +1,14 @@ +error[E0516]: `typeof` is a reserved keyword but unimplemented + --> $DIR/issue-100183.rs:2:9 + | +LL | y: (typeof("hey"),), + | ^^^^^^^^^^^^^ reserved keyword + | +help: consider replacing `typeof(...)` with an actual type + | +LL | y: (&'static str,), + | ~~~~~~~~~~~~ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0516`. diff --git a/triagebot.toml b/triagebot.toml index ceda7ef5f1658..4b2dcc246e4ee 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -11,6 +11,7 @@ allow-unauthenticated = [ "S-*", "T-*", "WG-*", + "const-hack", "needs-fcp", "relnotes", "requires-nightly",