diff options
Diffstat (limited to 'compiler')
27 files changed, 248 insertions, 169 deletions
diff --git a/compiler/rustc_arena/src/lib.rs b/compiler/rustc_arena/src/lib.rs index a9917f50cc2..c3198fb1043 100644 --- a/compiler/rustc_arena/src/lib.rs +++ b/compiler/rustc_arena/src/lib.rs @@ -298,22 +298,6 @@ impl<T> TypedArena<T> { } } - /// 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<T>) { diff --git a/compiler/rustc_arena/src/tests.rs b/compiler/rustc_arena/src/tests.rs index e8a1f2db1a1..911e577c1ed 100644 --- a/compiler/rustc_arena/src/tests.rs +++ b/compiler/rustc_arena/src/tests.rs @@ -11,6 +11,24 @@ struct Point { z: i32, } +impl<T> TypedArena<T> { + /// 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<Point> = TypedArena::default(); diff --git a/compiler/rustc_codegen_ssa/Cargo.toml b/compiler/rustc_codegen_ssa/Cargo.toml index 5e2f01b2c9d..15dbbbd49aa 100644 --- a/compiler/rustc_codegen_ssa/Cargo.toml +++ b/compiler/rustc_codegen_ssa/Cargo.toml @@ -11,7 +11,7 @@ test = false bitflags = "1.2.1" cc = "1.0.1" itertools = "0.9" -memmap = "0.7" +memmap2 = "0.2.1" tracing = "0.1" libc = "0.2.50" jobserver = "0.1.11" diff --git a/compiler/rustc_codegen_ssa/src/back/lto.rs b/compiler/rustc_codegen_ssa/src/back/lto.rs index 0d7f4447696..c6aea22a63e 100644 --- a/compiler/rustc_codegen_ssa/src/back/lto.rs +++ b/compiler/rustc_codegen_ssa/src/back/lto.rs @@ -93,7 +93,7 @@ impl<B: WriteBackendMethods> LtoModuleCodegen<B> { pub enum SerializedModule<M: ModuleBufferMethods> { Local(M), FromRlib(Vec<u8>), - FromUncompressedFile(memmap::Mmap), + FromUncompressedFile(memmap2::Mmap), } impl<M: ModuleBufferMethods> SerializedModule<M> { diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs index 854aaac757f..490b3d33112 100644 --- a/compiler/rustc_codegen_ssa/src/back/write.rs +++ b/compiler/rustc_codegen_ssa/src/back/write.rs @@ -1958,7 +1958,7 @@ pub fn submit_pre_lto_module_to_llvm<B: ExtraBackendMethods>( .unwrap_or_else(|e| panic!("failed to open bitcode file `{}`: {}", bc_path.display(), e)); let mmap = unsafe { - memmap::Mmap::map(&file).unwrap_or_else(|e| { + memmap2::Mmap::map(&file).unwrap_or_else(|e| { panic!("failed to mmap bitcode file `{}`: {}", bc_path.display(), e) }) }; diff --git a/compiler/rustc_codegen_ssa/src/lib.rs b/compiler/rustc_codegen_ssa/src/lib.rs index 2c2330409fd..dd04d3e548f 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 e94a0c6eb59..f88bcc29481 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<T: PartialEq> { +pub struct TinyList<T> { head: Option<Element<T>>, } @@ -56,20 +56,10 @@ impl<T: PartialEq> TinyList<T> { } 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<T: PartialEq> { +struct Element<T> { data: T, next: Option<Box<Element<T>>>, } diff --git a/compiler/rustc_data_structures/src/tiny_list/tests.rs b/compiler/rustc_data_structures/src/tiny_list/tests.rs index a8ae2bc8727..c0334d2e23e 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<T> TinyList<T> { + 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 2e1512b3929..ccf8bd69ebd 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<T: Eq + Hash> { +pub struct TransitiveRelation<T> { // List of elements. This is used to map from a T to a usize. elements: FxIndexSet<T>, @@ -49,7 +49,7 @@ struct Edge { target: Index, } -impl<T: Clone + Debug + Eq + Hash> TransitiveRelation<T> { +impl<T: Eq + Hash> TransitiveRelation<T> { pub fn is_empty(&self) -> bool { self.edges.is_empty() } @@ -322,12 +322,6 @@ impl<T: Clone + Debug + Eq + Hash> TransitiveRelation<T> { .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<OP, R>(&self, op: OP) -> R where OP: FnOnce(&BitMatrix<usize, usize>) -> R, diff --git a/compiler/rustc_data_structures/src/transitive_relation/tests.rs b/compiler/rustc_data_structures/src/transitive_relation/tests.rs index ca90ba176ae..9fa7224376c 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<T: Eq + Hash> TransitiveRelation<T> { + /// 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 c09cce21bf2..79507e61522 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 1db39fbfba5..fa855f544e8 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 67edfe19da3..cb41bc81225 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<token::DelimToken> for Delimiter { } } -impl FromInternal<(TreeAndSpacing, &'_ ParseSess, &'_ mut Vec<Self>)> +impl FromInternal<(TreeAndSpacing, &'_ mut Vec<Self>, &mut Rustc<'_>)> for TokenTree<Group, Punct, Ident, Literal> { fn from_internal( - ((tree, spacing), sess, stack): (TreeAndSpacing, &ParseSess, &mut Vec<Self>), + ((tree, spacing), stack, rustc): (TreeAndSpacing, &mut Vec<Self>, &mut Rustc<'_>), ) -> Self { use rustc_ast::token::*; @@ -146,10 +146,10 @@ impl FromInternal<(TreeAndSpacing, &'_ ParseSess, &'_ mut Vec<Self>)> 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<Self>)> } 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_metadata/Cargo.toml b/compiler/rustc_metadata/Cargo.toml index 2aabc2c407b..48effed9274 100644 --- a/compiler/rustc_metadata/Cargo.toml +++ b/compiler/rustc_metadata/Cargo.toml @@ -11,7 +11,7 @@ doctest = false libc = "0.2" snap = "1" tracing = "0.1" -memmap = "0.7" +memmap2 = "0.2.1" smallvec = { version = "1.6.1", features = ["union", "may_dangle"] } rustc_middle = { path = "../rustc_middle" } rustc_attr = { path = "../rustc_attr" } diff --git a/compiler/rustc_metadata/src/locator.rs b/compiler/rustc_metadata/src/locator.rs index a9f58b08f58..39a39917f57 100644 --- a/compiler/rustc_metadata/src/locator.rs +++ b/compiler/rustc_metadata/src/locator.rs @@ -728,7 +728,7 @@ impl<'a> CrateLocator<'a> { } /// A trivial wrapper for `Mmap` that implements `StableDeref`. -struct StableDerefMmap(memmap::Mmap); +struct StableDerefMmap(memmap2::Mmap); impl Deref for StableDerefMmap { type Target = [u8]; @@ -779,7 +779,7 @@ fn get_metadata_section( // mmap the file, because only a small fraction of it is read. let file = std::fs::File::open(filename) .map_err(|_| format!("failed to open rmeta metadata: '{}'", filename.display()))?; - let mmap = unsafe { memmap::Mmap::map(&file) }; + let mmap = unsafe { memmap2::Mmap::map(&file) }; let mmap = mmap .map_err(|_| format!("failed to mmap rmeta metadata: '{}'", filename.display()))?; diff --git a/compiler/rustc_middle/src/ich/impls_syntax.rs b/compiler/rustc_middle/src/ich/impls_syntax.rs index bfbe15749ee..31374429940 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 d9e88265050..2d807591bfd 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 48595f2badc..766d6a06f7e 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<Tag>> Allocation<Tag, Extra> { 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 f3e373813ca..fe5ebf0b6fe 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 194bc74c0fb..f73d5dc0c11 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 2cd0dc6b1f2..aabfee53acb 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 c4b51099f53..e102512e1f3 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<BasicBlock, Basi // The basic block was already in the hashmap, which means we have a duplicate let value = *occupied.get(); debug!("Inserting {:?} -> {:?}", 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 775e27e68f8..d91d0e1765b 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 e67a4ca8fb2..eb5b7c4a74a 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<ExpnData>) -> 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 6030c8a86d9..d2790335b5a 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<CTX: HashStableContext> HashStable<CTX> 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 b7eb6d5b379..f612d1425b9 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<Span> { - // 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 0aca677248b..7d814f1d82c 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<Span> { + // 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() { |
