From 5e354932fe2e2b6b4f55f404148e6b5fa0a3392a Mon Sep 17 00:00:00 2001 From: Igor Matuszewski Date: Tue, 5 May 2020 13:26:02 +0200 Subject: [PATCH 01/12] cargo update -p serde_derive --- Cargo.lock | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 033ebc884a3e3..012d3328f12c4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4630,13 +4630,13 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.81" +version = "1.0.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "477b13b646f5b5b56fc95bedfc3b550d12141ce84f466f6c44b9a17589923885" +checksum = "9e549e3abf4fb8621bd1609f11dfc9f5e50320802273b12f3811a67e6716ea6c" dependencies = [ - "proc-macro2 0.4.30", - "quote 0.6.12", - "syn 0.15.35", + "proc-macro2 1.0.3", + "quote 1.0.2", + "syn 1.0.11", ] [[package]] From 403a9d0867ca01a5aecbe88b535ed902a9d4a633 Mon Sep 17 00:00:00 2001 From: Igor Matuszewski Date: Tue, 5 May 2020 13:26:16 +0200 Subject: [PATCH 02/12] cargo update -p failure_derive --- Cargo.lock | 30 +++++++++--------------------- 1 file changed, 9 insertions(+), 21 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 012d3328f12c4..f05a1562d0dfb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -438,7 +438,7 @@ dependencies = [ "proc-macro2 1.0.3", "quote 1.0.2", "syn 1.0.11", - "synstructure 0.12.1", + "synstructure", ] [[package]] @@ -1145,14 +1145,14 @@ dependencies = [ [[package]] name = "failure_derive" -version = "0.1.5" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea1063915fd7ef4309e222a5a07cf9c319fb9c7836b1f89b85458672dbb127e1" +checksum = "aa4da3c766cd7a0db8242e326e9e4e081edd567072893ed320008189715366a4" dependencies = [ - "proc-macro2 0.4.30", - "quote 0.6.12", - "syn 0.15.35", - "synstructure 0.10.2", + "proc-macro2 1.0.3", + "quote 1.0.2", + "syn 1.0.11", + "synstructure", ] [[package]] @@ -3449,7 +3449,7 @@ dependencies = [ "proc-macro2 1.0.3", "quote 1.0.2", "syn 1.0.11", - "synstructure 0.12.1", + "synstructure", ] [[package]] @@ -4059,7 +4059,7 @@ dependencies = [ "proc-macro2 1.0.3", "quote 1.0.2", "syn 1.0.11", - "synstructure 0.12.1", + "synstructure", ] [[package]] @@ -4932,18 +4932,6 @@ dependencies = [ "unicode-xid 0.2.0", ] -[[package]] -name = "synstructure" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02353edf96d6e4dc81aea2d8490a7e9db177bf8acb0e951c24940bf866cb313f" -dependencies = [ - "proc-macro2 0.4.30", - "quote 0.6.12", - "syn 0.15.35", - "unicode-xid 0.1.0", -] - [[package]] name = "synstructure" version = "0.12.1" From 8c6e568141977702a43d70e0bf0258d32ef71f76 Mon Sep 17 00:00:00 2001 From: Igor Matuszewski Date: Tue, 5 May 2020 13:26:29 +0200 Subject: [PATCH 03/12] cargo update -p pest_generator --- Cargo.lock | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f05a1562d0dfb..51a166890bd58 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2557,15 +2557,15 @@ dependencies = [ [[package]] name = "pest_generator" -version = "2.1.0" +version = "2.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63120576c4efd69615b5537d3d052257328a4ca82876771d6944424ccfd9f646" +checksum = "99b8db626e31e5b81787b9783425769681b347011cc59471e33ea46d2ea0cf55" dependencies = [ "pest", "pest_meta", - "proc-macro2 0.4.30", - "quote 0.6.12", - "syn 0.15.35", + "proc-macro2 1.0.3", + "quote 1.0.2", + "syn 1.0.11", ] [[package]] From 3bdacedfd9264549b6368cc060da16993701ec14 Mon Sep 17 00:00:00 2001 From: Igor Matuszewski Date: Tue, 5 May 2020 13:30:49 +0200 Subject: [PATCH 04/12] cargo update -p derive-new --- Cargo.lock | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 51a166890bd58..43dcc6b9dae92 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -938,13 +938,13 @@ checksum = "a0afaad2b26fa326569eb264b1363e8ae3357618c43982b3f285f0774ce76b69" [[package]] name = "derive-new" -version = "0.5.6" +version = "0.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ca414e896ae072546f4d789f452daaecf60ddee4c9df5dc6d5936d769e3d87c" +checksum = "71f31892cd5c62e414316f2963c5689242c43d8e7bbcaaeca97e5e28c95d91d9" dependencies = [ - "proc-macro2 0.4.30", - "quote 0.6.12", - "syn 0.15.35", + "proc-macro2 1.0.3", + "quote 1.0.2", + "syn 1.0.11", ] [[package]] From e26f35d343c1266012af31437a84e40eb33eaffb Mon Sep 17 00:00:00 2001 From: Igor Matuszewski Date: Tue, 5 May 2020 14:05:06 +0200 Subject: [PATCH 05/12] rustbook: Bump mdbook dependency --- Cargo.lock | 26 +++++++------------------- src/tools/rustbook/Cargo.toml | 2 +- 2 files changed, 8 insertions(+), 20 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 43dcc6b9dae92..cbdd43f758638 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1405,30 +1405,18 @@ dependencies = [ [[package]] name = "handlebars" -version = "2.0.1" +version = "3.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df044dd42cdb7e32f28557b661406fc0f2494be75199779998810dbc35030e0d" +checksum = "ba758d094d31274eb49d15da6f326b96bf3185239a6359bf684f3d5321148900" dependencies = [ - "hashbrown 0.5.0", - "lazy_static 1.4.0", "log", "pest", "pest_derive", "quick-error", - "regex", "serde", "serde_json", ] -[[package]] -name = "hashbrown" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1de41fb8dba9714efd92241565cdff73f78508c95697dd56787d3cba27e2353" -dependencies = [ - "serde", -] - [[package]] name = "hashbrown" version = "0.6.2" @@ -2055,9 +2043,9 @@ dependencies = [ [[package]] name = "mdbook" -version = "0.3.5" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "031bdd9d4893c983e2f69ebc4b59070feee8276a584c4aabdcb351235ea28016" +checksum = "e7ec525f7ebccc2dd935c263717250cd37f9a4b264a77c5dbc950ea2734d8159" dependencies = [ "ammonia", "chrono", @@ -2785,9 +2773,9 @@ checksum = "6ddd112cca70a4d30883b2d21568a1d376ff8be4758649f64f973c6845128ad3" [[package]] name = "quick-error" -version = "1.2.2" +version = "1.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9274b940887ce9addde99c4eee6b5c44cc494b182b97e73dc8ffdcb3397fd3f0" +checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" [[package]] name = "quine-mc_cluskey" @@ -4800,7 +4788,7 @@ dependencies = [ "core", "dlmalloc", "fortanix-sgx-abi", - "hashbrown 0.6.2", + "hashbrown", "hermit-abi", "libc", "panic_abort", diff --git a/src/tools/rustbook/Cargo.toml b/src/tools/rustbook/Cargo.toml index e6e758dccdf0a..ff41197faa1a6 100644 --- a/src/tools/rustbook/Cargo.toml +++ b/src/tools/rustbook/Cargo.toml @@ -23,6 +23,6 @@ codespan-reporting = { version = "0.5", optional = true } rustc-workspace-hack = "1.0.0" [dependencies.mdbook] -version = "0.3.0" +version = "0.3.7" default-features = false features = ["search"] From 5a0ac0552e05c079f252482cfcdaab3c4b39d614 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 13 May 2020 15:47:19 +1000 Subject: [PATCH 06/12] Use simpler impls for some `Iterator` methods for slices. The default implementations of several `Iterator` methods use `fold` or `try_fold`, which works, but is overkill for slices and bloats the amount of LLVM IR generated and consequently hurts compile times. This commit adds the simple, obvious implementations for `for_each`, `all`, `any`, `find`, `find_map`, and simplifies the existing implementations for `position` and `rposition`. These changes reduce compile times significantly on some benchmarks. --- src/libcore/slice/mod.rs | 122 +++++++++++++++++++++++++++++++++------ 1 file changed, 105 insertions(+), 17 deletions(-) diff --git a/src/libcore/slice/mod.rs b/src/libcore/slice/mod.rs index f74c6862006c1..3386f83ec810f 100644 --- a/src/libcore/slice/mod.rs +++ b/src/libcore/slice/mod.rs @@ -3179,6 +3179,7 @@ macro_rules! is_empty { $self.ptr.as_ptr() as *const T == $self.end }; } + // To get rid of some bounds checks (see `position`), we compute the length in a somewhat // unexpected way. (Tested by `codegen/slice-position-bounds-check`.) macro_rules! len { @@ -3347,40 +3348,127 @@ macro_rules! iterator { self.next_back() } + // We override the default implementation, which uses `try_fold`, + // because this simple implementation generates less LLVM IR and is + // faster to compile. + #[inline] + fn for_each(mut self, mut f: F) + where + Self: Sized, + F: FnMut(Self::Item), + { + while let Some(x) = self.next() { + f(x); + } + } + + // We override the default implementation, which uses `try_fold`, + // because this simple implementation generates less LLVM IR and is + // faster to compile. + #[inline] + fn all(&mut self, mut f: F) -> bool + where + Self: Sized, + F: FnMut(Self::Item) -> bool, + { + while let Some(x) = self.next() { + if !f(x) { + return false; + } + } + true + } + + // We override the default implementation, which uses `try_fold`, + // because this simple implementation generates less LLVM IR and is + // faster to compile. + #[inline] + fn any(&mut self, mut f: F) -> bool + where + Self: Sized, + F: FnMut(Self::Item) -> bool, + { + while let Some(x) = self.next() { + if f(x) { + return true; + } + } + false + } + + // We override the default implementation, which uses `try_fold`, + // because this simple implementation generates less LLVM IR and is + // faster to compile. + #[inline] + fn find

(&mut self, mut predicate: P) -> Option + where + Self: Sized, + P: FnMut(&Self::Item) -> bool, + { + while let Some(x) = self.next() { + if predicate(&x) { + return Some(x); + } + } + None + } + + // We override the default implementation, which uses `try_fold`, + // because this simple implementation generates less LLVM IR and is + // faster to compile. + #[inline] + fn find_map(&mut self, mut f: F) -> Option + where + Self: Sized, + F: FnMut(Self::Item) -> Option, + { + while let Some(x) = self.next() { + if let Some(y) = f(x) { + return Some(y); + } + } + None + } + + // We override the default implementation, which uses `try_fold`, + // because this simple implementation generates less LLVM IR and is + // faster to compile. Also, the `assume` avoids a bounds check. #[inline] #[rustc_inherit_overflow_checks] fn position

(&mut self, mut predicate: P) -> Option where Self: Sized, P: FnMut(Self::Item) -> bool, { - // The addition might panic on overflow. let n = len!(self); - self.try_fold(0, move |i, x| { - if predicate(x) { Err(i) } - else { Ok(i + 1) } - }).err() - .map(|i| { + let mut i = 0; + while let Some(x) = self.next() { + if predicate(x) { unsafe { assume(i < n) }; - i - }) + return Some(i); + } + i += 1; + } + None } + // We override the default implementation, which uses `try_fold`, + // because this simple implementation generates less LLVM IR and is + // faster to compile. Also, the `assume` avoids a bounds check. #[inline] fn rposition

(&mut self, mut predicate: P) -> Option where P: FnMut(Self::Item) -> bool, Self: Sized + ExactSizeIterator + DoubleEndedIterator { - // No need for an overflow check here, because `ExactSizeIterator` let n = len!(self); - self.try_rfold(n, move |i, x| { - let i = i - 1; - if predicate(x) { Err(i) } - else { Ok(i) } - }).err() - .map(|i| { + let mut i = n; + while let Some(x) = self.next_back() { + i -= 1; + if predicate(x) { unsafe { assume(i < n) }; - i - }) + return Some(i); + } + } + None } $($extra)* From 3b108588d159b4f4600ec226679f5ce64341b82e Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 13 May 2020 15:48:08 +1000 Subject: [PATCH 07/12] Change `Iterator::nth` to use `self.next()` in a `while` loop. Currently it uses `for x in self`, which seems dubious within an iterator method. Furthermore, `self.next()` is used in all the other iterator methods. --- src/libcore/iter/traits/iterator.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libcore/iter/traits/iterator.rs b/src/libcore/iter/traits/iterator.rs index 34ca79154b68f..447db405c0280 100644 --- a/src/libcore/iter/traits/iterator.rs +++ b/src/libcore/iter/traits/iterator.rs @@ -333,7 +333,7 @@ pub trait Iterator { #[inline] #[stable(feature = "rust1", since = "1.0.0")] fn nth(&mut self, mut n: usize) -> Option { - for x in self { + while let Some(x) = self.next() { if n == 0 { return Some(x); } From 00268be9da13215398d779b2e344ffa3e300693c Mon Sep 17 00:00:00 2001 From: Nathan Corbyn Date: Thu, 14 May 2020 22:06:44 +0100 Subject: [PATCH 08/12] Remove lang_items\(\).*\.unwrap\(\) --- src/librustc_mir/monomorphize/mod.rs | 4 +++- .../hair/pattern/const_to_pat.rs | 3 ++- .../traits/structural_match.rs | 5 +++-- src/librustc_typeck/check/closure.rs | 6 +++--- src/librustc_typeck/check/demand.rs | 8 ++++---- src/librustc_typeck/check/mod.rs | 16 ++++++++-------- src/librustc_typeck/coherence/builtin.rs | 19 +++++++++++-------- 7 files changed, 34 insertions(+), 27 deletions(-) diff --git a/src/librustc_mir/monomorphize/mod.rs b/src/librustc_mir/monomorphize/mod.rs index 98a3d9584f587..28edd87a3add5 100644 --- a/src/librustc_mir/monomorphize/mod.rs +++ b/src/librustc_mir/monomorphize/mod.rs @@ -2,6 +2,8 @@ use rustc_middle::traits; use rustc_middle::ty::adjustment::CustomCoerceUnsized; use rustc_middle::ty::{self, Ty, TyCtxt}; +use rustc_hir::lang_items::CoerceUnsizedTraitLangItem; + pub mod collector; pub mod partitioning; @@ -10,7 +12,7 @@ pub fn custom_coerce_unsize_info<'tcx>( source_ty: Ty<'tcx>, target_ty: Ty<'tcx>, ) -> CustomCoerceUnsized { - let def_id = tcx.lang_items().coerce_unsized_trait().unwrap(); + let def_id = tcx.require_lang_item(CoerceUnsizedTraitLangItem, None); let trait_ref = ty::Binder::bind(ty::TraitRef { def_id, diff --git a/src/librustc_mir_build/hair/pattern/const_to_pat.rs b/src/librustc_mir_build/hair/pattern/const_to_pat.rs index d3129751586af..28ec2ca13d5af 100644 --- a/src/librustc_mir_build/hair/pattern/const_to_pat.rs +++ b/src/librustc_mir_build/hair/pattern/const_to_pat.rs @@ -141,7 +141,8 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> { // code at the moment, because types like `for <'a> fn(&'a ())` do // not *yet* implement `PartialEq`. So for now we leave this here. let ty_is_partial_eq: bool = { - let partial_eq_trait_id = self.tcx().require_lang_item(EqTraitLangItem, None); + let partial_eq_trait_id = + self.tcx().require_lang_item(EqTraitLangItem, Some(self.span)); let obligation: PredicateObligation<'_> = predicate_for_trait_def( self.tcx(), self.param_env, diff --git a/src/librustc_trait_selection/traits/structural_match.rs b/src/librustc_trait_selection/traits/structural_match.rs index 8007290f35d85..eb63505b69b41 100644 --- a/src/librustc_trait_selection/traits/structural_match.rs +++ b/src/librustc_trait_selection/traits/structural_match.rs @@ -4,6 +4,7 @@ use crate::traits::{self, ConstPatternStructural, TraitEngine}; use rustc_data_structures::fx::FxHashSet; use rustc_hir as hir; +use rustc_hir::lang_items::{StructuralPeqTraitLangItem, StructuralTeqTraitLangItem}; use rustc_middle::ty::{self, AdtDef, Ty, TyCtxt, TypeFoldable, TypeVisitor}; use rustc_span::Span; @@ -69,7 +70,7 @@ pub fn type_marked_structural( let mut fulfillment_cx = traits::FulfillmentContext::new(); let cause = ObligationCause::new(span, id, ConstPatternStructural); // require `#[derive(PartialEq)]` - let structural_peq_def_id = infcx.tcx.lang_items().structural_peq_trait().unwrap(); + let structural_peq_def_id = infcx.tcx.require_lang_item(StructuralPeqTraitLangItem, Some(span)); fulfillment_cx.register_bound( infcx, ty::ParamEnv::empty(), @@ -80,7 +81,7 @@ pub fn type_marked_structural( // for now, require `#[derive(Eq)]`. (Doing so is a hack to work around // the type `for<'a> fn(&'a ())` failing to implement `Eq` itself.) let cause = ObligationCause::new(span, id, ConstPatternStructural); - let structural_teq_def_id = infcx.tcx.lang_items().structural_teq_trait().unwrap(); + let structural_teq_def_id = infcx.tcx.require_lang_item(StructuralTeqTraitLangItem, Some(span)); fulfillment_cx.register_bound( infcx, ty::ParamEnv::empty(), diff --git a/src/librustc_typeck/check/closure.rs b/src/librustc_typeck/check/closure.rs index 035e5880dc522..87a6f119acb09 100644 --- a/src/librustc_typeck/check/closure.rs +++ b/src/librustc_typeck/check/closure.rs @@ -6,7 +6,7 @@ use crate::astconv::AstConv; use crate::middle::region; use rustc_hir as hir; use rustc_hir::def_id::DefId; -use rustc_hir::lang_items; +use rustc_hir::lang_items::{FutureTraitLangItem, GeneratorTraitLangItem}; use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; use rustc_infer::infer::LateBoundRegionConversionTime; use rustc_infer::infer::{InferOk, InferResult}; @@ -245,7 +245,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let trait_ref = projection.to_poly_trait_ref(tcx); let is_fn = tcx.fn_trait_kind_from_lang_item(trait_ref.def_id()).is_some(); - let gen_trait = tcx.require_lang_item(lang_items::GeneratorTraitLangItem, cause_span); + let gen_trait = tcx.require_lang_item(GeneratorTraitLangItem, cause_span); let is_gen = gen_trait == trait_ref.def_id(); if !is_fn && !is_gen { debug!("deduce_sig_from_projection: not fn or generator"); @@ -678,7 +678,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Check that this is a projection from the `Future` trait. let trait_ref = predicate.projection_ty.trait_ref(self.tcx); - let future_trait = self.tcx.lang_items().future_trait().unwrap(); + let future_trait = self.tcx.require_lang_item(FutureTraitLangItem, Some(cause_span)); if trait_ref.def_id != future_trait { debug!("deduce_future_output_from_projection: not a future"); return None; diff --git a/src/librustc_typeck/check/demand.rs b/src/librustc_typeck/check/demand.rs index 64de94ea58cf4..9694ce9450c27 100644 --- a/src/librustc_typeck/check/demand.rs +++ b/src/librustc_typeck/check/demand.rs @@ -7,7 +7,7 @@ use rustc_trait_selection::traits::{self, ObligationCause}; use rustc_ast::util::parser::PREC_POSTFIX; use rustc_errors::{Applicability, DiagnosticBuilder}; use rustc_hir as hir; -use rustc_hir::lang_items::DerefTraitLangItem; +use rustc_hir::lang_items::{CloneTraitLangItem, DerefTraitLangItem}; use rustc_hir::{is_range_literal, Node}; use rustc_middle::ty::adjustment::AllowTwoPhase; use rustc_middle::ty::{self, AssocItem, Ty, TypeAndMut}; @@ -456,8 +456,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }; if self.can_coerce(ref_ty, expected) { let mut sugg_sp = sp; - if let hir::ExprKind::MethodCall(segment, _sp, args) = &expr.kind { - let clone_trait = self.tcx.lang_items().clone_trait().unwrap(); + if let hir::ExprKind::MethodCall(ref segment, sp, ref args) = expr.kind { + let clone_trait = self.tcx.require_lang_item(CloneTraitLangItem, Some(sp)); if let ([arg], Some(true), sym::clone) = ( &args[..], self.tables.borrow().type_dependent_def_id(expr.hir_id).map(|did| { @@ -635,7 +635,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { _ if sp == expr.span && !is_macro => { // Check for `Deref` implementations by constructing a predicate to // prove: `::Output == U` - let deref_trait = self.tcx.require_lang_item(DerefTraitLangItem, Some(expr.span)); + let deref_trait = self.tcx.require_lang_item(DerefTraitLangItem, Some(sp)); let item_def_id = self .tcx .associated_items(deref_trait) diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 956e09ec52b4a..f06303ecff985 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -100,7 +100,9 @@ use rustc_hir::def::{CtorOf, DefKind, Res}; use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, DefIdSet, LocalDefId, LOCAL_CRATE}; use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor}; use rustc_hir::itemlikevisit::ItemLikeVisitor; -use rustc_hir::lang_items; +use rustc_hir::lang_items::{ + FutureTraitLangItem, PinTypeLangItem, SizedTraitLangItem, VaListTypeLangItem, +}; use rustc_hir::{ExprKind, GenericArg, HirIdMap, Item, ItemKind, Node, PatKind, QPath}; use rustc_index::bit_set::BitSet; use rustc_index::vec::Idx; @@ -1342,10 +1344,8 @@ fn check_fn<'a, 'tcx>( // C-variadic fns also have a `VaList` input that's not listed in `fn_sig` // (as it's created inside the body itself, not passed in from outside). let maybe_va_list = if fn_sig.c_variadic { - let va_list_did = tcx.require_lang_item( - lang_items::VaListTypeLangItem, - Some(body.params.last().unwrap().span), - ); + let va_list_did = + tcx.require_lang_item(VaListTypeLangItem, Some(body.params.last().unwrap().span)); let region = tcx.mk_region(ty::ReScope(region::Scope { id: body.value.hir_id.local_id, data: region::ScopeData::CallSite, @@ -3303,7 +3303,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { code: traits::ObligationCauseCode<'tcx>, ) { if !ty.references_error() { - let lang_item = self.tcx.require_lang_item(lang_items::SizedTraitLangItem, None); + let lang_item = self.tcx.require_lang_item(SizedTraitLangItem, None); self.require_type_meets(ty, span, code, lang_item); } } @@ -5142,7 +5142,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { _ => {} } let boxed_found = self.tcx.mk_box(found); - let new_found = self.tcx.mk_lang_item(boxed_found, lang_items::PinTypeLangItem).unwrap(); + let new_found = self.tcx.mk_lang_item(boxed_found, PinTypeLangItem).unwrap(); if let (true, Ok(snippet)) = ( self.can_coerce(new_found, expected), self.sess().source_map().span_to_snippet(expr.span), @@ -5298,7 +5298,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let sp = expr.span; // Check for `Future` implementations by constructing a predicate to // prove: `::Output == U` - let future_trait = self.tcx.lang_items().future_trait().unwrap(); + let future_trait = self.tcx.require_lang_item(FutureTraitLangItem, Some(sp)); let item_def_id = self .tcx .associated_items(future_trait) diff --git a/src/librustc_typeck/coherence/builtin.rs b/src/librustc_typeck/coherence/builtin.rs index c01c4d90c8e17..efa3cd9955b49 100644 --- a/src/librustc_typeck/coherence/builtin.rs +++ b/src/librustc_typeck/coherence/builtin.rs @@ -4,7 +4,9 @@ use rustc_errors::struct_span_err; use rustc_hir as hir; use rustc_hir::def_id::{DefId, LocalDefId}; -use rustc_hir::lang_items::UnsizeTraitLangItem; +use rustc_hir::lang_items::{ + CoerceUnsizedTraitLangItem, DispatchFromDynTraitLangItem, UnsizeTraitLangItem, +}; use rustc_hir::ItemKind; use rustc_infer::infer; use rustc_infer::infer::outlives::env::OutlivesEnvironment; @@ -145,11 +147,11 @@ fn visit_implementation_of_coerce_unsized(tcx: TyCtxt<'tcx>, impl_did: LocalDefI fn visit_implementation_of_dispatch_from_dyn(tcx: TyCtxt<'_>, impl_did: LocalDefId) { debug!("visit_implementation_of_dispatch_from_dyn: impl_did={:?}", impl_did); - let dispatch_from_dyn_trait = tcx.lang_items().dispatch_from_dyn_trait().unwrap(); - let impl_hir_id = tcx.hir().as_local_hir_id(impl_did); let span = tcx.hir().span(impl_hir_id); + let dispatch_from_dyn_trait = tcx.require_lang_item(DispatchFromDynTraitLangItem, Some(span)); + let source = tcx.type_of(impl_did); assert!(!source.has_escaping_bound_vars()); let target = { @@ -314,22 +316,23 @@ fn visit_implementation_of_dispatch_from_dyn(tcx: TyCtxt<'_>, impl_did: LocalDef pub fn coerce_unsized_info(tcx: TyCtxt<'tcx>, impl_did: DefId) -> CoerceUnsizedInfo { debug!("compute_coerce_unsized_info(impl_did={:?})", impl_did); - let coerce_unsized_trait = tcx.lang_items().coerce_unsized_trait().unwrap(); + + // this provider should only get invoked for local def-ids + let impl_hir_id = tcx.hir().as_local_hir_id(impl_did.expect_local()); + let span = tcx.hir().span(impl_hir_id); + + let coerce_unsized_trait = tcx.require_lang_item(CoerceUnsizedTraitLangItem, Some(span)); let unsize_trait = tcx.lang_items().require(UnsizeTraitLangItem).unwrap_or_else(|err| { tcx.sess.fatal(&format!("`CoerceUnsized` implementation {}", err)); }); - // this provider should only get invoked for local def-ids - let impl_hir_id = tcx.hir().as_local_hir_id(impl_did.expect_local()); - let source = tcx.type_of(impl_did); let trait_ref = tcx.impl_trait_ref(impl_did).unwrap(); assert_eq!(trait_ref.def_id, coerce_unsized_trait); let target = trait_ref.substs.type_at(1); debug!("visit_implementation_of_coerce_unsized: {:?} -> {:?} (bound)", source, target); - let span = tcx.hir().span(impl_hir_id); let param_env = tcx.param_env(impl_did); assert!(!source.has_escaping_bound_vars()); From 084cdde976e2485104bc14b8079238b37ab8aac1 Mon Sep 17 00:00:00 2001 From: SOFe Date: Fri, 15 May 2020 22:41:36 +0800 Subject: [PATCH 09/12] Updated documentation of Prefix::VerbatimDisk PrefixComponent with Prefix::VerbatimDisk does not contain the trailing slash. The documentation here is also inconsistent with the documentation on other variants that reflect the `PrefixComponent::as_os_str()` return value. --- src/libstd/path.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libstd/path.rs b/src/libstd/path.rs index 173d6d1cfa7ef..8516e80f3b876 100644 --- a/src/libstd/path.rs +++ b/src/libstd/path.rs @@ -157,10 +157,10 @@ pub enum Prefix<'a> { #[stable(feature = "rust1", since = "1.0.0")] &'a OsStr, ), - /// Verbatim disk prefix, e.g., `\\?\C:\`. + /// Verbatim disk prefix, e.g., `\\?\C:`. /// /// Verbatim disk prefixes consist of `\\?\` immediately followed by the - /// drive letter and `:\`. + /// drive letter and `:`. #[stable(feature = "rust1", since = "1.0.0")] VerbatimDisk(#[stable(feature = "rust1", since = "1.0.0")] u8), From d5ea92526549e40ff43b34f25fe6bee4418a3186 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Fri, 15 May 2020 09:12:41 -0700 Subject: [PATCH 10/12] Implement Default for proc_macro::TokenStream --- src/libproc_macro/lib.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/libproc_macro/lib.rs b/src/libproc_macro/lib.rs index 31bc61263abe6..b6544341fa95b 100644 --- a/src/libproc_macro/lib.rs +++ b/src/libproc_macro/lib.rs @@ -158,6 +158,13 @@ impl fmt::Debug for TokenStream { } } +#[stable(feature = "proc_macro_token_stream_default", since = "1.45.0")] +impl Default for TokenStream { + fn default() -> Self { + TokenStream::new() + } +} + #[unstable(feature = "proc_macro_quote", issue = "54722")] pub use quote::{quote, quote_span}; From 7433c4ddf3c226fc6beeed7a79f7d48777a3e807 Mon Sep 17 00:00:00 2001 From: Diggory Blake Date: Mon, 27 Apr 2020 22:50:55 +0100 Subject: [PATCH 11/12] Improve the documentation for ManuallyDrop to resolve conflicting usage of terminology. --- src/libcore/mem/manually_drop.rs | 39 ++++++++++++++++++++++++-------- src/libcore/ptr/mod.rs | 8 ++++++- 2 files changed, 36 insertions(+), 11 deletions(-) diff --git a/src/libcore/mem/manually_drop.rs b/src/libcore/mem/manually_drop.rs index 9e5c2b10d0d9e..17863dd38afee 100644 --- a/src/libcore/mem/manually_drop.rs +++ b/src/libcore/mem/manually_drop.rs @@ -7,14 +7,14 @@ use crate::ptr; /// /// `ManuallyDrop` is subject to the same layout optimizations as `T`. /// As a consequence, it has *no effect* on the assumptions that the compiler makes -/// about all values being initialized at their type. In particular, initializing -/// a `ManuallyDrop<&mut T>` with [`mem::zeroed`] is undefined behavior. +/// about its contents. For example, initializing a `ManuallyDrop<&mut T>` +/// with [`mem::zeroed`] is undefined behavior. /// If you need to handle uninitialized data, use [`MaybeUninit`] instead. /// /// # Examples /// -/// This wrapper helps with explicitly documenting the drop order dependencies between fields of -/// the type: +/// This wrapper can be used to enforce a particular drop order on fields, regardless +/// of how they are defined in the struct: /// /// ```rust /// use std::mem::ManuallyDrop; @@ -43,8 +43,18 @@ use crate::ptr; /// } /// ``` /// +/// However, care should be taken when using this pattern as it can lead to *leak amplification*. +/// In this example, if the `Drop` implementation for `Peach` were to panic, the `banana` field +/// would also be leaked. +/// +/// In contrast, the automatically-generated compiler drop implementation would have ensured +/// that all fields are dropped even in the presence of panics. This is especially important when +/// working with [pinned] data, where reusing the memory without calling the destructor could lead +/// to Undefined Behaviour. +/// /// [`mem::zeroed`]: fn.zeroed.html /// [`MaybeUninit`]: union.MaybeUninit.html +/// [pinned]: ../pin/index.html #[stable(feature = "manually_drop", since = "1.20.0")] #[lang = "manually_drop"] #[derive(Copy, Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)] @@ -113,19 +123,28 @@ impl ManuallyDrop { } impl ManuallyDrop { - /// Manually drops the contained value. + /// Manually drops the contained value. This is exactly equivalent to calling + /// [`ptr::drop_in_place`] with a pointer to the contained value. As such, unless + /// the contained value is a packed struct, the destructor will be called in-place + /// without moving the value, and thus can be used to safely drop [pinned] data. /// /// If you have ownership of the value, you can use [`ManuallyDrop::into_inner`] instead. /// /// # Safety /// - /// This function runs the destructor of the contained value and thus the wrapped value - /// now represents uninitialized data. It is up to the user of this method to ensure the - /// uninitialized data is not actually used. - /// In particular, this function can only be called at most once - /// for a given instance of `ManuallyDrop`. + /// This function runs the destructor of the contained value. Other than changes made by + /// the destructor itself, the memory is left unchanged, and so as far as the compiler is + /// concerned still holds a bit-pattern which is valid for the type `T`. + /// + /// However, this "zombie" value should not be exposed to safe code, and this function + /// should not be called more than once. To use a value after it's been dropped, or drop + /// a value multiple times, can cause Undefined Behavior (depending on what `drop` does). + /// This is normally prevented by the type system, but users of `ManuallyDrop` must + /// uphold those guarantees without assistance from the compiler. /// /// [`ManuallyDrop::into_inner`]: #method.into_inner + /// [`ptr::drop_in_place`]: ../ptr/fn.drop_in_place.html + /// [pinned]: ../pin/index.html #[stable(feature = "manually_drop", since = "1.20.0")] #[inline] pub unsafe fn drop(slot: &mut ManuallyDrop) { diff --git a/src/libcore/ptr/mod.rs b/src/libcore/ptr/mod.rs index 84f28488c74b6..115194a65a0c2 100644 --- a/src/libcore/ptr/mod.rs +++ b/src/libcore/ptr/mod.rs @@ -112,11 +112,17 @@ mod mut_ptr; /// as the compiler doesn't need to prove that it's sound to elide the /// copy. /// +/// * It can be used to drop [pinned] data when `T` is not `repr(packed)` +/// (pinned data must not be moved before it is dropped). +/// /// Unaligned values cannot be dropped in place, they must be copied to an aligned -/// location first using [`ptr::read_unaligned`]. +/// location first using [`ptr::read_unaligned`]. For packed structs, this move is +/// done automatically by the compiler. This means the fields of packed structs +/// are not dropped in-place. /// /// [`ptr::read`]: ../ptr/fn.read.html /// [`ptr::read_unaligned`]: ../ptr/fn.read_unaligned.html +/// [pinned]: ../pin/index.html /// /// # Safety /// From 78eb64f35acf2c998c2ea6d9007f18d247d4ce88 Mon Sep 17 00:00:00 2001 From: Rustin-Liu Date: Sat, 16 May 2020 14:40:45 +0800 Subject: [PATCH 12/12] Fix typo Arbintrary to Arbitrary Signed-off-by: Rustin-Liu --- src/librustc_error_codes/error_codes/E0307.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc_error_codes/error_codes/E0307.md b/src/librustc_error_codes/error_codes/E0307.md index 52707b93acc86..0d29d56ea1a75 100644 --- a/src/librustc_error_codes/error_codes/E0307.md +++ b/src/librustc_error_codes/error_codes/E0307.md @@ -64,7 +64,7 @@ impl Trait for Foo { } ``` -The nightly feature [Arbintrary self types][AST] extends the accepted +The nightly feature [Arbitrary self types][AST] extends the accepted set of receiver types to also include any type that can dereference to `Self`: