From 7ec9dc71a73beb00259ec1a7f2391b7d6790ca66 Mon Sep 17 00:00:00 2001 From: vivekvpandya Date: Mon, 16 Dec 2019 21:02:03 +0530 Subject: [PATCH 01/22] Remove LLVMRustBuildCleanupPad() LLVMRustBuildCleanupRet() LLVMRustBuildCatchPad() LLVMRustBuildCatchRet() LLVMRustBuildCatchSwitch() from llvmrust/RustWrapper.cpp as after https://reviews.llvm.org/D45100 requied C API are avaliable in LLVM. r? @alexcrichton --- src/librustc_codegen_llvm/builder.rs | 26 +++++++------- src/librustc_codegen_llvm/llvm/ffi.rs | 46 ++++++++++++------------- src/rustllvm/RustWrapper.cpp | 49 --------------------------- 3 files changed, 36 insertions(+), 85 deletions(-) diff --git a/src/librustc_codegen_llvm/builder.rs b/src/librustc_codegen_llvm/builder.rs index 7509584df277e..80a5b150a1383 100644 --- a/src/librustc_codegen_llvm/builder.rs +++ b/src/librustc_codegen_llvm/builder.rs @@ -889,11 +889,11 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { args: &[&'ll Value]) -> Funclet<'ll> { let name = const_cstr!("cleanuppad"); let ret = unsafe { - llvm::LLVMRustBuildCleanupPad(self.llbuilder, - parent, - args.len() as c_uint, - args.as_ptr(), - name.as_ptr()) + llvm::LLVMBuildCleanupPad(self.llbuilder, + parent, + args.as_ptr(), + args.len() as c_uint, + name.as_ptr()) }; Funclet::new(ret.expect("LLVM does not have support for cleanuppad")) } @@ -903,7 +903,7 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { unwind: Option<&'ll BasicBlock>, ) -> &'ll Value { let ret = unsafe { - llvm::LLVMRustBuildCleanupRet(self.llbuilder, funclet.cleanuppad(), unwind) + llvm::LLVMBuildCleanupRet(self.llbuilder, funclet.cleanuppad(), unwind) }; ret.expect("LLVM does not have support for cleanupret") } @@ -913,9 +913,9 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { args: &[&'ll Value]) -> Funclet<'ll> { let name = const_cstr!("catchpad"); let ret = unsafe { - llvm::LLVMRustBuildCatchPad(self.llbuilder, parent, - args.len() as c_uint, args.as_ptr(), - name.as_ptr()) + llvm::LLVMBuildCatchPad(self.llbuilder, parent, + args.as_ptr(), args.len() as c_uint, + name.as_ptr()) }; Funclet::new(ret.expect("LLVM does not have support for catchpad")) } @@ -928,9 +928,9 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { ) -> &'ll Value { let name = const_cstr!("catchswitch"); let ret = unsafe { - llvm::LLVMRustBuildCatchSwitch(self.llbuilder, parent, unwind, - num_handlers as c_uint, - name.as_ptr()) + llvm::LLVMBuildCatchSwitch(self.llbuilder, parent, unwind, + num_handlers as c_uint, + name.as_ptr()) }; ret.expect("LLVM does not have support for catchswitch") } @@ -1182,7 +1182,7 @@ impl Builder<'a, 'll, 'tcx> { pub fn catch_ret(&mut self, funclet: &Funclet<'ll>, unwind: &'ll BasicBlock) -> &'ll Value { let ret = unsafe { - llvm::LLVMRustBuildCatchRet(self.llbuilder, funclet.cleanuppad(), unwind) + llvm::LLVMBuildCatchRet(self.llbuilder, funclet.cleanuppad(), unwind) }; ret.expect("LLVM does not have support for catchret") } diff --git a/src/librustc_codegen_llvm/llvm/ffi.rs b/src/librustc_codegen_llvm/llvm/ffi.rs index b8a1003b11866..63d1edb93a87f 100644 --- a/src/librustc_codegen_llvm/llvm/ffi.rs +++ b/src/librustc_codegen_llvm/llvm/ffi.rs @@ -886,33 +886,33 @@ extern "C" { pub fn LLVMBuildResume(B: &Builder<'a>, Exn: &'a Value) -> &'a Value; pub fn LLVMBuildUnreachable(B: &Builder<'a>) -> &'a Value; - pub fn LLVMRustBuildCleanupPad(B: &Builder<'a>, - ParentPad: Option<&'a Value>, - ArgCnt: c_uint, - Args: *const &'a Value, - Name: *const c_char) - -> Option<&'a Value>; - pub fn LLVMRustBuildCleanupRet(B: &Builder<'a>, - CleanupPad: &'a Value, - UnwindBB: Option<&'a BasicBlock>) - -> Option<&'a Value>; - pub fn LLVMRustBuildCatchPad(B: &Builder<'a>, - ParentPad: &'a Value, - ArgCnt: c_uint, - Args: *const &'a Value, - Name: *const c_char) - -> Option<&'a Value>; - pub fn LLVMRustBuildCatchRet( + pub fn LLVMBuildCleanupPad(B: &Builder<'a>, + ParentPad: Option<&'a Value>, + Args: *const &'a Value, + ArgCnt: c_uint, + Name: *const c_char) + -> Option<&'a Value>; + pub fn LLVMBuildCleanupRet(B: &Builder<'a>, + CleanupPad: &'a Value, + UnwindBB: Option<&'a BasicBlock>) + -> Option<&'a Value>; + pub fn LLVMBuildCatchPad(B: &Builder<'a>, + ParentPad: &'a Value, + Args: *const &'a Value, + ArgCnt: c_uint, + Name: *const c_char) + -> Option<&'a Value>; + pub fn LLVMBuildCatchRet( B: &Builder<'a>, Pad: &'a Value, BB: &'a BasicBlock, ) -> Option<&'a Value>; - pub fn LLVMRustBuildCatchSwitch(Builder: &Builder<'a>, - ParentPad: Option<&'a Value>, - BB: Option<&'a BasicBlock>, - NumHandlers: c_uint, - Name: *const c_char) - -> Option<&'a Value>; + pub fn LLVMBuildCatchSwitch(Builder: &Builder<'a>, + ParentPad: Option<&'a Value>, + BB: Option<&'a BasicBlock>, + NumHandlers: c_uint, + Name: *const c_char) + -> Option<&'a Value>; pub fn LLVMRustAddHandler(CatchSwitch: &'a Value, Handler: &'a BasicBlock); pub fn LLVMSetPersonalityFn(Func: &'a Value, Pers: &'a Value); diff --git a/src/rustllvm/RustWrapper.cpp b/src/rustllvm/RustWrapper.cpp index 720928e48e382..4de4a433f341c 100644 --- a/src/rustllvm/RustWrapper.cpp +++ b/src/rustllvm/RustWrapper.cpp @@ -1174,55 +1174,6 @@ extern "C" void LLVMRustWriteSMDiagnosticToString(LLVMSMDiagnosticRef D, unwrap(D)->print("", OS); } -extern "C" LLVMValueRef LLVMRustBuildCleanupPad(LLVMBuilderRef B, - LLVMValueRef ParentPad, - unsigned ArgCount, - LLVMValueRef *LLArgs, - const char *Name) { - Value **Args = unwrap(LLArgs); - if (ParentPad == nullptr) { - Type *Ty = Type::getTokenTy(unwrap(B)->getContext()); - ParentPad = wrap(Constant::getNullValue(Ty)); - } - return wrap(unwrap(B)->CreateCleanupPad( - unwrap(ParentPad), ArrayRef(Args, ArgCount), Name)); -} - -extern "C" LLVMValueRef LLVMRustBuildCleanupRet(LLVMBuilderRef B, - LLVMValueRef CleanupPad, - LLVMBasicBlockRef UnwindBB) { - CleanupPadInst *Inst = cast(unwrap(CleanupPad)); - return wrap(unwrap(B)->CreateCleanupRet(Inst, unwrap(UnwindBB))); -} - -extern "C" LLVMValueRef -LLVMRustBuildCatchPad(LLVMBuilderRef B, LLVMValueRef ParentPad, - unsigned ArgCount, LLVMValueRef *LLArgs, const char *Name) { - Value **Args = unwrap(LLArgs); - return wrap(unwrap(B)->CreateCatchPad( - unwrap(ParentPad), ArrayRef(Args, ArgCount), Name)); -} - -extern "C" LLVMValueRef LLVMRustBuildCatchRet(LLVMBuilderRef B, - LLVMValueRef Pad, - LLVMBasicBlockRef BB) { - return wrap(unwrap(B)->CreateCatchRet(cast(unwrap(Pad)), - unwrap(BB))); -} - -extern "C" LLVMValueRef LLVMRustBuildCatchSwitch(LLVMBuilderRef B, - LLVMValueRef ParentPad, - LLVMBasicBlockRef BB, - unsigned NumHandlers, - const char *Name) { - if (ParentPad == nullptr) { - Type *Ty = Type::getTokenTy(unwrap(B)->getContext()); - ParentPad = wrap(Constant::getNullValue(Ty)); - } - return wrap(unwrap(B)->CreateCatchSwitch(unwrap(ParentPad), unwrap(BB), - NumHandlers, Name)); -} - extern "C" void LLVMRustAddHandler(LLVMValueRef CatchSwitchRef, LLVMBasicBlockRef Handler) { Value *CatchSwitch = unwrap(CatchSwitchRef); From 61f995fd2e7514b8fe7c81aa261325ba66597ef1 Mon Sep 17 00:00:00 2001 From: Andrea Canciani Date: Wed, 11 Dec 2019 21:24:35 +0100 Subject: [PATCH 02/22] Improve `str` prefix/suffix comparison The comparison can be performed on the raw bytes, as the chars can only match if their UTF8 encoding matches. This avoids the `is_char_boundary` checks and translates to a straight `u8` slice comparison which is optimized to a memcmp or inline comparison where appropriate. --- src/libcore/str/pattern.rs | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/libcore/str/pattern.rs b/src/libcore/str/pattern.rs index 1037da14b5f62..7b2e6da75c4f6 100644 --- a/src/libcore/str/pattern.rs +++ b/src/libcore/str/pattern.rs @@ -710,16 +710,13 @@ impl<'a, 'b> Pattern<'a> for &'b str { /// Checks whether the pattern matches at the front of the haystack #[inline] fn is_prefix_of(self, haystack: &'a str) -> bool { - haystack.is_char_boundary(self.len()) && - self == &haystack[..self.len()] + haystack.as_bytes().starts_with(self.as_bytes()) } /// Checks whether the pattern matches at the back of the haystack #[inline] fn is_suffix_of(self, haystack: &'a str) -> bool { - self.len() <= haystack.len() && - haystack.is_char_boundary(haystack.len() - self.len()) && - self == &haystack[haystack.len() - self.len()..] + haystack.as_bytes().ends_with(self.as_bytes()) } } From c59272ca890982f1b4e9c98aa46ab84f91f06723 Mon Sep 17 00:00:00 2001 From: Andrea Canciani Date: Wed, 11 Dec 2019 21:28:37 +0100 Subject: [PATCH 03/22] Prefer encoding the char when checking for string prefix/suffix This enables constant folding when matching a literal char. Fixes #41993. --- src/libcore/str/pattern.rs | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/src/libcore/str/pattern.rs b/src/libcore/str/pattern.rs index 7b2e6da75c4f6..8b52f7927a526 100644 --- a/src/libcore/str/pattern.rs +++ b/src/libcore/str/pattern.rs @@ -445,21 +445,15 @@ impl<'a> Pattern<'a> for char { #[inline] fn is_prefix_of(self, haystack: &'a str) -> bool { - if let Some(ch) = haystack.chars().next() { - self == ch - } else { - false - } + let mut buffer = [0u8; 4]; + self.encode_utf8(&mut buffer).is_prefix_of(haystack) } #[inline] fn is_suffix_of(self, haystack: &'a str) -> bool where Self::Searcher: ReverseSearcher<'a> { - if let Some(ch) = haystack.chars().next_back() { - self == ch - } else { - false - } + let mut buffer = [0u8; 4]; + self.encode_utf8(&mut buffer).is_suffix_of(haystack) } } From c657406f4271985313d80ccfd0e7b305696b73ae Mon Sep 17 00:00:00 2001 From: Andrea Canciani Date: Thu, 12 Dec 2019 21:09:17 +0100 Subject: [PATCH 04/22] Minor cleanup in `Pattern::{is_prefix_of,is_suffix_of}` for `char` --- src/libcore/str/pattern.rs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/libcore/str/pattern.rs b/src/libcore/str/pattern.rs index 8b52f7927a526..b7ebd5f88b589 100644 --- a/src/libcore/str/pattern.rs +++ b/src/libcore/str/pattern.rs @@ -445,15 +445,13 @@ impl<'a> Pattern<'a> for char { #[inline] fn is_prefix_of(self, haystack: &'a str) -> bool { - let mut buffer = [0u8; 4]; - self.encode_utf8(&mut buffer).is_prefix_of(haystack) + self.encode_utf8(&mut [0u8; 4]).is_prefix_of(haystack) } #[inline] fn is_suffix_of(self, haystack: &'a str) -> bool where Self::Searcher: ReverseSearcher<'a> { - let mut buffer = [0u8; 4]; - self.encode_utf8(&mut buffer).is_suffix_of(haystack) + self.encode_utf8(&mut [0u8; 4]).is_suffix_of(haystack) } } From 5e8cab4c0e3bf10097ee541f25352e8b25fc2869 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Sat, 14 Dec 2019 18:43:54 -0800 Subject: [PATCH 05/22] Delete flaky test net::tcp::tests::fast_rebind --- src/libstd/net/tcp.rs | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/src/libstd/net/tcp.rs b/src/libstd/net/tcp.rs index 5c02215997088..c33f98bdd8329 100644 --- a/src/libstd/net/tcp.rs +++ b/src/libstd/net/tcp.rs @@ -1312,21 +1312,6 @@ mod tests { }) } - #[test] - fn fast_rebind() { - each_ip(&mut |addr| { - let acceptor = t!(TcpListener::bind(&addr)); - - let _t = thread::spawn(move || { - t!(TcpStream::connect(&addr)); - }); - - t!(acceptor.accept()); - drop(acceptor); - t!(TcpListener::bind(&addr)); - }); - } - #[test] fn tcp_clone_smoke() { each_ip(&mut |addr| { From 8c8cdddaa96ad0c3068b10614b837bcad69ddf4c Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Sun, 15 Dec 2019 13:13:52 +0100 Subject: [PATCH 06/22] comment -> doc comment --- src/librustc_typeck/check/mod.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 43e7bbcf0c0dc..65a5405c03772 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -5351,9 +5351,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { directly, not through a function pointer"); } - // Resolves `typ` by a single level if `typ` is a type variable. - // If no resolution is possible, then an error is reported. - // Numeric inference variables may be left unresolved. + /// Resolves `typ` by a single level if `typ` is a type variable. + /// If no resolution is possible, then an error is reported. + /// Numeric inference variables may be left unresolved. pub fn structurally_resolved_type(&self, sp: Span, ty: Ty<'tcx>) -> Ty<'tcx> { let ty = self.resolve_vars_with_obligations(ty); if !ty.is_ty_var() { From d7bb25c6c25169078b7ff9a1cb1362f5bd4493e7 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Sun, 15 Dec 2019 13:16:01 +0100 Subject: [PATCH 07/22] document check_pat_slice --- src/librustc_typeck/check/pat.rs | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/src/librustc_typeck/check/pat.rs b/src/librustc_typeck/check/pat.rs index 71d1cd869a6a2..4fb57a6562574 100644 --- a/src/librustc_typeck/check/pat.rs +++ b/src/librustc_typeck/check/pat.rs @@ -1154,6 +1154,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.tcx.mk_ref(region, mt) } + /// Type check a slice pattern. + /// + /// Syntactically, these look like `[pat_0, ..., pat_n]`. + /// Semantically, we are type checking a pattern with structure: + /// ``` + /// [before_0, ..., before_n, (slice, after_0, ... after_n)?] + /// ``` + /// The type of `slice`, if it is present, depends on the `expected` type. + /// If `slice` is missing, then so is `after_i`. + /// If `slice` is present, it can still represent 0 elements. fn check_pat_slice( &self, span: Span, @@ -1167,27 +1177,39 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let tcx = self.tcx; let expected_ty = self.structurally_resolved_type(span, expected); let (inner_ty, slice_ty) = match expected_ty.kind { + // An array, so we might have something like `let [a, b, c] = [0, 1, 2];`. ty::Array(inner_ty, size) => { let slice_ty = if let Some(size) = size.try_eval_usize(tcx, self.param_env) { + // Now we know the length... let min_len = before.len() as u64 + after.len() as u64; if slice.is_none() { + // ...and since there is no variable-length pattern, + // we require an exact match between the number of elements + // in the array pattern and as provided by the matched type. if min_len != size { self.error_scrutinee_inconsistent_length(span, min_len, size) } tcx.types.err } else if let Some(rest) = size.checked_sub(min_len) { + // The variable-length pattern was there, + // so it has an array type with the remaining elements left as its size... tcx.mk_array(inner_ty, rest) } else { + // ...however, in this case, there were no remaining elements. + // That is, the slice pattern requires more than the array type offers. self.error_scrutinee_with_rest_inconsistent_length(span, min_len, size); tcx.types.err } } else { + // No idea what the length is, which happens if we have e.g., + // `let [a, b] = arr` where `arr: [T; N]` where `const N: usize`. self.error_scrutinee_unfixed_length(span); tcx.types.err }; (inner_ty, slice_ty) } ty::Slice(inner_ty) => (inner_ty, expected_ty), + // The expected type must be an array or slice, but was neither, so error. _ => { if !expected_ty.references_error() { self.error_expected_array_or_slice(span, expected_ty); @@ -1196,12 +1218,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } }; + // Type check all the patterns before `slice`. for elt in before { self.check_pat(&elt, inner_ty, def_bm, discrim_span); } + // Type check the `slice`, if present, against its expected type. if let Some(slice) = slice { self.check_pat(&slice, slice_ty, def_bm, discrim_span); } + // Type check the elements after `slice`, if present. for elt in after { self.check_pat(&elt, inner_ty, def_bm, discrim_span); } From e0463813bace18048ba0fada0d8c0aee076530a7 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Sun, 15 Dec 2019 13:16:29 +0100 Subject: [PATCH 08/22] improve hir::PatKind::Slice docs --- src/librustc/hir/mod.rs | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs index 66bb3a8d883a4..6b354b01518ea 100644 --- a/src/librustc/hir/mod.rs +++ b/src/librustc/hir/mod.rs @@ -1048,8 +1048,15 @@ pub enum PatKind { /// A range pattern (e.g., `1..=2` or `1..2`). Range(P, P, RangeEnd), - /// `[a, b, ..i, y, z]` is represented as: - /// `PatKind::Slice(box [a, b], Some(i), box [y, z])`. + /// A slice pattern, `[before_0, ..., before_n, (slice, after_0, ..., after_n)?]`. + /// + /// Here, `slice` is lowered from the syntax `($binding_mode $ident @)? ..`. + /// If `slice` exists, then `after` can be non-empty. + /// + /// The representation for e.g., `[a, b, .., c, d]` is: + /// ``` + /// PatKind::Slice([Binding(a), Binding(b)], Some(Wild), [Binding(c), Binding(d)]) + /// ``` Slice(HirVec>, Option>, HirVec>), } From ad533a11679f05b645fcebd41d266ed531377a49 Mon Sep 17 00:00:00 2001 From: Lzu Tao Date: Sun, 15 Dec 2019 06:07:46 +0000 Subject: [PATCH 09/22] use Self alias in place of macros --- src/libcore/num/mod.rs | 4 ++-- src/libcore/sync/atomic.rs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs index 33715418ffd73..d091a8d86ea49 100644 --- a/src/libcore/num/mod.rs +++ b/src/libcore/num/mod.rs @@ -67,7 +67,7 @@ assert_eq!(size_of::>(), size_of::<", s )] #[inline] pub const unsafe fn new_unchecked(n: $Int) -> Self { - $Ty(n) + Self(n) } /// Creates a non-zero if the given value is not zero. @@ -76,7 +76,7 @@ assert_eq!(size_of::>(), size_of::<", s pub fn new(n: $Int) -> Option { if n != 0 { // SAFETY: we just checked that there's no `0` - Some(unsafe { $Ty(n) }) + Some(unsafe { Self(n) }) } else { None } diff --git a/src/libcore/sync/atomic.rs b/src/libcore/sync/atomic.rs index 7756335ee207d..d5b0bc420382f 100644 --- a/src/libcore/sync/atomic.rs +++ b/src/libcore/sync/atomic.rs @@ -1263,7 +1263,7 @@ let atomic_forty_two = ", stringify!($atomic_type), "::new(42); #[$stable] #[cfg_attr(not(bootstrap), $const_stable)] pub const fn new(v: $int_type) -> Self { - $atomic_type {v: UnsafeCell::new(v)} + Self {v: UnsafeCell::new(v)} } } From fe3f435d070a2f538d156d8637c0420454d3a4e4 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Sun, 15 Dec 2019 15:11:34 +0100 Subject: [PATCH 10/22] make transparent enums more ordinary --- src/librustc_typeck/check/mod.rs | 35 ++++++++++++++++---------------- 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 65a5405c03772..09771bb762536 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -2330,7 +2330,7 @@ fn bad_variant_count<'tcx>(tcx: TyCtxt<'tcx>, adt: &'tcx ty::AdtDef, sp: Span, d ); let mut err = struct_span_err!(tcx.sess, sp, E0731, "transparent enum {}", msg); err.span_label(sp, &msg); - if let &[ref start @ .., ref end] = &variant_spans[..] { + if let [start @ .., end] = &*variant_spans { for variant_span in start { err.span_label(*variant_span, ""); } @@ -2372,23 +2372,14 @@ fn check_transparent(tcx: TyCtxt<'_>, sp: Span, def_id: DefId) { } let sp = tcx.sess.source_map().def_span(sp); - if adt.is_enum() { - if !tcx.features().transparent_enums { - feature_err( - &tcx.sess.parse_sess, - sym::transparent_enums, - sp, - "transparent enums are unstable", - ) - .emit(); - } - if adt.variants.len() != 1 { - bad_variant_count(tcx, adt, sp, def_id); - if adt.variants.is_empty() { - // Don't bother checking the fields. No variants (and thus no fields) exist. - return; - } - } + if adt.is_enum() && !tcx.features().transparent_enums { + feature_err( + &tcx.sess.parse_sess, + sym::transparent_enums, + sp, + "transparent enums are unstable", + ) + .emit(); } if adt.is_union() && !tcx.features().transparent_unions { @@ -2401,6 +2392,14 @@ fn check_transparent(tcx: TyCtxt<'_>, sp: Span, def_id: DefId) { .emit(); } + if adt.variants.len() != 1 { + bad_variant_count(tcx, adt, sp, def_id); + if adt.variants.is_empty() { + // Don't bother checking the fields. No variants (and thus no fields) exist. + return; + } + } + // For each field, figure out if it's known to be a ZST and align(1) let field_infos = adt.all_fields().map(|field| { let ty = field.ty(tcx, InternalSubsts::identity_for_item(tcx, field.did)); From d10ec95d7971dbd303ff5d58296789a8d4a9773e Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sun, 15 Dec 2019 21:27:25 +0100 Subject: [PATCH 11/22] Fix JS error when loading page with search --- src/librustdoc/html/static/main.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js index 49a9cb093da2a..1459e8f37cd32 100644 --- a/src/librustdoc/html/static/main.js +++ b/src/librustdoc/html/static/main.js @@ -2683,7 +2683,7 @@ function getSearchElement() { insertAfter(popup, getSearchElement()); } - onHashChange(); + onHashChange(null); window.onhashchange = onHashChange; buildHelperPopup(); From da3265c3ac6a223ae53b33221179291f57206bc9 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Sun, 15 Dec 2019 13:17:39 +0100 Subject: [PATCH 12/22] improve lower_pat_slice docs + while -> for --- src/librustc/hir/lowering.rs | 38 ++++++++++++++++++++++++------------ 1 file changed, 26 insertions(+), 12 deletions(-) diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index e13f6cabb5296..ec9d6802defa3 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -2852,19 +2852,23 @@ impl<'a> LoweringContext<'a> { let mut rest = None; let mut iter = pats.iter().enumerate(); - while let Some((idx, pat)) = iter.next() { - // Interpret the first `..` pattern as a subtuple pattern. + for (idx, pat) in iter.by_ref() { + // Interpret the first `..` pattern as a sub-tuple pattern. + // Note that unlike for slice patterns, + // where `xs @ ..` is a legal sub-slice pattern, + // it is not a legal sub-tuple pattern. if pat.is_rest() { rest = Some((idx, pat.span)); break; } - // It was not a subslice pattern so lower it normally. + // It was not a sub-tuple pattern so lower it normally. elems.push(self.lower_pat(pat)); } - while let Some((_, pat)) = iter.next() { - // There was a previous subtuple pattern; make sure we don't allow more. + for (_, pat) in iter { + // There was a previous sub-tuple pattern; make sure we don't allow more... if pat.is_rest() { + // ...but there was one again, so error. self.ban_extra_rest_pat(pat.span, rest.unwrap().1, ctx); } else { elems.push(self.lower_pat(pat)); @@ -2874,6 +2878,12 @@ impl<'a> LoweringContext<'a> { (elems.into(), rest.map(|(ddpos, _)| ddpos)) } + /// Lower a slice pattern of form `[pat_0, ..., pat_n]` into + /// `hir::PatKind::Slice(before, slice, after)`. + /// + /// When encountering `($binding_mode $ident @)? ..` (`slice`), + /// this is interpreted as a sub-slice pattern semantically. + /// Patterns that follow, which are not like `slice` -- or an error occurs, are in `after`. fn lower_pat_slice(&mut self, pats: &[AstP]) -> hir::PatKind { let mut before = Vec::new(); let mut after = Vec::new(); @@ -2881,14 +2891,17 @@ impl<'a> LoweringContext<'a> { let mut prev_rest_span = None; let mut iter = pats.iter(); - while let Some(pat) = iter.next() { - // Interpret the first `((ref mut?)? x @)? ..` pattern as a subslice pattern. + // Lower all the patterns until the first occurence of a sub-slice pattern. + for pat in iter.by_ref() { match pat.kind { + // Found a sub-slice pattern `..`. Record, lower it to `_`, and stop here. PatKind::Rest => { prev_rest_span = Some(pat.span); slice = Some(self.pat_wild_with_node_id_of(pat)); break; }, + // Found a sub-slice pattern `$binding_mode $ident @ ..`. + // Record, lower it to `$binding_mode $ident @ _`, and stop here. PatKind::Ident(ref bm, ident, Some(ref sub)) if sub.is_rest() => { prev_rest_span = Some(sub.span); let lower_sub = |this: &mut Self| Some(this.pat_wild_with_node_id_of(sub)); @@ -2896,14 +2909,13 @@ impl<'a> LoweringContext<'a> { slice = Some(self.pat_with_node_id_of(pat, node)); break; }, - _ => {} + // It was not a subslice pattern so lower it normally. + _ => before.push(self.lower_pat(pat)), } - - // It was not a subslice pattern so lower it normally. - before.push(self.lower_pat(pat)); } - while let Some(pat) = iter.next() { + // Lower all the patterns after the first sub-slice pattern. + for pat in iter { // There was a previous subslice pattern; make sure we don't allow more. let rest_span = match pat.kind { PatKind::Rest => Some(pat.span), @@ -2915,8 +2927,10 @@ impl<'a> LoweringContext<'a> { _ => None, }; if let Some(rest_span) = rest_span { + // We have e.g., `[a, .., b, ..]`. That's no good, error! self.ban_extra_rest_pat(rest_span, prev_rest_span.unwrap(), "slice"); } else { + // Lower the pattern normally. after.push(self.lower_pat(pat)); } } From e4feeaabf11003439bb32dbacf85775324e05224 Mon Sep 17 00:00:00 2001 From: Josh Triplett Date: Sun, 15 Dec 2019 23:17:06 -0800 Subject: [PATCH 13/22] .gitignore: Don't ignore a file that exists in the repository .gitignore should not ignore files that exist in the repository. The ignore of .cargo applies to the committed .cargo directory used in an example: $ git ls-files --exclude-standard --ignored src/test/run-make/thumb-none-qemu/example/.cargo/config Explicitly un-ignore that file. --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 487867c375d45..1428ee6c9bc23 100644 --- a/.gitignore +++ b/.gitignore @@ -55,5 +55,6 @@ config.mk config.stamp Session.vim .cargo +!/src/test/run-make/thumb-none-qemu/example/.cargo no_llvm_build # Before adding new lines, see the comment at the top. From f2eba30ff40c598b35eda4831b0c0d068d2a6842 Mon Sep 17 00:00:00 2001 From: Peter Todd Date: Mon, 16 Dec 2019 07:22:40 -0500 Subject: [PATCH 14/22] Minor: update Unsize docs for dyn syntax --- src/libcore/marker.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libcore/marker.rs b/src/libcore/marker.rs index 2db55508ad546..1b586c3e5fe30 100644 --- a/src/libcore/marker.rs +++ b/src/libcore/marker.rs @@ -97,7 +97,7 @@ pub trait Sized { /// Types that can be "unsized" to a dynamically-sized type. /// /// For example, the sized array type `[i8; 2]` implements `Unsize<[i8]>` and -/// `Unsize`. +/// `Unsize`. /// /// All implementations of `Unsize` are provided automatically by the compiler. /// From 64b7b9bb4482c2c8949db01cc314d31cc7c38601 Mon Sep 17 00:00:00 2001 From: Andrea Canciani Date: Mon, 16 Dec 2019 15:33:16 +0100 Subject: [PATCH 15/22] Add benchmarks for `start_with` and `ends_with` --- src/libcore/benches/lib.rs | 1 + src/libcore/benches/pattern.rs | 43 ++++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+) create mode 100644 src/libcore/benches/pattern.rs diff --git a/src/libcore/benches/lib.rs b/src/libcore/benches/lib.rs index 6932c7fe221d0..570fc4ab93390 100644 --- a/src/libcore/benches/lib.rs +++ b/src/libcore/benches/lib.rs @@ -11,4 +11,5 @@ mod hash; mod iter; mod num; mod ops; +mod pattern; mod slice; diff --git a/src/libcore/benches/pattern.rs b/src/libcore/benches/pattern.rs new file mode 100644 index 0000000000000..a49490cec1219 --- /dev/null +++ b/src/libcore/benches/pattern.rs @@ -0,0 +1,43 @@ +use test::black_box; +use test::Bencher; + +#[bench] +fn starts_with_char(b: &mut Bencher) { + let text = black_box("kdjsfhlakfhlsghlkvcnljknfqiunvcijqenwodind"); + b.iter(|| { + for _ in 0..1024 { + black_box(text.starts_with('k')); + } + }) +} + +#[bench] +fn starts_with_str(b: &mut Bencher) { + let text = black_box("kdjsfhlakfhlsghlkvcnljknfqiunvcijqenwodind"); + b.iter(|| { + for _ in 0..1024 { + black_box(text.starts_with("k")); + } + }) +} + + +#[bench] +fn ends_with_char(b: &mut Bencher) { + let text = black_box("kdjsfhlakfhlsghlkvcnljknfqiunvcijqenwodind"); + b.iter(|| { + for _ in 0..1024 { + black_box(text.ends_with('k')); + } + }) +} + +#[bench] +fn ends_with_str(b: &mut Bencher) { + let text = black_box("kdjsfhlakfhlsghlkvcnljknfqiunvcijqenwodind"); + b.iter(|| { + for _ in 0..1024 { + black_box(text.ends_with("k")); + } + }) +} From 0a25a5799ce906eb76244cd7495a4a2a963e97d9 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Mon, 16 Dec 2019 16:23:07 -0500 Subject: [PATCH 16/22] Change the default thread count to min(4, vCPUs) This avoids the problems of high thread counts (i.e., contention in the kernel on the jobserver pipe due to thundering herd of readers) while stil giving rustc some parallelism to work with. --- src/librustc_session/config.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/librustc_session/config.rs b/src/librustc_session/config.rs index 7f3bab8f23299..359c8b3e73a90 100644 --- a/src/librustc_session/config.rs +++ b/src/librustc_session/config.rs @@ -1358,11 +1358,11 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options, "prints the LLVM optimization passes being run"), ast_json: bool = (false, parse_bool, [UNTRACKED], "print the AST as JSON and halt"), - // We default to 1 here since we want to behave like - // a sequential compiler for now. This'll likely be adjusted - // in the future. Note that -Zthreads=0 is the way to get - // the num_cpus behavior. - threads: usize = (1, parse_threads, [UNTRACKED], + // We default to min(4, vCPUs) here since we want to avoid spawning *too* + // many threads -- that causes scalability issues due to contention on + // the jobserver pipe (at least) -- but 4 is a reasonable amount on systems + // with lots of cores. + threads: usize = (std::cmp::min(::num_cpus::get(), 4), parse_threads, [UNTRACKED], "use a thread pool with N threads"), ast_json_noexpand: bool = (false, parse_bool, [UNTRACKED], "print the pre-expansion AST as JSON and halt"), From 20eed303a7874187a243756c720666af6fc2574a Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Mon, 16 Dec 2019 16:27:35 -0500 Subject: [PATCH 17/22] Always build and ship parallel-enabled compilers This also removes the unused NO_PARALLEL_COMPILER flag; if we want that functionality we can readd it but this makes sure we really are parallel everywhere. This also patches a test that has differing output in the parallel case (hopefully deterministically so!). --- src/ci/run.sh | 5 ++--- src/test/ui/traits/cycle-cache-err-60010.rs | 2 +- .../ui/traits/cycle-cache-err-60010.stderr | 18 +----------------- 3 files changed, 4 insertions(+), 21 deletions(-) diff --git a/src/ci/run.sh b/src/ci/run.sh index 38d1d2baf2507..4afd61bf8a7ba 100755 --- a/src/ci/run.sh +++ b/src/ci/run.sh @@ -37,6 +37,8 @@ if [ "$DIST_SRC" = "" ]; then RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --disable-dist-src" fi +RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --set rust.parallel-compiler" + # If we're deploying artifacts then we set the release channel, otherwise if # we're not deploying then we want to be sure to enable all assertions because # we'll be running tests @@ -53,9 +55,6 @@ if [ "$DEPLOY$DEPLOY_ALT" = "1" ]; then if [ "$NO_LLVM_ASSERTIONS" = "1" ]; then RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --disable-llvm-assertions" elif [ "$DEPLOY_ALT" != "" ]; then - if [ "$NO_PARALLEL_COMPILER" = "" ]; then - RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --set rust.parallel-compiler" - fi RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --enable-llvm-assertions" RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --set rust.verify-llvm-ir" fi diff --git a/src/test/ui/traits/cycle-cache-err-60010.rs b/src/test/ui/traits/cycle-cache-err-60010.rs index cbddef082be67..ebed4a02d0f33 100644 --- a/src/test/ui/traits/cycle-cache-err-60010.rs +++ b/src/test/ui/traits/cycle-cache-err-60010.rs @@ -28,7 +28,7 @@ struct SalsaStorage { } impl Database for RootDatabase { - type Storage = SalsaStorage; //~ ERROR overflow + type Storage = SalsaStorage; } impl HasQueryGroup for RootDatabase {} impl Query for ParseQuery diff --git a/src/test/ui/traits/cycle-cache-err-60010.stderr b/src/test/ui/traits/cycle-cache-err-60010.stderr index 295845b1146ef..2fc26bb11e3e3 100644 --- a/src/test/ui/traits/cycle-cache-err-60010.stderr +++ b/src/test/ui/traits/cycle-cache-err-60010.stderr @@ -6,22 +6,6 @@ LL | _parse: >::Data, | = note: required because of the requirements on the impl of `Query` for `ParseQuery` -error[E0275]: overflow evaluating the requirement `Runtime: std::panic::RefUnwindSafe` - --> $DIR/cycle-cache-err-60010.rs:31:5 - | -LL | type Storage; - | ------- associated type defined here -... -LL | impl Database for RootDatabase { - | ------------------------------ in this `impl` item -LL | type Storage = SalsaStorage; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: required because it appears within the type `RootDatabase` - = note: required because of the requirements on the impl of `SourceDatabase` for `RootDatabase` - = note: required because of the requirements on the impl of `Query` for `ParseQuery` - = note: required because it appears within the type `SalsaStorage` - -error: aborting due to 2 previous errors +error: aborting due to previous error For more information about this error, try `rustc --explain E0275`. From 496cc300faf46b7d43fcd44717fa06ad1663e904 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Tue, 17 Dec 2019 08:55:54 -0500 Subject: [PATCH 18/22] Move AtomicU64 usage to AtomicUsize --- src/librustc/dep_graph/graph.rs | 14 +++++++------- src/librustc_data_structures/lib.rs | 1 + src/librustc_data_structures/sync.rs | 4 +++- src/librustc_session/session.rs | 6 +++--- 4 files changed, 14 insertions(+), 11 deletions(-) diff --git a/src/librustc/dep_graph/graph.rs b/src/librustc/dep_graph/graph.rs index d952bf7ab9e25..aa7f4f2155dd1 100644 --- a/src/librustc/dep_graph/graph.rs +++ b/src/librustc/dep_graph/graph.rs @@ -3,7 +3,7 @@ use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_index::vec::{Idx, IndexVec}; use smallvec::SmallVec; -use rustc_data_structures::sync::{Lrc, Lock, AtomicU32, AtomicU64, Ordering}; +use rustc_data_structures::sync::{Lrc, Lock, AtomicU32, AtomicUsize, Ordering}; use rustc_data_structures::sharded::{self, Sharded}; use std::sync::atomic::Ordering::SeqCst; use std::env; @@ -485,8 +485,8 @@ impl DepGraph { if cfg!(debug_assertions) { let current_dep_graph = &self.data.as_ref().unwrap().current; - Some((current_dep_graph.total_read_count.load(SeqCst), - current_dep_graph.total_duplicate_read_count.load(SeqCst))) + Some((current_dep_graph.total_read_count.load(SeqCst) as u64, + current_dep_graph.total_duplicate_read_count.load(SeqCst) as u64)) } else { None } @@ -970,8 +970,8 @@ pub(super) struct CurrentDepGraph { /// These are simple counters that are for profiling and /// debugging and only active with `debug_assertions`. - total_read_count: AtomicU64, - total_duplicate_read_count: AtomicU64, + total_read_count: AtomicUsize, + total_duplicate_read_count: AtomicUsize, } impl CurrentDepGraph { @@ -1012,8 +1012,8 @@ impl CurrentDepGraph { )), anon_id_seed: stable_hasher.finish(), forbidden_edge, - total_read_count: AtomicU64::new(0), - total_duplicate_read_count: AtomicU64::new(0), + total_read_count: AtomicUsize::new(0), + total_duplicate_read_count: AtomicUsize::new(0), } } diff --git a/src/librustc_data_structures/lib.rs b/src/librustc_data_structures/lib.rs index fb541637e5f79..02611a36aaebc 100644 --- a/src/librustc_data_structures/lib.rs +++ b/src/librustc_data_structures/lib.rs @@ -24,6 +24,7 @@ #![feature(integer_atomics)] #![feature(test)] #![feature(associated_type_bounds)] +#![feature(cfg_target_has_atomic)] #![cfg_attr(unix, feature(libc))] diff --git a/src/librustc_data_structures/sync.rs b/src/librustc_data_structures/sync.rs index 6a19f52897e5d..c4aed0628ba42 100644 --- a/src/librustc_data_structures/sync.rs +++ b/src/librustc_data_structures/sync.rs @@ -317,7 +317,9 @@ cfg_if! { pub use parking_lot::MutexGuard as LockGuard; pub use parking_lot::MappedMutexGuard as MappedLockGuard; - pub use std::sync::atomic::{AtomicBool, AtomicUsize, AtomicU32, AtomicU64}; + pub use std::sync::atomic::{AtomicBool, AtomicUsize, AtomicU32}; + #[cfg(target_has_atomic = "64")] + pub use std::sync::atomic::{AtomicU64}; pub use crossbeam_utils::atomic::AtomicCell; diff --git a/src/librustc_session/session.rs b/src/librustc_session/session.rs index 150d207e5bfe9..4e72249aed129 100644 --- a/src/librustc_session/session.rs +++ b/src/librustc_session/session.rs @@ -14,7 +14,7 @@ use rustc_errors::ErrorReported; use rustc_data_structures::base_n; use rustc_data_structures::sync::{ - self, Lrc, Lock, OneThread, Once, AtomicU64, AtomicUsize, Ordering, + self, Lrc, Lock, OneThread, Once, AtomicUsize, Ordering, Ordering::SeqCst, }; use rustc_data_structures::impl_stable_hash_via_hash; @@ -119,7 +119,7 @@ pub struct Session { /// If `-zprint-fuel=crate`, `Some(crate)`. pub print_fuel_crate: Option, /// Always set to zero and incremented so that we can print fuel expended by a crate. - pub print_fuel: AtomicU64, + pub print_fuel: AtomicUsize, /// Loaded up early on in the initialization of this `Session` to avoid /// false positives about a job server in our environment. @@ -1116,7 +1116,7 @@ fn build_session_( out_of_fuel: false, }); let print_fuel_crate = sopts.debugging_opts.print_fuel.clone(); - let print_fuel = AtomicU64::new(0); + let print_fuel = AtomicUsize::new(0); let working_dir = env::current_dir().unwrap_or_else(|e| parse_sess.span_diagnostic From 8a6f726d035db56c3a1c15c51d467190c2db547e Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Tue, 17 Dec 2019 12:47:10 -0500 Subject: [PATCH 19/22] Disable cargo tests for now These depend on rustc being bug-free and it looks like that's not currently entirely the case (e.g., we know of at least one bug that introduces nondeterminism). --- src/bootstrap/test.rs | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs index f3b2a73d3c5dc..c086bf2cf402a 100644 --- a/src/bootstrap/test.rs +++ b/src/bootstrap/test.rs @@ -4,10 +4,10 @@ //! our CI. use std::env; -use std::ffi::OsString; +//use std::ffi::OsString; use std::fmt; use std::fs; -use std::iter; +//use std::iter; use std::path::{Path, PathBuf}; use std::process::Command; @@ -204,8 +204,8 @@ impl Step for Cargo { } /// Runs `cargo test` for `cargo` packaged with Rust. - fn run(self, builder: &Builder<'_>) { - let compiler = builder.compiler(self.stage, self.host); + fn run(self, _builder: &Builder<'_>) { + /*let compiler = builder.compiler(self.stage, self.host); builder.ensure(tool::Cargo { compiler, @@ -235,7 +235,7 @@ impl Step for Cargo { cargo.env("PATH", &path_for_cargo(builder, compiler)); - try_run(builder, &mut cargo.into()); + try_run(builder, &mut cargo.into());*/ } } @@ -590,14 +590,14 @@ impl Step for Clippy { } } -fn path_for_cargo(builder: &Builder<'_>, compiler: Compiler) -> OsString { - // Configure PATH to find the right rustc. NB. we have to use PATH - // and not RUSTC because the Cargo test suite has tests that will - // fail if rustc is not spelled `rustc`. - let path = builder.sysroot(compiler).join("bin"); - let old_path = env::var_os("PATH").unwrap_or_default(); - env::join_paths(iter::once(path).chain(env::split_paths(&old_path))).expect("") -} +//fn path_for_cargo(builder: &Builder<'_>, compiler: Compiler) -> OsString { +// // Configure PATH to find the right rustc. NB. we have to use PATH +// // and not RUSTC because the Cargo test suite has tests that will +// // fail if rustc is not spelled `rustc`. +// let path = builder.sysroot(compiler).join("bin"); +// let old_path = env::var_os("PATH").unwrap_or_default(); +// env::join_paths(iter::once(path).chain(env::split_paths(&old_path))).expect("") +//} #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] pub struct RustdocTheme { From 2b3259e5161b38893345a3e95ad7fad98dab096c Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Tue, 17 Dec 2019 16:28:33 -0500 Subject: [PATCH 20/22] Revert "Auto merge of #67362 - Mark-Simulacrum:par-4-default, r=alexcrichton" This reverts commit 3ed3b8bb7b100afecf7d5f52eafbb70fec27f537, reversing changes made to 99b89533d4cdf7682ea4054ad0ee36c351d05df1. We will reland a similar patch at a future date but for now we should get a nightly released in a few hours with the parallel patch, so this should be reverted to make sure that the next nightly is not parallel-enabled. --- src/bootstrap/test.rs | 26 +++++++++---------- src/ci/run.sh | 5 ++-- src/librustc/dep_graph/graph.rs | 14 +++++----- src/librustc_data_structures/lib.rs | 1 - src/librustc_data_structures/sync.rs | 4 +-- src/librustc_session/config.rs | 10 +++---- src/librustc_session/session.rs | 6 ++--- src/test/ui/traits/cycle-cache-err-60010.rs | 2 +- .../ui/traits/cycle-cache-err-60010.stderr | 18 ++++++++++++- 9 files changed, 50 insertions(+), 36 deletions(-) diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs index c086bf2cf402a..f3b2a73d3c5dc 100644 --- a/src/bootstrap/test.rs +++ b/src/bootstrap/test.rs @@ -4,10 +4,10 @@ //! our CI. use std::env; -//use std::ffi::OsString; +use std::ffi::OsString; use std::fmt; use std::fs; -//use std::iter; +use std::iter; use std::path::{Path, PathBuf}; use std::process::Command; @@ -204,8 +204,8 @@ impl Step for Cargo { } /// Runs `cargo test` for `cargo` packaged with Rust. - fn run(self, _builder: &Builder<'_>) { - /*let compiler = builder.compiler(self.stage, self.host); + fn run(self, builder: &Builder<'_>) { + let compiler = builder.compiler(self.stage, self.host); builder.ensure(tool::Cargo { compiler, @@ -235,7 +235,7 @@ impl Step for Cargo { cargo.env("PATH", &path_for_cargo(builder, compiler)); - try_run(builder, &mut cargo.into());*/ + try_run(builder, &mut cargo.into()); } } @@ -590,14 +590,14 @@ impl Step for Clippy { } } -//fn path_for_cargo(builder: &Builder<'_>, compiler: Compiler) -> OsString { -// // Configure PATH to find the right rustc. NB. we have to use PATH -// // and not RUSTC because the Cargo test suite has tests that will -// // fail if rustc is not spelled `rustc`. -// let path = builder.sysroot(compiler).join("bin"); -// let old_path = env::var_os("PATH").unwrap_or_default(); -// env::join_paths(iter::once(path).chain(env::split_paths(&old_path))).expect("") -//} +fn path_for_cargo(builder: &Builder<'_>, compiler: Compiler) -> OsString { + // Configure PATH to find the right rustc. NB. we have to use PATH + // and not RUSTC because the Cargo test suite has tests that will + // fail if rustc is not spelled `rustc`. + let path = builder.sysroot(compiler).join("bin"); + let old_path = env::var_os("PATH").unwrap_or_default(); + env::join_paths(iter::once(path).chain(env::split_paths(&old_path))).expect("") +} #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] pub struct RustdocTheme { diff --git a/src/ci/run.sh b/src/ci/run.sh index 4afd61bf8a7ba..38d1d2baf2507 100755 --- a/src/ci/run.sh +++ b/src/ci/run.sh @@ -37,8 +37,6 @@ if [ "$DIST_SRC" = "" ]; then RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --disable-dist-src" fi -RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --set rust.parallel-compiler" - # If we're deploying artifacts then we set the release channel, otherwise if # we're not deploying then we want to be sure to enable all assertions because # we'll be running tests @@ -55,6 +53,9 @@ if [ "$DEPLOY$DEPLOY_ALT" = "1" ]; then if [ "$NO_LLVM_ASSERTIONS" = "1" ]; then RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --disable-llvm-assertions" elif [ "$DEPLOY_ALT" != "" ]; then + if [ "$NO_PARALLEL_COMPILER" = "" ]; then + RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --set rust.parallel-compiler" + fi RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --enable-llvm-assertions" RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --set rust.verify-llvm-ir" fi diff --git a/src/librustc/dep_graph/graph.rs b/src/librustc/dep_graph/graph.rs index aa7f4f2155dd1..d952bf7ab9e25 100644 --- a/src/librustc/dep_graph/graph.rs +++ b/src/librustc/dep_graph/graph.rs @@ -3,7 +3,7 @@ use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_index::vec::{Idx, IndexVec}; use smallvec::SmallVec; -use rustc_data_structures::sync::{Lrc, Lock, AtomicU32, AtomicUsize, Ordering}; +use rustc_data_structures::sync::{Lrc, Lock, AtomicU32, AtomicU64, Ordering}; use rustc_data_structures::sharded::{self, Sharded}; use std::sync::atomic::Ordering::SeqCst; use std::env; @@ -485,8 +485,8 @@ impl DepGraph { if cfg!(debug_assertions) { let current_dep_graph = &self.data.as_ref().unwrap().current; - Some((current_dep_graph.total_read_count.load(SeqCst) as u64, - current_dep_graph.total_duplicate_read_count.load(SeqCst) as u64)) + Some((current_dep_graph.total_read_count.load(SeqCst), + current_dep_graph.total_duplicate_read_count.load(SeqCst))) } else { None } @@ -970,8 +970,8 @@ pub(super) struct CurrentDepGraph { /// These are simple counters that are for profiling and /// debugging and only active with `debug_assertions`. - total_read_count: AtomicUsize, - total_duplicate_read_count: AtomicUsize, + total_read_count: AtomicU64, + total_duplicate_read_count: AtomicU64, } impl CurrentDepGraph { @@ -1012,8 +1012,8 @@ impl CurrentDepGraph { )), anon_id_seed: stable_hasher.finish(), forbidden_edge, - total_read_count: AtomicUsize::new(0), - total_duplicate_read_count: AtomicUsize::new(0), + total_read_count: AtomicU64::new(0), + total_duplicate_read_count: AtomicU64::new(0), } } diff --git a/src/librustc_data_structures/lib.rs b/src/librustc_data_structures/lib.rs index 02611a36aaebc..fb541637e5f79 100644 --- a/src/librustc_data_structures/lib.rs +++ b/src/librustc_data_structures/lib.rs @@ -24,7 +24,6 @@ #![feature(integer_atomics)] #![feature(test)] #![feature(associated_type_bounds)] -#![feature(cfg_target_has_atomic)] #![cfg_attr(unix, feature(libc))] diff --git a/src/librustc_data_structures/sync.rs b/src/librustc_data_structures/sync.rs index c4aed0628ba42..6a19f52897e5d 100644 --- a/src/librustc_data_structures/sync.rs +++ b/src/librustc_data_structures/sync.rs @@ -317,9 +317,7 @@ cfg_if! { pub use parking_lot::MutexGuard as LockGuard; pub use parking_lot::MappedMutexGuard as MappedLockGuard; - pub use std::sync::atomic::{AtomicBool, AtomicUsize, AtomicU32}; - #[cfg(target_has_atomic = "64")] - pub use std::sync::atomic::{AtomicU64}; + pub use std::sync::atomic::{AtomicBool, AtomicUsize, AtomicU32, AtomicU64}; pub use crossbeam_utils::atomic::AtomicCell; diff --git a/src/librustc_session/config.rs b/src/librustc_session/config.rs index 359c8b3e73a90..7f3bab8f23299 100644 --- a/src/librustc_session/config.rs +++ b/src/librustc_session/config.rs @@ -1358,11 +1358,11 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options, "prints the LLVM optimization passes being run"), ast_json: bool = (false, parse_bool, [UNTRACKED], "print the AST as JSON and halt"), - // We default to min(4, vCPUs) here since we want to avoid spawning *too* - // many threads -- that causes scalability issues due to contention on - // the jobserver pipe (at least) -- but 4 is a reasonable amount on systems - // with lots of cores. - threads: usize = (std::cmp::min(::num_cpus::get(), 4), parse_threads, [UNTRACKED], + // We default to 1 here since we want to behave like + // a sequential compiler for now. This'll likely be adjusted + // in the future. Note that -Zthreads=0 is the way to get + // the num_cpus behavior. + threads: usize = (1, parse_threads, [UNTRACKED], "use a thread pool with N threads"), ast_json_noexpand: bool = (false, parse_bool, [UNTRACKED], "print the pre-expansion AST as JSON and halt"), diff --git a/src/librustc_session/session.rs b/src/librustc_session/session.rs index 4e72249aed129..150d207e5bfe9 100644 --- a/src/librustc_session/session.rs +++ b/src/librustc_session/session.rs @@ -14,7 +14,7 @@ use rustc_errors::ErrorReported; use rustc_data_structures::base_n; use rustc_data_structures::sync::{ - self, Lrc, Lock, OneThread, Once, AtomicUsize, Ordering, + self, Lrc, Lock, OneThread, Once, AtomicU64, AtomicUsize, Ordering, Ordering::SeqCst, }; use rustc_data_structures::impl_stable_hash_via_hash; @@ -119,7 +119,7 @@ pub struct Session { /// If `-zprint-fuel=crate`, `Some(crate)`. pub print_fuel_crate: Option, /// Always set to zero and incremented so that we can print fuel expended by a crate. - pub print_fuel: AtomicUsize, + pub print_fuel: AtomicU64, /// Loaded up early on in the initialization of this `Session` to avoid /// false positives about a job server in our environment. @@ -1116,7 +1116,7 @@ fn build_session_( out_of_fuel: false, }); let print_fuel_crate = sopts.debugging_opts.print_fuel.clone(); - let print_fuel = AtomicUsize::new(0); + let print_fuel = AtomicU64::new(0); let working_dir = env::current_dir().unwrap_or_else(|e| parse_sess.span_diagnostic diff --git a/src/test/ui/traits/cycle-cache-err-60010.rs b/src/test/ui/traits/cycle-cache-err-60010.rs index ebed4a02d0f33..cbddef082be67 100644 --- a/src/test/ui/traits/cycle-cache-err-60010.rs +++ b/src/test/ui/traits/cycle-cache-err-60010.rs @@ -28,7 +28,7 @@ struct SalsaStorage { } impl Database for RootDatabase { - type Storage = SalsaStorage; + type Storage = SalsaStorage; //~ ERROR overflow } impl HasQueryGroup for RootDatabase {} impl Query for ParseQuery diff --git a/src/test/ui/traits/cycle-cache-err-60010.stderr b/src/test/ui/traits/cycle-cache-err-60010.stderr index 2fc26bb11e3e3..295845b1146ef 100644 --- a/src/test/ui/traits/cycle-cache-err-60010.stderr +++ b/src/test/ui/traits/cycle-cache-err-60010.stderr @@ -6,6 +6,22 @@ LL | _parse: >::Data, | = note: required because of the requirements on the impl of `Query` for `ParseQuery` -error: aborting due to previous error +error[E0275]: overflow evaluating the requirement `Runtime: std::panic::RefUnwindSafe` + --> $DIR/cycle-cache-err-60010.rs:31:5 + | +LL | type Storage; + | ------- associated type defined here +... +LL | impl Database for RootDatabase { + | ------------------------------ in this `impl` item +LL | type Storage = SalsaStorage; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: required because it appears within the type `RootDatabase` + = note: required because of the requirements on the impl of `SourceDatabase` for `RootDatabase` + = note: required because of the requirements on the impl of `Query` for `ParseQuery` + = note: required because it appears within the type `SalsaStorage` + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0275`. From 8e61952b2acd5d22ab5c3160bcf6645fe33611ac Mon Sep 17 00:00:00 2001 From: vivekvpandya Date: Tue, 17 Dec 2019 22:16:01 +0530 Subject: [PATCH 21/22] Remove LLVMRustGetLinkage --- src/librustc_codegen_llvm/back/write.rs | 2 +- src/librustc_codegen_llvm/consts.rs | 2 +- src/librustc_codegen_llvm/llvm/ffi.rs | 2 +- src/rustllvm/RustWrapper.cpp | 33 ------------------------- 4 files changed, 3 insertions(+), 36 deletions(-) diff --git a/src/librustc_codegen_llvm/back/write.rs b/src/librustc_codegen_llvm/back/write.rs index 796ea7aac36a2..d30fad2b9ce57 100644 --- a/src/librustc_codegen_llvm/back/write.rs +++ b/src/librustc_codegen_llvm/back/write.rs @@ -830,7 +830,7 @@ fn create_msvc_imps( let i8p_ty = Type::i8p_llcx(llcx); let globals = base::iter_globals(llmod) .filter(|&val| { - llvm::LLVMRustGetLinkage(val) == llvm::Linkage::ExternalLinkage && + llvm::LLVMGetLinkage(val) == llvm::Linkage::ExternalLinkage && llvm::LLVMIsDeclaration(val) == 0 }) .filter_map(|val| { diff --git a/src/librustc_codegen_llvm/consts.rs b/src/librustc_codegen_llvm/consts.rs index 11a105c1828ca..2cf3eeabf3d3c 100644 --- a/src/librustc_codegen_llvm/consts.rs +++ b/src/librustc_codegen_llvm/consts.rs @@ -397,7 +397,7 @@ impl StaticMethods for CodegenCx<'ll, 'tcx> { let name = llvm::get_value_name(g).to_vec(); llvm::set_value_name(g, b""); - let linkage = llvm::LLVMRustGetLinkage(g); + let linkage = llvm::LLVMGetLinkage(g); let visibility = llvm::LLVMRustGetVisibility(g); let new_g = llvm::LLVMRustGetOrInsertGlobal( diff --git a/src/librustc_codegen_llvm/llvm/ffi.rs b/src/librustc_codegen_llvm/llvm/ffi.rs index 63d1edb93a87f..eab667042532d 100644 --- a/src/librustc_codegen_llvm/llvm/ffi.rs +++ b/src/librustc_codegen_llvm/llvm/ffi.rs @@ -761,7 +761,7 @@ extern "C" { // Operations on global variables, functions, and aliases (globals) pub fn LLVMIsDeclaration(Global: &Value) -> Bool; - pub fn LLVMRustGetLinkage(Global: &Value) -> Linkage; + pub fn LLVMGetLinkage(Global: &Value) -> Linkage; pub fn LLVMRustSetLinkage(Global: &Value, RustLinkage: Linkage); pub fn LLVMSetSection(Global: &Value, Section: *const c_char); pub fn LLVMRustGetVisibility(Global: &Value) -> Visibility; diff --git a/src/rustllvm/RustWrapper.cpp b/src/rustllvm/RustWrapper.cpp index 4de4a433f341c..0ceac59ddd2b1 100644 --- a/src/rustllvm/RustWrapper.cpp +++ b/src/rustllvm/RustWrapper.cpp @@ -1267,35 +1267,6 @@ enum class LLVMRustLinkage { CommonLinkage = 10, }; -static LLVMRustLinkage toRust(LLVMLinkage Linkage) { - switch (Linkage) { - case LLVMExternalLinkage: - return LLVMRustLinkage::ExternalLinkage; - case LLVMAvailableExternallyLinkage: - return LLVMRustLinkage::AvailableExternallyLinkage; - case LLVMLinkOnceAnyLinkage: - return LLVMRustLinkage::LinkOnceAnyLinkage; - case LLVMLinkOnceODRLinkage: - return LLVMRustLinkage::LinkOnceODRLinkage; - case LLVMWeakAnyLinkage: - return LLVMRustLinkage::WeakAnyLinkage; - case LLVMWeakODRLinkage: - return LLVMRustLinkage::WeakODRLinkage; - case LLVMAppendingLinkage: - return LLVMRustLinkage::AppendingLinkage; - case LLVMInternalLinkage: - return LLVMRustLinkage::InternalLinkage; - case LLVMPrivateLinkage: - return LLVMRustLinkage::PrivateLinkage; - case LLVMExternalWeakLinkage: - return LLVMRustLinkage::ExternalWeakLinkage; - case LLVMCommonLinkage: - return LLVMRustLinkage::CommonLinkage; - default: - report_fatal_error("Invalid LLVMRustLinkage value!"); - } -} - static LLVMLinkage fromRust(LLVMRustLinkage Linkage) { switch (Linkage) { case LLVMRustLinkage::ExternalLinkage: @@ -1324,10 +1295,6 @@ static LLVMLinkage fromRust(LLVMRustLinkage Linkage) { report_fatal_error("Invalid LLVMRustLinkage value!"); } -extern "C" LLVMRustLinkage LLVMRustGetLinkage(LLVMValueRef V) { - return toRust(LLVMGetLinkage(V)); -} - extern "C" void LLVMRustSetLinkage(LLVMValueRef V, LLVMRustLinkage RustLinkage) { LLVMSetLinkage(V, fromRust(RustLinkage)); From 6c5868354210c40ab9b7e8b1c5abc0ba9f34ca63 Mon Sep 17 00:00:00 2001 From: vivekvpandya Date: Wed, 18 Dec 2019 21:07:51 +0530 Subject: [PATCH 22/22] Remove LLVMRustAddHandler() instead use LLVMAddHandler() --- src/librustc_codegen_llvm/builder.rs | 2 +- src/librustc_codegen_llvm/llvm/ffi.rs | 2 +- src/rustllvm/RustWrapper.cpp | 6 ------ 3 files changed, 2 insertions(+), 8 deletions(-) diff --git a/src/librustc_codegen_llvm/builder.rs b/src/librustc_codegen_llvm/builder.rs index 80a5b150a1383..b4d56413905db 100644 --- a/src/librustc_codegen_llvm/builder.rs +++ b/src/librustc_codegen_llvm/builder.rs @@ -937,7 +937,7 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { fn add_handler(&mut self, catch_switch: &'ll Value, handler: &'ll BasicBlock) { unsafe { - llvm::LLVMRustAddHandler(catch_switch, handler); + llvm::LLVMAddHandler(catch_switch, handler); } } diff --git a/src/librustc_codegen_llvm/llvm/ffi.rs b/src/librustc_codegen_llvm/llvm/ffi.rs index eab667042532d..288c6d09d6ab4 100644 --- a/src/librustc_codegen_llvm/llvm/ffi.rs +++ b/src/librustc_codegen_llvm/llvm/ffi.rs @@ -913,7 +913,7 @@ extern "C" { NumHandlers: c_uint, Name: *const c_char) -> Option<&'a Value>; - pub fn LLVMRustAddHandler(CatchSwitch: &'a Value, Handler: &'a BasicBlock); + pub fn LLVMAddHandler(CatchSwitch: &'a Value, Handler: &'a BasicBlock); pub fn LLVMSetPersonalityFn(Func: &'a Value, Pers: &'a Value); // Add a case to the switch instruction diff --git a/src/rustllvm/RustWrapper.cpp b/src/rustllvm/RustWrapper.cpp index 0ceac59ddd2b1..432f707b4cbef 100644 --- a/src/rustllvm/RustWrapper.cpp +++ b/src/rustllvm/RustWrapper.cpp @@ -1174,12 +1174,6 @@ extern "C" void LLVMRustWriteSMDiagnosticToString(LLVMSMDiagnosticRef D, unwrap(D)->print("", OS); } -extern "C" void LLVMRustAddHandler(LLVMValueRef CatchSwitchRef, - LLVMBasicBlockRef Handler) { - Value *CatchSwitch = unwrap(CatchSwitchRef); - cast(CatchSwitch)->addHandler(unwrap(Handler)); -} - extern "C" OperandBundleDef *LLVMRustBuildOperandBundleDef(const char *Name, LLVMValueRef *Inputs, unsigned NumInputs) {