diff --git a/.gitattributes b/.gitattributes index 4038db6f7dab1..d29c15fe712f3 100644 --- a/.gitattributes +++ b/.gitattributes @@ -7,11 +7,11 @@ *.fixed linguist-language=Rust *.mir linguist-language=Rust src/etc/installer/gfx/* binary -*.woff binary -*.woff2 binary src/vendor/** -text Cargo.lock linguist-generated=false -# Older git versions try to fix line endings on images, this prevents it. +# Older git versions try to fix line endings on images and fonts, this prevents it. *.png binary *.ico binary +*.woff binary +*.woff2 binary diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 99a0c0b4b85de..2ead68638fa4a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -622,7 +622,7 @@ jobs: if: "github.event_name == 'push' && github.ref == 'refs/heads/master' && github.repository == 'rust-lang-ci/rust'" steps: - name: checkout the source code - uses: actions/checkout@v1 + uses: actions/checkout@v2 with: fetch-depth: 2 - name: publish toolstate diff --git a/compiler/rustc_arena/src/lib.rs b/compiler/rustc_arena/src/lib.rs index a9917f50cc202..c3198fb10431c 100644 --- a/compiler/rustc_arena/src/lib.rs +++ b/compiler/rustc_arena/src/lib.rs @@ -298,22 +298,6 @@ impl TypedArena { } } - /// Clears the arena. Deallocates all but the longest chunk which may be reused. - pub fn clear(&mut self) { - unsafe { - // Clear the last chunk, which is partially filled. - let mut chunks_borrow = self.chunks.borrow_mut(); - if let Some(mut last_chunk) = chunks_borrow.last_mut() { - self.clear_last_chunk(&mut last_chunk); - let len = chunks_borrow.len(); - // If `T` is ZST, code below has no effect. - for mut chunk in chunks_borrow.drain(..len - 1) { - chunk.destroy(chunk.entries); - } - } - } - } - // Drops the contents of the last chunk. The last chunk is partially empty, unlike all other // chunks. fn clear_last_chunk(&self, last_chunk: &mut TypedArenaChunk) { diff --git a/compiler/rustc_arena/src/tests.rs b/compiler/rustc_arena/src/tests.rs index e8a1f2db1a16b..911e577c1edc7 100644 --- a/compiler/rustc_arena/src/tests.rs +++ b/compiler/rustc_arena/src/tests.rs @@ -11,6 +11,24 @@ struct Point { z: i32, } +impl TypedArena { + /// Clears the arena. Deallocates all but the longest chunk which may be reused. + fn clear(&mut self) { + unsafe { + // Clear the last chunk, which is partially filled. + let mut chunks_borrow = self.chunks.borrow_mut(); + if let Some(mut last_chunk) = chunks_borrow.last_mut() { + self.clear_last_chunk(&mut last_chunk); + let len = chunks_borrow.len(); + // If `T` is ZST, code below has no effect. + for mut chunk in chunks_borrow.drain(..len - 1) { + chunk.destroy(chunk.entries); + } + } + } + } +} + #[test] pub fn test_unused() { let arena: TypedArena = TypedArena::default(); diff --git a/compiler/rustc_codegen_ssa/src/lib.rs b/compiler/rustc_codegen_ssa/src/lib.rs index 2c2330409fd70..dd04d3e548f8c 100644 --- a/compiler/rustc_codegen_ssa/src/lib.rs +++ b/compiler/rustc_codegen_ssa/src/lib.rs @@ -1,6 +1,6 @@ #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] +#![feature(assert_matches)] #![feature(bool_to_option)] -#![feature(option_expect_none)] #![feature(box_patterns)] #![feature(drain_filter)] #![feature(try_blocks)] diff --git a/compiler/rustc_data_structures/src/tiny_list.rs b/compiler/rustc_data_structures/src/tiny_list.rs index e94a0c6eb5943..f88bcc2948150 100644 --- a/compiler/rustc_data_structures/src/tiny_list.rs +++ b/compiler/rustc_data_structures/src/tiny_list.rs @@ -15,7 +15,7 @@ mod tests; #[derive(Clone)] -pub struct TinyList { +pub struct TinyList { head: Option>, } @@ -56,20 +56,10 @@ impl TinyList { } false } - - #[inline] - pub fn len(&self) -> usize { - let (mut elem, mut count) = (self.head.as_ref(), 0); - while let Some(ref e) = elem { - count += 1; - elem = e.next.as_deref(); - } - count - } } #[derive(Clone)] -struct Element { +struct Element { data: T, next: Option>>, } diff --git a/compiler/rustc_data_structures/src/tiny_list/tests.rs b/compiler/rustc_data_structures/src/tiny_list/tests.rs index a8ae2bc872789..c0334d2e23e55 100644 --- a/compiler/rustc_data_structures/src/tiny_list/tests.rs +++ b/compiler/rustc_data_structures/src/tiny_list/tests.rs @@ -3,6 +3,17 @@ use super::*; extern crate test; use test::{black_box, Bencher}; +impl TinyList { + fn len(&self) -> usize { + let (mut elem, mut count) = (self.head.as_ref(), 0); + while let Some(ref e) = elem { + count += 1; + elem = e.next.as_deref(); + } + count + } +} + #[test] fn test_contains_and_insert() { fn do_insert(i: u32) -> bool { diff --git a/compiler/rustc_data_structures/src/transitive_relation.rs b/compiler/rustc_data_structures/src/transitive_relation.rs index 2e1512b3929ca..ccf8bd69ebd06 100644 --- a/compiler/rustc_data_structures/src/transitive_relation.rs +++ b/compiler/rustc_data_structures/src/transitive_relation.rs @@ -9,7 +9,7 @@ use std::mem; mod tests; #[derive(Clone, Debug)] -pub struct TransitiveRelation { +pub struct TransitiveRelation { // List of elements. This is used to map from a T to a usize. elements: FxIndexSet, @@ -49,7 +49,7 @@ struct Edge { target: Index, } -impl TransitiveRelation { +impl TransitiveRelation { pub fn is_empty(&self) -> bool { self.edges.is_empty() } @@ -322,12 +322,6 @@ impl TransitiveRelation { .collect() } - /// A "best" parent in some sense. See `parents` and - /// `postdom_upper_bound` for more details. - pub fn postdom_parent(&self, a: &T) -> Option<&T> { - self.mutual_immediate_postdominator(self.parents(a)) - } - fn with_closure(&self, op: OP) -> R where OP: FnOnce(&BitMatrix) -> R, diff --git a/compiler/rustc_data_structures/src/transitive_relation/tests.rs b/compiler/rustc_data_structures/src/transitive_relation/tests.rs index ca90ba176ae1a..9fa7224376c1c 100644 --- a/compiler/rustc_data_structures/src/transitive_relation/tests.rs +++ b/compiler/rustc_data_structures/src/transitive_relation/tests.rs @@ -1,5 +1,13 @@ use super::*; +impl TransitiveRelation { + /// A "best" parent in some sense. See `parents` and + /// `postdom_upper_bound` for more details. + fn postdom_parent(&self, a: &T) -> Option<&T> { + self.mutual_immediate_postdominator(self.parents(a)) + } +} + #[test] fn test_one_step() { let mut relation = TransitiveRelation::default(); diff --git a/compiler/rustc_errors/src/diagnostic_builder.rs b/compiler/rustc_errors/src/diagnostic_builder.rs index c09cce21bf24c..79507e6152219 100644 --- a/compiler/rustc_errors/src/diagnostic_builder.rs +++ b/compiler/rustc_errors/src/diagnostic_builder.rs @@ -30,15 +30,6 @@ struct DiagnosticBuilderInner<'a> { allow_suggestions: bool, } -/// This is a helper macro for [`forward!`] that allows automatically adding documentation -/// that uses tokens from [`forward!`]'s input. -macro_rules! forward_inner_docs { - ($e:expr => $i:item) => { - #[doc = $e] - $i - }; -} - /// In general, the `DiagnosticBuilder` uses deref to allow access to /// the fields and methods of the embedded `diagnostic` in a /// transparent way. *However,* many of the methods are intended to @@ -54,11 +45,11 @@ macro_rules! forward { pub fn $n:ident(&self, $($name:ident: $ty:ty),* $(,)?) -> &Self ) => { $(#[$attrs])* - forward_inner_docs!(concat!("See [`Diagnostic::", stringify!($n), "()`].") => + #[doc = concat!("See [`Diagnostic::", stringify!($n), "()`].")] pub fn $n(&self, $($name: $ty),*) -> &Self { self.diagnostic.$n($($name),*); self - }); + } }; // Forward pattern for &mut self -> &mut Self @@ -67,11 +58,11 @@ macro_rules! forward { pub fn $n:ident(&mut self, $($name:ident: $ty:ty),* $(,)?) -> &mut Self ) => { $(#[$attrs])* - forward_inner_docs!(concat!("See [`Diagnostic::", stringify!($n), "()`].") => + #[doc = concat!("See [`Diagnostic::", stringify!($n), "()`].")] pub fn $n(&mut self, $($name: $ty),*) -> &mut Self { self.0.diagnostic.$n($($name),*); self - }); + } }; // Forward pattern for &mut self -> &mut Self, with generic parameters. @@ -84,11 +75,11 @@ macro_rules! forward { ) -> &mut Self ) => { $(#[$attrs])* - forward_inner_docs!(concat!("See [`Diagnostic::", stringify!($n), "()`].") => + #[doc = concat!("See [`Diagnostic::", stringify!($n), "()`].")] pub fn $n<$($generic: $bound),*>(&mut self, $($name: $ty),*) -> &mut Self { self.0.diagnostic.$n($($name),*); self - }); + } }; } diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index 1db39fbfba502..fa855f544e819 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -5,6 +5,7 @@ #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] #![feature(crate_visibility_modifier)] #![feature(backtrace)] +#![feature(extended_key_value_attributes)] #![feature(nll)] #[macro_use] diff --git a/compiler/rustc_expand/src/proc_macro_server.rs b/compiler/rustc_expand/src/proc_macro_server.rs index 67edfe19da383..cb41bc81225ec 100644 --- a/compiler/rustc_expand/src/proc_macro_server.rs +++ b/compiler/rustc_expand/src/proc_macro_server.rs @@ -53,11 +53,11 @@ impl ToInternal for Delimiter { } } -impl FromInternal<(TreeAndSpacing, &'_ ParseSess, &'_ mut Vec)> +impl FromInternal<(TreeAndSpacing, &'_ mut Vec, &mut Rustc<'_>)> for TokenTree { fn from_internal( - ((tree, spacing), sess, stack): (TreeAndSpacing, &ParseSess, &mut Vec), + ((tree, spacing), stack, rustc): (TreeAndSpacing, &mut Vec, &mut Rustc<'_>), ) -> Self { use rustc_ast::token::*; @@ -146,10 +146,10 @@ impl FromInternal<(TreeAndSpacing, &'_ ParseSess, &'_ mut Vec)> SingleQuote => op!('\''), Ident(name, false) if name == kw::DollarCrate => tt!(Ident::dollar_crate()), - Ident(name, is_raw) => tt!(Ident::new(sess, name, is_raw)), + Ident(name, is_raw) => tt!(Ident::new(rustc.sess, name, is_raw)), Lifetime(name) => { let ident = symbol::Ident::new(name, span).without_first_quote(); - stack.push(tt!(Ident::new(sess, ident.name, false))); + stack.push(tt!(Ident::new(rustc.sess, ident.name, false))); tt!(Punct::new('\'', true)) } Literal(lit) => tt!(Literal { lit }), @@ -179,15 +179,15 @@ impl FromInternal<(TreeAndSpacing, &'_ ParseSess, &'_ mut Vec)> } Interpolated(nt) => { - if let Some((name, is_raw)) = ident_name_compatibility_hack(&nt, span, sess) { - TokenTree::Ident(Ident::new(sess, name.name, is_raw, name.span)) + if let Some((name, is_raw)) = ident_name_compatibility_hack(&nt, span, rustc) { + TokenTree::Ident(Ident::new(rustc.sess, name.name, is_raw, name.span)) } else { - let stream = nt_to_tokenstream(&nt, sess, CanSynthesizeMissingTokens::No); + let stream = nt_to_tokenstream(&nt, rustc.sess, CanSynthesizeMissingTokens::No); TokenTree::Group(Group { delimiter: Delimiter::None, stream, span: DelimSpan::from_single(span), - flatten: crate::base::pretty_printing_compatibility_hack(&nt, sess), + flatten: crate::base::pretty_printing_compatibility_hack(&nt, rustc.sess), }) } } @@ -449,7 +449,7 @@ impl server::TokenStreamIter for Rustc<'_> { loop { let tree = iter.stack.pop().or_else(|| { let next = iter.cursor.next_with_spacing()?; - Some(TokenTree::from_internal((next, self.sess, &mut iter.stack))) + Some(TokenTree::from_internal((next, &mut iter.stack, self))) })?; // A hack used to pass AST fragments to attribute and derive macros // as a single nonterminal token instead of a token stream. @@ -719,11 +719,11 @@ impl server::Span for Rustc<'_> { fn ident_name_compatibility_hack( nt: &Nonterminal, orig_span: Span, - sess: &ParseSess, + rustc: &mut Rustc<'_>, ) -> Option<(rustc_span::symbol::Ident, bool)> { if let NtIdent(ident, is_raw) = nt { if let ExpnKind::Macro(_, macro_name) = orig_span.ctxt().outer_expn_data().kind { - let source_map = sess.source_map(); + let source_map = rustc.sess.source_map(); let filename = source_map.span_to_filename(orig_span); if let FileName::Real(RealFileName::Named(path)) = filename { let matches_prefix = |prefix, filename| { @@ -745,7 +745,7 @@ fn ident_name_compatibility_hack( let snippet = source_map.span_to_snippet(orig_span); if snippet.as_deref() == Ok("$name") { if time_macros_impl { - sess.buffer_lint_with_diagnostic( + rustc.sess.buffer_lint_with_diagnostic( &PROC_MACRO_BACK_COMPAT, orig_span, ast::CRATE_NODE_ID, @@ -759,13 +759,25 @@ fn ident_name_compatibility_hack( } } - if macro_name == sym::tuple_from_req - && (matches_prefix("actix-web", "extract.rs") - || matches_prefix("actori-web", "extract.rs")) - { + if macro_name == sym::tuple_from_req && matches_prefix("actix-web", "extract.rs") { let snippet = source_map.span_to_snippet(orig_span); if snippet.as_deref() == Ok("$T") { - return Some((*ident, *is_raw)); + if let FileName::Real(RealFileName::Named(macro_path)) = + source_map.span_to_filename(rustc.def_site) + { + if macro_path.to_string_lossy().contains("pin-project-internal-0.") { + rustc.sess.buffer_lint_with_diagnostic( + &PROC_MACRO_BACK_COMPAT, + orig_span, + ast::CRATE_NODE_ID, + "using an old version of `actix-web`", + BuiltinLintDiagnostics::ProcMacroBackCompat( + "the version of `actix-web` you are using might stop compiling in future versions of Rust; \ + please update to the latest version of the `actix-web` crate to avoid breakage".to_string()) + ); + return Some((*ident, *is_raw)); + } + } } } } diff --git a/compiler/rustc_middle/src/ich/impls_syntax.rs b/compiler/rustc_middle/src/ich/impls_syntax.rs index bfbe15749ee1c..31374429940ca 100644 --- a/compiler/rustc_middle/src/ich/impls_syntax.rs +++ b/compiler/rustc_middle/src/ich/impls_syntax.rs @@ -45,7 +45,11 @@ impl<'ctx> rustc_ast::HashStableContext for StableHashingContext<'ctx> { item.hash_stable(self, hasher); style.hash_stable(self, hasher); span.hash_stable(self, hasher); - tokens.as_ref().expect_none("Tokens should have been removed during lowering!"); + assert_matches!( + tokens.as_ref(), + None, + "Tokens should have been removed during lowering!" + ); } else { unreachable!(); } diff --git a/compiler/rustc_middle/src/lib.rs b/compiler/rustc_middle/src/lib.rs index d9e8826505002..2d807591bfdd2 100644 --- a/compiler/rustc_middle/src/lib.rs +++ b/compiler/rustc_middle/src/lib.rs @@ -24,6 +24,7 @@ #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] #![feature(array_windows)] +#![feature(assert_matches)] #![feature(assoc_char_funcs)] #![feature(backtrace)] #![feature(bool_to_option)] @@ -38,7 +39,6 @@ #![feature(extern_types)] #![feature(nll)] #![feature(once_cell)] -#![feature(option_expect_none)] #![feature(or_patterns)] #![feature(min_specialization)] #![feature(trusted_len)] diff --git a/compiler/rustc_middle/src/mir/interpret/allocation.rs b/compiler/rustc_middle/src/mir/interpret/allocation.rs index 48595f2badc8f..766d6a06f7e59 100644 --- a/compiler/rustc_middle/src/mir/interpret/allocation.rs +++ b/compiler/rustc_middle/src/mir/interpret/allocation.rs @@ -339,7 +339,7 @@ impl<'tcx, Tag: Copy, Extra: AllocationExtra> Allocation { for dest in bytes { *dest = src.next().expect("iterator was shorter than it said it would be"); } - src.next().expect_none("iterator was longer than it said it would be"); + assert_matches!(src.next(), None, "iterator was longer than it said it would be"); Ok(()) } diff --git a/compiler/rustc_mir/src/interpret/memory.rs b/compiler/rustc_mir/src/interpret/memory.rs index f3e373813ca53..fe5ebf0b6fe97 100644 --- a/compiler/rustc_mir/src/interpret/memory.rs +++ b/compiler/rustc_mir/src/interpret/memory.rs @@ -854,7 +854,11 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { Some(ptr) => ptr, None => { // zero-sized access - src.next().expect_none("iterator said it was empty but returned an element"); + assert_matches!( + src.next(), + None, + "iterator said it was empty but returned an element" + ); return Ok(()); } }; @@ -880,7 +884,11 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { Some(ptr) => ptr, None => { // zero-sized access - src.next().expect_none("iterator said it was empty but returned an element"); + assert_matches!( + src.next(), + None, + "iterator said it was empty but returned an element" + ); return Ok(()); } }; @@ -894,7 +902,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { let offset_ptr = ptr.offset(Size::from_bytes(idx) * 2, &tcx)?; // `Size` multiplication allocation.write_scalar(&tcx, offset_ptr, val.into(), Size::from_bytes(2))?; } - src.next().expect_none("iterator was longer than it said it would be"); + assert_matches!(src.next(), None, "iterator was longer than it said it would be"); Ok(()) } diff --git a/compiler/rustc_mir/src/lib.rs b/compiler/rustc_mir/src/lib.rs index 194bc74c0fb1a..f73d5dc0c116d 100644 --- a/compiler/rustc_mir/src/lib.rs +++ b/compiler/rustc_mir/src/lib.rs @@ -7,6 +7,7 @@ Rust MIR: a lowered representation of Rust. #![feature(nll)] #![feature(in_band_lifetimes)] #![feature(array_windows)] +#![feature(assert_matches)] #![feature(bindings_after_at)] #![feature(bool_to_option)] #![feature(box_patterns)] @@ -18,13 +19,13 @@ Rust MIR: a lowered representation of Rust. #![feature(exact_size_is_empty)] #![feature(exhaustive_patterns)] #![feature(never_type)] +#![feature(map_try_insert)] #![feature(min_specialization)] #![feature(trusted_len)] #![feature(try_blocks)] #![feature(associated_type_defaults)] #![feature(stmt_expr_attributes)] #![feature(trait_alias)] -#![feature(option_expect_none)] #![feature(option_get_or_insert_default)] #![feature(or_patterns)] #![feature(once_cell)] diff --git a/compiler/rustc_mir/src/transform/coverage/debug.rs b/compiler/rustc_mir/src/transform/coverage/debug.rs index 2cd0dc6b1f2fd..aabfee53acb29 100644 --- a/compiler/rustc_mir/src/transform/coverage/debug.rs +++ b/compiler/rustc_mir/src/transform/coverage/debug.rs @@ -285,10 +285,8 @@ impl DebugCounters { ), }; counters - .insert(id, DebugCounter::new(counter_kind.clone(), some_block_label)) - .expect_none( - "attempt to add the same counter_kind to DebugCounters more than once", - ); + .try_insert(id, DebugCounter::new(counter_kind.clone(), some_block_label)) + .expect("attempt to add the same counter_kind to DebugCounters more than once"); } } @@ -479,9 +477,9 @@ impl GraphvizData { counter_kind: &CoverageKind, ) { if let Some(edge_to_counter) = self.some_edge_to_counter.as_mut() { - edge_to_counter.insert((from_bcb, to_bb), counter_kind.clone()).expect_none( - "invalid attempt to insert more than one edge counter for the same edge", - ); + edge_to_counter + .try_insert((from_bcb, to_bb), counter_kind.clone()) + .expect("invalid attempt to insert more than one edge counter for the same edge"); } } diff --git a/compiler/rustc_mir/src/transform/deduplicate_blocks.rs b/compiler/rustc_mir/src/transform/deduplicate_blocks.rs index c4b51099f5389..e102512e1f37f 100644 --- a/compiler/rustc_mir/src/transform/deduplicate_blocks.rs +++ b/compiler/rustc_mir/src/transform/deduplicate_blocks.rs @@ -86,7 +86,7 @@ fn find_duplicates<'a, 'tcx>(body: &'a Body<'tcx>) -> FxHashMap {:?}", bb, value); - duplicates.insert(bb, value).expect_none("key was already inserted"); + duplicates.try_insert(bb, value).expect("key was already inserted"); } Entry::Vacant(vacant) => { vacant.insert(bb); diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 775e27e68f8a2..d91d0e1765bbf 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -394,33 +394,50 @@ impl CheckAttrVisitor<'tcx> { .emit(); } - fn check_doc_alias(&self, meta: &NestedMetaItem, hir_id: HirId, target: Target) -> bool { - let doc_alias = meta.value_str().map(|s| s.to_string()).unwrap_or_else(String::new); + fn check_doc_alias_value( + &self, + meta: &NestedMetaItem, + doc_alias: &str, + hir_id: HirId, + target: Target, + is_list: bool, + ) -> bool { + let tcx = self.tcx; + let err_fn = move |span: Span, msg: &str| { + tcx.sess.span_err( + span, + &format!( + "`#[doc(alias{})]` {}", + if is_list { "(\"...\")" } else { " = \"...\"" }, + msg, + ), + ); + false + }; if doc_alias.is_empty() { - self.doc_attr_str_error(meta, "alias"); - return false; + return err_fn( + meta.name_value_literal_span().unwrap_or_else(|| meta.span()), + "attribute cannot have empty value", + ); } if let Some(c) = doc_alias.chars().find(|&c| c == '"' || c == '\'' || (c.is_whitespace() && c != ' ')) { - self.tcx - .sess - .struct_span_err( - meta.name_value_literal_span().unwrap_or_else(|| meta.span()), - &format!("{:?} character isn't allowed in `#[doc(alias = \"...\")]`", c), - ) - .emit(); + self.tcx.sess.span_err( + meta.name_value_literal_span().unwrap_or_else(|| meta.span()), + &format!( + "{:?} character isn't allowed in `#[doc(alias{})]`", + c, + if is_list { "(\"...\")" } else { " = \"...\"" }, + ), + ); return false; } if doc_alias.starts_with(' ') || doc_alias.ends_with(' ') { - self.tcx - .sess - .struct_span_err( - meta.name_value_literal_span().unwrap_or_else(|| meta.span()), - "`#[doc(alias = \"...\")]` cannot start or end with ' '", - ) - .emit(); - return false; + return err_fn( + meta.name_value_literal_span().unwrap_or_else(|| meta.span()), + "cannot start or end with ' '", + ); } if let Some(err) = match target { Target::Impl => Some("implementation block"), @@ -446,27 +463,63 @@ impl CheckAttrVisitor<'tcx> { } _ => None, } { - self.tcx - .sess - .struct_span_err( - meta.span(), - &format!("`#[doc(alias = \"...\")]` isn't allowed on {}", err), - ) - .emit(); - return false; + return err_fn(meta.span(), &format!("isn't allowed on {}", err)); } let item_name = self.tcx.hir().name(hir_id); if &*item_name.as_str() == doc_alias { + return err_fn(meta.span(), "is the same as the item's name"); + } + true + } + + fn check_doc_alias(&self, meta: &NestedMetaItem, hir_id: HirId, target: Target) -> bool { + if let Some(values) = meta.meta_item_list() { + let mut errors = 0; + for v in values { + match v.literal() { + Some(l) => match l.kind { + LitKind::Str(s, _) => { + if !self.check_doc_alias_value(v, &s.as_str(), hir_id, target, true) { + errors += 1; + } + } + _ => { + self.tcx + .sess + .struct_span_err( + v.span(), + "`#[doc(alias(\"a\"))]` expects string literals", + ) + .emit(); + errors += 1; + } + }, + None => { + self.tcx + .sess + .struct_span_err( + v.span(), + "`#[doc(alias(\"a\"))]` expects string literals", + ) + .emit(); + errors += 1; + } + } + } + errors == 0 + } else if let Some(doc_alias) = meta.value_str().map(|s| s.to_string()) { + self.check_doc_alias_value(meta, &doc_alias, hir_id, target, false) + } else { self.tcx .sess .struct_span_err( meta.span(), - &format!("`#[doc(alias = \"...\")]` is the same as the item's name"), + "doc alias attribute expects a string `#[doc(alias = \"a\")]` or a list of \ + strings `#[doc(alias(\"a\", \"b\"))]`", ) .emit(); - return false; + false } - true } fn check_doc_keyword(&self, meta: &NestedMetaItem, hir_id: HirId) -> bool { diff --git a/compiler/rustc_span/src/hygiene.rs b/compiler/rustc_span/src/hygiene.rs index e67a4ca8fb26b..eb5b7c4a74a1d 100644 --- a/compiler/rustc_span/src/hygiene.rs +++ b/compiler/rustc_span/src/hygiene.rs @@ -118,7 +118,8 @@ impl ExpnId { HygieneData::with(|data| { let old_expn_data = &mut data.expn_data[self.0 as usize]; assert!(old_expn_data.is_none(), "expansion data is reset for an expansion ID"); - expn_data.orig_id.replace(self.as_u32()).expect_none("orig_id should be None"); + assert_eq!(expn_data.orig_id, None); + expn_data.orig_id = Some(self.as_u32()); *old_expn_data = Some(expn_data); }); update_disambiguator(self) @@ -202,7 +203,8 @@ impl HygieneData { fn fresh_expn(&mut self, mut expn_data: Option) -> ExpnId { let raw_id = self.expn_data.len() as u32; if let Some(data) = expn_data.as_mut() { - data.orig_id.replace(raw_id).expect_none("orig_id should be None"); + assert_eq!(data.orig_id, None); + data.orig_id = Some(raw_id); } self.expn_data.push(expn_data); ExpnId(raw_id) @@ -1410,9 +1412,11 @@ fn update_disambiguator(expn_id: ExpnId) { let new_hash: Fingerprint = hasher.finish(); HygieneData::with(|data| { - data.expn_data_disambiguators - .get(&new_hash) - .expect_none("Hash collision after disambiguator update!"); + assert_eq!( + data.expn_data_disambiguators.get(&new_hash), + None, + "Hash collision after disambiguator update!", + ); }); }; } diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs index 6030c8a86d9f9..d2790335b5abc 100644 --- a/compiler/rustc_span/src/lib.rs +++ b/compiler/rustc_span/src/lib.rs @@ -21,7 +21,6 @@ #![feature(negative_impls)] #![feature(nll)] #![feature(min_specialization)] -#![feature(option_expect_none)] #[macro_use] extern crate rustc_macros; @@ -1996,7 +1995,8 @@ impl HashStable for ExpnId { if cache.len() < new_len { cache.resize(new_len, None); } - cache[index].replace(sub_hash).expect_none("Cache slot was filled"); + let prev = cache[index].replace(sub_hash); + assert_eq!(prev, None, "Cache slot was filled"); }); sub_hash.hash_stable(ctx, hasher); } diff --git a/compiler/rustc_span/src/source_map.rs b/compiler/rustc_span/src/source_map.rs index b7eb6d5b3790b..f612d1425b932 100644 --- a/compiler/rustc_span/src/source_map.rs +++ b/compiler/rustc_span/src/source_map.rs @@ -453,41 +453,6 @@ impl SourceMap { } } - /// Returns `Some(span)`, a union of the LHS and RHS span. The LHS must precede the RHS. If - /// there are gaps between LHS and RHS, the resulting union will cross these gaps. - /// For this to work, - /// - /// * the syntax contexts of both spans much match, - /// * the LHS span needs to end on the same line the RHS span begins, - /// * the LHS span must start at or before the RHS span. - pub fn merge_spans(&self, sp_lhs: Span, sp_rhs: Span) -> Option { - // Ensure we're at the same expansion ID. - if sp_lhs.ctxt() != sp_rhs.ctxt() { - return None; - } - - let lhs_end = match self.lookup_line(sp_lhs.hi()) { - Ok(x) => x, - Err(_) => return None, - }; - let rhs_begin = match self.lookup_line(sp_rhs.lo()) { - Ok(x) => x, - Err(_) => return None, - }; - - // If we must cross lines to merge, don't merge. - if lhs_end.line != rhs_begin.line { - return None; - } - - // Ensure these follow the expected order and that we don't overlap. - if (sp_lhs.lo() <= sp_rhs.lo()) && (sp_lhs.hi() <= sp_rhs.lo()) { - Some(sp_lhs.to(sp_rhs)) - } else { - None - } - } - pub fn span_to_string(&self, sp: Span) -> String { if self.files.borrow().source_files.is_empty() && sp.is_dummy() { return "no-location".to_string(); @@ -931,13 +896,6 @@ impl SourceMap { SourceFileAndBytePos { sf, pos: offset } } - /// Converts an absolute `BytePos` to a `CharPos` relative to the `SourceFile`. - pub fn bytepos_to_file_charpos(&self, bpos: BytePos) -> CharPos { - let idx = self.lookup_source_file_idx(bpos); - let sf = &(*self.files.borrow().source_files)[idx]; - sf.bytepos_to_file_charpos(bpos) - } - // Returns the index of the `SourceFile` (in `self.files`) that contains `pos`. // This index is guaranteed to be valid for the lifetime of this `SourceMap`, // since `source_files` is a `MonotonicVec` diff --git a/compiler/rustc_span/src/source_map/tests.rs b/compiler/rustc_span/src/source_map/tests.rs index 0aca677248b72..7d814f1d82c11 100644 --- a/compiler/rustc_span/src/source_map/tests.rs +++ b/compiler/rustc_span/src/source_map/tests.rs @@ -10,6 +10,50 @@ fn init_source_map() -> SourceMap { sm } +impl SourceMap { + /// Returns `Some(span)`, a union of the LHS and RHS span. The LHS must precede the RHS. If + /// there are gaps between LHS and RHS, the resulting union will cross these gaps. + /// For this to work, + /// + /// * the syntax contexts of both spans much match, + /// * the LHS span needs to end on the same line the RHS span begins, + /// * the LHS span must start at or before the RHS span. + fn merge_spans(&self, sp_lhs: Span, sp_rhs: Span) -> Option { + // Ensure we're at the same expansion ID. + if sp_lhs.ctxt() != sp_rhs.ctxt() { + return None; + } + + let lhs_end = match self.lookup_line(sp_lhs.hi()) { + Ok(x) => x, + Err(_) => return None, + }; + let rhs_begin = match self.lookup_line(sp_rhs.lo()) { + Ok(x) => x, + Err(_) => return None, + }; + + // If we must cross lines to merge, don't merge. + if lhs_end.line != rhs_begin.line { + return None; + } + + // Ensure these follow the expected order and that we don't overlap. + if (sp_lhs.lo() <= sp_rhs.lo()) && (sp_lhs.hi() <= sp_rhs.lo()) { + Some(sp_lhs.to(sp_rhs)) + } else { + None + } + } + + /// Converts an absolute `BytePos` to a `CharPos` relative to the `SourceFile`. + fn bytepos_to_file_charpos(&self, bpos: BytePos) -> CharPos { + let idx = self.lookup_source_file_idx(bpos); + let sf = &(*self.files.borrow().source_files)[idx]; + sf.bytepos_to_file_charpos(bpos) + } +} + /// Tests `lookup_byte_offset`. #[test] fn t3() { diff --git a/library/core/src/iter/traits/iterator.rs b/library/core/src/iter/traits/iterator.rs index f8504e842ee33..a07750f4ad1fe 100644 --- a/library/core/src/iter/traits/iterator.rs +++ b/library/core/src/iter/traits/iterator.rs @@ -1012,7 +1012,7 @@ pub trait Iterator { /// /// Because the closure passed to `skip_while()` takes a reference, and many /// iterators iterate over references, this leads to a possibly confusing - /// situation, where the type of the closure is a double reference: + /// situation, where the type of the closure argument is a double reference: /// /// ``` /// let a = [-1, 0, 1]; diff --git a/library/std/src/io/mod.rs b/library/std/src/io/mod.rs index 17002e3b8602d..6abb300054af8 100644 --- a/library/std/src/io/mod.rs +++ b/library/std/src/io/mod.rs @@ -514,8 +514,8 @@ pub trait Read { /// waiting for data, but if an object needs to block for a read and cannot, /// it will typically signal this via an [`Err`] return value. /// - /// If the return value of this method is [`Ok(n)`], then it must be - /// guaranteed that `0 <= n <= buf.len()`. A nonzero `n` value indicates + /// If the return value of this method is [`Ok(n)`], then implementations must + /// guarantee that `0 <= n <= buf.len()`. A nonzero `n` value indicates /// that the buffer `buf` has been filled in with `n` bytes of data from this /// source. If `n` is `0`, then it can indicate one of two scenarios: /// @@ -529,6 +529,11 @@ pub trait Read { /// This may happen for example because fewer bytes are actually available right now /// (e. g. being close to end-of-file) or because read() was interrupted by a signal. /// + /// As this trait is safe to implement, callers cannot rely on `n <= buf.len()` for safety. + /// Extra care needs to be taken when `unsafe` functions are used to access the read bytes. + /// Callers have to ensure that no unchecked out-of-bounds accesses are possible even if + /// `n > buf.len()`. + /// /// No guarantees are provided about the contents of `buf` when this /// function is called, implementations cannot rely on any property of the /// contents of `buf` being true. It is recommended that *implementations* diff --git a/library/std/src/os/haiku/raw.rs b/library/std/src/os/haiku/raw.rs index 0d7e70b6b351d..48117d288ae47 100644 --- a/library/std/src/os/haiku/raw.rs +++ b/library/std/src/os/haiku/raw.rs @@ -1,6 +1,13 @@ //! Haiku-specific raw type definitions #![stable(feature = "raw_ext", since = "1.1.0")] +#![rustc_deprecated( + since = "1.53.0", + reason = "these type aliases are no longer supported by \ + the standard library, the `libc` crate on \ + crates.io should be used instead for the correct \ + definitions" +)] #![allow(deprecated)] use crate::os::raw::c_long; diff --git a/library/std/src/sys/hermit/mod.rs b/library/std/src/sys/hermit/mod.rs index f185635b7a0a6..17a51abeb0ef6 100644 --- a/library/std/src/sys/hermit/mod.rs +++ b/library/std/src/sys/hermit/mod.rs @@ -32,6 +32,7 @@ pub mod mutex; pub mod net; pub mod os; pub mod path; +#[path = "../unsupported/pipe.rs"] pub mod pipe; #[path = "../unsupported/process.rs"] pub mod process; diff --git a/library/std/src/sys/hermit/pipe.rs b/library/std/src/sys/hermit/pipe.rs deleted file mode 100644 index 10d0925823eb9..0000000000000 --- a/library/std/src/sys/hermit/pipe.rs +++ /dev/null @@ -1,38 +0,0 @@ -use crate::io::{self, IoSlice, IoSliceMut}; -use crate::sys::Void; - -pub struct AnonPipe(Void); - -impl AnonPipe { - pub fn read(&self, _buf: &mut [u8]) -> io::Result { - match self.0 {} - } - - pub fn read_vectored(&self, _bufs: &mut [IoSliceMut<'_>]) -> io::Result { - match self.0 {} - } - - pub fn is_read_vectored(&self) -> bool { - match self.0 {} - } - - pub fn write(&self, _buf: &[u8]) -> io::Result { - match self.0 {} - } - - pub fn write_vectored(&self, _bufs: &[IoSlice<'_>]) -> io::Result { - match self.0 {} - } - - pub fn is_write_vectored(&self) -> bool { - match self.0 {} - } - - pub fn diverge(&self) -> ! { - match self.0 {} - } -} - -pub fn read2(p1: AnonPipe, _v1: &mut Vec, _p2: AnonPipe, _v2: &mut Vec) -> io::Result<()> { - match p1.0 {} -} diff --git a/src/ci/github-actions/ci.yml b/src/ci/github-actions/ci.yml index 7125b33699a0c..c0a84444a5928 100644 --- a/src/ci/github-actions/ci.yml +++ b/src/ci/github-actions/ci.yml @@ -655,7 +655,7 @@ jobs: if: github.event_name == 'push' && github.ref == 'refs/heads/master' && github.repository == 'rust-lang-ci/rust' steps: - name: checkout the source code - uses: actions/checkout@v1 + uses: actions/checkout@v2 with: fetch-depth: 2 diff --git a/src/doc/rustdoc/src/advanced-features.md b/src/doc/rustdoc/src/advanced-features.md index abdc2e4025d0e..6147bd0a97a96 100644 --- a/src/doc/rustdoc/src/advanced-features.md +++ b/src/doc/rustdoc/src/advanced-features.md @@ -81,3 +81,10 @@ Then, when looking for it through the `rustdoc` search, if you enter "x" or "big", search will show the `BigX` struct first. There are some limitations on the doc alias names though: you can't use `"` or whitespace. + +You can add multiple aliases at the same time by using a list: + +```rust,no_run +#[doc(alias("x", "big"))] +pub struct BigX; +``` diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 114b68c56b812..840a42c2b8aab 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -910,12 +910,23 @@ impl Attributes { } crate fn get_doc_aliases(&self) -> FxHashSet { - self.other_attrs - .lists(sym::doc) - .filter(|a| a.has_name(sym::alias)) - .filter_map(|a| a.value_str().map(|s| s.to_string())) - .filter(|v| !v.is_empty()) - .collect::>() + let mut aliases = FxHashSet::default(); + + for attr in self.other_attrs.lists(sym::doc).filter(|a| a.has_name(sym::alias)) { + if let Some(values) = attr.meta_item_list() { + for l in values { + match l.literal().unwrap().kind { + ast::LitKind::Str(s, _) => { + aliases.insert(s.as_str().to_string()); + } + _ => unreachable!(), + } + } + } else { + aliases.insert(attr.value_str().map(|s| s.to_string()).unwrap()); + } + } + aliases } } diff --git a/src/test/rustdoc-ui/check-doc-alias-attr.rs b/src/test/rustdoc-ui/check-doc-alias-attr.rs index 912e35f916545..719b98604c497 100644 --- a/src/test/rustdoc-ui/check-doc-alias-attr.rs +++ b/src/test/rustdoc-ui/check-doc-alias-attr.rs @@ -1,11 +1,11 @@ #![crate_type = "lib"] #[doc(alias = "foo")] // ok! +#[doc(alias("bar", "baz"))] // ok! pub struct Bar; #[doc(alias)] //~ ERROR #[doc(alias = 0)] //~ ERROR -#[doc(alias("bar"))] //~ ERROR #[doc(alias = "\"")] //~ ERROR #[doc(alias = "\n")] //~ ERROR #[doc(alias = " @@ -13,4 +13,16 @@ pub struct Bar; #[doc(alias = "\t")] //~ ERROR #[doc(alias = " hello")] //~ ERROR #[doc(alias = "hello ")] //~ ERROR +#[doc(alias = "")] //~ ERROR pub struct Foo; + +#[doc(alias(0))] //~ ERROR +#[doc(alias("\""))] //~ ERROR +#[doc(alias("\n"))] //~ ERROR +#[doc(alias(" +"))] //~^ ERROR +#[doc(alias("\t"))] //~ ERROR +#[doc(alias(" hello"))] //~ ERROR +#[doc(alias("hello "))] //~ ERROR +#[doc(alias(""))] //~ ERROR +pub struct Foo2; diff --git a/src/test/rustdoc-ui/check-doc-alias-attr.stderr b/src/test/rustdoc-ui/check-doc-alias-attr.stderr index 1c7fc83bb8dea..f99d69dc101b6 100644 --- a/src/test/rustdoc-ui/check-doc-alias-attr.stderr +++ b/src/test/rustdoc-ui/check-doc-alias-attr.stderr @@ -1,21 +1,15 @@ -error: doc alias attribute expects a string: #[doc(alias = "a")] - --> $DIR/check-doc-alias-attr.rs:6:7 +error: doc alias attribute expects a string `#[doc(alias = "a")]` or a list of strings `#[doc(alias("a", "b"))]` + --> $DIR/check-doc-alias-attr.rs:7:7 | LL | #[doc(alias)] | ^^^^^ -error: doc alias attribute expects a string: #[doc(alias = "a")] - --> $DIR/check-doc-alias-attr.rs:7:7 +error: doc alias attribute expects a string `#[doc(alias = "a")]` or a list of strings `#[doc(alias("a", "b"))]` + --> $DIR/check-doc-alias-attr.rs:8:7 | LL | #[doc(alias = 0)] | ^^^^^^^^^ -error: doc alias attribute expects a string: #[doc(alias = "a")] - --> $DIR/check-doc-alias-attr.rs:8:7 - | -LL | #[doc(alias("bar"))] - | ^^^^^^^^^^^^ - error: '\"' character isn't allowed in `#[doc(alias = "...")]` --> $DIR/check-doc-alias-attr.rs:9:15 | @@ -54,5 +48,61 @@ error: `#[doc(alias = "...")]` cannot start or end with ' ' LL | #[doc(alias = "hello ")] | ^^^^^^^^ -error: aborting due to 9 previous errors +error: `#[doc(alias = "...")]` attribute cannot have empty value + --> $DIR/check-doc-alias-attr.rs:16:15 + | +LL | #[doc(alias = "")] + | ^^ + +error: `#[doc(alias("a"))]` expects string literals + --> $DIR/check-doc-alias-attr.rs:19:13 + | +LL | #[doc(alias(0))] + | ^ + +error: '\"' character isn't allowed in `#[doc(alias("..."))]` + --> $DIR/check-doc-alias-attr.rs:20:13 + | +LL | #[doc(alias("\""))] + | ^^^^ + +error: '\n' character isn't allowed in `#[doc(alias("..."))]` + --> $DIR/check-doc-alias-attr.rs:21:13 + | +LL | #[doc(alias("\n"))] + | ^^^^ + +error: '\n' character isn't allowed in `#[doc(alias("..."))]` + --> $DIR/check-doc-alias-attr.rs:22:13 + | +LL | #[doc(alias(" + | _____________^ +LL | | "))] + | |_^ + +error: '\t' character isn't allowed in `#[doc(alias("..."))]` + --> $DIR/check-doc-alias-attr.rs:24:13 + | +LL | #[doc(alias("\t"))] + | ^^^^ + +error: `#[doc(alias("..."))]` cannot start or end with ' ' + --> $DIR/check-doc-alias-attr.rs:25:13 + | +LL | #[doc(alias(" hello"))] + | ^^^^^^^^ + +error: `#[doc(alias("..."))]` cannot start or end with ' ' + --> $DIR/check-doc-alias-attr.rs:26:13 + | +LL | #[doc(alias("hello "))] + | ^^^^^^^^ + +error: `#[doc(alias("..."))]` attribute cannot have empty value + --> $DIR/check-doc-alias-attr.rs:27:13 + | +LL | #[doc(alias(""))] + | ^^ + +error: aborting due to 17 previous errors diff --git a/src/test/ui/proc-macro/group-compat-hack/auxiliary/group-compat-hack.rs b/src/test/ui/proc-macro/group-compat-hack/auxiliary/pin-project-internal-0.4.0.rs similarity index 68% rename from src/test/ui/proc-macro/group-compat-hack/auxiliary/group-compat-hack.rs rename to src/test/ui/proc-macro/group-compat-hack/auxiliary/pin-project-internal-0.4.0.rs index 5cd3b40a2e42a..baa4fd3a10559 100644 --- a/src/test/ui/proc-macro/group-compat-hack/auxiliary/group-compat-hack.rs +++ b/src/test/ui/proc-macro/group-compat-hack/auxiliary/pin-project-internal-0.4.0.rs @@ -2,6 +2,10 @@ // no-prefer-dynamic #![crate_type = "proc-macro"] +#![crate_name = "group_compat_hack"] + +// This file has an unusual name in order to trigger the back-compat +// code in the compiler extern crate proc_macro; use proc_macro::TokenStream; diff --git a/src/test/ui/proc-macro/group-compat-hack/group-compat-hack.rs b/src/test/ui/proc-macro/group-compat-hack/group-compat-hack.rs index 7f3f5e36f50a9..d9687490cad75 100644 --- a/src/test/ui/proc-macro/group-compat-hack/group-compat-hack.rs +++ b/src/test/ui/proc-macro/group-compat-hack/group-compat-hack.rs @@ -1,5 +1,5 @@ // check-pass -// aux-build:group-compat-hack.rs +// aux-build:pin-project-internal-0.4.0.rs // compile-flags: -Z span-debug #![no_std] // Don't load unnecessary hygiene information from std @@ -51,14 +51,16 @@ mod actix_web_test { include!("actix-web/src/extract.rs"); struct Foo; - tuple_from_req!(Foo); + tuple_from_req!(Foo); //~ WARN using an old version + //~| WARN this was previously } mod actix_web_version_test { include!("actix-web-2.0.0/src/extract.rs"); struct Foo; - tuple_from_req!(Foo); + tuple_from_req!(Foo); //~ WARN using an old version + //~| WARN this was previously } mod actori_web_test { diff --git a/src/test/ui/proc-macro/group-compat-hack/group-compat-hack.stderr b/src/test/ui/proc-macro/group-compat-hack/group-compat-hack.stderr index 9370440a63511..e2b680f8d2760 100644 --- a/src/test/ui/proc-macro/group-compat-hack/group-compat-hack.stderr +++ b/src/test/ui/proc-macro/group-compat-hack/group-compat-hack.stderr @@ -31,7 +31,39 @@ LL | impl_macros!(Foo); = note: the `time-macros-impl` crate will stop compiling in futures version of Rust. Please update to the latest version of the `time` crate to avoid breakage = note: this warning originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) -warning: 2 warnings emitted +warning: using an old version of `actix-web` + --> $DIR/actix-web/src/extract.rs:5:34 + | +LL | #[my_macro] struct Three($T); + | ^^ + | + ::: $DIR/group-compat-hack.rs:54:5 + | +LL | tuple_from_req!(Foo); + | --------------------- in this macro invocation + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #83125 + = note: the version of `actix-web` you are using might stop compiling in future versions of Rust; please update to the latest version of the `actix-web` crate to avoid breakage + = note: this warning originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) + +warning: using an old version of `actix-web` + --> $DIR/actix-web-2.0.0/src/extract.rs:5:34 + | +LL | #[my_macro] struct Three($T); + | ^^ + | + ::: $DIR/group-compat-hack.rs:62:5 + | +LL | tuple_from_req!(Foo); + | --------------------- in this macro invocation + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #83125 + = note: the version of `actix-web` you are using might stop compiling in future versions of Rust; please update to the latest version of the `actix-web` crate to avoid breakage + = note: this warning originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) + +warning: 4 warnings emitted Future incompatibility report: Future breakage date: None, diagnostic: warning: using an old version of `time-macros-impl` @@ -68,3 +100,37 @@ LL | impl_macros!(Foo); = note: the `time-macros-impl` crate will stop compiling in futures version of Rust. Please update to the latest version of the `time` crate to avoid breakage = note: this warning originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) +Future breakage date: None, diagnostic: +warning: using an old version of `actix-web` + --> $DIR/actix-web/src/extract.rs:5:34 + | +LL | #[my_macro] struct Three($T); + | ^^ + | + ::: $DIR/group-compat-hack.rs:54:5 + | +LL | tuple_from_req!(Foo); + | --------------------- in this macro invocation + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #83125 + = note: the version of `actix-web` you are using might stop compiling in future versions of Rust; please update to the latest version of the `actix-web` crate to avoid breakage + = note: this warning originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) + +Future breakage date: None, diagnostic: +warning: using an old version of `actix-web` + --> $DIR/actix-web-2.0.0/src/extract.rs:5:34 + | +LL | #[my_macro] struct Three($T); + | ^^ + | + ::: $DIR/group-compat-hack.rs:62:5 + | +LL | tuple_from_req!(Foo); + | --------------------- in this macro invocation + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #83125 + = note: the version of `actix-web` you are using might stop compiling in future versions of Rust; please update to the latest version of the `actix-web` crate to avoid breakage + = note: this warning originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) + diff --git a/src/test/ui/proc-macro/group-compat-hack/group-compat-hack.stdout b/src/test/ui/proc-macro/group-compat-hack/group-compat-hack.stdout index 468cb51191517..3fe744e12ff04 100644 --- a/src/test/ui/proc-macro/group-compat-hack/group-compat-hack.stdout +++ b/src/test/ui/proc-macro/group-compat-hack/group-compat-hack.stdout @@ -5,6 +5,6 @@ Called proc_macro_hack with TokenStream [Ident { ident: "struct", span: $DIR/tim Called proc_macro_hack with TokenStream [Ident { ident: "struct", span: $DIR/js-sys-0.3.17/src/lib.rs:5:21: 5:27 (#24) }, Ident { ident: "Two", span: $DIR/js-sys-0.3.17/src/lib.rs:5:28: 5:31 (#24) }, Group { delimiter: Parenthesis, stream: TokenStream [Ident { ident: "Foo", span: $DIR/group-compat-hack.rs:46:13: 46:16 (#0) }], span: $DIR/js-sys-0.3.17/src/lib.rs:5:31: 5:38 (#24) }, Punct { ch: ';', spacing: Alone, span: $DIR/js-sys-0.3.17/src/lib.rs:5:38: 5:39 (#24) }] Called proc_macro_hack with TokenStream [Ident { ident: "struct", span: $DIR/group-compat-hack.rs:39:25: 39:31 (#28) }, Ident { ident: "Three", span: $DIR/group-compat-hack.rs:39:32: 39:37 (#28) }, Group { delimiter: Parenthesis, stream: TokenStream [Group { delimiter: None, stream: TokenStream [Ident { ident: "Foo", span: $DIR/group-compat-hack.rs:47:12: 47:15 (#0) }], span: $DIR/group-compat-hack.rs:39:38: 39:43 (#28) }], span: $DIR/group-compat-hack.rs:39:37: 39:44 (#28) }, Punct { ch: ';', spacing: Alone, span: $DIR/group-compat-hack.rs:39:44: 39:45 (#28) }] Called proc_macro_hack with TokenStream [Ident { ident: "struct", span: $DIR/actix-web/src/extract.rs:5:21: 5:27 (#33) }, Ident { ident: "Three", span: $DIR/actix-web/src/extract.rs:5:28: 5:33 (#33) }, Group { delimiter: Parenthesis, stream: TokenStream [Ident { ident: "Foo", span: $DIR/group-compat-hack.rs:54:21: 54:24 (#0) }], span: $DIR/actix-web/src/extract.rs:5:33: 5:37 (#33) }, Punct { ch: ';', spacing: Alone, span: $DIR/actix-web/src/extract.rs:5:37: 5:38 (#33) }] -Called proc_macro_hack with TokenStream [Ident { ident: "struct", span: $DIR/actix-web-2.0.0/src/extract.rs:5:21: 5:27 (#38) }, Ident { ident: "Three", span: $DIR/actix-web-2.0.0/src/extract.rs:5:28: 5:33 (#38) }, Group { delimiter: Parenthesis, stream: TokenStream [Ident { ident: "Foo", span: $DIR/group-compat-hack.rs:61:21: 61:24 (#0) }], span: $DIR/actix-web-2.0.0/src/extract.rs:5:33: 5:37 (#38) }, Punct { ch: ';', spacing: Alone, span: $DIR/actix-web-2.0.0/src/extract.rs:5:37: 5:38 (#38) }] -Called proc_macro_hack with TokenStream [Ident { ident: "struct", span: $DIR/actori-web/src/extract.rs:5:21: 5:27 (#43) }, Ident { ident: "Four", span: $DIR/actori-web/src/extract.rs:5:28: 5:32 (#43) }, Group { delimiter: Parenthesis, stream: TokenStream [Ident { ident: "Foo", span: $DIR/group-compat-hack.rs:68:21: 68:24 (#0) }], span: $DIR/actori-web/src/extract.rs:5:32: 5:36 (#43) }, Punct { ch: ';', spacing: Alone, span: $DIR/actori-web/src/extract.rs:5:36: 5:37 (#43) }] -Called proc_macro_hack with TokenStream [Ident { ident: "struct", span: $DIR/actori-web-2.0.0/src/extract.rs:5:21: 5:27 (#48) }, Ident { ident: "Four", span: $DIR/actori-web-2.0.0/src/extract.rs:5:28: 5:32 (#48) }, Group { delimiter: Parenthesis, stream: TokenStream [Ident { ident: "Foo", span: $DIR/group-compat-hack.rs:75:21: 75:24 (#0) }], span: $DIR/actori-web-2.0.0/src/extract.rs:5:32: 5:36 (#48) }, Punct { ch: ';', spacing: Alone, span: $DIR/actori-web-2.0.0/src/extract.rs:5:36: 5:37 (#48) }] +Called proc_macro_hack with TokenStream [Ident { ident: "struct", span: $DIR/actix-web-2.0.0/src/extract.rs:5:21: 5:27 (#38) }, Ident { ident: "Three", span: $DIR/actix-web-2.0.0/src/extract.rs:5:28: 5:33 (#38) }, Group { delimiter: Parenthesis, stream: TokenStream [Ident { ident: "Foo", span: $DIR/group-compat-hack.rs:62:21: 62:24 (#0) }], span: $DIR/actix-web-2.0.0/src/extract.rs:5:33: 5:37 (#38) }, Punct { ch: ';', spacing: Alone, span: $DIR/actix-web-2.0.0/src/extract.rs:5:37: 5:38 (#38) }] +Called proc_macro_hack with TokenStream [Ident { ident: "struct", span: $DIR/actori-web/src/extract.rs:5:21: 5:27 (#43) }, Ident { ident: "Four", span: $DIR/actori-web/src/extract.rs:5:28: 5:32 (#43) }, Group { delimiter: Parenthesis, stream: TokenStream [Group { delimiter: None, stream: TokenStream [Ident { ident: "Foo", span: $DIR/group-compat-hack.rs:70:21: 70:24 (#0) }], span: $DIR/actori-web/src/extract.rs:5:33: 5:35 (#43) }], span: $DIR/actori-web/src/extract.rs:5:32: 5:36 (#43) }, Punct { ch: ';', spacing: Alone, span: $DIR/actori-web/src/extract.rs:5:36: 5:37 (#43) }] +Called proc_macro_hack with TokenStream [Ident { ident: "struct", span: $DIR/actori-web-2.0.0/src/extract.rs:5:21: 5:27 (#48) }, Ident { ident: "Four", span: $DIR/actori-web-2.0.0/src/extract.rs:5:28: 5:32 (#48) }, Group { delimiter: Parenthesis, stream: TokenStream [Group { delimiter: None, stream: TokenStream [Ident { ident: "Foo", span: $DIR/group-compat-hack.rs:77:21: 77:24 (#0) }], span: $DIR/actori-web-2.0.0/src/extract.rs:5:33: 5:35 (#48) }], span: $DIR/actori-web-2.0.0/src/extract.rs:5:32: 5:36 (#48) }, Punct { ch: ';', spacing: Alone, span: $DIR/actori-web-2.0.0/src/extract.rs:5:36: 5:37 (#48) }] diff --git a/src/test/ui/rustdoc/check-doc-alias-attr.rs b/src/test/ui/rustdoc/check-doc-alias-attr.rs index 912e35f916545..719b98604c497 100644 --- a/src/test/ui/rustdoc/check-doc-alias-attr.rs +++ b/src/test/ui/rustdoc/check-doc-alias-attr.rs @@ -1,11 +1,11 @@ #![crate_type = "lib"] #[doc(alias = "foo")] // ok! +#[doc(alias("bar", "baz"))] // ok! pub struct Bar; #[doc(alias)] //~ ERROR #[doc(alias = 0)] //~ ERROR -#[doc(alias("bar"))] //~ ERROR #[doc(alias = "\"")] //~ ERROR #[doc(alias = "\n")] //~ ERROR #[doc(alias = " @@ -13,4 +13,16 @@ pub struct Bar; #[doc(alias = "\t")] //~ ERROR #[doc(alias = " hello")] //~ ERROR #[doc(alias = "hello ")] //~ ERROR +#[doc(alias = "")] //~ ERROR pub struct Foo; + +#[doc(alias(0))] //~ ERROR +#[doc(alias("\""))] //~ ERROR +#[doc(alias("\n"))] //~ ERROR +#[doc(alias(" +"))] //~^ ERROR +#[doc(alias("\t"))] //~ ERROR +#[doc(alias(" hello"))] //~ ERROR +#[doc(alias("hello "))] //~ ERROR +#[doc(alias(""))] //~ ERROR +pub struct Foo2; diff --git a/src/test/ui/rustdoc/check-doc-alias-attr.stderr b/src/test/ui/rustdoc/check-doc-alias-attr.stderr index 1c7fc83bb8dea..f99d69dc101b6 100644 --- a/src/test/ui/rustdoc/check-doc-alias-attr.stderr +++ b/src/test/ui/rustdoc/check-doc-alias-attr.stderr @@ -1,21 +1,15 @@ -error: doc alias attribute expects a string: #[doc(alias = "a")] - --> $DIR/check-doc-alias-attr.rs:6:7 +error: doc alias attribute expects a string `#[doc(alias = "a")]` or a list of strings `#[doc(alias("a", "b"))]` + --> $DIR/check-doc-alias-attr.rs:7:7 | LL | #[doc(alias)] | ^^^^^ -error: doc alias attribute expects a string: #[doc(alias = "a")] - --> $DIR/check-doc-alias-attr.rs:7:7 +error: doc alias attribute expects a string `#[doc(alias = "a")]` or a list of strings `#[doc(alias("a", "b"))]` + --> $DIR/check-doc-alias-attr.rs:8:7 | LL | #[doc(alias = 0)] | ^^^^^^^^^ -error: doc alias attribute expects a string: #[doc(alias = "a")] - --> $DIR/check-doc-alias-attr.rs:8:7 - | -LL | #[doc(alias("bar"))] - | ^^^^^^^^^^^^ - error: '\"' character isn't allowed in `#[doc(alias = "...")]` --> $DIR/check-doc-alias-attr.rs:9:15 | @@ -54,5 +48,61 @@ error: `#[doc(alias = "...")]` cannot start or end with ' ' LL | #[doc(alias = "hello ")] | ^^^^^^^^ -error: aborting due to 9 previous errors +error: `#[doc(alias = "...")]` attribute cannot have empty value + --> $DIR/check-doc-alias-attr.rs:16:15 + | +LL | #[doc(alias = "")] + | ^^ + +error: `#[doc(alias("a"))]` expects string literals + --> $DIR/check-doc-alias-attr.rs:19:13 + | +LL | #[doc(alias(0))] + | ^ + +error: '\"' character isn't allowed in `#[doc(alias("..."))]` + --> $DIR/check-doc-alias-attr.rs:20:13 + | +LL | #[doc(alias("\""))] + | ^^^^ + +error: '\n' character isn't allowed in `#[doc(alias("..."))]` + --> $DIR/check-doc-alias-attr.rs:21:13 + | +LL | #[doc(alias("\n"))] + | ^^^^ + +error: '\n' character isn't allowed in `#[doc(alias("..."))]` + --> $DIR/check-doc-alias-attr.rs:22:13 + | +LL | #[doc(alias(" + | _____________^ +LL | | "))] + | |_^ + +error: '\t' character isn't allowed in `#[doc(alias("..."))]` + --> $DIR/check-doc-alias-attr.rs:24:13 + | +LL | #[doc(alias("\t"))] + | ^^^^ + +error: `#[doc(alias("..."))]` cannot start or end with ' ' + --> $DIR/check-doc-alias-attr.rs:25:13 + | +LL | #[doc(alias(" hello"))] + | ^^^^^^^^ + +error: `#[doc(alias("..."))]` cannot start or end with ' ' + --> $DIR/check-doc-alias-attr.rs:26:13 + | +LL | #[doc(alias("hello "))] + | ^^^^^^^^ + +error: `#[doc(alias("..."))]` attribute cannot have empty value + --> $DIR/check-doc-alias-attr.rs:27:13 + | +LL | #[doc(alias(""))] + | ^^ + +error: aborting due to 17 previous errors