From 32d07cc2fc23e7cfa8b23a495e6667bcc7cf643a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Kr=C3=BCger?= Date: Fri, 26 Oct 2018 16:23:02 +0200 Subject: [PATCH 01/50] bootstrap: be more explicit on what we collect into. NFC --- src/bootstrap/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs index ba601249ea895..957ebd2540ad9 100644 --- a/src/bootstrap/lib.rs +++ b/src/bootstrap/lib.rs @@ -783,10 +783,10 @@ impl Build { fn cflags(&self, target: Interned, which: GitRepo) -> Vec { // Filter out -O and /O (the optimization flags) that we picked up from // cc-rs because the build scripts will determine that for themselves. - let mut base: Vec = self.cc[&target].args().iter() + let mut base = self.cc[&target].args().iter() .map(|s| s.to_string_lossy().into_owned()) .filter(|s| !s.starts_with("-O") && !s.starts_with("/O")) - .collect::>(); + .collect::>(); // If we're compiling on macOS then we add a few unconditional flags // indicating that we want libc++ (more filled out than libstdc++) and From cc63bd47efe4387982b399e2397adab6ac4030ef Mon Sep 17 00:00:00 2001 From: Michal 'vorner' Vaner Date: Sat, 17 Nov 2018 14:48:18 +0100 Subject: [PATCH 02/50] atomic::Ordering: Get rid of misleading parts of intro Remove the parts of atomic::Ordering's intro that wrongly claimed that SeqCst prevents all reorderings around it. Closes #55196 --- src/libcore/sync/atomic.rs | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/libcore/sync/atomic.rs b/src/libcore/sync/atomic.rs index 56d3b429fdb44..27eeb045bb196 100644 --- a/src/libcore/sync/atomic.rs +++ b/src/libcore/sync/atomic.rs @@ -173,11 +173,11 @@ unsafe impl Sync for AtomicPtr {} /// Atomic memory orderings /// -/// Memory orderings limit the ways that both the compiler and CPU may reorder -/// instructions around atomic operations. At its most restrictive, -/// "sequentially consistent" atomics allow neither reads nor writes -/// to be moved either before or after the atomic operation; on the other end -/// "relaxed" atomics allow all reorderings. +/// Memory orderings specify the way atomic operations synchronize memory. +/// In its weakest [`Relaxed`][Ordering::Relaxed], only the memory directly touched by the +/// operation is synchronized. On the other hand, a store-load pair of [`SeqCst`][Ordering::SeqCst] +/// operations synchronize other memory while additionally preserving a total order of such +/// operations across all threads. /// /// Rust's memory orderings are [the same as /// LLVM's](https://llvm.org/docs/LangRef.html#memory-model-for-concurrent-operations). @@ -185,6 +185,8 @@ unsafe impl Sync for AtomicPtr {} /// For more information see the [nomicon]. /// /// [nomicon]: ../../../nomicon/atomics.html +/// [Ordering::Relaxed]: #variant.Relaxed +/// [Ordering::SeqCst]: #variant.SeqCst #[stable(feature = "rust1", since = "1.0.0")] #[derive(Copy, Clone, Debug)] #[non_exhaustive] @@ -234,8 +236,8 @@ pub enum Ordering { /// For loads it uses [`Acquire`] ordering. For stores it uses the [`Release`] ordering. /// /// Notice that in the case of `compare_and_swap`, it is possible that the operation ends up - /// not performing any store and hence it has just `Acquire` ordering. However, - /// `AcqRel` will never perform [`Relaxed`] accesses. + /// not performing any store and hence it has just [`Acquire`] ordering. However, + /// [`AcqRel`][`AcquireRelease`] will never perform [`Relaxed`] accesses. /// /// This ordering is only applicable for operations that combine both loads and stores. /// From 7dc0dd292ba31681f35c62af6cc0f641761f36b1 Mon Sep 17 00:00:00 2001 From: Matthew Jasper Date: Sun, 18 Nov 2018 14:49:24 +0000 Subject: [PATCH 03/50] Drop function parameters in expected order Given the function fn foo((_x, _): (LogDrop, LogDrop), (_, _y): (LogDrop, LogDrop)) {} Prior to 1.12 we dropped both `_x` and `_y` before the rest of their respective parameters, since then we dropped `_x` and `_y` after. The original order appears to be the correct order, as the value created later is dropped first, so we revert to that order and add a test for it. --- src/librustc_mir/build/mod.rs | 14 ++--- .../fn-arg-incomplete-pattern-drop-order.rs | 54 +++++++++++++++++++ 2 files changed, 61 insertions(+), 7 deletions(-) create mode 100644 src/test/run-pass/binding/fn-arg-incomplete-pattern-drop-order.rs diff --git a/src/librustc_mir/build/mod.rs b/src/librustc_mir/build/mod.rs index a01f8940a948a..a123f97efa832 100644 --- a/src/librustc_mir/build/mod.rs +++ b/src/librustc_mir/build/mod.rs @@ -915,6 +915,13 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { let place = Place::Local(local); let &ArgInfo(ty, opt_ty_info, pattern, ref self_binding) = arg_info; + // Make sure we drop (parts of) the argument even when not matched on. + self.schedule_drop( + pattern.as_ref().map_or(ast_body.span, |pat| pat.span), + argument_scope, &place, ty, + DropKind::Value { cached_block: CachedBlock::default() }, + ); + if let Some(pattern) = pattern { let pattern = self.hir.pattern_from_hir(pattern); let span = pattern.span; @@ -946,13 +953,6 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { } } } - - // Make sure we drop (parts of) the argument even when not matched on. - self.schedule_drop( - pattern.as_ref().map_or(ast_body.span, |pat| pat.span), - argument_scope, &place, ty, - DropKind::Value { cached_block: CachedBlock::default() }, - ); } // Enter the argument pattern bindings source scope, if it exists. diff --git a/src/test/run-pass/binding/fn-arg-incomplete-pattern-drop-order.rs b/src/test/run-pass/binding/fn-arg-incomplete-pattern-drop-order.rs new file mode 100644 index 0000000000000..41e0750000146 --- /dev/null +++ b/src/test/run-pass/binding/fn-arg-incomplete-pattern-drop-order.rs @@ -0,0 +1,54 @@ +// Check that partially moved from function parameters are dropped after the +// named bindings that move from them. + +use std::{panic, cell::RefCell}; + +struct LogDrop<'a>(i32, Context<'a>); + +#[derive(Copy, Clone)] +struct Context<'a> { + panic_on: i32, + drops: &'a RefCell>, +} + +impl<'a> Context<'a> { + fn record_drop(self, index: i32) { + self.drops.borrow_mut().push(index); + if index == self.panic_on { + panic!(); + } + } +} + +impl<'a> Drop for LogDrop<'a> { + fn drop(&mut self) { + self.1.record_drop(self.0); + } +} + +fn foo((_x, _): (LogDrop, LogDrop), (_, _y): (LogDrop, LogDrop)) {} + +fn test_drop_order(panic_on: i32) { + let context = Context { + panic_on, + drops: &RefCell::new(Vec::new()), + }; + let one = LogDrop(1, context); + let two = LogDrop(2, context); + let three = LogDrop(3, context); + let four = LogDrop(4, context); + + let res = panic::catch_unwind(panic::AssertUnwindSafe(|| { + foo((three, four), (two, one)); + })); + if panic_on == 0 { + assert!(res.is_ok(), "should not have panicked"); + } else { + assert!(res.is_err(), "should have panicked"); + } + assert_eq!(*context.drops.borrow(), [1, 2, 3, 4], "incorrect drop order"); +} + +fn main() { + (0..=4).for_each(test_drop_order); +} From 28cc944530420bb3b1fc2dc96e2a8f433a41c6e4 Mon Sep 17 00:00:00 2001 From: Who? Me?! Date: Mon, 19 Nov 2018 15:50:24 -0600 Subject: [PATCH 04/50] Reduce the amount of bold text at doc.rust-lang.org --- src/doc/index.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/doc/index.md b/src/doc/index.md index 33ee76739c5b2..b79a349a453b6 100644 --- a/src/doc/index.md +++ b/src/doc/index.md @@ -21,6 +21,9 @@ nav { #search-but:hover, #search-input:focus { border-color: #55a9ff; } +h2 { + font-size: 18px; +} Welcome to an overview of the documentation provided by the Rust project. From 6674db48872c1b84fe3ac3feb94b8d3e0ee82b24 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 20 Nov 2018 20:16:57 +1100 Subject: [PATCH 05/50] Reuse the `P` in `InvocationCollector::fold_{,opt_}expr`. This requires adding a new method, `P::filter_map`. This commit reduces instruction counts for various benchmarks by up to 0.7%. --- src/libsyntax/ext/expand.rs | 84 +++++++++++++++++++++---------------- src/libsyntax/ptr.rs | 28 +++++++++++-- 2 files changed, 73 insertions(+), 39 deletions(-) diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index cc8af70a050c9..68a96293891a0 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -1201,50 +1201,62 @@ impl<'a, 'b> InvocationCollector<'a, 'b> { impl<'a, 'b> Folder for InvocationCollector<'a, 'b> { fn fold_expr(&mut self, expr: P) -> P { - let mut expr = self.cfg.configure_expr(expr).into_inner(); - expr.node = self.cfg.configure_expr_kind(expr.node); - - // ignore derives so they remain unused - let (attr, expr, after_derive) = self.classify_nonitem(expr); - - if attr.is_some() { - // collect the invoc regardless of whether or not attributes are permitted here - // expansion will eat the attribute so it won't error later - attr.as_ref().map(|a| self.cfg.maybe_emit_expr_attr_err(a)); - - // AstFragmentKind::Expr requires the macro to emit an expression - return self.collect_attr(attr, vec![], Annotatable::Expr(P(expr)), - AstFragmentKind::Expr, after_derive).make_expr(); - } + let expr = self.cfg.configure_expr(expr); + expr.map(|mut expr| { + expr.node = self.cfg.configure_expr_kind(expr.node); + + // ignore derives so they remain unused + let (attr, expr, after_derive) = self.classify_nonitem(expr); + + if attr.is_some() { + // Collect the invoc regardless of whether or not attributes are permitted here + // expansion will eat the attribute so it won't error later. + attr.as_ref().map(|a| self.cfg.maybe_emit_expr_attr_err(a)); + + // AstFragmentKind::Expr requires the macro to emit an expression. + return self.collect_attr(attr, vec![], Annotatable::Expr(P(expr)), + AstFragmentKind::Expr, after_derive) + .make_expr() + .into_inner() + } - if let ast::ExprKind::Mac(mac) = expr.node { - self.check_attributes(&expr.attrs); - self.collect_bang(mac, expr.span, AstFragmentKind::Expr).make_expr() - } else { - P(noop_fold_expr(expr, self)) - } + if let ast::ExprKind::Mac(mac) = expr.node { + self.check_attributes(&expr.attrs); + self.collect_bang(mac, expr.span, AstFragmentKind::Expr) + .make_expr() + .into_inner() + } else { + noop_fold_expr(expr, self) + } + }) } fn fold_opt_expr(&mut self, expr: P) -> Option> { - let mut expr = configure!(self, expr).into_inner(); - expr.node = self.cfg.configure_expr_kind(expr.node); + let expr = configure!(self, expr); + expr.filter_map(|mut expr| { + expr.node = self.cfg.configure_expr_kind(expr.node); - // ignore derives so they remain unused - let (attr, expr, after_derive) = self.classify_nonitem(expr); + // Ignore derives so they remain unused. + let (attr, expr, after_derive) = self.classify_nonitem(expr); - if attr.is_some() { - attr.as_ref().map(|a| self.cfg.maybe_emit_expr_attr_err(a)); + if attr.is_some() { + attr.as_ref().map(|a| self.cfg.maybe_emit_expr_attr_err(a)); - return self.collect_attr(attr, vec![], Annotatable::Expr(P(expr)), - AstFragmentKind::OptExpr, after_derive).make_opt_expr(); - } + return self.collect_attr(attr, vec![], Annotatable::Expr(P(expr)), + AstFragmentKind::OptExpr, after_derive) + .make_opt_expr() + .map(|expr| expr.into_inner()) + } - if let ast::ExprKind::Mac(mac) = expr.node { - self.check_attributes(&expr.attrs); - self.collect_bang(mac, expr.span, AstFragmentKind::OptExpr).make_opt_expr() - } else { - Some(P(noop_fold_expr(expr, self))) - } + if let ast::ExprKind::Mac(mac) = expr.node { + self.check_attributes(&expr.attrs); + self.collect_bang(mac, expr.span, AstFragmentKind::OptExpr) + .make_opt_expr() + .map(|expr| expr.into_inner()) + } else { + Some(noop_fold_expr(expr, self)) + } + }) } fn fold_pat(&mut self, pat: P) -> P { diff --git a/src/libsyntax/ptr.rs b/src/libsyntax/ptr.rs index bb47d9b535bef..9fbc64758da4d 100644 --- a/src/libsyntax/ptr.rs +++ b/src/libsyntax/ptr.rs @@ -72,7 +72,7 @@ impl P { *self.ptr } - /// Transform the inner value, consuming `self` and producing a new `P`. + /// Produce a new `P` from `self` without reallocating. pub fn map(mut self, f: F) -> P where F: FnOnce(T) -> T, { @@ -88,8 +88,30 @@ impl P { ptr::write(p, f(ptr::read(p))); // Recreate self from the raw pointer. - P { - ptr: Box::from_raw(p) + P { ptr: Box::from_raw(p) } + } + } + + /// Optionally produce a new `P` from `self` without reallocating. + pub fn filter_map(mut self, f: F) -> Option> where + F: FnOnce(T) -> Option, + { + let p: *mut T = &mut *self.ptr; + + // Leak self in case of panic. + // FIXME(eddyb) Use some sort of "free guard" that + // only deallocates, without dropping the pointee, + // in case the call the `f` below ends in a panic. + mem::forget(self); + + unsafe { + if let Some(v) = f(ptr::read(p)) { + ptr::write(p, v); + + // Recreate self from the raw pointer. + Some(P { ptr: Box::from_raw(p) }) + } else { + None } } } From b99f9f775c59de7223e810b303e56b39f7bbaf03 Mon Sep 17 00:00:00 2001 From: varkor Date: Tue, 20 Nov 2018 21:48:13 +0000 Subject: [PATCH 06/50] Enclose type in backticks for "non-exhaustive patterns" error This makes the error style consistent with the convention in error messages. --- src/librustc_mir/hair/pattern/check_match.rs | 2 +- src/test/ui/error-codes/E0004-2.stderr | 2 +- src/test/ui/issues/issue-3096-1.stderr | 2 +- src/test/ui/issues/issue-3096-2.stderr | 2 +- .../ui/uninhabited/uninhabited-matches-feature-gated.stderr | 6 +++--- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/librustc_mir/hair/pattern/check_match.rs b/src/librustc_mir/hair/pattern/check_match.rs index bafabe4e9972c..a6bd36e582fcd 100644 --- a/src/librustc_mir/hair/pattern/check_match.rs +++ b/src/librustc_mir/hair/pattern/check_match.rs @@ -234,7 +234,7 @@ impl<'a, 'tcx> MatchVisitor<'a, 'tcx> { if !scrutinee_is_uninhabited { // We know the type is inhabited, so this must be wrong let mut err = create_e0004(self.tcx.sess, scrut.span, - format!("non-exhaustive patterns: type {} \ + format!("non-exhaustive patterns: type `{}` \ is non-empty", pat_ty)); span_help!(&mut err, scrut.span, diff --git a/src/test/ui/error-codes/E0004-2.stderr b/src/test/ui/error-codes/E0004-2.stderr index 900812787bcf7..2d46196ddda55 100644 --- a/src/test/ui/error-codes/E0004-2.stderr +++ b/src/test/ui/error-codes/E0004-2.stderr @@ -1,4 +1,4 @@ -error[E0004]: non-exhaustive patterns: type std::option::Option is non-empty +error[E0004]: non-exhaustive patterns: type `std::option::Option` is non-empty --> $DIR/E0004-2.rs:14:11 | LL | match x { } //~ ERROR E0004 diff --git a/src/test/ui/issues/issue-3096-1.stderr b/src/test/ui/issues/issue-3096-1.stderr index b2bfe6b5e8c07..f0782bd973805 100644 --- a/src/test/ui/issues/issue-3096-1.stderr +++ b/src/test/ui/issues/issue-3096-1.stderr @@ -1,4 +1,4 @@ -error[E0004]: non-exhaustive patterns: type () is non-empty +error[E0004]: non-exhaustive patterns: type `()` is non-empty --> $DIR/issue-3096-1.rs:12:11 | LL | match () { } //~ ERROR non-exhaustive diff --git a/src/test/ui/issues/issue-3096-2.stderr b/src/test/ui/issues/issue-3096-2.stderr index bb9dfabe7be03..e0fa641ff39e7 100644 --- a/src/test/ui/issues/issue-3096-2.stderr +++ b/src/test/ui/issues/issue-3096-2.stderr @@ -1,4 +1,4 @@ -error[E0004]: non-exhaustive patterns: type *const bottom is non-empty +error[E0004]: non-exhaustive patterns: type `*const bottom` is non-empty --> $DIR/issue-3096-2.rs:15:11 | LL | match x { } //~ ERROR non-exhaustive patterns diff --git a/src/test/ui/uninhabited/uninhabited-matches-feature-gated.stderr b/src/test/ui/uninhabited/uninhabited-matches-feature-gated.stderr index 83fd736a997a9..f4974b8fa3854 100644 --- a/src/test/ui/uninhabited/uninhabited-matches-feature-gated.stderr +++ b/src/test/ui/uninhabited/uninhabited-matches-feature-gated.stderr @@ -4,7 +4,7 @@ error[E0004]: non-exhaustive patterns: `Err(_)` not covered LL | let _ = match x { //~ ERROR non-exhaustive | ^ pattern `Err(_)` not covered -error[E0004]: non-exhaustive patterns: type &Void is non-empty +error[E0004]: non-exhaustive patterns: type `&Void` is non-empty --> $DIR/uninhabited-matches-feature-gated.rs:20:19 | LL | let _ = match x {}; //~ ERROR non-exhaustive @@ -16,7 +16,7 @@ help: ensure that all possible cases are being handled, possibly by adding wildc LL | let _ = match x {}; //~ ERROR non-exhaustive | ^ -error[E0004]: non-exhaustive patterns: type (Void,) is non-empty +error[E0004]: non-exhaustive patterns: type `(Void,)` is non-empty --> $DIR/uninhabited-matches-feature-gated.rs:23:19 | LL | let _ = match x {}; //~ ERROR non-exhaustive @@ -28,7 +28,7 @@ help: ensure that all possible cases are being handled, possibly by adding wildc LL | let _ = match x {}; //~ ERROR non-exhaustive | ^ -error[E0004]: non-exhaustive patterns: type [Void; 1] is non-empty +error[E0004]: non-exhaustive patterns: type `[Void; 1]` is non-empty --> $DIR/uninhabited-matches-feature-gated.rs:26:19 | LL | let _ = match x {}; //~ ERROR non-exhaustive From 464c9da9c229111298d413882735ea707a30e077 Mon Sep 17 00:00:00 2001 From: ljedrz Date: Wed, 21 Nov 2018 10:07:33 +0100 Subject: [PATCH 07/50] serialize: preallocate VecDeque in Decodable::decode --- src/libserialize/collection_impls.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libserialize/collection_impls.rs b/src/libserialize/collection_impls.rs index 3e028d755c6d4..cbd642dd6ad91 100644 --- a/src/libserialize/collection_impls.rs +++ b/src/libserialize/collection_impls.rs @@ -86,7 +86,7 @@ impl Encodable for VecDeque { impl Decodable for VecDeque { fn decode(d: &mut D) -> Result, D::Error> { d.read_seq(|d, len| { - let mut deque: VecDeque = VecDeque::new(); + let mut deque: VecDeque = VecDeque::with_capacity(len); for i in 0..len { deque.push_back(d.read_seq_elt(i, |d| Decodable::decode(d))?); } From 591607d237665857880e16899788517b9b82d414 Mon Sep 17 00:00:00 2001 From: ljedrz Date: Wed, 21 Nov 2018 10:17:54 +0100 Subject: [PATCH 08/50] String: add a FIXME to from_utf16 --- src/liballoc/string.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/liballoc/string.rs b/src/liballoc/string.rs index 8d009101ce7da..0b25d911a299c 100644 --- a/src/liballoc/string.rs +++ b/src/liballoc/string.rs @@ -618,6 +618,8 @@ impl String { /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn from_utf16(v: &[u16]) -> Result { + // This isn't done via collect::>() for performance reasons. + // FIXME: the function can be simplified again when #48994 is closed. let mut ret = String::with_capacity(v.len()); for c in decode_utf16(v.iter().cloned()) { if let Ok(c) = c { From 1ed91951c3012e9aabb403d28b902c56cc143907 Mon Sep 17 00:00:00 2001 From: antoine-de Date: Wed, 21 Nov 2018 11:17:48 +0100 Subject: [PATCH 09/50] fix small doc mistake The std::io::read main documentation can lead to error because the buffer is prefilled with 10 zeros that will pad the response. Using an empty vector is better. The `read_to_end` documentation is already correct though. This is my first rust PR, don't hesitate to tell me if I did something wrong. --- src/libstd/io/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs index e263db24fc2c8..076524e624a47 100644 --- a/src/libstd/io/mod.rs +++ b/src/libstd/io/mod.rs @@ -431,7 +431,7 @@ fn read_to_end_with_reservation(r: &mut R, /// // read up to 10 bytes /// f.read(&mut buffer)?; /// -/// let mut buffer = vec![0; 10]; +/// let mut buffer = Vec::new(); /// // read the whole file /// f.read_to_end(&mut buffer)?; /// From 83388e84c25f86563d82514d7bf71cfd474e008a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20S=CC=B6c=CC=B6h=CC=B6n=CC=B6e=CC=B6i=CC=B6d=CC=B6?= =?UTF-8?q?e=CC=B6r=20Scherer?= Date: Wed, 21 Nov 2018 12:26:40 +0100 Subject: [PATCH 10/50] Update an outdated comment in mir building --- src/librustc_mir/build/expr/as_temp.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/librustc_mir/build/expr/as_temp.rs b/src/librustc_mir/build/expr/as_temp.rs index 8f50a1e9a21b9..19bfb35ed620d 100644 --- a/src/librustc_mir/build/expr/as_temp.rs +++ b/src/librustc_mir/build/expr/as_temp.rs @@ -85,9 +85,8 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { unpack!(block = this.into(&Place::Local(temp), block, expr)); - // In constants, temp_lifetime is None. We should not need to drop - // anything because no values with a destructor can be created in - // a constant at this time, even if the type may need dropping. + // In constants, temp_lifetime is None. We do not drop anything because + // values with a destructor will simply be leaked in constants. if let Some(temp_lifetime) = temp_lifetime { this.schedule_drop_storage_and_value( expr_span, From 5a2a251b9cb0358851bb9d8d8870163f43c081dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20S=CC=B6c=CC=B6h=CC=B6n=CC=B6e=CC=B6i=CC=B6d=CC=B6?= =?UTF-8?q?e=CC=B6r=20Scherer?= Date: Wed, 21 Nov 2018 12:40:53 +0100 Subject: [PATCH 11/50] Update as_temp.rs --- src/librustc_mir/build/expr/as_temp.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/librustc_mir/build/expr/as_temp.rs b/src/librustc_mir/build/expr/as_temp.rs index 19bfb35ed620d..f060eefe520a6 100644 --- a/src/librustc_mir/build/expr/as_temp.rs +++ b/src/librustc_mir/build/expr/as_temp.rs @@ -85,8 +85,10 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { unpack!(block = this.into(&Place::Local(temp), block, expr)); - // In constants, temp_lifetime is None. We do not drop anything because - // values with a destructor will simply be leaked in constants. + // In constants, temp_lifetime is None for temporaries that live for the + // entire constant. Thus we do not drop these temporaries and simply leak them. + // Anything with a shorter lifetime (e.g the `&foo()` in `bar(&foo())` or anything + // within a block will keep the regular drops just like runtime code. if let Some(temp_lifetime) = temp_lifetime { this.schedule_drop_storage_and_value( expr_span, From 925274ab70c15ac5dcb3537e3473c29771ab7df5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20S=CC=B6c=CC=B6h=CC=B6n=CC=B6e=CC=B6i=CC=B6d=CC=B6?= =?UTF-8?q?e=CC=B6r=20Scherer?= Date: Wed, 21 Nov 2018 13:10:10 +0100 Subject: [PATCH 12/50] Update as_temp.rs --- src/librustc_mir/build/expr/as_temp.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/librustc_mir/build/expr/as_temp.rs b/src/librustc_mir/build/expr/as_temp.rs index f060eefe520a6..2db9fb9cb99f4 100644 --- a/src/librustc_mir/build/expr/as_temp.rs +++ b/src/librustc_mir/build/expr/as_temp.rs @@ -86,7 +86,12 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { unpack!(block = this.into(&Place::Local(temp), block, expr)); // In constants, temp_lifetime is None for temporaries that live for the - // entire constant. Thus we do not drop these temporaries and simply leak them. + // 'static lifetime. Thus we do not drop these temporaries and simply leak them. + // This is equivalent to what `let x = &foo();` does in functions. The temporary + // is lifted to their surrounding scope. In a function that means the temporary lives + // until just before the function returns. In constants that means it outlives the + // constant's initialization value computation. Anything outliving a constant + // must have the `'static` lifetime and live forever. // Anything with a shorter lifetime (e.g the `&foo()` in `bar(&foo())` or anything // within a block will keep the regular drops just like runtime code. if let Some(temp_lifetime) = temp_lifetime { From f03987276656134f25f92f7434d7d1c63c9e981c Mon Sep 17 00:00:00 2001 From: varkor Date: Wed, 21 Nov 2018 16:06:24 +0000 Subject: [PATCH 13/50] Enclose type in backticks for "reached the recursion limit while auto-dereferencing" error --- src/librustc_typeck/check/autoderef.rs | 4 ++-- src/librustc_typeck/diagnostics.rs | 2 +- src/test/ui/did_you_mean/recursion_limit_deref.stderr | 2 +- src/test/ui/error-codes/E0055.stderr | 2 +- src/test/ui/infinite/infinite-autoderef.stderr | 6 +++--- src/test/ui/issues/issue-38940.rs | 2 +- src/test/ui/issues/issue-38940.stderr | 2 +- 7 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/librustc_typeck/check/autoderef.rs b/src/librustc_typeck/check/autoderef.rs index 73489309d0742..2cd2bb5064877 100644 --- a/src/librustc_typeck/check/autoderef.rs +++ b/src/librustc_typeck/check/autoderef.rs @@ -59,7 +59,7 @@ impl<'a, 'gcx, 'tcx> Iterator for Autoderef<'a, 'gcx, 'tcx> { if self.steps.len() >= *tcx.sess.recursion_limit.get() { // We've reached the recursion limit, error gracefully. let suggested_limit = *tcx.sess.recursion_limit.get() * 2; - let msg = format!("reached the recursion limit while auto-dereferencing {:?}", + let msg = format!("reached the recursion limit while auto-dereferencing `{:?}`", self.cur_ty); let error_id = (DiagnosticMessageId::ErrorId(55), Some(self.span), msg); let fresh = tcx.sess.one_time_diagnostics.borrow_mut().insert(error_id); @@ -67,7 +67,7 @@ impl<'a, 'gcx, 'tcx> Iterator for Autoderef<'a, 'gcx, 'tcx> { struct_span_err!(tcx.sess, self.span, E0055, - "reached the recursion limit while auto-dereferencing {:?}", + "reached the recursion limit while auto-dereferencing `{:?}`", self.cur_ty) .span_label(self.span, "deref recursion limit reached") .help(&format!( diff --git a/src/librustc_typeck/diagnostics.rs b/src/librustc_typeck/diagnostics.rs index a985c3e9fdf44..084951f4a2c16 100644 --- a/src/librustc_typeck/diagnostics.rs +++ b/src/librustc_typeck/diagnostics.rs @@ -538,7 +538,7 @@ fn main() { let foo = Foo; let ref_foo = &&Foo; - // error, reached the recursion limit while auto-dereferencing &&Foo + // error, reached the recursion limit while auto-dereferencing `&&Foo` ref_foo.foo(); } ``` diff --git a/src/test/ui/did_you_mean/recursion_limit_deref.stderr b/src/test/ui/did_you_mean/recursion_limit_deref.stderr index 20a94f7aac196..7e7f21dd69c92 100644 --- a/src/test/ui/did_you_mean/recursion_limit_deref.stderr +++ b/src/test/ui/did_you_mean/recursion_limit_deref.stderr @@ -1,4 +1,4 @@ -error[E0055]: reached the recursion limit while auto-dereferencing I +error[E0055]: reached the recursion limit while auto-dereferencing `I` --> $DIR/recursion_limit_deref.rs:60:22 | LL | let x: &Bottom = &t; //~ ERROR mismatched types diff --git a/src/test/ui/error-codes/E0055.stderr b/src/test/ui/error-codes/E0055.stderr index 9653f4eaeefd0..dddbd92765a5d 100644 --- a/src/test/ui/error-codes/E0055.stderr +++ b/src/test/ui/error-codes/E0055.stderr @@ -1,4 +1,4 @@ -error[E0055]: reached the recursion limit while auto-dereferencing Foo +error[E0055]: reached the recursion limit while auto-dereferencing `Foo` --> $DIR/E0055.rs:21:13 | LL | ref_foo.foo(); diff --git a/src/test/ui/infinite/infinite-autoderef.stderr b/src/test/ui/infinite/infinite-autoderef.stderr index b5e20ea5cbf99..ef68adecd1a5f 100644 --- a/src/test/ui/infinite/infinite-autoderef.stderr +++ b/src/test/ui/infinite/infinite-autoderef.stderr @@ -7,7 +7,7 @@ LL | x = box x; | cyclic type of infinite size | help: try using a conversion method: `box x.to_string()` -error[E0055]: reached the recursion limit while auto-dereferencing Foo +error[E0055]: reached the recursion limit while auto-dereferencing `Foo` --> $DIR/infinite-autoderef.rs:35:5 | LL | Foo.foo; @@ -15,7 +15,7 @@ LL | Foo.foo; | = help: consider adding a `#![recursion_limit="128"]` attribute to your crate -error[E0055]: reached the recursion limit while auto-dereferencing Foo +error[E0055]: reached the recursion limit while auto-dereferencing `Foo` --> $DIR/infinite-autoderef.rs:35:9 | LL | Foo.foo; @@ -29,7 +29,7 @@ error[E0609]: no field `foo` on type `Foo` LL | Foo.foo; | ^^^ unknown field -error[E0055]: reached the recursion limit while auto-dereferencing Foo +error[E0055]: reached the recursion limit while auto-dereferencing `Foo` --> $DIR/infinite-autoderef.rs:36:9 | LL | Foo.bar(); diff --git a/src/test/ui/issues/issue-38940.rs b/src/test/ui/issues/issue-38940.rs index 7f9b141e02e3c..1c785949547e5 100644 --- a/src/test/ui/issues/issue-38940.rs +++ b/src/test/ui/issues/issue-38940.rs @@ -42,5 +42,5 @@ fn main() { let t = Top::new(); let x: &Bottom = &t; //~^ ERROR mismatched types - //~| ERROR reached the recursion limit while auto-dereferencing I + //~| ERROR reached the recursion limit while auto-dereferencing `I` } diff --git a/src/test/ui/issues/issue-38940.stderr b/src/test/ui/issues/issue-38940.stderr index 2d3cfda9a5f72..d94a7101c0a38 100644 --- a/src/test/ui/issues/issue-38940.stderr +++ b/src/test/ui/issues/issue-38940.stderr @@ -1,4 +1,4 @@ -error[E0055]: reached the recursion limit while auto-dereferencing I +error[E0055]: reached the recursion limit while auto-dereferencing `I` --> $DIR/issue-38940.rs:43:22 | LL | let x: &Bottom = &t; From ec3ac112e115c02a942c7a84c37a0cfd270dbad4 Mon Sep 17 00:00:00 2001 From: ariasuni Date: Wed, 21 Nov 2018 23:39:33 +0100 Subject: [PATCH 14/50] Make std::os::unix/linux::fs::MetadataExt::a/m/ctime* documentation clearer --- src/libstd/os/linux/fs.rs | 18 ++++++++++++------ src/libstd/sys/unix/ext/fs.rs | 18 ++++++++++++------ 2 files changed, 24 insertions(+), 12 deletions(-) diff --git a/src/libstd/os/linux/fs.rs b/src/libstd/os/linux/fs.rs index 76fb10da850b1..b518f524e0b08 100644 --- a/src/libstd/os/linux/fs.rs +++ b/src/libstd/os/linux/fs.rs @@ -191,7 +191,7 @@ pub trait MetadataExt { /// ``` #[stable(feature = "metadata_ext2", since = "1.8.0")] fn st_size(&self) -> u64; - /// Returns the last access time. + /// Returns the last access time of the file, in seconds since Unix Epoch. /// /// # Examples /// @@ -208,7 +208,9 @@ pub trait MetadataExt { /// ``` #[stable(feature = "metadata_ext2", since = "1.8.0")] fn st_atime(&self) -> i64; - /// Returns the last access time, nano seconds part. + /// Returns the last access time of the file, in nanoseconds since [`st_atime`]. + /// + /// [`st_atime`]: #tymethod.st_atime /// /// # Examples /// @@ -225,7 +227,7 @@ pub trait MetadataExt { /// ``` #[stable(feature = "metadata_ext2", since = "1.8.0")] fn st_atime_nsec(&self) -> i64; - /// Returns the last modification time. + /// Returns the last modification time of the file, in seconds since Unix Epoch. /// /// # Examples /// @@ -242,7 +244,9 @@ pub trait MetadataExt { /// ``` #[stable(feature = "metadata_ext2", since = "1.8.0")] fn st_mtime(&self) -> i64; - /// Returns the last modification time, nano seconds part. + /// Returns the last modification time of the file, in nanoseconds since [`st_mtime`]. + /// + /// [`st_mtime`]: #tymethod.st_mtime /// /// # Examples /// @@ -259,7 +263,7 @@ pub trait MetadataExt { /// ``` #[stable(feature = "metadata_ext2", since = "1.8.0")] fn st_mtime_nsec(&self) -> i64; - /// Returns the last status change time. + /// Returns the last status change time of the file, in seconds since Unix Epoch. /// /// # Examples /// @@ -276,7 +280,9 @@ pub trait MetadataExt { /// ``` #[stable(feature = "metadata_ext2", since = "1.8.0")] fn st_ctime(&self) -> i64; - /// Returns the last status change time, nano seconds part. + /// Returns the last status change time of the file, in nanoseconds since [`st_ctime`]. + /// + /// [`st_ctime`]: #tymethod.st_ctime /// /// # Examples /// diff --git a/src/libstd/sys/unix/ext/fs.rs b/src/libstd/sys/unix/ext/fs.rs index 507e9d881717b..7e65bbdef2a96 100644 --- a/src/libstd/sys/unix/ext/fs.rs +++ b/src/libstd/sys/unix/ext/fs.rs @@ -522,7 +522,7 @@ pub trait MetadataExt { /// ``` #[stable(feature = "metadata_ext", since = "1.1.0")] fn size(&self) -> u64; - /// Returns the time of the last access to the file. + /// Returns the last access time of the file, in seconds since Unix Epoch. /// /// # Examples /// @@ -539,7 +539,9 @@ pub trait MetadataExt { /// ``` #[stable(feature = "metadata_ext", since = "1.1.0")] fn atime(&self) -> i64; - /// Returns the time of the last access to the file in nanoseconds. + /// Returns the last access time of the file, in nanoseconds since [`atime`]. + /// + /// [`atime`]: #tymethod.atime /// /// # Examples /// @@ -556,7 +558,7 @@ pub trait MetadataExt { /// ``` #[stable(feature = "metadata_ext", since = "1.1.0")] fn atime_nsec(&self) -> i64; - /// Returns the time of the last modification of the file. + /// Returns the last modification time of the file, in seconds since Unix Epoch. /// /// # Examples /// @@ -573,7 +575,9 @@ pub trait MetadataExt { /// ``` #[stable(feature = "metadata_ext", since = "1.1.0")] fn mtime(&self) -> i64; - /// Returns the time of the last modification of the file in nanoseconds. + /// Returns the last modification time of the file, in nanoseconds since [`mtime`]. + /// + /// [`mtime`]: #tymethod.mtime /// /// # Examples /// @@ -590,7 +594,7 @@ pub trait MetadataExt { /// ``` #[stable(feature = "metadata_ext", since = "1.1.0")] fn mtime_nsec(&self) -> i64; - /// Returns the time of the last status change of the file. + /// Returns the last status change time of the file, in seconds since Unix Epoch. /// /// # Examples /// @@ -607,7 +611,9 @@ pub trait MetadataExt { /// ``` #[stable(feature = "metadata_ext", since = "1.1.0")] fn ctime(&self) -> i64; - /// Returns the time of the last status change of the file in nanoseconds. + /// Returns the last status change time of the file, in nanoseconds since [`ctime`]. + /// + /// [`ctime`]: #tymethod.ctime /// /// # Examples /// From af9b057156f610df3528a502c668cfed99ce8a1a Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Thu, 22 Nov 2018 13:43:05 +0100 Subject: [PATCH 15/50] drop glue takes in mutable references, it should reflect that in its type --- src/libcore/ptr.rs | 14 ++++++++++++-- src/librustc_mir/interpret/terminator.rs | 3 +++ src/librustc_mir/shim.rs | 7 ++++++- 3 files changed, 21 insertions(+), 3 deletions(-) diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs index e9cf11424cae1..ba1028f76c1c3 100644 --- a/src/libcore/ptr.rs +++ b/src/libcore/ptr.rs @@ -189,12 +189,22 @@ pub use intrinsics::write_bytes; /// i.e., you do not usually have to worry about such issues unless you call `drop_in_place` /// manually. #[stable(feature = "drop_in_place", since = "1.8.0")] +#[inline(always)] +pub unsafe fn drop_in_place(to_drop: *mut T) { + real_drop_in_place(&mut *to_drop) +} + +// The real `drop_in_place` -- the one that gets called implicitly when variables go +// out of scope -- should have a safe reference and not a raw pointer as argument +// type. When we drop a local variable, we access it with a pointer that behaves +// like a safe reference; transmuting that to a raw pointer does not mean we can +// actually access it with raw pointers. #[lang = "drop_in_place"] #[allow(unconditional_recursion)] -pub unsafe fn drop_in_place(to_drop: *mut T) { +unsafe fn real_drop_in_place(to_drop: &mut T) { // Code here does not matter - this is replaced by the // real drop glue by the compiler. - drop_in_place(to_drop); + real_drop_in_place(to_drop) } /// Creates a null raw pointer. diff --git a/src/librustc_mir/interpret/terminator.rs b/src/librustc_mir/interpret/terminator.rs index 6070b31d3e7a3..4489465679740 100644 --- a/src/librustc_mir/interpret/terminator.rs +++ b/src/librustc_mir/interpret/terminator.rs @@ -196,6 +196,9 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> // that will take care to make it UB to leave the range, just // like for transmute). caller.value == callee.value, + (layout::Abi::ScalarPair(ref caller1, ref caller2), + layout::Abi::ScalarPair(ref callee1, ref callee2)) => + caller1.value == callee1.value && caller2.value == callee2.value, // Be conservative _ => false } diff --git a/src/librustc_mir/shim.rs b/src/librustc_mir/shim.rs index 93bf1b3e36e38..04079319a7877 100644 --- a/src/librustc_mir/shim.rs +++ b/src/librustc_mir/shim.rs @@ -226,8 +226,13 @@ fn build_drop_shim<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, // The first argument (index 0), but add 1 for the return value. let dropee_ptr = Place::Local(Local::new(1+0)); if tcx.sess.opts.debugging_opts.mir_emit_retag { - // We use raw ptr operations, better prepare the alias tracking for that + // Function arguments should be retagged mir.basic_blocks_mut()[START_BLOCK].statements.insert(0, Statement { + source_info, + kind: StatementKind::Retag { fn_entry: true, place: dropee_ptr.clone() }, + }); + // We use raw ptr operations, better prepare the alias tracking for that + mir.basic_blocks_mut()[START_BLOCK].statements.insert(1, Statement { source_info, kind: StatementKind::EscapeToRaw(Operand::Copy(dropee_ptr.clone())), }) From e1ca4f63f4cee0c468325572b86f00badce70ad7 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Thu, 22 Nov 2018 17:26:44 +0100 Subject: [PATCH 16/50] fix codegen-units tests --- .../item-collection/drop_in_place_intrinsic.rs | 5 +++-- .../item-collection/generic-drop-glue.rs | 12 ++++++------ .../instantiation-through-vtable.rs | 4 ++-- .../item-collection/non-generic-drop-glue.rs | 4 ++-- .../item-collection/transitive-drop-glue.rs | 18 +++++++++--------- .../item-collection/tuple-drop-glue.rs | 8 ++++---- .../codegen-units/item-collection/unsizing.rs | 8 ++++---- .../partitioning/extern-drop-glue.rs | 6 +++--- .../partitioning/local-drop-glue.rs | 8 ++++---- .../partitioning/vtable-through-const.rs | 2 +- 10 files changed, 38 insertions(+), 37 deletions(-) diff --git a/src/test/codegen-units/item-collection/drop_in_place_intrinsic.rs b/src/test/codegen-units/item-collection/drop_in_place_intrinsic.rs index cec88f1c6a245..1793a311f968a 100644 --- a/src/test/codegen-units/item-collection/drop_in_place_intrinsic.rs +++ b/src/test/codegen-units/item-collection/drop_in_place_intrinsic.rs @@ -14,7 +14,7 @@ #![feature(start)] -//~ MONO_ITEM fn core::ptr[0]::drop_in_place[0] @@ drop_in_place_intrinsic-cgu.0[Internal] +//~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0] @@ drop_in_place_intrinsic-cgu.0[Internal] struct StructWithDtor(u32); impl Drop for StructWithDtor { @@ -26,7 +26,7 @@ impl Drop for StructWithDtor { #[start] fn start(_: isize, _: *const *const u8) -> isize { - //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<[drop_in_place_intrinsic::StructWithDtor[0]; 2]> @@ drop_in_place_intrinsic-cgu.0[Internal] + //~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]<[drop_in_place_intrinsic::StructWithDtor[0]; 2]> @@ drop_in_place_intrinsic-cgu.0[Internal] let x = [StructWithDtor(0), StructWithDtor(1)]; drop_slice_in_place(&x); @@ -41,6 +41,7 @@ fn drop_slice_in_place(x: &[StructWithDtor]) { // not have drop-glue for the unsized [StructWithDtor]. This has to be // generated though when the drop_in_place() intrinsic is used. //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<[drop_in_place_intrinsic::StructWithDtor[0]]> @@ drop_in_place_intrinsic-cgu.0[Internal] + //~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]<[drop_in_place_intrinsic::StructWithDtor[0]]> @@ drop_in_place_intrinsic-cgu.0[Internal] ::std::ptr::drop_in_place(x as *const _ as *mut [StructWithDtor]); } } diff --git a/src/test/codegen-units/item-collection/generic-drop-glue.rs b/src/test/codegen-units/item-collection/generic-drop-glue.rs index 5afa519bc5902..4ae5832ec4ed4 100644 --- a/src/test/codegen-units/item-collection/generic-drop-glue.rs +++ b/src/test/codegen-units/item-collection/generic-drop-glue.rs @@ -47,7 +47,7 @@ enum EnumNoDrop { struct NonGenericNoDrop(i32); struct NonGenericWithDrop(i32); -//~ MONO_ITEM fn core::ptr[0]::drop_in_place[0] @@ generic_drop_glue-cgu.0[Internal] +//~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0] @@ generic_drop_glue-cgu.0[Internal] impl Drop for NonGenericWithDrop { //~ MONO_ITEM fn generic_drop_glue::{{impl}}[2]::drop[0] @@ -57,11 +57,11 @@ impl Drop for NonGenericWithDrop { //~ MONO_ITEM fn generic_drop_glue::start[0] #[start] fn start(_: isize, _: *const *const u8) -> isize { - //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]> @@ generic_drop_glue-cgu.0[Internal] + //~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]> @@ generic_drop_glue-cgu.0[Internal] //~ MONO_ITEM fn generic_drop_glue::{{impl}}[0]::drop[0] let _ = StructWithDrop { x: 0i8, y: 'a' }.x; - //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]> @@ generic_drop_glue-cgu.0[Internal] + //~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]> @@ generic_drop_glue-cgu.0[Internal] //~ MONO_ITEM fn generic_drop_glue::{{impl}}[0]::drop[0]<&str, generic_drop_glue::NonGenericNoDrop[0]> let _ = StructWithDrop { x: "&str", y: NonGenericNoDrop(0) }.y; @@ -70,17 +70,17 @@ fn start(_: isize, _: *const *const u8) -> isize { // This is supposed to generate drop-glue because it contains a field that // needs to be dropped. - //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]> @@ generic_drop_glue-cgu.0[Internal] + //~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]> @@ generic_drop_glue-cgu.0[Internal] let _ = StructNoDrop { x: NonGenericWithDrop(0), y: 0f64 }.y; - //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]> @@ generic_drop_glue-cgu.0[Internal] + //~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]> @@ generic_drop_glue-cgu.0[Internal] //~ MONO_ITEM fn generic_drop_glue::{{impl}}[1]::drop[0] let _ = match EnumWithDrop::A::(0) { EnumWithDrop::A(x) => x, EnumWithDrop::B(x) => x as i32 }; - //~MONO_ITEM fn core::ptr[0]::drop_in_place[0]> @@ generic_drop_glue-cgu.0[Internal] + //~MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]> @@ generic_drop_glue-cgu.0[Internal] //~ MONO_ITEM fn generic_drop_glue::{{impl}}[1]::drop[0] let _ = match EnumWithDrop::B::(1.0) { EnumWithDrop::A(x) => x, diff --git a/src/test/codegen-units/item-collection/instantiation-through-vtable.rs b/src/test/codegen-units/item-collection/instantiation-through-vtable.rs index d09d343a8458e..bfa67b16d0e63 100644 --- a/src/test/codegen-units/item-collection/instantiation-through-vtable.rs +++ b/src/test/codegen-units/item-collection/instantiation-through-vtable.rs @@ -34,13 +34,13 @@ impl Trait for Struct { fn start(_: isize, _: *const *const u8) -> isize { let s1 = Struct { _a: 0u32 }; - //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]> @@ instantiation_through_vtable-cgu.0[Internal] + //~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]> @@ instantiation_through_vtable-cgu.0[Internal] //~ MONO_ITEM fn instantiation_through_vtable::{{impl}}[0]::foo[0] //~ MONO_ITEM fn instantiation_through_vtable::{{impl}}[0]::bar[0] let _ = &s1 as &Trait; let s1 = Struct { _a: 0u64 }; - //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]> @@ instantiation_through_vtable-cgu.0[Internal] + //~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]> @@ instantiation_through_vtable-cgu.0[Internal] //~ MONO_ITEM fn instantiation_through_vtable::{{impl}}[0]::foo[0] //~ MONO_ITEM fn instantiation_through_vtable::{{impl}}[0]::bar[0] let _ = &s1 as &Trait; diff --git a/src/test/codegen-units/item-collection/non-generic-drop-glue.rs b/src/test/codegen-units/item-collection/non-generic-drop-glue.rs index a939dd56cda5b..2d72383391daa 100644 --- a/src/test/codegen-units/item-collection/non-generic-drop-glue.rs +++ b/src/test/codegen-units/item-collection/non-generic-drop-glue.rs @@ -15,7 +15,7 @@ #![deny(dead_code)] #![feature(start)] -//~ MONO_ITEM fn core::ptr[0]::drop_in_place[0] @@ non_generic_drop_glue-cgu.0[Internal] +//~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0] @@ non_generic_drop_glue-cgu.0[Internal] struct StructWithDrop { x: i32 } @@ -29,7 +29,7 @@ struct StructNoDrop { x: i32 } -//~ MONO_ITEM fn core::ptr[0]::drop_in_place[0] @@ non_generic_drop_glue-cgu.0[Internal] +//~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0] @@ non_generic_drop_glue-cgu.0[Internal] enum EnumWithDrop { A(i32) } diff --git a/src/test/codegen-units/item-collection/transitive-drop-glue.rs b/src/test/codegen-units/item-collection/transitive-drop-glue.rs index 7bbc9b6d0fbc9..d90171726b2c6 100644 --- a/src/test/codegen-units/item-collection/transitive-drop-glue.rs +++ b/src/test/codegen-units/item-collection/transitive-drop-glue.rs @@ -15,11 +15,11 @@ #![deny(dead_code)] #![feature(start)] -//~ MONO_ITEM fn core::ptr[0]::drop_in_place[0] @@ transitive_drop_glue-cgu.0[Internal] +//~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0] @@ transitive_drop_glue-cgu.0[Internal] struct Root(Intermediate); -//~ MONO_ITEM fn core::ptr[0]::drop_in_place[0] @@ transitive_drop_glue-cgu.0[Internal] +//~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0] @@ transitive_drop_glue-cgu.0[Internal] struct Intermediate(Leaf); -//~ MONO_ITEM fn core::ptr[0]::drop_in_place[0] @@ transitive_drop_glue-cgu.0[Internal] +//~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0] @@ transitive_drop_glue-cgu.0[Internal] struct Leaf; impl Drop for Leaf { @@ -40,15 +40,15 @@ impl Drop for LeafGen { fn start(_: isize, _: *const *const u8) -> isize { let _ = Root(Intermediate(Leaf)); - //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]> @@ transitive_drop_glue-cgu.0[Internal] - //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]> @@ transitive_drop_glue-cgu.0[Internal] - //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]> @@ transitive_drop_glue-cgu.0[Internal] + //~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]> @@ transitive_drop_glue-cgu.0[Internal] + //~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]> @@ transitive_drop_glue-cgu.0[Internal] + //~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]> @@ transitive_drop_glue-cgu.0[Internal] //~ MONO_ITEM fn transitive_drop_glue::{{impl}}[1]::drop[0] let _ = RootGen(IntermediateGen(LeafGen(0u32))); - //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]> @@ transitive_drop_glue-cgu.0[Internal] - //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]> @@ transitive_drop_glue-cgu.0[Internal] - //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]> @@ transitive_drop_glue-cgu.0[Internal] + //~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]> @@ transitive_drop_glue-cgu.0[Internal] + //~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]> @@ transitive_drop_glue-cgu.0[Internal] + //~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]> @@ transitive_drop_glue-cgu.0[Internal] //~ MONO_ITEM fn transitive_drop_glue::{{impl}}[1]::drop[0] let _ = RootGen(IntermediateGen(LeafGen(0i16))); diff --git a/src/test/codegen-units/item-collection/tuple-drop-glue.rs b/src/test/codegen-units/item-collection/tuple-drop-glue.rs index 865570ccfa55a..e94af0c2989b2 100644 --- a/src/test/codegen-units/item-collection/tuple-drop-glue.rs +++ b/src/test/codegen-units/item-collection/tuple-drop-glue.rs @@ -15,7 +15,7 @@ #![deny(dead_code)] #![feature(start)] -//~ MONO_ITEM fn core::ptr[0]::drop_in_place[0] @@ tuple_drop_glue-cgu.0[Internal] +//~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0] @@ tuple_drop_glue-cgu.0[Internal] struct Dropped; impl Drop for Dropped { @@ -26,11 +26,11 @@ impl Drop for Dropped { //~ MONO_ITEM fn tuple_drop_glue::start[0] #[start] fn start(_: isize, _: *const *const u8) -> isize { - //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<(u32, tuple_drop_glue::Dropped[0])> @@ tuple_drop_glue-cgu.0[Internal] + //~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]<(u32, tuple_drop_glue::Dropped[0])> @@ tuple_drop_glue-cgu.0[Internal] let x = (0u32, Dropped); - //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<(i16, (tuple_drop_glue::Dropped[0], bool))> @@ tuple_drop_glue-cgu.0[Internal] - //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<(tuple_drop_glue::Dropped[0], bool)> @@ tuple_drop_glue-cgu.0[Internal] + //~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]<(i16, (tuple_drop_glue::Dropped[0], bool))> @@ tuple_drop_glue-cgu.0[Internal] + //~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]<(tuple_drop_glue::Dropped[0], bool)> @@ tuple_drop_glue-cgu.0[Internal] let x = (0i16, (Dropped, true)); 0 diff --git a/src/test/codegen-units/item-collection/unsizing.rs b/src/test/codegen-units/item-collection/unsizing.rs index 5e9a3258c7adf..c85f7fc1bdd8d 100644 --- a/src/test/codegen-units/item-collection/unsizing.rs +++ b/src/test/codegen-units/item-collection/unsizing.rs @@ -59,13 +59,13 @@ impl, U: ?Sized> CoerceUnsized> for Wrapper fn start(_: isize, _: *const *const u8) -> isize { // simple case let bool_sized = &true; - //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0] @@ unsizing-cgu.0[Internal] + //~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0] @@ unsizing-cgu.0[Internal] //~ MONO_ITEM fn unsizing::{{impl}}[0]::foo[0] let _bool_unsized = bool_sized as &Trait; let char_sized = &'a'; - //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0] @@ unsizing-cgu.0[Internal] + //~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0] @@ unsizing-cgu.0[Internal] //~ MONO_ITEM fn unsizing::{{impl}}[1]::foo[0] let _char_unsized = char_sized as &Trait; @@ -75,13 +75,13 @@ fn start(_: isize, _: *const *const u8) -> isize { _b: 2, _c: 3.0f64 }; - //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0] @@ unsizing-cgu.0[Internal] + //~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0] @@ unsizing-cgu.0[Internal] //~ MONO_ITEM fn unsizing::{{impl}}[2]::foo[0] let _struct_unsized = struct_sized as &Struct; // custom coercion let wrapper_sized = Wrapper(&0u32); - //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0] @@ unsizing-cgu.0[Internal] + //~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0] @@ unsizing-cgu.0[Internal] //~ MONO_ITEM fn unsizing::{{impl}}[3]::foo[0] let _wrapper_sized = wrapper_sized as Wrapper; diff --git a/src/test/codegen-units/partitioning/extern-drop-glue.rs b/src/test/codegen-units/partitioning/extern-drop-glue.rs index cbad3a638840c..87b4430b4cab6 100644 --- a/src/test/codegen-units/partitioning/extern-drop-glue.rs +++ b/src/test/codegen-units/partitioning/extern-drop-glue.rs @@ -21,14 +21,14 @@ // aux-build:cgu_extern_drop_glue.rs extern crate cgu_extern_drop_glue; -//~ MONO_ITEM fn core::ptr[0]::drop_in_place[0] @@ extern_drop_glue[Internal] extern_drop_glue-mod1[Internal] +//~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0] @@ extern_drop_glue[Internal] extern_drop_glue-mod1[Internal] struct LocalStruct(cgu_extern_drop_glue::Struct); //~ MONO_ITEM fn extern_drop_glue::user[0] @@ extern_drop_glue[External] pub fn user() { - //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0] @@ extern_drop_glue[Internal] + //~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0] @@ extern_drop_glue[Internal] let _ = LocalStruct(cgu_extern_drop_glue::Struct(0)); } @@ -40,7 +40,7 @@ pub mod mod1 { //~ MONO_ITEM fn extern_drop_glue::mod1[0]::user[0] @@ extern_drop_glue-mod1[External] pub fn user() { - //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0] @@ extern_drop_glue-mod1[Internal] + //~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0] @@ extern_drop_glue-mod1[Internal] let _ = LocalStruct(cgu_extern_drop_glue::Struct(0)); } } diff --git a/src/test/codegen-units/partitioning/local-drop-glue.rs b/src/test/codegen-units/partitioning/local-drop-glue.rs index 98729d99ea950..e09eb318708e1 100644 --- a/src/test/codegen-units/partitioning/local-drop-glue.rs +++ b/src/test/codegen-units/partitioning/local-drop-glue.rs @@ -17,7 +17,7 @@ #![allow(dead_code)] #![crate_type="rlib"] -//~ MONO_ITEM fn core::ptr[0]::drop_in_place[0] @@ local_drop_glue[Internal] local_drop_glue-mod1[Internal] +//~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0] @@ local_drop_glue[Internal] local_drop_glue-mod1[Internal] struct Struct { _a: u32 } @@ -27,7 +27,7 @@ impl Drop for Struct { fn drop(&mut self) {} } -//~ MONO_ITEM fn core::ptr[0]::drop_in_place[0] @@ local_drop_glue[Internal] +//~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0] @@ local_drop_glue[Internal] struct Outer { _a: Struct } @@ -46,10 +46,10 @@ pub mod mod1 { use super::Struct; - //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0] @@ local_drop_glue-mod1[Internal] + //~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0] @@ local_drop_glue-mod1[Internal] struct Struct2 { _a: Struct, - //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<(u32, local_drop_glue::Struct[0])> @@ local_drop_glue-mod1[Internal] + //~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]<(u32, local_drop_glue::Struct[0])> @@ local_drop_glue-mod1[Internal] _b: (u32, Struct), } diff --git a/src/test/codegen-units/partitioning/vtable-through-const.rs b/src/test/codegen-units/partitioning/vtable-through-const.rs index ebda08a29f66d..459c6b6f15410 100644 --- a/src/test/codegen-units/partitioning/vtable-through-const.rs +++ b/src/test/codegen-units/partitioning/vtable-through-const.rs @@ -76,7 +76,7 @@ mod mod1 { //~ MONO_ITEM fn vtable_through_const::start[0] #[start] fn start(_: isize, _: *const *const u8) -> isize { - //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0] @@ vtable_through_const[Internal] + //~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0] @@ vtable_through_const[Internal] // Since Trait1::do_something() is instantiated via its default implementation, // it is considered a generic and is instantiated here only because it is From d9de72fcac7cfd90742a8fa8e4f6c0efd664ecde Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Thu, 22 Nov 2018 17:38:59 +0100 Subject: [PATCH 17/50] miri: restrict fn argument punning to Rust ABI --- src/librustc_mir/interpret/terminator.rs | 33 +++++++++++++++--------- 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/src/librustc_mir/interpret/terminator.rs b/src/librustc_mir/interpret/terminator.rs index 4489465679740..11c44fc943daa 100644 --- a/src/librustc_mir/interpret/terminator.rs +++ b/src/librustc_mir/interpret/terminator.rs @@ -182,6 +182,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> } fn check_argument_compat( + rust_abi: bool, caller: TyLayout<'tcx>, callee: TyLayout<'tcx>, ) -> bool { @@ -189,12 +190,16 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> // No question return true; } + if !rust_abi { + // Don't risk anything + return false; + } // Compare layout match (&caller.abi, &callee.abi) { + // Different valid ranges are okay (once we enforce validity, + // that will take care to make it UB to leave the range, just + // like for transmute). (layout::Abi::Scalar(ref caller), layout::Abi::Scalar(ref callee)) => - // Different valid ranges are okay (once we enforce validity, - // that will take care to make it UB to leave the range, just - // like for transmute). caller.value == callee.value, (layout::Abi::ScalarPair(ref caller1, ref caller2), layout::Abi::ScalarPair(ref callee1, ref callee2)) => @@ -207,22 +212,22 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> /// Pass a single argument, checking the types for compatibility. fn pass_argument( &mut self, - skip_zst: bool, + rust_abi: bool, caller_arg: &mut impl Iterator>, callee_arg: PlaceTy<'tcx, M::PointerTag>, ) -> EvalResult<'tcx> { - if skip_zst && callee_arg.layout.is_zst() { + if rust_abi && callee_arg.layout.is_zst() { // Nothing to do. trace!("Skipping callee ZST"); return Ok(()); } let caller_arg = caller_arg.next() .ok_or_else(|| EvalErrorKind::FunctionArgCountMismatch)?; - if skip_zst { + if rust_abi { debug_assert!(!caller_arg.layout.is_zst(), "ZSTs must have been already filtered out"); } // Now, check - if !Self::check_argument_compat(caller_arg.layout, callee_arg.layout) { + if !Self::check_argument_compat(rust_abi, caller_arg.layout, callee_arg.layout) { return err!(FunctionArgMismatch(caller_arg.layout.ty, callee_arg.layout.ty)); } // We allow some transmutes here @@ -322,7 +327,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> // Figure out how to pass which arguments. // We have two iterators: Where the arguments come from, // and where they go to. - let skip_zst = match caller_abi { + let rust_abi = match caller_abi { Abi::Rust | Abi::RustCall => true, _ => false }; @@ -347,7 +352,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> }; // Skip ZSTs let mut caller_iter = caller_args.iter() - .filter(|op| !skip_zst || !op.layout.is_zst()) + .filter(|op| !rust_abi || !op.layout.is_zst()) .map(|op| *op); // Now we have to spread them out across the callee's locals, @@ -362,11 +367,11 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> // Must be a tuple for i in 0..dest.layout.fields.count() { let dest = self.place_field(dest, i as u64)?; - self.pass_argument(skip_zst, &mut caller_iter, dest)?; + self.pass_argument(rust_abi, &mut caller_iter, dest)?; } } else { // Normal argument - self.pass_argument(skip_zst, &mut caller_iter, dest)?; + self.pass_argument(rust_abi, &mut caller_iter, dest)?; } } // Now we should have no more caller args @@ -377,7 +382,11 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> // Don't forget to check the return type! if let Some(caller_ret) = dest { let callee_ret = self.eval_place(&mir::Place::Local(mir::RETURN_PLACE))?; - if !Self::check_argument_compat(caller_ret.layout, callee_ret.layout) { + if !Self::check_argument_compat( + rust_abi, + caller_ret.layout, + callee_ret.layout, + ) { return err!(FunctionRetMismatch( caller_ret.layout.ty, callee_ret.layout.ty )); From 5c99ae6661311e42abaa590dcf592106155b3c98 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sat, 24 Nov 2018 17:12:28 -0800 Subject: [PATCH 18/50] Fix ICE with feature self_struct_ctor --- src/librustc/middle/reachable.rs | 1 + src/test/ui/issues/issue-56202.rs | 15 +++++++++++++++ src/test/ui/issues/issue-56202.stderr | 7 +++++++ 3 files changed, 23 insertions(+) create mode 100644 src/test/ui/issues/issue-56202.rs create mode 100644 src/test/ui/issues/issue-56202.stderr diff --git a/src/librustc/middle/reachable.rs b/src/librustc/middle/reachable.rs index 0009a517dd1db..cf81729bdaba8 100644 --- a/src/librustc/middle/reachable.rs +++ b/src/librustc/middle/reachable.rs @@ -116,6 +116,7 @@ impl<'a, 'tcx> Visitor<'tcx> for ReachableContext<'a, 'tcx> { Some(Def::Local(node_id)) | Some(Def::Upvar(node_id, ..)) => { self.reachable_symbols.insert(node_id); } + Some(Def::Err) => {} // #56202: calling `def.def_id()` would be an error Some(def) => { let def_id = def.def_id(); if let Some(node_id) = self.tcx.hir.as_local_node_id(def_id) { diff --git a/src/test/ui/issues/issue-56202.rs b/src/test/ui/issues/issue-56202.rs new file mode 100644 index 0000000000000..c80c372c9e2ea --- /dev/null +++ b/src/test/ui/issues/issue-56202.rs @@ -0,0 +1,15 @@ +#![feature(self_struct_ctor)] + +trait FooTrait {} + +trait BarTrait { + fn foo(_: T) -> Self; +} + +struct FooStruct(u32); + +impl BarTrait for FooStruct { + fn foo(_: T) -> Self { + Self(u32::default()) + } +} diff --git a/src/test/ui/issues/issue-56202.stderr b/src/test/ui/issues/issue-56202.stderr new file mode 100644 index 0000000000000..3007b08450298 --- /dev/null +++ b/src/test/ui/issues/issue-56202.stderr @@ -0,0 +1,7 @@ +error[E0601]: `main` function not found in crate `issue_56202` + | + = note: consider adding a `main` function to `$DIR/issue-56202.rs` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0601`. From 8d76f54fd8f866c2ccefb736cb084dddedd9230d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sun, 25 Nov 2018 07:40:26 -0800 Subject: [PATCH 19/50] Use opt_def_id instead of having special branch --- src/librustc/middle/reachable.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/librustc/middle/reachable.rs b/src/librustc/middle/reachable.rs index cf81729bdaba8..ab0094df0e219 100644 --- a/src/librustc/middle/reachable.rs +++ b/src/librustc/middle/reachable.rs @@ -116,10 +116,10 @@ impl<'a, 'tcx> Visitor<'tcx> for ReachableContext<'a, 'tcx> { Some(Def::Local(node_id)) | Some(Def::Upvar(node_id, ..)) => { self.reachable_symbols.insert(node_id); } - Some(Def::Err) => {} // #56202: calling `def.def_id()` would be an error Some(def) => { - let def_id = def.def_id(); - if let Some(node_id) = self.tcx.hir.as_local_node_id(def_id) { + if let Some((node_id, def_id)) = def.opt_def_id().and_then(|def_id| { + self.tcx.hir.as_local_node_id(def_id).map(|node_id| (node_id, def_id)) + }) { if self.def_id_represents_local_inlined_item(def_id) { self.worklist.push(node_id); } else { From 79ee8f329d1d3105555fd40be5b0eac56c9a8e8f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sun, 25 Nov 2018 12:41:38 -0800 Subject: [PATCH 20/50] Suggest appropriate place for lifetime when declared after type arguments --- src/libsyntax/parse/parser.rs | 43 +++++++++++++++---- src/test/ui/parser/issue-14303-enum.stderr | 4 ++ src/test/ui/parser/issue-14303-fn-def.stderr | 4 ++ src/test/ui/parser/issue-14303-impl.stderr | 4 ++ src/test/ui/parser/issue-14303-struct.stderr | 4 ++ src/test/ui/parser/issue-14303-trait.stderr | 4 ++ .../ui/suggestions/suggest-move-lifetimes.rs | 15 +++++++ .../suggestions/suggest-move-lifetimes.stderr | 32 ++++++++++++++ 8 files changed, 102 insertions(+), 8 deletions(-) create mode 100644 src/test/ui/suggestions/suggest-move-lifetimes.rs create mode 100644 src/test/ui/suggestions/suggest-move-lifetimes.stderr diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index e2f09affd4fea..07e13ffc3143b 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -5178,8 +5178,10 @@ impl<'a> Parser<'a> { /// Parses (possibly empty) list of lifetime and type parameters, possibly including /// trailing comma and erroneous trailing attributes. crate fn parse_generic_params(&mut self) -> PResult<'a, Vec> { + let mut lifetimes = Vec::new(); let mut params = Vec::new(); - let mut seen_ty_param = false; + let mut seen_ty_param: Option = None; + let mut last_comma_span = None; loop { let attrs = self.parse_outer_attributes()?; if self.check_lifetime() { @@ -5190,25 +5192,48 @@ impl<'a> Parser<'a> { } else { Vec::new() }; - params.push(ast::GenericParam { + lifetimes.push(ast::GenericParam { ident: lifetime.ident, id: lifetime.id, attrs: attrs.into(), bounds, kind: ast::GenericParamKind::Lifetime, }); - if seen_ty_param { - self.span_err(self.prev_span, - "lifetime parameters must be declared prior to type parameters"); + if let Some(sp) = seen_ty_param { + let param_span = self.prev_span; + let ate_comma = self.eat(&token::Comma); + let remove_sp = if ate_comma { + param_span.until(self.span) + } else { + last_comma_span.unwrap_or(param_span).to(param_span) + }; + let mut err = self.struct_span_err( + self.prev_span, + "lifetime parameters must be declared prior to type parameters", + ); + if let Ok(snippet) = self.sess.source_map().span_to_snippet(param_span) { + err.multipart_suggestion( + "move the lifetime parameter prior to the first type parameter", + vec![ + (remove_sp, String::new()), + (sp.shrink_to_lo(), format!("{}, ", snippet)), + ], + ); + } + err.emit(); + if ate_comma { + last_comma_span = Some(self.prev_span); + continue + } } } else if self.check_ident() { // Parse type parameter. params.push(self.parse_ty_param(attrs)?); - seen_ty_param = true; + seen_ty_param = Some(self.prev_span); } else { // Check for trailing attributes and stop parsing. if !attrs.is_empty() { - let param_kind = if seen_ty_param { "type" } else { "lifetime" }; + let param_kind = if seen_ty_param.is_some() { "type" } else { "lifetime" }; self.span_err(attrs[0].span, &format!("trailing attribute after {} parameters", param_kind)); } @@ -5218,8 +5243,10 @@ impl<'a> Parser<'a> { if !self.eat(&token::Comma) { break } + last_comma_span = Some(self.prev_span); } - Ok(params) + lifetimes.extend(params); // ensure the correct order of lifetimes and type params + Ok(lifetimes) } /// Parse a set of optional generic type parameter declarations. Where diff --git a/src/test/ui/parser/issue-14303-enum.stderr b/src/test/ui/parser/issue-14303-enum.stderr index 7d546cb2180e3..622066a94f80a 100644 --- a/src/test/ui/parser/issue-14303-enum.stderr +++ b/src/test/ui/parser/issue-14303-enum.stderr @@ -3,6 +3,10 @@ error: lifetime parameters must be declared prior to type parameters | LL | enum X<'a, T, 'b> { | ^^ +help: move the lifetime parameter prior to the first type parameter + | +LL | enum X<'a, 'b, T> { + | ^^^ -- error: aborting due to previous error diff --git a/src/test/ui/parser/issue-14303-fn-def.stderr b/src/test/ui/parser/issue-14303-fn-def.stderr index c7b57f36376b5..630c9cb40de37 100644 --- a/src/test/ui/parser/issue-14303-fn-def.stderr +++ b/src/test/ui/parser/issue-14303-fn-def.stderr @@ -3,6 +3,10 @@ error: lifetime parameters must be declared prior to type parameters | LL | fn foo<'a, T, 'b>(x: &'a T) {} | ^^ +help: move the lifetime parameter prior to the first type parameter + | +LL | fn foo<'a, 'b, T>(x: &'a T) {} + | ^^^ -- error: aborting due to previous error diff --git a/src/test/ui/parser/issue-14303-impl.stderr b/src/test/ui/parser/issue-14303-impl.stderr index 0b7016eb7f71d..2e3181de90275 100644 --- a/src/test/ui/parser/issue-14303-impl.stderr +++ b/src/test/ui/parser/issue-14303-impl.stderr @@ -3,6 +3,10 @@ error: lifetime parameters must be declared prior to type parameters | LL | impl<'a, T, 'b> X {} | ^^ +help: move the lifetime parameter prior to the first type parameter + | +LL | impl<'a, 'b, T> X {} + | ^^^ -- error: aborting due to previous error diff --git a/src/test/ui/parser/issue-14303-struct.stderr b/src/test/ui/parser/issue-14303-struct.stderr index 4a4b678919495..c6b33120c18f0 100644 --- a/src/test/ui/parser/issue-14303-struct.stderr +++ b/src/test/ui/parser/issue-14303-struct.stderr @@ -3,6 +3,10 @@ error: lifetime parameters must be declared prior to type parameters | LL | struct X<'a, T, 'b> { | ^^ +help: move the lifetime parameter prior to the first type parameter + | +LL | struct X<'a, 'b, T> { + | ^^^ -- error: aborting due to previous error diff --git a/src/test/ui/parser/issue-14303-trait.stderr b/src/test/ui/parser/issue-14303-trait.stderr index ab5cc5655bbe1..6d00f284bbbe7 100644 --- a/src/test/ui/parser/issue-14303-trait.stderr +++ b/src/test/ui/parser/issue-14303-trait.stderr @@ -3,6 +3,10 @@ error: lifetime parameters must be declared prior to type parameters | LL | trait Foo<'a, T, 'b> {} | ^^ +help: move the lifetime parameter prior to the first type parameter + | +LL | trait Foo<'a, 'b, T> {} + | ^^^ -- error: aborting due to previous error diff --git a/src/test/ui/suggestions/suggest-move-lifetimes.rs b/src/test/ui/suggestions/suggest-move-lifetimes.rs new file mode 100644 index 0000000000000..be6d29d933763 --- /dev/null +++ b/src/test/ui/suggestions/suggest-move-lifetimes.rs @@ -0,0 +1,15 @@ +struct A { + t: &'a T, +} + +struct B { + t: &'a T, + u: U, +} + +struct C { + t: &'a T, + u: U, +} + +fn main() {} diff --git a/src/test/ui/suggestions/suggest-move-lifetimes.stderr b/src/test/ui/suggestions/suggest-move-lifetimes.stderr new file mode 100644 index 0000000000000..57e6780b35984 --- /dev/null +++ b/src/test/ui/suggestions/suggest-move-lifetimes.stderr @@ -0,0 +1,32 @@ +error: lifetime parameters must be declared prior to type parameters + --> $DIR/suggest-move-lifetimes.rs:1:13 + | +LL | struct A { + | ^^ +help: move the lifetime parameter prior to the first type parameter + | +LL | struct A<'a, T> { + | ^^^ -- + +error: lifetime parameters must be declared prior to type parameters + --> $DIR/suggest-move-lifetimes.rs:5:15 + | +LL | struct B { + | ^ +help: move the lifetime parameter prior to the first type parameter + | +LL | struct B<'a, T, U> { + | ^^^ -- + +error: lifetime parameters must be declared prior to type parameters + --> $DIR/suggest-move-lifetimes.rs:10:16 + | +LL | struct C { + | ^^ +help: move the lifetime parameter prior to the first type parameter + | +LL | struct C { + | ^^^ -- + +error: aborting due to 3 previous errors + From 234d043d18175aff37200a91df2a1b7c3064fc80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sun, 25 Nov 2018 12:46:42 -0800 Subject: [PATCH 21/50] Move lifetimes before the *first* type argument --- src/libsyntax/parse/parser.rs | 4 +++- src/test/ui/suggestions/suggest-move-lifetimes.stderr | 4 ++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 07e13ffc3143b..1fdf86d48670b 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -5229,7 +5229,9 @@ impl<'a> Parser<'a> { } else if self.check_ident() { // Parse type parameter. params.push(self.parse_ty_param(attrs)?); - seen_ty_param = Some(self.prev_span); + if seen_ty_param.is_none() { + seen_ty_param = Some(self.prev_span); + } } else { // Check for trailing attributes and stop parsing. if !attrs.is_empty() { diff --git a/src/test/ui/suggestions/suggest-move-lifetimes.stderr b/src/test/ui/suggestions/suggest-move-lifetimes.stderr index 57e6780b35984..fa1cfe66ab530 100644 --- a/src/test/ui/suggestions/suggest-move-lifetimes.stderr +++ b/src/test/ui/suggestions/suggest-move-lifetimes.stderr @@ -25,8 +25,8 @@ LL | struct C { | ^^ help: move the lifetime parameter prior to the first type parameter | -LL | struct C { - | ^^^ -- +LL | struct C<'a, T, U> { + | ^^^ -- error: aborting due to 3 previous errors From db8540e746ef3d2532c820d02a77f0111fda09fb Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 21 Nov 2018 22:03:59 +1100 Subject: [PATCH 22/50] Avoid a useless `FxHashSet::insert` in `FileSearch::for_each_lib_search_path`. --- src/librustc/session/filesearch.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/librustc/session/filesearch.rs b/src/librustc/session/filesearch.rs index f410c270bcef9..2b84317b3d6dd 100644 --- a/src/librustc/session/filesearch.rs +++ b/src/librustc/session/filesearch.rs @@ -53,8 +53,6 @@ impl<'a> FileSearch<'a> { if !visited_dirs.contains(&tlib_path) { f(&tlib_path, PathKind::All); } - - visited_dirs.insert(tlib_path); } pub fn get_lib_path(&self) -> PathBuf { From 145e2abc069b27c28ee6c32ddb8b6d2851fa5fd7 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 22 Nov 2018 15:49:48 +1100 Subject: [PATCH 23/50] Remove `Session::sysroot()`. Instead of maybe storing its own sysroot and maybe deferring to the one in `Session::opts`, just clone the latter when necessary so one is always directly available. This removes the need for the getter. --- src/librustc/session/mod.rs | 24 ++++++++---------------- src/librustc_codegen_llvm/back/link.rs | 3 +-- src/librustc_codegen_ssa/back/linker.rs | 3 +-- src/librustc_driver/lib.rs | 2 +- src/librustc_metadata/locator.rs | 2 +- 5 files changed, 12 insertions(+), 22 deletions(-) diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs index 1187c53305d1c..79441eec3922f 100644 --- a/src/librustc/session/mod.rs +++ b/src/librustc/session/mod.rs @@ -48,7 +48,7 @@ use std::cell::{self, Cell, RefCell}; use std::env; use std::fmt; use std::io::Write; -use std::path::{Path, PathBuf}; +use std::path::PathBuf; use std::time::Duration; use std::sync::mpsc; use std::sync::atomic::{AtomicUsize, Ordering}; @@ -69,7 +69,7 @@ pub struct Session { pub entry_fn: Once>, pub plugin_registrar_fn: Once>, pub derive_registrar_fn: Once>, - pub default_sysroot: Option, + pub sysroot: PathBuf, /// The name of the root source file of the crate, in the local file system. /// `None` means that there is no source file. pub local_crate_source_file: Option, @@ -694,17 +694,9 @@ impl Session { ) } - pub fn sysroot<'a>(&'a self) -> &'a Path { - match self.opts.maybe_sysroot { - Some(ref sysroot) => sysroot, - None => self.default_sysroot - .as_ref() - .expect("missing sysroot and default_sysroot in Session"), - } - } pub fn target_filesearch(&self, kind: PathKind) -> filesearch::FileSearch<'_> { filesearch::FileSearch::new( - self.sysroot(), + &self.sysroot, self.opts.target_triple.triple(), &self.opts.search_paths, kind, @@ -712,7 +704,7 @@ impl Session { } pub fn host_filesearch(&self, kind: PathKind) -> filesearch::FileSearch<'_> { filesearch::FileSearch::new( - self.sysroot(), + &self.sysroot, config::host_triple(), &self.opts.search_paths, kind, @@ -1109,9 +1101,9 @@ pub fn build_session_( let target_cfg = config::build_target_config(&sopts, &span_diagnostic); let p_s = parse::ParseSess::with_span_handler(span_diagnostic, source_map); - let default_sysroot = match sopts.maybe_sysroot { - Some(_) => None, - None => Some(filesearch::get_or_default_sysroot()), + let sysroot = match &sopts.maybe_sysroot { + Some(sysroot) => sysroot.clone(), + None => filesearch::get_or_default_sysroot(), }; let file_path_mapping = sopts.file_path_mapping(); @@ -1147,7 +1139,7 @@ pub fn build_session_( entry_fn: Once::new(), plugin_registrar_fn: Once::new(), derive_registrar_fn: Once::new(), - default_sysroot, + sysroot, local_crate_source_file, working_dir, lint_store: RwLock::new(lint::LintStore::new()), diff --git a/src/librustc_codegen_llvm/back/link.rs b/src/librustc_codegen_llvm/back/link.rs index 89d84acdd8876..60dc1a72a3295 100644 --- a/src/librustc_codegen_llvm/back/link.rs +++ b/src/librustc_codegen_llvm/back/link.rs @@ -1024,11 +1024,10 @@ fn link_args(cmd: &mut dyn Linker, // where extern libraries might live, based on the // addl_lib_search_paths if sess.opts.cg.rpath { - let sysroot = sess.sysroot(); let target_triple = sess.opts.target_triple.triple(); let mut get_install_prefix_lib_path = || { let install_prefix = option_env!("CFG_PREFIX").expect("CFG_PREFIX"); - let tlib = filesearch::relative_target_lib_path(sysroot, target_triple); + let tlib = filesearch::relative_target_lib_path(&sess.sysroot, target_triple); let mut path = PathBuf::from(install_prefix); path.push(&tlib); diff --git a/src/librustc_codegen_ssa/back/linker.rs b/src/librustc_codegen_ssa/back/linker.rs index ec5ca5801049e..c15ac12401582 100644 --- a/src/librustc_codegen_ssa/back/linker.rs +++ b/src/librustc_codegen_ssa/back/linker.rs @@ -606,8 +606,7 @@ impl<'a> Linker for MsvcLinker<'a> { self.cmd.arg("/DEBUG"); // This will cause the Microsoft linker to embed .natvis info into the PDB file - let sysroot = self.sess.sysroot(); - let natvis_dir_path = sysroot.join("lib\\rustlib\\etc"); + let natvis_dir_path = self.sess.sysroot.join("lib\\rustlib\\etc"); if let Ok(natvis_dir) = fs::read_dir(&natvis_dir_path) { // LLVM 5.0.0's lld-link frontend doesn't yet recognize, and chokes // on, the /NATVIS:... flags. LLVM 6 (or earlier) should at worst ignore diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index ec3cb95db88f8..960cdcb1a95b1 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -1042,7 +1042,7 @@ impl RustcDefaultCalls { targets.sort(); println!("{}", targets.join("\n")); }, - Sysroot => println!("{}", sess.sysroot().display()), + Sysroot => println!("{}", sess.sysroot.display()), TargetSpec => println!("{}", sess.target.target.to_json().pretty()), FileNames | CrateName => { let input = input.unwrap_or_else(|| diff --git a/src/librustc_metadata/locator.rs b/src/librustc_metadata/locator.rs index 528c96f240dba..f58cc00477789 100644 --- a/src/librustc_metadata/locator.rs +++ b/src/librustc_metadata/locator.rs @@ -678,7 +678,7 @@ impl<'a> Context<'a> { // candidates are all canonicalized, so we canonicalize the sysroot // as well. if let Some((ref prev, _)) = ret { - let sysroot = self.sess.sysroot(); + let sysroot = &self.sess.sysroot; let sysroot = sysroot.canonicalize() .unwrap_or_else(|_| sysroot.to_path_buf()); if prev.starts_with(&sysroot) { From 057e6d3a35a54e8b88c2cef1e6a1b9e590066276 Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Sun, 25 Nov 2018 17:33:16 +0100 Subject: [PATCH 24/50] Add TryFrom<&[T]> for [T; $N] where T: Copy `TryFrom<&[T]> for &[T; $N]` (note *reference* to an array) already exists, but not needing to dereference makes type inference easier for example when using `u32::from_be_bytes`. Also add doc examples doing just that. --- src/libcore/array.rs | 9 +++++ src/libcore/num/mod.rs | 78 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 87 insertions(+) diff --git a/src/libcore/array.rs b/src/libcore/array.rs index 3d24f8902bd83..26e7a79d35df6 100644 --- a/src/libcore/array.rs +++ b/src/libcore/array.rs @@ -148,6 +148,15 @@ macro_rules! array_impls { } } + #[unstable(feature = "try_from", issue = "33417")] + impl<'a, T> TryFrom<&'a [T]> for [T; $N] where T: Copy { + type Error = TryFromSliceError; + + fn try_from(slice: &[T]) -> Result<[T; $N], TryFromSliceError> { + <&Self>::try_from(slice).map(|r| *r) + } + } + #[unstable(feature = "try_from", issue = "33417")] impl<'a, T> TryFrom<&'a [T]> for &'a [T; $N] { type Error = TryFromSliceError; diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs index 9deae12482976..f6f649bc06d01 100644 --- a/src/libcore/num/mod.rs +++ b/src/libcore/num/mod.rs @@ -1989,6 +1989,19 @@ big endian. ``` let value = ", stringify!($SelfT), "::from_be_bytes(", $be_bytes, "); assert_eq!(value, ", $swap_op, "); +``` + +When starting from a slice rather than an array, fallible conversion APIs can be used: + +``` +#![feature(try_from)] +use std::convert::TryInto; + +fn read_be_", stringify!($SelfT), "(input: &mut &[u8]) -> ", stringify!($SelfT), " { + let (int_bytes, rest) = input.split_at(std::mem::size_of::<", stringify!($SelfT), ">()); + *input = rest; + ", stringify!($SelfT), "::from_be_bytes(int_bytes.try_into().unwrap()) +} ```"), #[stable(feature = "int_to_from_bytes", since = "1.32.0")] #[rustc_const_unstable(feature = "const_int_conversion")] @@ -2008,6 +2021,19 @@ little endian. ``` let value = ", stringify!($SelfT), "::from_le_bytes(", $le_bytes, "); assert_eq!(value, ", $swap_op, "); +``` + +When starting from a slice rather than an array, fallible conversion APIs can be used: + +``` +#![feature(try_from)] +use std::convert::TryInto; + +fn read_be_", stringify!($SelfT), "(input: &mut &[u8]) -> ", stringify!($SelfT), " { + let (int_bytes, rest) = input.split_at(std::mem::size_of::<", stringify!($SelfT), ">()); + *input = rest; + ", stringify!($SelfT), "::from_be_bytes(int_bytes.try_into().unwrap()) +} ```"), #[stable(feature = "int_to_from_bytes", since = "1.32.0")] #[rustc_const_unstable(feature = "const_int_conversion")] @@ -2037,6 +2063,19 @@ let value = ", stringify!($SelfT), "::from_ne_bytes(if cfg!(target_endian = \"bi ", $le_bytes, " }); assert_eq!(value, ", $swap_op, "); +``` + +When starting from a slice rather than an array, fallible conversion APIs can be used: + +``` +#![feature(try_from)] +use std::convert::TryInto; + +fn read_be_", stringify!($SelfT), "(input: &mut &[u8]) -> ", stringify!($SelfT), " { + let (int_bytes, rest) = input.split_at(std::mem::size_of::<", stringify!($SelfT), ">()); + *input = rest; + ", stringify!($SelfT), "::from_be_bytes(int_bytes.try_into().unwrap()) +} ```"), #[stable(feature = "int_to_from_bytes", since = "1.32.0")] #[rustc_const_unstable(feature = "const_int_conversion")] @@ -3719,6 +3758,19 @@ big endian. ``` let value = ", stringify!($SelfT), "::from_be_bytes(", $be_bytes, "); assert_eq!(value, ", $swap_op, "); +``` + +When starting from a slice rather than an array, fallible conversion APIs can be used: + +``` +#![feature(try_from)] +use std::convert::TryInto; + +fn read_be_", stringify!($SelfT), "(input: &mut &[u8]) -> ", stringify!($SelfT), " { + let (int_bytes, rest) = input.split_at(std::mem::size_of::<", stringify!($SelfT), ">()); + *input = rest; + ", stringify!($SelfT), "::from_be_bytes(int_bytes.try_into().unwrap()) +} ```"), #[stable(feature = "int_to_from_bytes", since = "1.32.0")] #[rustc_const_unstable(feature = "const_int_conversion")] @@ -3738,6 +3790,19 @@ little endian. ``` let value = ", stringify!($SelfT), "::from_le_bytes(", $le_bytes, "); assert_eq!(value, ", $swap_op, "); +``` + +When starting from a slice rather than an array, fallible conversion APIs can be used: + +``` +#![feature(try_from)] +use std::convert::TryInto; + +fn read_be_", stringify!($SelfT), "(input: &mut &[u8]) -> ", stringify!($SelfT), " { + let (int_bytes, rest) = input.split_at(std::mem::size_of::<", stringify!($SelfT), ">()); + *input = rest; + ", stringify!($SelfT), "::from_be_bytes(int_bytes.try_into().unwrap()) +} ```"), #[stable(feature = "int_to_from_bytes", since = "1.32.0")] #[rustc_const_unstable(feature = "const_int_conversion")] @@ -3767,6 +3832,19 @@ let value = ", stringify!($SelfT), "::from_ne_bytes(if cfg!(target_endian = \"bi ", $le_bytes, " }); assert_eq!(value, ", $swap_op, "); +``` + +When starting from a slice rather than an array, fallible conversion APIs can be used: + +``` +#![feature(try_from)] +use std::convert::TryInto; + +fn read_be_", stringify!($SelfT), "(input: &mut &[u8]) -> ", stringify!($SelfT), " { + let (int_bytes, rest) = input.split_at(std::mem::size_of::<", stringify!($SelfT), ">()); + *input = rest; + ", stringify!($SelfT), "::from_be_bytes(int_bytes.try_into().unwrap()) +} ```"), #[stable(feature = "int_to_from_bytes", since = "1.32.0")] #[rustc_const_unstable(feature = "const_int_conversion")] From 8e75844d95284599d6ea3c43cb1bb82e9292ebe7 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 22 Nov 2018 16:33:07 +1100 Subject: [PATCH 25/50] Introduce `SearchPath` and replace `SearchPaths` with `Vec`. It's more idiomatic, makes the code shorter, and will help with the next commit. --- src/librustc/session/config.rs | 51 ++++++++++++----------- src/librustc/session/filesearch.rs | 33 +++++++-------- src/librustc/session/search_paths.rs | 57 +++++++++----------------- src/librustc_codegen_llvm/back/link.rs | 12 +++--- src/librustdoc/config.rs | 11 +++-- src/librustdoc/core.rs | 2 +- src/librustdoc/test.rs | 8 ++-- 7 files changed, 79 insertions(+), 95 deletions(-) diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index 3fd22793a08a0..c5799d9130256 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -14,7 +14,7 @@ use std::str::FromStr; use session::{early_error, early_warn, Session}; -use session::search_paths::SearchPaths; +use session::search_paths::SearchPath; use rustc_target::spec::{LinkerFlavor, PanicStrategy, RelroLevel}; use rustc_target::spec::{Target, TargetTriple}; @@ -374,7 +374,7 @@ top_level_options!( lint_cap: Option [TRACKED], describe_lints: bool [UNTRACKED], output_types: OutputTypes [TRACKED], - search_paths: SearchPaths [UNTRACKED], + search_paths: Vec [UNTRACKED], libs: Vec<(String, Option, Option)> [TRACKED], maybe_sysroot: Option [TRACKED], @@ -593,7 +593,7 @@ impl Default for Options { lint_cap: None, describe_lints: false, output_types: OutputTypes(BTreeMap::new()), - search_paths: SearchPaths::new(), + search_paths: vec![], maybe_sysroot: None, target_triple: TargetTriple::from_triple(host_triple()), test: false, @@ -2112,9 +2112,9 @@ pub fn build_session_options_and_crate_config( } }; - let mut search_paths = SearchPaths::new(); + let mut search_paths = vec![]; for s in &matches.opt_strs("L") { - search_paths.add_path(&s[..], error_format); + search_paths.push(SearchPath::from_cli_opt(&s[..], error_format)); } let libs = matches @@ -2532,6 +2532,7 @@ mod tests { use session::config::{build_configuration, build_session_options_and_crate_config}; use session::config::{LtoCli, CrossLangLto}; use session::build_session; + use session::search_paths::SearchPath; use std::collections::{BTreeMap, BTreeSet}; use std::iter::FromIterator; use std::path::PathBuf; @@ -2787,48 +2788,48 @@ mod tests { // Reference v1.search_paths - .add_path("native=abc", super::ErrorOutputType::Json(false)); + .push(SearchPath::from_cli_opt("native=abc", super::ErrorOutputType::Json(false))); v1.search_paths - .add_path("crate=def", super::ErrorOutputType::Json(false)); + .push(SearchPath::from_cli_opt("crate=def", super::ErrorOutputType::Json(false))); v1.search_paths - .add_path("dependency=ghi", super::ErrorOutputType::Json(false)); + .push(SearchPath::from_cli_opt("dependency=ghi", super::ErrorOutputType::Json(false))); v1.search_paths - .add_path("framework=jkl", super::ErrorOutputType::Json(false)); + .push(SearchPath::from_cli_opt("framework=jkl", super::ErrorOutputType::Json(false))); v1.search_paths - .add_path("all=mno", super::ErrorOutputType::Json(false)); + .push(SearchPath::from_cli_opt("all=mno", super::ErrorOutputType::Json(false))); v2.search_paths - .add_path("native=abc", super::ErrorOutputType::Json(false)); + .push(SearchPath::from_cli_opt("native=abc", super::ErrorOutputType::Json(false))); v2.search_paths - .add_path("dependency=ghi", super::ErrorOutputType::Json(false)); + .push(SearchPath::from_cli_opt("dependency=ghi", super::ErrorOutputType::Json(false))); v2.search_paths - .add_path("crate=def", super::ErrorOutputType::Json(false)); + .push(SearchPath::from_cli_opt("crate=def", super::ErrorOutputType::Json(false))); v2.search_paths - .add_path("framework=jkl", super::ErrorOutputType::Json(false)); + .push(SearchPath::from_cli_opt("framework=jkl", super::ErrorOutputType::Json(false))); v2.search_paths - .add_path("all=mno", super::ErrorOutputType::Json(false)); + .push(SearchPath::from_cli_opt("all=mno", super::ErrorOutputType::Json(false))); v3.search_paths - .add_path("crate=def", super::ErrorOutputType::Json(false)); + .push(SearchPath::from_cli_opt("crate=def", super::ErrorOutputType::Json(false))); v3.search_paths - .add_path("framework=jkl", super::ErrorOutputType::Json(false)); + .push(SearchPath::from_cli_opt("framework=jkl", super::ErrorOutputType::Json(false))); v3.search_paths - .add_path("native=abc", super::ErrorOutputType::Json(false)); + .push(SearchPath::from_cli_opt("native=abc", super::ErrorOutputType::Json(false))); v3.search_paths - .add_path("dependency=ghi", super::ErrorOutputType::Json(false)); + .push(SearchPath::from_cli_opt("dependency=ghi", super::ErrorOutputType::Json(false))); v3.search_paths - .add_path("all=mno", super::ErrorOutputType::Json(false)); + .push(SearchPath::from_cli_opt("all=mno", super::ErrorOutputType::Json(false))); v4.search_paths - .add_path("all=mno", super::ErrorOutputType::Json(false)); + .push(SearchPath::from_cli_opt("all=mno", super::ErrorOutputType::Json(false))); v4.search_paths - .add_path("native=abc", super::ErrorOutputType::Json(false)); + .push(SearchPath::from_cli_opt("native=abc", super::ErrorOutputType::Json(false))); v4.search_paths - .add_path("crate=def", super::ErrorOutputType::Json(false)); + .push(SearchPath::from_cli_opt("crate=def", super::ErrorOutputType::Json(false))); v4.search_paths - .add_path("dependency=ghi", super::ErrorOutputType::Json(false)); + .push(SearchPath::from_cli_opt("dependency=ghi", super::ErrorOutputType::Json(false))); v4.search_paths - .add_path("framework=jkl", super::ErrorOutputType::Json(false)); + .push(SearchPath::from_cli_opt("framework=jkl", super::ErrorOutputType::Json(false))); assert!(v1.dep_tracking_hash() == v2.dep_tracking_hash()); assert!(v1.dep_tracking_hash() == v3.dep_tracking_hash()); diff --git a/src/librustc/session/filesearch.rs b/src/librustc/session/filesearch.rs index 2b84317b3d6dd..d9abbe6cf6925 100644 --- a/src/librustc/session/filesearch.rs +++ b/src/librustc/session/filesearch.rs @@ -18,7 +18,7 @@ use std::env; use std::fs; use std::path::{Path, PathBuf}; -use session::search_paths::{SearchPaths, PathKind}; +use session::search_paths::{SearchPath, PathKind}; use rustc_fs_util::fix_windows_verbatim_for_gcc; #[derive(Copy, Clone)] @@ -31,27 +31,28 @@ pub enum FileMatch { pub struct FileSearch<'a> { pub sysroot: &'a Path, - pub search_paths: &'a SearchPaths, + pub search_paths: &'a [SearchPath], pub triple: &'a str, pub kind: PathKind, } impl<'a> FileSearch<'a> { pub fn for_each_lib_search_path(&self, mut f: F) where - F: FnMut(&Path, PathKind) + F: FnMut(&SearchPath) { let mut visited_dirs = FxHashSet::default(); - visited_dirs.reserve(self.search_paths.paths.len() + 1); - for (path, kind) in self.search_paths.iter(self.kind) { - f(path, kind); - visited_dirs.insert(path.to_path_buf()); + visited_dirs.reserve(self.search_paths.len() + 1); + let iter = self.search_paths.iter().filter(|sp| sp.kind.matches(self.kind)); + for search_path in iter { + f(search_path); + visited_dirs.insert(search_path.dir.to_path_buf()); } debug!("filesearch: searching lib path"); let tlib_path = make_target_lib_path(self.sysroot, self.triple); if !visited_dirs.contains(&tlib_path) { - f(&tlib_path, PathKind::All); + f(&SearchPath { kind: PathKind::All, dir: tlib_path }); } } @@ -62,9 +63,9 @@ impl<'a> FileSearch<'a> { pub fn search(&self, mut pick: F) where F: FnMut(&Path, PathKind) -> FileMatch { - self.for_each_lib_search_path(|lib_search_path, kind| { - debug!("searching {}", lib_search_path.display()); - let files = match fs::read_dir(lib_search_path) { + self.for_each_lib_search_path(|search_path| { + debug!("searching {}", search_path.dir.display()); + let files = match fs::read_dir(&search_path.dir) { Ok(files) => files, Err(..) => return, }; @@ -81,7 +82,7 @@ impl<'a> FileSearch<'a> { let files2 = files.iter().filter(|p| !is_rlib(p)); for path in files1.chain(files2) { debug!("testing {}", path.display()); - let maybe_picked = pick(path, kind); + let maybe_picked = pick(path, search_path.kind); match maybe_picked { FileMatches => { debug!("picked {}", path.display()); @@ -96,7 +97,7 @@ impl<'a> FileSearch<'a> { pub fn new(sysroot: &'a Path, triple: &'a str, - search_paths: &'a SearchPaths, + search_paths: &'a Vec, kind: PathKind) -> FileSearch<'a> { debug!("using sysroot = {}, triple = {}", sysroot.display(), triple); FileSearch { @@ -110,8 +111,8 @@ impl<'a> FileSearch<'a> { // Returns a list of directories where target-specific dylibs might be located. pub fn get_dylib_search_paths(&self) -> Vec { let mut paths = Vec::new(); - self.for_each_lib_search_path(|lib_search_path, _| { - paths.push(lib_search_path.to_path_buf()); + self.for_each_lib_search_path(|search_path| { + paths.push(search_path.dir.to_path_buf()); }); paths } @@ -136,7 +137,7 @@ pub fn relative_target_lib_path(sysroot: &Path, target_triple: &str) -> PathBuf p } -fn make_target_lib_path(sysroot: &Path, +pub fn make_target_lib_path(sysroot: &Path, target_triple: &str) -> PathBuf { sysroot.join(&relative_target_lib_path(sysroot, target_triple)) } diff --git a/src/librustc/session/search_paths.rs b/src/librustc/session/search_paths.rs index 768d4f1e5fb65..7a0bd2ed439b2 100644 --- a/src/librustc/session/search_paths.rs +++ b/src/librustc/session/search_paths.rs @@ -8,18 +8,14 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use std::slice; use std::path::{Path, PathBuf}; use session::{early_error, config}; +use session::filesearch::make_target_lib_path; #[derive(Clone, Debug)] -pub struct SearchPaths { - crate paths: Vec<(PathKind, PathBuf)>, -} - -pub struct Iter<'a> { - kind: PathKind, - iter: slice::Iter<'a, (PathKind, PathBuf)>, +pub struct SearchPath { + pub kind: PathKind, + pub dir: PathBuf, } #[derive(Eq, PartialEq, Clone, Copy, Debug, PartialOrd, Ord, Hash)] @@ -32,12 +28,17 @@ pub enum PathKind { All, } -impl SearchPaths { - pub fn new() -> SearchPaths { - SearchPaths { paths: Vec::new() } +impl PathKind { + pub fn matches(&self, kind: PathKind) -> bool { + match (self, kind) { + (PathKind::All, _) | (_, PathKind::All) => true, + _ => *self == kind, + } } +} - pub fn add_path(&mut self, path: &str, output: config::ErrorOutputType) { +impl SearchPath { + pub fn from_cli_opt(path: &str, output: config::ErrorOutputType) -> Self { let (kind, path) = if path.starts_with("native=") { (PathKind::Native, &path["native=".len()..]) } else if path.starts_with("crate=") { @@ -54,35 +55,17 @@ impl SearchPaths { if path.is_empty() { early_error(output, "empty search path given via `-L`"); } - self.paths.push((kind, PathBuf::from(path))); - } - pub fn iter(&self, kind: PathKind) -> Iter<'_> { - Iter { kind: kind, iter: self.paths.iter() } + let dir = PathBuf::from(path); + Self::new(kind, dir) } -} - -impl<'a> Iterator for Iter<'a> { - type Item = (&'a Path, PathKind); - fn next(&mut self) -> Option<(&'a Path, PathKind)> { - loop { - match self.iter.next() { - Some(&(kind, ref p)) if self.kind == PathKind::All || - kind == PathKind::All || - kind == self.kind => { - return Some((p, kind)) - } - Some(..) => {} - None => return None, - } - } + pub fn from_sysroot_and_triple(sysroot: &Path, triple: &str) -> Self { + Self::new(PathKind::All, make_target_lib_path(sysroot, triple)) } - fn size_hint(&self) -> (usize, Option) { - // This iterator will never return more elements than the base iterator; - // but it can ignore all the remaining elements. - let (_, upper) = self.iter.size_hint(); - (0, upper) + fn new(kind: PathKind, dir: PathBuf) -> Self { + SearchPath { kind, dir } } } + diff --git a/src/librustc_codegen_llvm/back/link.rs b/src/librustc_codegen_llvm/back/link.rs index 60dc1a72a3295..392e3ff3a8812 100644 --- a/src/librustc_codegen_llvm/back/link.rs +++ b/src/librustc_codegen_llvm/back/link.rs @@ -213,8 +213,8 @@ fn link_binary_output(sess: &Session, fn archive_search_paths(sess: &Session) -> Vec { let mut search = Vec::new(); - sess.target_filesearch(PathKind::Native).for_each_lib_search_path(|path, _| { - search.push(path.to_path_buf()); + sess.target_filesearch(PathKind::Native).for_each_lib_search_path(|search_path| { + search.push(search_path.dir.to_path_buf()); }); search @@ -1067,10 +1067,10 @@ fn link_args(cmd: &mut dyn Linker, fn add_local_native_libraries(cmd: &mut dyn Linker, sess: &Session, codegen_results: &CodegenResults) { - sess.target_filesearch(PathKind::All).for_each_lib_search_path(|path, k| { - match k { - PathKind::Framework => { cmd.framework_path(path); } - _ => { cmd.include_path(&fix_windows_verbatim_for_gcc(path)); } + sess.target_filesearch(PathKind::All).for_each_lib_search_path(|search_path| { + match search_path.kind { + PathKind::Framework => { cmd.framework_path(&search_path.dir); } + _ => { cmd.include_path(&fix_windows_verbatim_for_gcc(&search_path.dir)); } } }); diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs index f4d05c6dbd65c..b421f07ddafa2 100644 --- a/src/librustdoc/config.rs +++ b/src/librustdoc/config.rs @@ -20,7 +20,7 @@ use rustc::session::early_error; use rustc::session::config::{CodegenOptions, DebuggingOptions, ErrorOutputType, Externs}; use rustc::session::config::{nightly_options, build_codegen_options, build_debugging_options, get_cmd_lint_options}; -use rustc::session::search_paths::SearchPaths; +use rustc::session::search_paths::SearchPath; use rustc_driver; use rustc_target::spec::TargetTriple; use syntax::edition::Edition; @@ -46,7 +46,7 @@ pub struct Options { /// How to format errors and warnings. pub error_format: ErrorOutputType, /// Library search paths to hand to the compiler. - pub libs: SearchPaths, + pub libs: Vec, /// The list of external crates to link against. pub externs: Externs, /// List of `cfg` flags to hand to the compiler. Always includes `rustdoc`. @@ -295,10 +295,9 @@ impl Options { } let input = PathBuf::from(&matches.free[0]); - let mut libs = SearchPaths::new(); - for s in &matches.opt_strs("L") { - libs.add_path(s, error_format); - } + let libs = matches.opt_strs("L").iter() + .map(|s| SearchPath::from_cli_opt(s, error_format)) + .collect(); let externs = match parse_externs(&matches) { Ok(ex) => ex, Err(err) => { diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index aac0f9f94e329..9502993ed243c 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -51,7 +51,7 @@ use html::render::RenderInfo; use passes; pub use rustc::session::config::{Input, Options, CodegenOptions}; -pub use rustc::session::search_paths::SearchPaths; +pub use rustc::session::search_paths::SearchPath; pub type ExternalPaths = FxHashMap, clean::TypeKind)>; diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs index d9bab91fd0c78..918fdc1f38a48 100644 --- a/src/librustdoc/test.rs +++ b/src/librustdoc/test.rs @@ -25,7 +25,7 @@ use rustc::hir; use rustc::hir::intravisit; use rustc::session::{self, CompileIncomplete, config}; use rustc::session::config::{OutputType, OutputTypes, Externs, CodegenOptions}; -use rustc::session::search_paths::{SearchPaths, PathKind}; +use rustc::session::search_paths::{SearchPath, PathKind}; use rustc_metadata::dynamic_lib::DynamicLibrary; use tempfile::Builder as TempFileBuilder; use rustc_driver::{self, driver, target_features, Compilation}; @@ -187,7 +187,7 @@ fn scrape_test_config(krate: &::rustc::hir::Crate) -> TestOptions { } fn run_test(test: &str, cratename: &str, filename: &FileName, line: usize, - cfgs: Vec, libs: SearchPaths, + cfgs: Vec, libs: Vec, cg: CodegenOptions, externs: Externs, should_panic: bool, no_run: bool, as_test_harness: bool, compile_fail: bool, mut error_codes: Vec, opts: &TestOptions, @@ -557,7 +557,7 @@ pub struct Collector { names: Vec, cfgs: Vec, - libs: SearchPaths, + libs: Vec, cg: CodegenOptions, externs: Externs, use_headers: bool, @@ -572,7 +572,7 @@ pub struct Collector { } impl Collector { - pub fn new(cratename: String, cfgs: Vec, libs: SearchPaths, cg: CodegenOptions, + pub fn new(cratename: String, cfgs: Vec, libs: Vec, cg: CodegenOptions, externs: Externs, use_headers: bool, opts: TestOptions, maybe_sysroot: Option, source_map: Option>, filename: Option, linker: Option, edition: Edition) -> Collector { From ca82a8238520de6add93e9bd6d8a56935b88931d Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 20 Nov 2018 11:06:45 +1100 Subject: [PATCH 26/50] Avoid regenerating the `Vec` in `FileSearch::search()`. `FileSearch::search()` traverses one or more directories. For each directory it generates a `Vec` containing one element per file in that directory. In some benchmarks this occurs enough that the allocations done for the `PathBuf`s are significant, and in practice a small number of directories are being traversed over and over again. For example, when compiling the `tokio-webpush-simple` benchmark, two directories are traversed 58 times each. Each of these directories have more than 100 files. This commit changes things so that all the `Vec`s that will be needed by a `Session` are precomputed when that `Session` is created; they are stored in `SearchPath`. `FileSearch` gets a reference to the necessary `SearchPath`s. This reduces instruction counts on several benchmarks by 1--5%. The commit also removes the barely-used `visited_dirs` hash in `for_each_lib_searchPath`. It only detects if `tlib_path` is the same as one of the previously seen paths, which is unlikely. --- src/librustc/session/filesearch.rs | 34 +++++++++------------------- src/librustc/session/mod.rs | 19 +++++++++++++++- src/librustc/session/search_paths.rs | 14 +++++++++++- 3 files changed, 42 insertions(+), 25 deletions(-) diff --git a/src/librustc/session/filesearch.rs b/src/librustc/session/filesearch.rs index d9abbe6cf6925..73fb95bd9744b 100644 --- a/src/librustc/session/filesearch.rs +++ b/src/librustc/session/filesearch.rs @@ -12,7 +12,6 @@ pub use self::FileMatch::*; -use rustc_data_structures::fx::FxHashSet; use std::borrow::Cow; use std::env; use std::fs; @@ -31,8 +30,9 @@ pub enum FileMatch { pub struct FileSearch<'a> { pub sysroot: &'a Path, - pub search_paths: &'a [SearchPath], pub triple: &'a str, + pub search_paths: &'a [SearchPath], + pub tlib_path: &'a SearchPath, pub kind: PathKind, } @@ -40,20 +40,12 @@ impl<'a> FileSearch<'a> { pub fn for_each_lib_search_path(&self, mut f: F) where F: FnMut(&SearchPath) { - let mut visited_dirs = FxHashSet::default(); - visited_dirs.reserve(self.search_paths.len() + 1); let iter = self.search_paths.iter().filter(|sp| sp.kind.matches(self.kind)); for search_path in iter { f(search_path); - visited_dirs.insert(search_path.dir.to_path_buf()); } - debug!("filesearch: searching lib path"); - let tlib_path = make_target_lib_path(self.sysroot, - self.triple); - if !visited_dirs.contains(&tlib_path) { - f(&SearchPath { kind: PathKind::All, dir: tlib_path }); - } + f(self.tlib_path); } pub fn get_lib_path(&self) -> PathBuf { @@ -65,12 +57,6 @@ impl<'a> FileSearch<'a> { { self.for_each_lib_search_path(|search_path| { debug!("searching {}", search_path.dir.display()); - let files = match fs::read_dir(&search_path.dir) { - Ok(files) => files, - Err(..) => return, - }; - let files = files.filter_map(|p| p.ok().map(|s| s.path())) - .collect::>(); fn is_rlib(p: &Path) -> bool { p.extension() == Some("rlib".as_ref()) } @@ -78,8 +64,8 @@ impl<'a> FileSearch<'a> { // an rlib and a dylib we only read one of the files of // metadata, so in the name of speed, bring all rlib files to // the front of the search list. - let files1 = files.iter().filter(|p| is_rlib(p)); - let files2 = files.iter().filter(|p| !is_rlib(p)); + let files1 = search_path.files.iter().filter(|p| is_rlib(p)); + let files2 = search_path.files.iter().filter(|p| !is_rlib(p)); for path in files1.chain(files2) { debug!("testing {}", path.display()); let maybe_picked = pick(path, search_path.kind); @@ -98,12 +84,15 @@ impl<'a> FileSearch<'a> { pub fn new(sysroot: &'a Path, triple: &'a str, search_paths: &'a Vec, - kind: PathKind) -> FileSearch<'a> { + tlib_path: &'a SearchPath, + kind: PathKind) + -> FileSearch<'a> { debug!("using sysroot = {}, triple = {}", sysroot.display(), triple); FileSearch { sysroot, - search_paths, triple, + search_paths, + tlib_path, kind, } } @@ -137,8 +126,7 @@ pub fn relative_target_lib_path(sysroot: &Path, target_triple: &str) -> PathBuf p } -pub fn make_target_lib_path(sysroot: &Path, - target_triple: &str) -> PathBuf { +pub fn make_target_lib_path(sysroot: &Path, target_triple: &str) -> PathBuf { sysroot.join(&relative_target_lib_path(sysroot, target_triple)) } diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs index 79441eec3922f..6b323d89ed0dd 100644 --- a/src/librustc/session/mod.rs +++ b/src/librustc/session/mod.rs @@ -19,8 +19,8 @@ use lint; use lint::builtin::BuiltinLintDiagnostics; use middle::allocator::AllocatorKind; use middle::dependency_format; -use session::search_paths::PathKind; use session::config::{OutputType, Lto}; +use session::search_paths::{PathKind, SearchPath}; use util::nodemap::{FxHashMap, FxHashSet}; use util::common::{duration_to_secs_str, ErrorReported}; use util::common::ProfileQueriesMsg; @@ -64,6 +64,9 @@ pub struct Session { pub target: config::Config, pub host: Target, pub opts: config::Options, + pub host_tlib_path: SearchPath, + /// This is `None` if the host and target are the same. + pub target_tlib_path: Option, pub parse_sess: ParseSess, /// For a library crate, this is always none pub entry_fn: Once>, @@ -699,6 +702,8 @@ impl Session { &self.sysroot, self.opts.target_triple.triple(), &self.opts.search_paths, + // target_tlib_path==None means it's the same as host_tlib_path. + self.target_tlib_path.as_ref().unwrap_or(&self.host_tlib_path), kind, ) } @@ -707,6 +712,7 @@ impl Session { &self.sysroot, config::host_triple(), &self.opts.search_paths, + &self.host_tlib_path, kind, ) } @@ -1106,6 +1112,15 @@ pub fn build_session_( None => filesearch::get_or_default_sysroot(), }; + let host_triple = config::host_triple(); + let target_triple = sopts.target_triple.triple(); + let host_tlib_path = SearchPath::from_sysroot_and_triple(&sysroot, host_triple); + let target_tlib_path = if host_triple == target_triple { + None + } else { + Some(SearchPath::from_sysroot_and_triple(&sysroot, target_triple)) + }; + let file_path_mapping = sopts.file_path_mapping(); let local_crate_source_file = @@ -1134,6 +1149,8 @@ pub fn build_session_( target: target_cfg, host, opts: sopts, + host_tlib_path, + target_tlib_path, parse_sess: p_s, // For a library crate, this is always none entry_fn: Once::new(), diff --git a/src/librustc/session/search_paths.rs b/src/librustc/session/search_paths.rs index 7a0bd2ed439b2..5c44a07f84341 100644 --- a/src/librustc/session/search_paths.rs +++ b/src/librustc/session/search_paths.rs @@ -16,6 +16,7 @@ use session::filesearch::make_target_lib_path; pub struct SearchPath { pub kind: PathKind, pub dir: PathBuf, + pub files: Vec, } #[derive(Eq, PartialEq, Clone, Copy, Debug, PartialOrd, Ord, Hash)] @@ -65,7 +66,18 @@ impl SearchPath { } fn new(kind: PathKind, dir: PathBuf) -> Self { - SearchPath { kind, dir } + // Get the files within the directory. + let files = match std::fs::read_dir(&dir) { + Ok(files) => { + files.filter_map(|p| { + p.ok().map(|s| s.path()) + }) + .collect::>() + } + Err(..) => vec![], + }; + + SearchPath { kind, dir, files } } } From 2d2b7c01ebee3f2926af58b9461284e271955855 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Sun, 25 Nov 2018 15:43:00 -0700 Subject: [PATCH 27/50] Make JSON output from -Zprofile-json valid --- src/librustc/util/profiling.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc/util/profiling.rs b/src/librustc/util/profiling.rs index 6540a09d87763..bea3453b31adf 100644 --- a/src/librustc/util/profiling.rs +++ b/src/librustc/util/profiling.rs @@ -102,7 +102,7 @@ macro_rules! define_categories { }; json.push_str(&format!( - "{{ \"category\": {}, \"time_ms\": {}, + "{{ \"category\": \"{}\", \"time_ms\": {},\ \"query_count\": {}, \"query_hits\": {} }},", stringify!($name), self.times.$name / 1_000_000, From 4dd0f66f12564a9be2ebd1e1fb03f0b722a63a4d Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Fri, 23 Nov 2018 13:36:41 +1100 Subject: [PATCH 28/50] Replace `FileSearch::for_each_lib_search_path` with `search_paths`. Returning an iterator leads to nicer code all around. --- src/librustc/session/filesearch.rs | 40 +++++++++++--------------- src/librustc_codegen_llvm/back/link.rs | 12 +++----- src/librustc_driver/driver.rs | 2 +- 3 files changed, 22 insertions(+), 32 deletions(-) diff --git a/src/librustc/session/filesearch.rs b/src/librustc/session/filesearch.rs index 73fb95bd9744b..402f6216250d4 100644 --- a/src/librustc/session/filesearch.rs +++ b/src/librustc/session/filesearch.rs @@ -29,23 +29,19 @@ pub enum FileMatch { // A module for searching for libraries pub struct FileSearch<'a> { - pub sysroot: &'a Path, - pub triple: &'a str, - pub search_paths: &'a [SearchPath], - pub tlib_path: &'a SearchPath, - pub kind: PathKind, + sysroot: &'a Path, + triple: &'a str, + search_paths: &'a [SearchPath], + tlib_path: &'a SearchPath, + kind: PathKind, } impl<'a> FileSearch<'a> { - pub fn for_each_lib_search_path(&self, mut f: F) where - F: FnMut(&SearchPath) - { - let iter = self.search_paths.iter().filter(|sp| sp.kind.matches(self.kind)); - for search_path in iter { - f(search_path); - } - - f(self.tlib_path); + pub fn search_paths(&self) -> impl Iterator { + let kind = self.kind; + self.search_paths.iter() + .filter(move |sp| sp.kind.matches(kind)) + .chain(std::iter::once(self.tlib_path)) } pub fn get_lib_path(&self) -> PathBuf { @@ -55,7 +51,7 @@ impl<'a> FileSearch<'a> { pub fn search(&self, mut pick: F) where F: FnMut(&Path, PathKind) -> FileMatch { - self.for_each_lib_search_path(|search_path| { + for search_path in self.search_paths() { debug!("searching {}", search_path.dir.display()); fn is_rlib(p: &Path) -> bool { p.extension() == Some("rlib".as_ref()) @@ -78,7 +74,7 @@ impl<'a> FileSearch<'a> { } } } - }); + } } pub fn new(sysroot: &'a Path, @@ -97,13 +93,11 @@ impl<'a> FileSearch<'a> { } } - // Returns a list of directories where target-specific dylibs might be located. - pub fn get_dylib_search_paths(&self) -> Vec { - let mut paths = Vec::new(); - self.for_each_lib_search_path(|search_path| { - paths.push(search_path.dir.to_path_buf()); - }); - paths + // Returns just the directories within the search paths. + pub fn search_path_dirs(&self) -> Vec { + self.search_paths() + .map(|sp| sp.dir.to_path_buf()) + .collect() } // Returns a list of directories where target-specific tool binaries are located. diff --git a/src/librustc_codegen_llvm/back/link.rs b/src/librustc_codegen_llvm/back/link.rs index 392e3ff3a8812..6242ad80a8c90 100644 --- a/src/librustc_codegen_llvm/back/link.rs +++ b/src/librustc_codegen_llvm/back/link.rs @@ -212,12 +212,7 @@ fn link_binary_output(sess: &Session, } fn archive_search_paths(sess: &Session) -> Vec { - let mut search = Vec::new(); - sess.target_filesearch(PathKind::Native).for_each_lib_search_path(|search_path| { - search.push(search_path.dir.to_path_buf()); - }); - - search + sess.target_filesearch(PathKind::Native).search_path_dirs() } fn archive_config<'a>(sess: &'a Session, @@ -1067,12 +1062,13 @@ fn link_args(cmd: &mut dyn Linker, fn add_local_native_libraries(cmd: &mut dyn Linker, sess: &Session, codegen_results: &CodegenResults) { - sess.target_filesearch(PathKind::All).for_each_lib_search_path(|search_path| { + let filesearch = sess.target_filesearch(PathKind::All); + for search_path in filesearch.search_paths() { match search_path.kind { PathKind::Framework => { cmd.framework_path(&search_path.dir); } _ => { cmd.include_path(&fix_windows_verbatim_for_gcc(&search_path.dir)); } } - }); + } let relevant_libs = codegen_results.crate_info.used_libraries.iter().filter(|l| { relevant_lib(sess, l) diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index 7ad012409b53a..1ac3a9ff9c870 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -977,7 +977,7 @@ where let mut old_path = OsString::new(); if cfg!(windows) { old_path = env::var_os("PATH").unwrap_or(old_path); - let mut new_path = sess.host_filesearch(PathKind::All).get_dylib_search_paths(); + let mut new_path = sess.host_filesearch(PathKind::All).search_path_dirs(); for path in env::split_paths(&old_path) { if !new_path.contains(&path) { new_path.push(path); From cc466851bc458219121142ae75f5cc47bb3a927f Mon Sep 17 00:00:00 2001 From: Corey Farwell Date: Mon, 26 Nov 2018 08:40:34 -0500 Subject: [PATCH 29/50] Remove unsafe `unsafe` inner function. Within this `Iterator` implementation, a function `unsafe_get` is defined which unsafely allows _unchecked_ indexing of any element in a slice. This should be marked as _unsafe_, but it is not. To address this issue, I removed that inner function. --- src/libcore/str/lossy.rs | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/libcore/str/lossy.rs b/src/libcore/str/lossy.rs index 186d6adbc91cf..52abd8f99529b 100644 --- a/src/libcore/str/lossy.rs +++ b/src/libcore/str/lossy.rs @@ -62,18 +62,15 @@ impl<'a> Iterator for Utf8LossyChunksIter<'a> { } const TAG_CONT_U8: u8 = 128; - fn unsafe_get(xs: &[u8], i: usize) -> u8 { - unsafe { *xs.get_unchecked(i) } - } fn safe_get(xs: &[u8], i: usize) -> u8 { - if i >= xs.len() { 0 } else { unsafe_get(xs, i) } + *xs.get(i).unwrap_or(&0) } let mut i = 0; while i < self.source.len() { let i_ = i; - let byte = unsafe_get(self.source, i); + let byte = unsafe { *self.source.get_unchecked(i) }; i += 1; if byte < 128 { From 45dfe43887fee6c2ce4cbc3e46b31626330be094 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Mon, 26 Nov 2018 08:32:47 -0800 Subject: [PATCH 30/50] Emit one diagnostic for multiple misplaced lifetimes --- src/libsyntax/parse/parser.rs | 31 ++++++++++++------- .../ui/suggestions/suggest-move-lifetimes.rs | 6 ++++ .../suggestions/suggest-move-lifetimes.stderr | 16 ++++++++-- 3 files changed, 38 insertions(+), 15 deletions(-) diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 1fdf86d48670b..ab5afaf3d99fe 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -5182,6 +5182,8 @@ impl<'a> Parser<'a> { let mut params = Vec::new(); let mut seen_ty_param: Option = None; let mut last_comma_span = None; + let mut bad_lifetime_pos = vec![]; + let mut suggestions = vec![]; loop { let attrs = self.parse_outer_attributes()?; if self.check_lifetime() { @@ -5207,20 +5209,12 @@ impl<'a> Parser<'a> { } else { last_comma_span.unwrap_or(param_span).to(param_span) }; - let mut err = self.struct_span_err( - self.prev_span, - "lifetime parameters must be declared prior to type parameters", - ); + bad_lifetime_pos.push(param_span); + if let Ok(snippet) = self.sess.source_map().span_to_snippet(param_span) { - err.multipart_suggestion( - "move the lifetime parameter prior to the first type parameter", - vec![ - (remove_sp, String::new()), - (sp.shrink_to_lo(), format!("{}, ", snippet)), - ], - ); + suggestions.push((remove_sp, String::new())); + suggestions.push((sp.shrink_to_lo(), format!("{}, ", snippet))); } - err.emit(); if ate_comma { last_comma_span = Some(self.prev_span); continue @@ -5247,6 +5241,19 @@ impl<'a> Parser<'a> { } last_comma_span = Some(self.prev_span); } + if !bad_lifetime_pos.is_empty() { + let mut err = self.struct_span_err( + bad_lifetime_pos, + "lifetime parameters must be declared prior to type parameters", + ); + if !suggestions.is_empty() { + err.multipart_suggestion( + "move the lifetime parameter prior to the first type parameter", + suggestions, + ); + } + err.emit(); + } lifetimes.extend(params); // ensure the correct order of lifetimes and type params Ok(lifetimes) } diff --git a/src/test/ui/suggestions/suggest-move-lifetimes.rs b/src/test/ui/suggestions/suggest-move-lifetimes.rs index be6d29d933763..5051a406078aa 100644 --- a/src/test/ui/suggestions/suggest-move-lifetimes.rs +++ b/src/test/ui/suggestions/suggest-move-lifetimes.rs @@ -12,4 +12,10 @@ struct C { u: U, } +struct D { + t: &'a T, + u: &'b U, + v: &'c V, +} + fn main() {} diff --git a/src/test/ui/suggestions/suggest-move-lifetimes.stderr b/src/test/ui/suggestions/suggest-move-lifetimes.stderr index fa1cfe66ab530..f3d6469b51255 100644 --- a/src/test/ui/suggestions/suggest-move-lifetimes.stderr +++ b/src/test/ui/suggestions/suggest-move-lifetimes.stderr @@ -9,10 +9,10 @@ LL | struct A<'a, T> { | ^^^ -- error: lifetime parameters must be declared prior to type parameters - --> $DIR/suggest-move-lifetimes.rs:5:15 + --> $DIR/suggest-move-lifetimes.rs:5:13 | LL | struct B { - | ^ + | ^^ help: move the lifetime parameter prior to the first type parameter | LL | struct B<'a, T, U> { @@ -28,5 +28,15 @@ help: move the lifetime parameter prior to the first type parameter LL | struct C<'a, T, U> { | ^^^ -- -error: aborting due to 3 previous errors +error: lifetime parameters must be declared prior to type parameters + --> $DIR/suggest-move-lifetimes.rs:15:16 + | +LL | struct D { + | ^^ ^^ ^^ +help: move the lifetime parameter prior to the first type parameter + | +LL | struct D<'a, 'b, 'c, T, U, V> { + | ^^^ ^^^ ^^^ --- + +error: aborting due to 4 previous errors From 769d7115fed078c93f66d8db24de2046a6ab6334 Mon Sep 17 00:00:00 2001 From: Andy Russell Date: Wed, 14 Nov 2018 14:51:28 -0500 Subject: [PATCH 31/50] add test for issue #21335 Fixes #21335. --- src/test/run-make/llvm-outputs/Makefile | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 src/test/run-make/llvm-outputs/Makefile diff --git a/src/test/run-make/llvm-outputs/Makefile b/src/test/run-make/llvm-outputs/Makefile new file mode 100644 index 0000000000000..d7f67577b04ce --- /dev/null +++ b/src/test/run-make/llvm-outputs/Makefile @@ -0,0 +1,5 @@ +-include ../../run-make-fulldeps/tools.mk + +all: + echo 'fn main() {}' | $(BARE_RUSTC) - --out-dir=$(TMPDIR)/random_directory_that_does_not_exist_ir/ --emit=llvm-ir + echo 'fn main() {}' | $(BARE_RUSTC) - --out-dir=$(TMPDIR)/random_directory_that_does_not_exist_bc/ --emit=llvm-bc From cd20be50912170842689e4f936c31c5a28184432 Mon Sep 17 00:00:00 2001 From: Jason Langenauer Date: Mon, 26 Nov 2018 21:21:17 +0100 Subject: [PATCH 32/50] Update outdated code comments in StringReader --- src/libsyntax/parse/lexer/mod.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/libsyntax/parse/lexer/mod.rs b/src/libsyntax/parse/lexer/mod.rs index 0584cd5a3df47..c90c62c13f969 100644 --- a/src/libsyntax/parse/lexer/mod.rs +++ b/src/libsyntax/parse/lexer/mod.rs @@ -60,11 +60,11 @@ pub struct StringReader<'a> { // cache a direct reference to the source text, so that we don't have to // retrieve it via `self.source_file.src.as_ref().unwrap()` all the time. src: Lrc, - /// Stack of open delimiters and their spans. Used for error message. token: token::Token, span: Span, /// The raw source span which *does not* take `override_span` into account span_src_raw: Span, + /// Stack of open delimiters and their spans. Used for error message. open_braces: Vec<(token::DelimToken, Span)>, /// The type and spans for all braces /// @@ -506,8 +506,7 @@ impl<'a> StringReader<'a> { } } - /// Advance the StringReader by one character. If a newline is - /// discovered, add it to the SourceFile's list of line start offsets. + /// Advance the StringReader by one character. crate fn bump(&mut self) { let next_src_index = self.src_index(self.next_pos); if next_src_index < self.end_src_index { From a1865edb75288b88cba7f26f754daee0b4a37f3f Mon Sep 17 00:00:00 2001 From: Mark Mansi Date: Wed, 21 Nov 2018 18:57:14 -0600 Subject: [PATCH 33/50] Add rustc-guide as a submodule --- .gitmodules | 3 +++ src/doc/rustc-guide | 1 + 2 files changed, 4 insertions(+) create mode 160000 src/doc/rustc-guide diff --git a/.gitmodules b/.gitmodules index bf9bdd9a5b4b0..5cc4cab62d173 100644 --- a/.gitmodules +++ b/.gitmodules @@ -62,3 +62,6 @@ url = https://github.com/rust-lang-nursery/clang.git branch = rust-release-80-v1 +[submodule "src/doc/rustc-guide"] + path = src/doc/rustc-guide + url = https://github.com/rust-lang/rustc-guide.git diff --git a/src/doc/rustc-guide b/src/doc/rustc-guide new file mode 160000 index 0000000000000..3a804956e3c28 --- /dev/null +++ b/src/doc/rustc-guide @@ -0,0 +1 @@ +Subproject commit 3a804956e3c28d7e44e38804207a00013594e1d3 From 6494f1e60e1931ac62eaef0a203bcb013fd77acf Mon Sep 17 00:00:00 2001 From: Mark Mansi Date: Mon, 26 Nov 2018 15:03:13 -0600 Subject: [PATCH 34/50] rustc-guide has moved --- CONTRIBUTING.md | 4 ++-- README.md | 2 +- src/README.md | 2 +- src/doc/rustc/src/contributing.md | 4 ++-- src/librustc/README.md | 2 +- src/librustc/dep_graph/README.md | 2 +- src/librustc/dep_graph/graph.rs | 2 +- src/librustc/hir/mod.rs | 2 +- src/librustc/infer/canonical/canonicalizer.rs | 6 +++--- src/librustc/infer/canonical/mod.rs | 2 +- src/librustc/infer/canonical/query_response.rs | 4 ++-- src/librustc/infer/canonical/substitute.rs | 2 +- src/librustc/infer/higher_ranked/mod.rs | 2 +- src/librustc/infer/lexical_region_resolve/README.md | 2 +- src/librustc/infer/region_constraints/README.md | 4 ++-- src/librustc/lib.rs | 2 +- src/librustc/middle/region.rs | 2 +- src/librustc/mir/mod.rs | 2 +- src/librustc/traits/coherence.rs | 4 ++-- src/librustc/traits/mod.rs | 2 +- src/librustc/traits/query/type_op/mod.rs | 2 +- src/librustc/traits/select.rs | 6 +++--- src/librustc/traits/specialize/mod.rs | 2 +- src/librustc/ty/context.rs | 2 +- src/librustc/ty/sty.rs | 2 +- src/librustc_borrowck/borrowck/README.md | 2 +- src/librustc_codegen_llvm/README.md | 2 +- src/librustc_driver/README.md | 2 +- src/librustc_target/README.md | 2 +- src/librustc_typeck/README.md | 4 ++-- src/librustc_typeck/check/method/mod.rs | 2 +- src/librustc_typeck/variance/mod.rs | 2 +- src/librustc_typeck/variance/terms.rs | 4 ++-- src/librustdoc/README.md | 2 +- src/libsyntax/README.md | 4 ++-- src/test/COMPILER_TESTS.md | 2 +- 36 files changed, 48 insertions(+), 48 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index e04b1bdfefdd8..137fe61320796 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -640,7 +640,7 @@ are: * **Google!** ([search only in Rust Documentation][gsearchdocs] to find types, traits, etc. quickly) * Don't be afraid to ask! The Rust community is friendly and helpful. -[rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/about-this-guide.html +[rustc guide]: https://rust-lang.github.io/rustc-guide/about-this-guide.html [gdfrustc]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc/ [gsearchdocs]: https://www.google.com/search?q=site:doc.rust-lang.org+your+query+here [rif]: http://internals.rust-lang.org @@ -648,5 +648,5 @@ are: [rustforge]: https://forge.rust-lang.org/ [tlgba]: http://tomlee.co/2014/04/a-more-detailed-tour-of-the-rust-compiler/ [ro]: http://www.rustaceans.org/ -[rctd]: https://rust-lang-nursery.github.io/rustc-guide/tests/intro.html +[rctd]: https://rust-lang.github.io/rustc-guide/tests/intro.html [cheatsheet]: https://buildbot2.rust-lang.org/homu/ diff --git a/README.md b/README.md index 0e5b7170bc6b4..37442661bcbc1 100644 --- a/README.md +++ b/README.md @@ -233,7 +233,7 @@ Also, you may find the [rustdocs for the compiler itself][rustdocs] useful. [IRC]: https://en.wikipedia.org/wiki/Internet_Relay_Chat [#rust]: irc://irc.mozilla.org/rust [#rust-beginners]: irc://irc.mozilla.org/rust-beginners -[rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/about-this-guide.html +[rustc guide]: https://rust-lang.github.io/rustc-guide/about-this-guide.html [rustdocs]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc/ ## License diff --git a/src/README.md b/src/README.md index a4f89960a0bfd..65228915866ea 100644 --- a/src/README.md +++ b/src/README.md @@ -12,4 +12,4 @@ There is also useful content in the following READMEs, which are gradually being - https://github.com/rust-lang/rust/tree/master/src/librustc/infer/higher_ranked - https://github.com/rust-lang/rust/tree/master/src/librustc/infer/lexical_region_resolve -[rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/about-this-guide.html +[rustc guide]: https://rust-lang.github.io/rustc-guide/about-this-guide.html diff --git a/src/doc/rustc/src/contributing.md b/src/doc/rustc/src/contributing.md index fcb8e6b27dbf0..3a1cafe8a6153 100644 --- a/src/doc/rustc/src/contributing.md +++ b/src/doc/rustc/src/contributing.md @@ -1,6 +1,6 @@ # Contributing to rustc We'd love to have your help improving `rustc`! To that end, we've written [a -whole book](https://rust-lang-nursery.github.io/rustc-guide/) on its +whole book](https://rust-lang.github.io/rustc-guide/) on its internals, how it works, and how to get started working on it. To learn -more, you'll want to check that out. \ No newline at end of file +more, you'll want to check that out. diff --git a/src/librustc/README.md b/src/librustc/README.md index 9909ff91a18aa..c0e5c542bdc8b 100644 --- a/src/librustc/README.md +++ b/src/librustc/README.md @@ -1,3 +1,3 @@ For more information about how rustc works, see the [rustc guide]. -[rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/ +[rustc guide]: https://rust-lang.github.io/rustc-guide/ diff --git a/src/librustc/dep_graph/README.md b/src/librustc/dep_graph/README.md index f1f383d7ad126..91a06e452e5fd 100644 --- a/src/librustc/dep_graph/README.md +++ b/src/librustc/dep_graph/README.md @@ -1,4 +1,4 @@ To learn more about how dependency tracking works in rustc, see the [rustc guide]. -[rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/query.html +[rustc guide]: https://rust-lang.github.io/rustc-guide/query.html diff --git a/src/librustc/dep_graph/graph.rs b/src/librustc/dep_graph/graph.rs index 63b749c548e24..4c94c993ab405 100644 --- a/src/librustc/dep_graph/graph.rs +++ b/src/librustc/dep_graph/graph.rs @@ -195,7 +195,7 @@ impl DepGraph { /// - If you need 3+ arguments, use a tuple for the /// `arg` parameter. /// - /// [rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/incremental-compilation.html + /// [rustc guide]: https://rust-lang.github.io/rustc-guide/incremental-compilation.html pub fn with_task<'gcx, C, A, R>(&self, key: DepNode, cx: C, diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs index e28193be34a44..1674320165e65 100644 --- a/src/librustc/hir/mod.rs +++ b/src/librustc/hir/mod.rs @@ -689,7 +689,7 @@ pub struct WhereEqPredicate { /// /// For more details, see the [rustc guide]. /// -/// [rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/hir.html +/// [rustc guide]: https://rust-lang.github.io/rustc-guide/hir.html #[derive(Clone, RustcEncodable, RustcDecodable, Debug)] pub struct Crate { pub module: Mod, diff --git a/src/librustc/infer/canonical/canonicalizer.rs b/src/librustc/infer/canonical/canonicalizer.rs index ddb520775da0a..08cd3395ba16c 100644 --- a/src/librustc/infer/canonical/canonicalizer.rs +++ b/src/librustc/infer/canonical/canonicalizer.rs @@ -13,7 +13,7 @@ //! For an overview of what canonicalization is and how it fits into //! rustc, check out the [chapter in the rustc guide][c]. //! -//! [c]: https://rust-lang-nursery.github.io/rustc-guide/traits/canonicalization.html +//! [c]: https://rust-lang.github.io/rustc-guide/traits/canonicalization.html use infer::canonical::{ Canonical, CanonicalTyVarKind, CanonicalVarInfo, CanonicalVarKind, Canonicalized, @@ -44,7 +44,7 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> { /// To get a good understanding of what is happening here, check /// out the [chapter in the rustc guide][c]. /// - /// [c]: https://rust-lang-nursery.github.io/rustc-guide/traits/canonicalization.html#canonicalizing-the-query + /// [c]: https://rust-lang.github.io/rustc-guide/traits/canonicalization.html#canonicalizing-the-query pub fn canonicalize_query( &self, value: &V, @@ -92,7 +92,7 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> { /// To get a good understanding of what is happening here, check /// out the [chapter in the rustc guide][c]. /// - /// [c]: https://rust-lang-nursery.github.io/rustc-guide/traits/canonicalization.html#canonicalizing-the-query-result + /// [c]: https://rust-lang.github.io/rustc-guide/traits/canonicalization.html#canonicalizing-the-query-result pub fn canonicalize_response(&self, value: &V) -> Canonicalized<'gcx, V> where V: TypeFoldable<'tcx> + Lift<'gcx>, diff --git a/src/librustc/infer/canonical/mod.rs b/src/librustc/infer/canonical/mod.rs index 230f8958b3385..6b0fa79b201fc 100644 --- a/src/librustc/infer/canonical/mod.rs +++ b/src/librustc/infer/canonical/mod.rs @@ -29,7 +29,7 @@ //! For a more detailed look at what is happening here, check //! out the [chapter in the rustc guide][c]. //! -//! [c]: https://rust-lang-nursery.github.io/rustc-guide/traits/canonicalization.html +//! [c]: https://rust-lang.github.io/rustc-guide/traits/canonicalization.html use infer::{InferCtxt, RegionVariableOrigin, TypeVariableOrigin}; use rustc_data_structures::indexed_vec::IndexVec; diff --git a/src/librustc/infer/canonical/query_response.rs b/src/librustc/infer/canonical/query_response.rs index d32594ebdf366..8d2b1d74c554b 100644 --- a/src/librustc/infer/canonical/query_response.rs +++ b/src/librustc/infer/canonical/query_response.rs @@ -15,7 +15,7 @@ //! For an overview of what canonicaliation is and how it fits into //! rustc, check out the [chapter in the rustc guide][c]. //! -//! [c]: https://rust-lang-nursery.github.io/rustc-guide/traits/canonicalization.html +//! [c]: https://rust-lang.github.io/rustc-guide/traits/canonicalization.html use infer::canonical::substitute::substitute_value; use infer::canonical::{ @@ -184,7 +184,7 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> { /// To get a good understanding of what is happening here, check /// out the [chapter in the rustc guide][c]. /// - /// [c]: https://rust-lang-nursery.github.io/rustc-guide/traits/canonicalization.html#processing-the-canonicalized-query-result + /// [c]: https://rust-lang.github.io/rustc-guide/traits/canonicalization.html#processing-the-canonicalized-query-result pub fn instantiate_query_response_and_region_obligations( &self, cause: &ObligationCause<'tcx>, diff --git a/src/librustc/infer/canonical/substitute.rs b/src/librustc/infer/canonical/substitute.rs index e2110e148de52..ab575882f8a17 100644 --- a/src/librustc/infer/canonical/substitute.rs +++ b/src/librustc/infer/canonical/substitute.rs @@ -14,7 +14,7 @@ //! For an overview of what canonicalization is and how it fits into //! rustc, check out the [chapter in the rustc guide][c]. //! -//! [c]: https://rust-lang-nursery.github.io/rustc-guide/traits/canonicalization.html +//! [c]: https://rust-lang.github.io/rustc-guide/traits/canonicalization.html use infer::canonical::{Canonical, CanonicalVarValues}; use ty::fold::TypeFoldable; diff --git a/src/librustc/infer/higher_ranked/mod.rs b/src/librustc/infer/higher_ranked/mod.rs index 16140e748aa1e..cf91b85807632 100644 --- a/src/librustc/infer/higher_ranked/mod.rs +++ b/src/librustc/infer/higher_ranked/mod.rs @@ -329,7 +329,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { /// For more information about how placeholders and HRTBs work, see /// the [rustc guide]. /// - /// [rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/traits/hrtb.html + /// [rustc guide]: https://rust-lang.github.io/rustc-guide/traits/hrtb.html pub fn replace_bound_vars_with_placeholders( &self, binder: &ty::Binder diff --git a/src/librustc/infer/lexical_region_resolve/README.md b/src/librustc/infer/lexical_region_resolve/README.md index 6e1c4191173bc..4483e522f3a1f 100644 --- a/src/librustc/infer/lexical_region_resolve/README.md +++ b/src/librustc/infer/lexical_region_resolve/README.md @@ -3,7 +3,7 @@ > WARNING: This README is obsolete and will be removed soon! For > more info on how the current borrowck works, see the [rustc guide]. -[rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/mir/borrowck.html +[rustc guide]: https://rust-lang.github.io/rustc-guide/mir/borrowck.html ## Terminology diff --git a/src/librustc/infer/region_constraints/README.md b/src/librustc/infer/region_constraints/README.md index 61603e6dee686..775bbf955b830 100644 --- a/src/librustc/infer/region_constraints/README.md +++ b/src/librustc/infer/region_constraints/README.md @@ -3,7 +3,7 @@ > WARNING: This README is obsolete and will be removed soon! For > more info on how the current borrowck works, see the [rustc guide]. -[rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/mir/borrowck.html +[rustc guide]: https://rust-lang.github.io/rustc-guide/mir/borrowck.html ## Terminology @@ -18,7 +18,7 @@ constraints over the course of a function. Finally, at the end of processing a function, we process and solve the constraints all at once. -[ti]: https://rust-lang-nursery.github.io/rustc-guide/type-inference.html +[ti]: https://rust-lang.github.io/rustc-guide/type-inference.html The constraints are always of one of three possible forms: diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index 0aa964a44fd2c..edc97238f0530 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -30,7 +30,7 @@ //! //! For more information about how rustc works, see the [rustc guide]. //! -//! [rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/ +//! [rustc guide]: https://rust-lang.github.io/rustc-guide/ //! //! # Note //! diff --git a/src/librustc/middle/region.rs b/src/librustc/middle/region.rs index d00fbdeca21aa..35d1a4dd2cb7c 100644 --- a/src/librustc/middle/region.rs +++ b/src/librustc/middle/region.rs @@ -14,7 +14,7 @@ //! For more information about how MIR-based region-checking works, //! see the [rustc guide]. //! -//! [rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/mir/borrowck.html +//! [rustc guide]: https://rust-lang.github.io/rustc-guide/mir/borrowck.html use ich::{StableHashingContext, NodeIdHashingMode}; use util::nodemap::{FxHashMap, FxHashSet}; diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs index af1255c438a95..368f83eb61127 100644 --- a/src/librustc/mir/mod.rs +++ b/src/librustc/mir/mod.rs @@ -10,7 +10,7 @@ //! MIR datatypes and passes. See the [rustc guide] for more info. //! -//! [rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/mir/index.html +//! [rustc guide]: https://rust-lang.github.io/rustc-guide/mir/index.html use hir::def::CtorKind; use hir::def_id::DefId; diff --git a/src/librustc/traits/coherence.rs b/src/librustc/traits/coherence.rs index b7a84c99308f8..4bf8ba0d6d1c8 100644 --- a/src/librustc/traits/coherence.rs +++ b/src/librustc/traits/coherence.rs @@ -11,8 +11,8 @@ //! See rustc guide chapters on [trait-resolution] and [trait-specialization] for more info on how //! this works. //! -//! [trait-resolution]: https://rust-lang-nursery.github.io/rustc-guide/traits/resolution.html -//! [trait-specialization]: https://rust-lang-nursery.github.io/rustc-guide/traits/specialization.html +//! [trait-resolution]: https://rust-lang.github.io/rustc-guide/traits/resolution.html +//! [trait-specialization]: https://rust-lang.github.io/rustc-guide/traits/specialization.html use hir::def_id::{DefId, LOCAL_CRATE}; use syntax_pos::DUMMY_SP; diff --git a/src/librustc/traits/mod.rs b/src/librustc/traits/mod.rs index 8c3cd5e6612b9..e582a9020464d 100644 --- a/src/librustc/traits/mod.rs +++ b/src/librustc/traits/mod.rs @@ -10,7 +10,7 @@ //! Trait Resolution. See [rustc guide] for more info on how this works. //! -//! [rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/traits/resolution.html +//! [rustc guide]: https://rust-lang.github.io/rustc-guide/traits/resolution.html pub use self::SelectionError::*; pub use self::FulfillmentErrorCode::*; diff --git a/src/librustc/traits/query/type_op/mod.rs b/src/librustc/traits/query/type_op/mod.rs index d20d43cf7578c..f8f9650ebe1ae 100644 --- a/src/librustc/traits/query/type_op/mod.rs +++ b/src/librustc/traits/query/type_op/mod.rs @@ -53,7 +53,7 @@ pub trait TypeOp<'gcx, 'tcx>: Sized + fmt::Debug { /// first canonicalize the key and then invoke the query on the tcx, /// which produces the resulting query region constraints. /// -/// [c]: https://rust-lang-nursery.github.io/rustc-guide/traits/canonicalization.html +/// [c]: https://rust-lang.github.io/rustc-guide/traits/canonicalization.html pub trait QueryTypeOp<'gcx: 'tcx, 'tcx>: fmt::Debug + Sized + TypeFoldable<'tcx> + Lift<'gcx> { diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs index 0f59f478cb415..fb4c9f3bad715 100644 --- a/src/librustc/traits/select.rs +++ b/src/librustc/traits/select.rs @@ -10,7 +10,7 @@ //! See [rustc guide] for more info on how this works. //! -//! [rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/traits/resolution.html#selection +//! [rustc guide]: https://rust-lang.github.io/rustc-guide/traits/resolution.html#selection use self::EvaluationResult::*; use self::SelectionCandidate::*; @@ -1173,7 +1173,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { // candidates. See [rustc guide] for more details. // // [rustc guide]: - // https://rust-lang-nursery.github.io/rustc-guide/traits/resolution.html#candidate-assembly + // https://rust-lang.github.io/rustc-guide/traits/resolution.html#candidate-assembly fn candidate_from_obligation<'o>( &mut self, @@ -2720,7 +2720,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { // type error. See [rustc guide] for more details. // // [rustc guide]: - // https://rust-lang-nursery.github.io/rustc-guide/traits/resolution.html#confirmation + // https://rust-lang.github.io/rustc-guide/traits/resolution.html#confirmation fn confirm_candidate( &mut self, diff --git a/src/librustc/traits/specialize/mod.rs b/src/librustc/traits/specialize/mod.rs index d3dc1655b0df2..19ef3171b13fc 100644 --- a/src/librustc/traits/specialize/mod.rs +++ b/src/librustc/traits/specialize/mod.rs @@ -17,7 +17,7 @@ //! See the [rustc guide] for a bit more detail on how specialization //! fits together with the rest of the trait machinery. //! -//! [rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/traits/specialization.html +//! [rustc guide]: https://rust-lang.github.io/rustc-guide/traits/specialization.html use super::{SelectionContext, FulfillmentContext}; use super::util::impl_trait_ref_and_oblig; diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index 22d5ea6e4bc93..9f26499e770da 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -876,7 +876,7 @@ pub struct FreeRegionInfo { /// various **compiler queries** that have been performed. See the /// [rustc guide] for more details. /// -/// [rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/ty.html +/// [rustc guide]: https://rust-lang.github.io/rustc-guide/ty.html #[derive(Copy, Clone)] pub struct TyCtxt<'a, 'gcx: 'tcx, 'tcx: 'a> { gcx: &'a GlobalCtxt<'gcx>, diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs index 3056abba95626..a18e3a275467d 100644 --- a/src/librustc/ty/sty.rs +++ b/src/librustc/ty/sty.rs @@ -1138,7 +1138,7 @@ pub type Region<'tcx> = &'tcx RegionKind; /// /// [1]: http://smallcultfollowing.com/babysteps/blog/2013/10/29/intermingled-parameter-lists/ /// [2]: http://smallcultfollowing.com/babysteps/blog/2013/11/04/intermingled-parameter-lists/ -/// [rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/traits/hrtb.html +/// [rustc guide]: https://rust-lang.github.io/rustc-guide/traits/hrtb.html #[derive(Clone, PartialEq, Eq, Hash, Copy, RustcEncodable, RustcDecodable, PartialOrd, Ord)] pub enum RegionKind { // Region bound in a type or fn declaration which will be diff --git a/src/librustc_borrowck/borrowck/README.md b/src/librustc_borrowck/borrowck/README.md index 8bc0b4969b8f9..a05c56e3629a3 100644 --- a/src/librustc_borrowck/borrowck/README.md +++ b/src/librustc_borrowck/borrowck/README.md @@ -3,7 +3,7 @@ > WARNING: This README is more or less obsolete, and will be removed > soon! The new system is described in the [rustc guide]. -[rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/mir/borrowck.html +[rustc guide]: https://rust-lang.github.io/rustc-guide/mir/borrowck.html This pass has the job of enforcing memory safety. This is a subtle topic. This docs aim to explain both the practice and the theory diff --git a/src/librustc_codegen_llvm/README.md b/src/librustc_codegen_llvm/README.md index 8d1c9a52b2428..dda2e5ac18f01 100644 --- a/src/librustc_codegen_llvm/README.md +++ b/src/librustc_codegen_llvm/README.md @@ -4,4 +4,4 @@ that runs towards the end of the compilation process. For more information about how codegen works, see the [rustc guide]. -[rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/codegen.html +[rustc guide]: https://rust-lang.github.io/rustc-guide/codegen.html diff --git a/src/librustc_driver/README.md b/src/librustc_driver/README.md index fef249a9e4eb8..c4d73953e9b2e 100644 --- a/src/librustc_driver/README.md +++ b/src/librustc_driver/README.md @@ -7,4 +7,4 @@ options). For more information about how the driver works, see the [rustc guide]. -[rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/rustc-driver.html +[rustc guide]: https://rust-lang.github.io/rustc-guide/rustc-driver.html diff --git a/src/librustc_target/README.md b/src/librustc_target/README.md index f5b1acb192133..a22000ea9d280 100644 --- a/src/librustc_target/README.md +++ b/src/librustc_target/README.md @@ -3,4 +3,4 @@ specific to different compilation targets and so forth. For more information about how rustc works, see the [rustc guide]. -[rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/ +[rustc guide]: https://rust-lang.github.io/rustc-guide/ diff --git a/src/librustc_typeck/README.md b/src/librustc_typeck/README.md index f00597cb27f0c..fdcbd935524db 100644 --- a/src/librustc_typeck/README.md +++ b/src/librustc_typeck/README.md @@ -1,5 +1,5 @@ For high-level intro to how type checking works in rustc, see the [type checking] chapter of the [rustc guide]. -[type checking]: https://rust-lang-nursery.github.io/rustc-guide/type-checking.html -[rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/ +[type checking]: https://rust-lang.github.io/rustc-guide/type-checking.html +[rustc guide]: https://rust-lang.github.io/rustc-guide/ diff --git a/src/librustc_typeck/check/method/mod.rs b/src/librustc_typeck/check/method/mod.rs index ac338ba667865..37f4ae56779b2 100644 --- a/src/librustc_typeck/check/method/mod.rs +++ b/src/librustc_typeck/check/method/mod.rs @@ -10,7 +10,7 @@ //! Method lookup: the secret sauce of Rust. See the [rustc guide] chapter. //! -//! [rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/method-lookup.html +//! [rustc guide]: https://rust-lang.github.io/rustc-guide/method-lookup.html use check::FnCtxt; use hir::def::Def; diff --git a/src/librustc_typeck/variance/mod.rs b/src/librustc_typeck/variance/mod.rs index 7cc56bc192bb2..e3c82d50a8d9b 100644 --- a/src/librustc_typeck/variance/mod.rs +++ b/src/librustc_typeck/variance/mod.rs @@ -11,7 +11,7 @@ //! Module for inferring the variance of type and lifetime parameters. See the [rustc guide] //! chapter for more info. //! -//! [rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/variance.html +//! [rustc guide]: https://rust-lang.github.io/rustc-guide/variance.html use arena; use rustc::hir; diff --git a/src/librustc_typeck/variance/terms.rs b/src/librustc_typeck/variance/terms.rs index 087d53b92d496..3692221a3fc3f 100644 --- a/src/librustc_typeck/variance/terms.rs +++ b/src/librustc_typeck/variance/terms.rs @@ -89,8 +89,8 @@ pub fn determine_parameters_to_be_inferred<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx> // See the following for a discussion on dep-graph management. // - // - https://rust-lang-nursery.github.io/rustc-guide/query.html - // - https://rust-lang-nursery.github.io/rustc-guide/variance.html + // - https://rust-lang.github.io/rustc-guide/query.html + // - https://rust-lang.github.io/rustc-guide/variance.html tcx.hir.krate().visit_all_item_likes(&mut terms_cx); terms_cx diff --git a/src/librustdoc/README.md b/src/librustdoc/README.md index 2cfe43a8389bb..e4f7bc30e3fcf 100644 --- a/src/librustdoc/README.md +++ b/src/librustdoc/README.md @@ -1,3 +1,3 @@ For more information about how `librustdoc` works, see the [rustc guide]. -[rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/rustdoc.html +[rustc guide]: https://rust-lang.github.io/rustc-guide/rustdoc.html diff --git a/src/libsyntax/README.md b/src/libsyntax/README.md index 7214203830e74..daa252ef4551b 100644 --- a/src/libsyntax/README.md +++ b/src/libsyntax/README.md @@ -5,5 +5,5 @@ lexer, macro expander, and utilities for traversing ASTs. For more information about how these things work in rustc, see the rustc guide: -- [Parsing](https://rust-lang-nursery.github.io/rustc-guide/the-parser.html) -- [Macro Expansion](https://rust-lang-nursery.github.io/rustc-guide/macro-expansion.html) +- [Parsing](https://rust-lang.github.io/rustc-guide/the-parser.html) +- [Macro Expansion](https://rust-lang.github.io/rustc-guide/macro-expansion.html) diff --git a/src/test/COMPILER_TESTS.md b/src/test/COMPILER_TESTS.md index 81a46ea0fe718..c4ca478134399 100644 --- a/src/test/COMPILER_TESTS.md +++ b/src/test/COMPILER_TESTS.md @@ -1,4 +1,4 @@ # Compiler Test Documentation Documentation the compiler testing framework has moved to -[the rustc guide](https://rust-lang-nursery.github.io/rustc-guide/tests/intro.html). +[the rustc guide](https://rust-lang.github.io/rustc-guide/tests/intro.html). From 6f028fe8e0db8c1251f24d694fc001aa933cf0ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Mon, 26 Nov 2018 13:58:46 -0800 Subject: [PATCH 35/50] Specify suggestion applicability --- src/libsyntax/parse/parser.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index ab5afaf3d99fe..c224f18259294 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -5247,9 +5247,10 @@ impl<'a> Parser<'a> { "lifetime parameters must be declared prior to type parameters", ); if !suggestions.is_empty() { - err.multipart_suggestion( + err.multipart_suggestion_with_applicability( "move the lifetime parameter prior to the first type parameter", suggestions, + Applicability::MachineApplicable, ); } err.emit(); From d4a6e739f3322c56e66fa8fef31569b7f16bc325 Mon Sep 17 00:00:00 2001 From: ljedrz Date: Fri, 9 Nov 2018 15:12:09 +0100 Subject: [PATCH 36/50] Use sort_by_cached_key when key the function is not trivial/free --- src/librustc/middle/resolve_lifetime.rs | 2 +- src/librustc/traits/object_safety.rs | 2 +- src/librustc_mir/monomorphize/partitioning.rs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs index 6ff450508d136..07054ee99af76 100644 --- a/src/librustc/middle/resolve_lifetime.rs +++ b/src/librustc/middle/resolve_lifetime.rs @@ -1573,7 +1573,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { .collect(); // ensure that we issue lints in a repeatable order - def_ids.sort_by_key(|&def_id| self.tcx.def_path_hash(def_id)); + def_ids.sort_by_cached_key(|&def_id| self.tcx.def_path_hash(def_id)); for def_id in def_ids { debug!( diff --git a/src/librustc/traits/object_safety.rs b/src/librustc/traits/object_safety.rs index c79fa3861234f..2909daf22b3ba 100644 --- a/src/librustc/traits/object_safety.rs +++ b/src/librustc/traits/object_safety.rs @@ -409,7 +409,7 @@ impl<'a, 'tcx> TyCtxt<'a, 'tcx, 'tcx> { .collect::>(); // existential predicates need to be in a specific order - associated_types.sort_by_key(|item| self.def_path_hash(item.def_id)); + associated_types.sort_by_cached_key(|item| self.def_path_hash(item.def_id)); let projection_predicates = associated_types.into_iter().map(|item| { ty::ExistentialPredicate::Projection(ty::ExistentialProjection { diff --git a/src/librustc_mir/monomorphize/partitioning.rs b/src/librustc_mir/monomorphize/partitioning.rs index 6dba020120f84..3a6ee6da42215 100644 --- a/src/librustc_mir/monomorphize/partitioning.rs +++ b/src/librustc_mir/monomorphize/partitioning.rs @@ -985,7 +985,7 @@ fn collect_and_partition_mono_items<'a, 'tcx>( output.push_str(" @@"); let mut empty = Vec::new(); let cgus = item_to_cgus.get_mut(i).unwrap_or(&mut empty); - cgus.as_mut_slice().sort_by_key(|&(ref name, _)| name.clone()); + cgus.as_mut_slice().sort_by_cached_key(|&(ref name, _)| name.clone()); cgus.dedup(); for &(ref cgu_name, (linkage, _)) in cgus.iter() { output.push_str(" "); From 6739c0e935ecfc838f818c27bfaa5665b6831e69 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 27 Nov 2018 09:59:44 +0100 Subject: [PATCH 37/50] Add missing doc link --- src/libcore/iter/iterator.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/libcore/iter/iterator.rs b/src/libcore/iter/iterator.rs index fd4189ef50df5..3063cb1a7df44 100644 --- a/src/libcore/iter/iterator.rs +++ b/src/libcore/iter/iterator.rs @@ -519,7 +519,7 @@ pub trait Iterator { /// element. /// /// `map()` transforms one iterator into another, by means of its argument: - /// something that implements `FnMut`. It produces a new iterator which + /// something that implements [`FnMut`]. It produces a new iterator which /// calls this closure on each element of the original iterator. /// /// If you are good at thinking in types, you can think of `map()` like this: @@ -533,6 +533,7 @@ pub trait Iterator { /// more idiomatic to use [`for`] than `map()`. /// /// [`for`]: ../../book/ch03-05-control-flow.html#looping-through-a-collection-with-for + /// [`FnMut`]: ../../std/ops/trait.FnMut.html /// /// # Examples /// From a8f9302047c97a07ecce3a85cdf222ff4da0d1e7 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 17 Nov 2018 13:57:53 +0100 Subject: [PATCH 38/50] avoid features_untracked --- src/librustc/ty/constness.rs | 2 +- src/librustc_mir/transform/qualify_consts.rs | 18 +++++++++--------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/librustc/ty/constness.rs b/src/librustc/ty/constness.rs index 47aea7a5f0796..e32913b8905b7 100644 --- a/src/librustc/ty/constness.rs +++ b/src/librustc/ty/constness.rs @@ -66,7 +66,7 @@ impl<'a, 'tcx> TyCtxt<'a, 'tcx, 'tcx> { } } else { // users enabling the `const_fn` feature gate can do what they want - !self.sess.features_untracked().const_fn + !self.features().const_fn } } } diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs index fc2c6c3ab1f37..09fe7b14c7973 100644 --- a/src/librustc_mir/transform/qualify_consts.rs +++ b/src/librustc_mir/transform/qualify_consts.rs @@ -357,7 +357,7 @@ impl<'a, 'tcx> Qualifier<'a, 'tcx, 'tcx> { TerminatorKind::FalseUnwind { .. } => None, TerminatorKind::Return => { - if !self.tcx.sess.features_untracked().const_let { + if !self.tcx.features().const_let { // Check for unused values. This usually means // there are extra statements in the AST. for temp in mir.temps_iter() { @@ -464,7 +464,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> { LocalKind::ReturnPointer => { self.not_const(); } - LocalKind::Var if !self.tcx.sess.features_untracked().const_let => { + LocalKind::Var if !self.tcx.features().const_let => { if self.mode != Mode::Fn { emit_feature_err(&self.tcx.sess.parse_sess, "const_let", self.span, GateIssue::Language, @@ -558,7 +558,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> { Mode::Fn => {}, _ => { if let ty::RawPtr(_) = base_ty.sty { - if !this.tcx.sess.features_untracked().const_raw_ptr_deref { + if !this.tcx.features().const_raw_ptr_deref { emit_feature_err( &this.tcx.sess.parse_sess, "const_raw_ptr_deref", this.span, GateIssue::Language, @@ -581,7 +581,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> { match this.mode { Mode::Fn => this.not_const(), Mode::ConstFn => { - if !this.tcx.sess.features_untracked().const_fn_union { + if !this.tcx.features().const_fn_union { emit_feature_err( &this.tcx.sess.parse_sess, "const_fn_union", this.span, GateIssue::Language, @@ -807,7 +807,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> { if let Mode::Fn = self.mode { // in normal functions, mark such casts as not promotable self.add(Qualif::NOT_CONST); - } else if !self.tcx.sess.features_untracked().const_raw_ptr_to_usize_cast { + } else if !self.tcx.features().const_raw_ptr_to_usize_cast { // in const fn and constants require the feature gate // FIXME: make it unsafe inside const fn and constants emit_feature_err( @@ -834,7 +834,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> { if let Mode::Fn = self.mode { // raw pointer operations are not allowed inside promoteds self.add(Qualif::NOT_CONST); - } else if !self.tcx.sess.features_untracked().const_compare_raw_pointers { + } else if !self.tcx.features().const_compare_raw_pointers { // require the feature gate inside constants and const fn // FIXME: make it unsafe to use these operations emit_feature_err( @@ -933,7 +933,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> { if self.mode != Mode::Fn { is_const_fn = true; // const eval transmute calls only with the feature gate - if !self.tcx.sess.features_untracked().const_transmute { + if !self.tcx.features().const_transmute { emit_feature_err( &self.tcx.sess.parse_sess, "const_transmute", self.span, GateIssue::Language, @@ -971,7 +971,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> { // FIXME: cannot allow this inside `allow_internal_unstable` because // that would make `panic!` insta stable in constants, since the // macro is marked with the attr - if self.tcx.sess.features_untracked().const_panic { + if self.tcx.features().const_panic { is_const_fn = true; } else { // don't allow panics in constants without the feature gate @@ -1158,7 +1158,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> { if let (Mode::ConstFn, &Place::Local(index)) = (self.mode, dest) { if self.mir.local_kind(index) == LocalKind::Var && self.const_fn_arg_vars.insert(index) && - !self.tcx.sess.features_untracked().const_let { + !self.tcx.features().const_let { // Direct use of an argument is permitted. match *rvalue { From c4e0b89454ae8eb8d888830fa2563f8d5c52fe07 Mon Sep 17 00:00:00 2001 From: Marc-Antoine Perennou Date: Sat, 24 Nov 2018 10:13:27 +0100 Subject: [PATCH 39/50] move stage0.txt to toplevel directory This way all files needed by packagers now reside in toplevel Signed-off-by: Marc-Antoine Perennou --- config.toml.example | 4 ++-- src/bootstrap/bootstrap.py | 2 +- src/bootstrap/bootstrap_test.py | 3 +-- src/bootstrap/lib.rs | 2 +- src/bootstrap/sanity.rs | 2 +- src/stage0.txt => stage0.txt | 0 6 files changed, 6 insertions(+), 7 deletions(-) rename src/stage0.txt => stage0.txt (100%) diff --git a/config.toml.example b/config.toml.example index 8b11014edae79..fefbb227f00b9 100644 --- a/config.toml.example +++ b/config.toml.example @@ -112,11 +112,11 @@ # for each target triple. #target = ["x86_64-unknown-linux-gnu"] # defaults to just the build triple -# Instead of downloading the src/stage0.txt version of Cargo specified, use +# Instead of downloading the stage0.txt version of Cargo specified, use # this Cargo binary instead to build all Rust code #cargo = "/path/to/bin/cargo" -# Instead of downloading the src/stage0.txt version of the compiler +# Instead of downloading the stage0.txt version of the compiler # specified, use this rustc binary instead as the stage0 snapshot compiler. #rustc = "/path/to/bin/rustc" diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py index d143dffb24be5..b36c1bd7bb13b 100644 --- a/src/bootstrap/bootstrap.py +++ b/src/bootstrap/bootstrap.py @@ -154,7 +154,7 @@ def run(args, verbose=False, exception=False, **kwargs): def stage0_data(rust_root): """Build a dictionary from stage0.txt""" - nightlies = os.path.join(rust_root, "src/stage0.txt") + nightlies = os.path.join(rust_root, "stage0.txt") with open(nightlies, 'r') as nightlies: lines = [line.rstrip() for line in nightlies if not line.startswith("#")] diff --git a/src/bootstrap/bootstrap_test.py b/src/bootstrap/bootstrap_test.py index 4db7e2ec016f0..43cbe9967e312 100644 --- a/src/bootstrap/bootstrap_test.py +++ b/src/bootstrap/bootstrap_test.py @@ -28,8 +28,7 @@ class Stage0DataTestCase(unittest.TestCase): def setUp(self): self.rust_root = tempfile.mkdtemp() os.mkdir(os.path.join(self.rust_root, "src")) - with open(os.path.join(self.rust_root, "src", - "stage0.txt"), "w") as stage0: + with open(os.path.join(self.rust_root, "stage0.txt"), "w") as stage0: stage0.write("#ignore\n\ndate: 2017-06-15\nrustc: beta\ncargo: beta") def tearDown(self): diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs index 76697e482d3a8..548d5312dc7ce 100644 --- a/src/bootstrap/lib.rs +++ b/src/bootstrap/lib.rs @@ -41,7 +41,7 @@ //! When you execute `x.py build`, the steps which are executed are: //! //! * First, the python script is run. This will automatically download the -//! stage0 rustc and cargo according to `src/stage0.txt`, or use the cached +//! stage0 rustc and cargo according to `stage0.txt`, or use the cached //! versions if they're available. These are then used to compile rustbuild //! itself (using Cargo). Finally, control is then transferred to rustbuild. //! diff --git a/src/bootstrap/sanity.rs b/src/bootstrap/sanity.rs index 15d3bccba09cc..c62ce5a5b93a2 100644 --- a/src/bootstrap/sanity.rs +++ b/src/bootstrap/sanity.rs @@ -236,7 +236,7 @@ $ pacman -R cmake && pacman -S mingw-w64-x86_64-cmake if build.config.channel == "stable" { let mut stage0 = String::new(); - t!(t!(File::open(build.src.join("src/stage0.txt"))) + t!(t!(File::open(build.src.join("stage0.txt"))) .read_to_string(&mut stage0)); if stage0.contains("\ndev:") { panic!("bootstrapping from a dev compiler in a stable release, but \ diff --git a/src/stage0.txt b/stage0.txt similarity index 100% rename from src/stage0.txt rename to stage0.txt From 73b656bbb306047d072b41321153b62c5a4a2b0d Mon Sep 17 00:00:00 2001 From: Marius Nuennerich Date: Tue, 27 Nov 2018 18:57:55 +0100 Subject: [PATCH 40/50] Fix small typo in comment --- src/libstd/thread/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libstd/thread/mod.rs b/src/libstd/thread/mod.rs index 8a845efd41362..3a9f3ec5c6fc1 100644 --- a/src/libstd/thread/mod.rs +++ b/src/libstd/thread/mod.rs @@ -326,7 +326,7 @@ impl Builder { /// Sets the size of the stack (in bytes) for the new thread. /// /// The actual stack size may be greater than this value if - /// the platform specifies minimal stack size. + /// the platform specifies a minimal stack size. /// /// For more information about the stack size for threads, see /// [this module-level documentation][stack-size]. From c75ed34732f67ce41faf84e22e4896cabab14a40 Mon Sep 17 00:00:00 2001 From: Mark Mansi Date: Sat, 24 Nov 2018 16:09:37 -0600 Subject: [PATCH 41/50] move feature gate to accepted --- src/libsyntax/feature_gate.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index 73567765a04c4..cd503f25cfe68 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -393,9 +393,6 @@ declare_features! ( // `extern` in paths (active, extern_in_paths, "1.23.0", Some(55600), None), - // Use `?` as the Kleene "at most one" operator - (active, macro_at_most_once_rep, "1.25.0", Some(48075), None), - // Infer static outlives requirements; RFC 2093 (active, infer_static_outlives_requirements, "1.26.0", Some(54185), None), @@ -689,6 +686,8 @@ declare_features! ( (accepted, extern_crate_item_prelude, "1.31.0", Some(55599), None), // Allows use of the :literal macro fragment specifier (RFC 1576) (accepted, macro_literal_matcher, "1.31.0", Some(35625), None), + // Use `?` as the Kleene "at most one" operator + (accepted, macro_at_most_once_rep, "1.32.0", Some(48075), None), ); // If you change this, please modify src/doc/unstable-book as well. You must From a542e48871e040ea2db3b4fad5d88a83b6200855 Mon Sep 17 00:00:00 2001 From: Mark Mansi Date: Sat, 24 Nov 2018 16:12:16 -0600 Subject: [PATCH 42/50] remove feature gate --- src/libsyntax/ext/tt/quoted.rs | 46 ++++++---------------------------- src/libsyntax/feature_gate.rs | 3 --- 2 files changed, 7 insertions(+), 42 deletions(-) diff --git a/src/libsyntax/ext/tt/quoted.rs b/src/libsyntax/ext/tt/quoted.rs index 218486748315d..c8ece7b3a88fd 100644 --- a/src/libsyntax/ext/tt/quoted.rs +++ b/src/libsyntax/ext/tt/quoted.rs @@ -576,22 +576,7 @@ where let span = match parse_kleene_op(input, span) { // #1 is a `?` (needs feature gate) Ok(Ok((op, op1_span))) if op == KleeneOp::ZeroOrOne => { - if !features.macro_at_most_once_rep - && !attr::contains_name(attrs, "allow_internal_unstable") - { - let explain = feature_gate::EXPLAIN_MACRO_AT_MOST_ONCE_REP; - emit_feature_err( - sess, - "macro_at_most_once_rep", - op1_span, - GateIssue::Language, - explain, - ); - - op1_span - } else { - return (None, op); - } + return (None, op); } // #1 is a `+` or `*` KleeneOp @@ -602,22 +587,10 @@ where // #2 is the `?` Kleene op, which does not take a separator (error) Ok(Ok((op, op2_span))) if op == KleeneOp::ZeroOrOne => { // Error! - - if !features.macro_at_most_once_rep - && !attr::contains_name(attrs, "allow_internal_unstable") - { - // FIXME: when `?` as a Kleene op is stabilized, we only need the "does not - // take a macro separator" error (i.e. the `else` case). - sess.span_diagnostic - .struct_span_err(op2_span, "expected `*` or `+`") - .note("`?` is not a macro repetition operator") - .emit(); - } else { - sess.span_diagnostic.span_err( - span, - "the `?` macro repetition operator does not take a separator", - ); - } + sess.span_diagnostic.span_err( + span, + "the `?` macro repetition operator does not take a separator", + ); // Return a dummy return (None, KleeneOp::ZeroOrMore); @@ -638,13 +611,8 @@ where }; // If we ever get to this point, we have experienced an "unexpected token" error - - if !features.macro_at_most_once_rep && !attr::contains_name(attrs, "allow_internal_unstable") { - sess.span_diagnostic.span_err(span, "expected `*` or `+`"); - } else { - sess.span_diagnostic - .span_err(span, "expected one of: `*`, `+`, or `?`"); - } + sess.span_diagnostic + .span_err(span, "expected one of: `*`, `+`, or `?`"); // Return a dummy (None, KleeneOp::ZeroOrMore) diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index cd503f25cfe68..3bc349170514c 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -1426,9 +1426,6 @@ pub const EXPLAIN_DERIVE_UNDERSCORE: &'static str = pub const EXPLAIN_UNSIZED_TUPLE_COERCION: &'static str = "unsized tuple coercion is not stable enough for use and is subject to change"; -pub const EXPLAIN_MACRO_AT_MOST_ONCE_REP: &'static str = - "using the `?` macro Kleene operator for \"at most one\" repetition is unstable"; - struct PostExpansionVisitor<'a> { context: &'a Context<'a>, } From 32aafb220313fbc91e8f55b12886d77d3e1cf24b Mon Sep 17 00:00:00 2001 From: Mark Mansi Date: Sat, 24 Nov 2018 16:20:25 -0600 Subject: [PATCH 43/50] remove some unused vars --- src/libsyntax/ext/tt/quoted.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/libsyntax/ext/tt/quoted.rs b/src/libsyntax/ext/tt/quoted.rs index c8ece7b3a88fd..edc431be3694b 100644 --- a/src/libsyntax/ext/tt/quoted.rs +++ b/src/libsyntax/ext/tt/quoted.rs @@ -11,13 +11,13 @@ use ast::NodeId; use early_buffered_lints::BufferedEarlyLintId; use ext::tt::macro_parser; -use feature_gate::{self, emit_feature_err, Features, GateIssue}; +use feature_gate::Features; use parse::{token, ParseSess}; use print::pprust; use symbol::keywords; use syntax_pos::{edition::Edition, BytePos, Span}; use tokenstream::{self, DelimSpan}; -use {ast, attr}; +use ast; use rustc_data_structures::sync::Lrc; use std::iter::Peekable; @@ -566,8 +566,8 @@ fn parse_sep_and_kleene_op_2018( input: &mut Peekable, span: Span, sess: &ParseSess, - features: &Features, - attrs: &[ast::Attribute], + _features: &Features, + _attrs: &[ast::Attribute], ) -> (Option, KleeneOp) where I: Iterator, @@ -575,7 +575,7 @@ where // We basically look at two token trees here, denoted as #1 and #2 below let span = match parse_kleene_op(input, span) { // #1 is a `?` (needs feature gate) - Ok(Ok((op, op1_span))) if op == KleeneOp::ZeroOrOne => { + Ok(Ok((op, _op1_span))) if op == KleeneOp::ZeroOrOne => { return (None, op); } @@ -585,7 +585,7 @@ where // #1 is a separator followed by #2, a KleeneOp Ok(Err((tok, span))) => match parse_kleene_op(input, span) { // #2 is the `?` Kleene op, which does not take a separator (error) - Ok(Ok((op, op2_span))) if op == KleeneOp::ZeroOrOne => { + Ok(Ok((op, _op2_span))) if op == KleeneOp::ZeroOrOne => { // Error! sess.span_diagnostic.span_err( span, From e97edad935c8eb05d0c67475e81dbb0618ac72fb Mon Sep 17 00:00:00 2001 From: Mark Mansi Date: Sat, 24 Nov 2018 16:27:13 -0600 Subject: [PATCH 44/50] update tests --- ...ost-once-rep-2015-ques-rep-feature-flag.rs | 28 ------- ...once-rep-2015-ques-rep-feature-flag.stderr | 18 ----- ...acro-at-most-once-rep-2018-feature-gate.rs | 45 ----------- ...-at-most-once-rep-2018-feature-gate.stderr | 80 ------------------- .../ui/macros/macro-at-most-once-rep-2018.rs | 12 ++- .../macros/macro-at-most-once-rep-2018.stderr | 22 ++--- 6 files changed, 16 insertions(+), 189 deletions(-) delete mode 100644 src/test/ui/macros/macro-at-most-once-rep-2015-ques-rep-feature-flag.rs delete mode 100644 src/test/ui/macros/macro-at-most-once-rep-2015-ques-rep-feature-flag.stderr delete mode 100644 src/test/ui/macros/macro-at-most-once-rep-2018-feature-gate.rs delete mode 100644 src/test/ui/macros/macro-at-most-once-rep-2018-feature-gate.stderr diff --git a/src/test/ui/macros/macro-at-most-once-rep-2015-ques-rep-feature-flag.rs b/src/test/ui/macros/macro-at-most-once-rep-2015-ques-rep-feature-flag.rs deleted file mode 100644 index 63a4ef16a2581..0000000000000 --- a/src/test/ui/macros/macro-at-most-once-rep-2015-ques-rep-feature-flag.rs +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// Test behavior of `?` macro _kleene op_ under the 2015 edition. Namely, it doesn't exist, even -// with the feature flag. - -// gate-test-macro_at_most_once_rep -// edition:2015 - -#![feature(macro_at_most_once_rep)] - -macro_rules! bar { - ($(a)?) => {} //~ERROR expected `*` or `+` -} - -macro_rules! baz { - ($(a),?) => {} //~ERROR expected `*` or `+` -} - -fn main() {} - diff --git a/src/test/ui/macros/macro-at-most-once-rep-2015-ques-rep-feature-flag.stderr b/src/test/ui/macros/macro-at-most-once-rep-2015-ques-rep-feature-flag.stderr deleted file mode 100644 index 5f687900421bf..0000000000000 --- a/src/test/ui/macros/macro-at-most-once-rep-2015-ques-rep-feature-flag.stderr +++ /dev/null @@ -1,18 +0,0 @@ -error: expected `*` or `+` - --> $DIR/macro-at-most-once-rep-2015-ques-rep-feature-flag.rs:20:10 - | -LL | ($(a)?) => {} //~ERROR expected `*` or `+` - | ^ - | - = note: `?` is not a macro repetition operator - -error: expected `*` or `+` - --> $DIR/macro-at-most-once-rep-2015-ques-rep-feature-flag.rs:24:11 - | -LL | ($(a),?) => {} //~ERROR expected `*` or `+` - | ^ - | - = note: `?` is not a macro repetition operator - -error: aborting due to 2 previous errors - diff --git a/src/test/ui/macros/macro-at-most-once-rep-2018-feature-gate.rs b/src/test/ui/macros/macro-at-most-once-rep-2018-feature-gate.rs deleted file mode 100644 index ffabf9bcdf685..0000000000000 --- a/src/test/ui/macros/macro-at-most-once-rep-2018-feature-gate.rs +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// Feature gate test for macro_at_most_once_rep under 2018 edition. - -// gate-test-macro_at_most_once_rep -// edition:2018 - -macro_rules! foo { - ($(a)?) => {} - //~^ERROR using the `?` macro Kleene operator for - //~|ERROR expected `*` or `+` -} - -macro_rules! baz { - ($(a),?) => {} //~ERROR expected `*` or `+` -} - -macro_rules! barplus { - ($(a)?+) => {} - //~^ERROR using the `?` macro Kleene operator for - //~|ERROR expected `*` or `+` -} - -macro_rules! barstar { - ($(a)?*) => {} - //~^ERROR using the `?` macro Kleene operator for - //~|ERROR expected `*` or `+` -} - -pub fn main() { - foo!(); - foo!(a); - foo!(a?); //~ ERROR no rules expected the token `?` - foo!(a?a); //~ ERROR no rules expected the token `?` - foo!(a?a?a); //~ ERROR no rules expected the token `?` -} - diff --git a/src/test/ui/macros/macro-at-most-once-rep-2018-feature-gate.stderr b/src/test/ui/macros/macro-at-most-once-rep-2018-feature-gate.stderr deleted file mode 100644 index 27dc03e1c3981..0000000000000 --- a/src/test/ui/macros/macro-at-most-once-rep-2018-feature-gate.stderr +++ /dev/null @@ -1,80 +0,0 @@ -error[E0658]: using the `?` macro Kleene operator for "at most one" repetition is unstable (see issue #48075) - --> $DIR/macro-at-most-once-rep-2018-feature-gate.rs:17:10 - | -LL | ($(a)?) => {} - | ^ - | - = help: add #![feature(macro_at_most_once_rep)] to the crate attributes to enable - -error: expected `*` or `+` - --> $DIR/macro-at-most-once-rep-2018-feature-gate.rs:17:10 - | -LL | ($(a)?) => {} - | ^ - -error: expected `*` or `+` - --> $DIR/macro-at-most-once-rep-2018-feature-gate.rs:23:11 - | -LL | ($(a),?) => {} //~ERROR expected `*` or `+` - | ^ - | - = note: `?` is not a macro repetition operator - -error[E0658]: using the `?` macro Kleene operator for "at most one" repetition is unstable (see issue #48075) - --> $DIR/macro-at-most-once-rep-2018-feature-gate.rs:27:10 - | -LL | ($(a)?+) => {} - | ^ - | - = help: add #![feature(macro_at_most_once_rep)] to the crate attributes to enable - -error: expected `*` or `+` - --> $DIR/macro-at-most-once-rep-2018-feature-gate.rs:27:10 - | -LL | ($(a)?+) => {} - | ^ - -error[E0658]: using the `?` macro Kleene operator for "at most one" repetition is unstable (see issue #48075) - --> $DIR/macro-at-most-once-rep-2018-feature-gate.rs:33:10 - | -LL | ($(a)?*) => {} - | ^ - | - = help: add #![feature(macro_at_most_once_rep)] to the crate attributes to enable - -error: expected `*` or `+` - --> $DIR/macro-at-most-once-rep-2018-feature-gate.rs:33:10 - | -LL | ($(a)?*) => {} - | ^ - -error: no rules expected the token `?` - --> $DIR/macro-at-most-once-rep-2018-feature-gate.rs:41:11 - | -LL | macro_rules! foo { - | ---------------- when calling this macro -... -LL | foo!(a?); //~ ERROR no rules expected the token `?` - | ^ no rules expected this token in macro call - -error: no rules expected the token `?` - --> $DIR/macro-at-most-once-rep-2018-feature-gate.rs:42:11 - | -LL | macro_rules! foo { - | ---------------- when calling this macro -... -LL | foo!(a?a); //~ ERROR no rules expected the token `?` - | ^ no rules expected this token in macro call - -error: no rules expected the token `?` - --> $DIR/macro-at-most-once-rep-2018-feature-gate.rs:43:11 - | -LL | macro_rules! foo { - | ---------------- when calling this macro -... -LL | foo!(a?a?a); //~ ERROR no rules expected the token `?` - | ^ no rules expected this token in macro call - -error: aborting due to 10 previous errors - -For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/macros/macro-at-most-once-rep-2018.rs b/src/test/ui/macros/macro-at-most-once-rep-2018.rs index 5dabe8d952801..d8012c05acf8f 100644 --- a/src/test/ui/macros/macro-at-most-once-rep-2018.rs +++ b/src/test/ui/macros/macro-at-most-once-rep-2018.rs @@ -12,22 +12,20 @@ // edition:2018 -#![feature(macro_at_most_once_rep)] - macro_rules! foo { - ($(a)?) => {} + ($(a)?) => {}; } macro_rules! baz { - ($(a),?) => {} //~ERROR the `?` macro repetition operator + ($(a),?) => {}; //~ERROR the `?` macro repetition operator } macro_rules! barplus { - ($(a)?+) => {} // ok. matches "a+" and "+" + ($(a)?+) => {}; // ok. matches "a+" and "+" } macro_rules! barstar { - ($(a)?*) => {} // ok. matches "a*" and "*" + ($(a)?*) => {}; // ok. matches "a*" and "*" } pub fn main() { @@ -41,7 +39,7 @@ pub fn main() { barplus!(a); //~ERROR unexpected end of macro invocation barplus!(a?); //~ ERROR no rules expected the token `?` barplus!(a?a); //~ ERROR no rules expected the token `?` - barplus!(a+); + barplus!(a); barplus!(+); barstar!(); //~ERROR unexpected end of macro invocation diff --git a/src/test/ui/macros/macro-at-most-once-rep-2018.stderr b/src/test/ui/macros/macro-at-most-once-rep-2018.stderr index d363b672680ee..efe0a2672c83c 100644 --- a/src/test/ui/macros/macro-at-most-once-rep-2018.stderr +++ b/src/test/ui/macros/macro-at-most-once-rep-2018.stderr @@ -1,11 +1,11 @@ error: the `?` macro repetition operator does not take a separator - --> $DIR/macro-at-most-once-rep-2018.rs:22:10 + --> $DIR/macro-at-most-once-rep-2018.rs:20:10 | LL | ($(a),?) => {} //~ERROR the `?` macro repetition operator | ^ error: no rules expected the token `?` - --> $DIR/macro-at-most-once-rep-2018.rs:36:11 + --> $DIR/macro-at-most-once-rep-2018.rs:34:11 | LL | macro_rules! foo { | ---------------- when calling this macro @@ -14,7 +14,7 @@ LL | foo!(a?); //~ ERROR no rules expected the token `?` | ^ no rules expected this token in macro call error: no rules expected the token `?` - --> $DIR/macro-at-most-once-rep-2018.rs:37:11 + --> $DIR/macro-at-most-once-rep-2018.rs:35:11 | LL | macro_rules! foo { | ---------------- when calling this macro @@ -23,7 +23,7 @@ LL | foo!(a?a); //~ ERROR no rules expected the token `?` | ^ no rules expected this token in macro call error: no rules expected the token `?` - --> $DIR/macro-at-most-once-rep-2018.rs:38:11 + --> $DIR/macro-at-most-once-rep-2018.rs:36:11 | LL | macro_rules! foo { | ---------------- when calling this macro @@ -32,7 +32,7 @@ LL | foo!(a?a?a); //~ ERROR no rules expected the token `?` | ^ no rules expected this token in macro call error: unexpected end of macro invocation - --> $DIR/macro-at-most-once-rep-2018.rs:40:5 + --> $DIR/macro-at-most-once-rep-2018.rs:38:5 | LL | macro_rules! barplus { | -------------------- when calling this macro @@ -50,7 +50,7 @@ LL | barplus!(a); //~ERROR unexpected end of macro invocation | ^ missing tokens in macro arguments error: no rules expected the token `?` - --> $DIR/macro-at-most-once-rep-2018.rs:42:15 + --> $DIR/macro-at-most-once-rep-2018.rs:40:15 | LL | macro_rules! barplus { | -------------------- when calling this macro @@ -59,7 +59,7 @@ LL | barplus!(a?); //~ ERROR no rules expected the token `?` | ^ no rules expected this token in macro call error: no rules expected the token `?` - --> $DIR/macro-at-most-once-rep-2018.rs:43:15 + --> $DIR/macro-at-most-once-rep-2018.rs:41:15 | LL | macro_rules! barplus { | -------------------- when calling this macro @@ -68,7 +68,7 @@ LL | barplus!(a?a); //~ ERROR no rules expected the token `?` | ^ no rules expected this token in macro call error: unexpected end of macro invocation - --> $DIR/macro-at-most-once-rep-2018.rs:47:5 + --> $DIR/macro-at-most-once-rep-2018.rs:45:5 | LL | macro_rules! barstar { | -------------------- when calling this macro @@ -77,7 +77,7 @@ LL | barstar!(); //~ERROR unexpected end of macro invocation | ^^^^^^^^^^^ missing tokens in macro arguments error: unexpected end of macro invocation - --> $DIR/macro-at-most-once-rep-2018.rs:48:15 + --> $DIR/macro-at-most-once-rep-2018.rs:46:14 | LL | macro_rules! barstar { | -------------------- when calling this macro @@ -86,7 +86,7 @@ LL | barstar!(a); //~ERROR unexpected end of macro invocation | ^ missing tokens in macro arguments error: no rules expected the token `?` - --> $DIR/macro-at-most-once-rep-2018.rs:49:15 + --> $DIR/macro-at-most-once-rep-2018.rs:47:15 | LL | macro_rules! barstar { | -------------------- when calling this macro @@ -95,7 +95,7 @@ LL | barstar!(a?); //~ ERROR no rules expected the token `?` | ^ no rules expected this token in macro call error: no rules expected the token `?` - --> $DIR/macro-at-most-once-rep-2018.rs:50:15 + --> $DIR/macro-at-most-once-rep-2018.rs:48:15 | LL | macro_rules! barstar { | -------------------- when calling this macro From f3b29ca1c21b1cd559441a57e1ff2b8a41d56e36 Mon Sep 17 00:00:00 2001 From: Mark Mansi Date: Sat, 24 Nov 2018 16:29:43 -0600 Subject: [PATCH 45/50] remove unstable book entry --- .../macro-at-most-once-rep.md | 22 ------------------- 1 file changed, 22 deletions(-) delete mode 100644 src/doc/unstable-book/src/language-features/macro-at-most-once-rep.md diff --git a/src/doc/unstable-book/src/language-features/macro-at-most-once-rep.md b/src/doc/unstable-book/src/language-features/macro-at-most-once-rep.md deleted file mode 100644 index 251fc7209122c..0000000000000 --- a/src/doc/unstable-book/src/language-features/macro-at-most-once-rep.md +++ /dev/null @@ -1,22 +0,0 @@ -# `macro_at_most_once_rep` - -NOTE: This feature is only available in the 2018 Edition. - -The tracking issue for this feature is: #48075 - -With this feature gate enabled, one can use `?` as a Kleene operator meaning "0 -or 1 repetitions" in a macro definition. Previously only `+` and `*` were allowed. - -For example: - -```rust,ignore -#![feature(macro_at_most_once_rep)] - -macro_rules! foo { - (something $(,)?) // `?` indicates `,` is "optional"... - => {} -} -``` - ------------------------- - From 59ae93daed93024a3dd413132451f246863f6f97 Mon Sep 17 00:00:00 2001 From: Mark Mansi Date: Sat, 24 Nov 2018 17:26:15 -0600 Subject: [PATCH 46/50] remove uses of feature gate --- src/doc/unstable-book/src/language-features/plugin.md | 1 - src/libcore/lib.rs | 1 - src/librustc/lib.rs | 1 - src/librustc_lint/lib.rs | 1 - src/librustc_metadata/lib.rs | 1 - src/libsyntax/lib.rs | 1 - src/test/compile-fail-fulldeps/auxiliary/lint_for_crate.rs | 1 - .../compile-fail-fulldeps/auxiliary/lint_group_plugin_test.rs | 1 - src/test/compile-fail-fulldeps/auxiliary/lint_plugin_test.rs | 1 - src/test/run-pass-fulldeps/auxiliary/lint_for_crate.rs | 1 - .../proc-macro/auxiliary/issue-40001-plugin.rs | 1 - src/test/run-pass/macros/macro-at-most-once-rep.rs | 2 -- src/test/ui-fulldeps/auxiliary/lint_group_plugin_test.rs | 1 - src/test/ui-fulldeps/auxiliary/lint_plugin_test.rs | 1 - src/test/ui-fulldeps/auxiliary/lint_tool_test.rs | 1 - 15 files changed, 16 deletions(-) diff --git a/src/doc/unstable-book/src/language-features/plugin.md b/src/doc/unstable-book/src/language-features/plugin.md index 74bdd4dc3b599..03ea392c86307 100644 --- a/src/doc/unstable-book/src/language-features/plugin.md +++ b/src/doc/unstable-book/src/language-features/plugin.md @@ -181,7 +181,6 @@ that warns about any item named `lintme`. ```rust,ignore #![feature(plugin_registrar)] #![feature(box_syntax, rustc_private)] -#![feature(macro_at_most_once_rep)] extern crate syntax; diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs index a02b5bc87c5e9..726e891df0ccf 100644 --- a/src/libcore/lib.rs +++ b/src/libcore/lib.rs @@ -93,7 +93,6 @@ #![feature(never_type)] #![feature(nll)] #![feature(exhaustive_patterns)] -#![feature(macro_at_most_once_rep)] #![feature(no_core)] #![feature(on_unimplemented)] #![feature(optin_builtin_traits)] diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index 0aa964a44fd2c..9ae59242fbfa5 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -67,7 +67,6 @@ #![feature(integer_atomics)] #![feature(test)] #![feature(in_band_lifetimes)] -#![feature(macro_at_most_once_rep)] #![feature(crate_visibility_modifier)] #![feature(transpose_result)] diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs index 57cbecb5c67be..71efc5654eff3 100644 --- a/src/librustc_lint/lib.rs +++ b/src/librustc_lint/lib.rs @@ -29,7 +29,6 @@ #![feature(nll)] #![feature(quote)] #![feature(rustc_diagnostic_macros)] -#![feature(macro_at_most_once_rep)] #[macro_use] extern crate syntax; diff --git a/src/librustc_metadata/lib.rs b/src/librustc_metadata/lib.rs index 0322c888ad5c9..ee99f7465b905 100644 --- a/src/librustc_metadata/lib.rs +++ b/src/librustc_metadata/lib.rs @@ -14,7 +14,6 @@ #![feature(box_patterns)] #![feature(libc)] -#![feature(macro_at_most_once_rep)] #![feature(nll)] #![feature(proc_macro_internals)] #![feature(proc_macro_quote)] diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs index 9bbd59e09be15..ca9c5ad7b600e 100644 --- a/src/libsyntax/lib.rs +++ b/src/libsyntax/lib.rs @@ -20,7 +20,6 @@ test(attr(deny(warnings))))] #![feature(crate_visibility_modifier)] -#![feature(macro_at_most_once_rep)] #![feature(nll)] #![feature(rustc_attrs)] #![feature(rustc_diagnostic_macros)] diff --git a/src/test/compile-fail-fulldeps/auxiliary/lint_for_crate.rs b/src/test/compile-fail-fulldeps/auxiliary/lint_for_crate.rs index 460e28fc794f0..fc53031e7f226 100644 --- a/src/test/compile-fail-fulldeps/auxiliary/lint_for_crate.rs +++ b/src/test/compile-fail-fulldeps/auxiliary/lint_for_crate.rs @@ -12,7 +12,6 @@ #![feature(plugin_registrar, rustc_private)] #![feature(box_syntax)] -#![feature(macro_at_most_once_rep)] #[macro_use] extern crate rustc; extern crate rustc_plugin; diff --git a/src/test/compile-fail-fulldeps/auxiliary/lint_group_plugin_test.rs b/src/test/compile-fail-fulldeps/auxiliary/lint_group_plugin_test.rs index 1057649d969d1..f697642f8431d 100644 --- a/src/test/compile-fail-fulldeps/auxiliary/lint_group_plugin_test.rs +++ b/src/test/compile-fail-fulldeps/auxiliary/lint_group_plugin_test.rs @@ -12,7 +12,6 @@ #![feature(plugin_registrar)] #![feature(box_syntax, rustc_private)] -#![feature(macro_at_most_once_rep)] // Load rustc as a plugin to get macros #[macro_use] diff --git a/src/test/compile-fail-fulldeps/auxiliary/lint_plugin_test.rs b/src/test/compile-fail-fulldeps/auxiliary/lint_plugin_test.rs index b0183a3c56bc4..8647797270f9a 100644 --- a/src/test/compile-fail-fulldeps/auxiliary/lint_plugin_test.rs +++ b/src/test/compile-fail-fulldeps/auxiliary/lint_plugin_test.rs @@ -12,7 +12,6 @@ #![feature(plugin_registrar)] #![feature(box_syntax, rustc_private)] -#![feature(macro_at_most_once_rep)] extern crate syntax; diff --git a/src/test/run-pass-fulldeps/auxiliary/lint_for_crate.rs b/src/test/run-pass-fulldeps/auxiliary/lint_for_crate.rs index 00c419a8d09e8..9f6927d21640e 100644 --- a/src/test/run-pass-fulldeps/auxiliary/lint_for_crate.rs +++ b/src/test/run-pass-fulldeps/auxiliary/lint_for_crate.rs @@ -12,7 +12,6 @@ #![feature(plugin_registrar, rustc_private)] #![feature(box_syntax)] -#![feature(macro_at_most_once_rep)] #[macro_use] extern crate rustc; extern crate rustc_plugin; diff --git a/src/test/run-pass-fulldeps/proc-macro/auxiliary/issue-40001-plugin.rs b/src/test/run-pass-fulldeps/proc-macro/auxiliary/issue-40001-plugin.rs index e0acf340a79fd..f4d3f2c94caf1 100644 --- a/src/test/run-pass-fulldeps/proc-macro/auxiliary/issue-40001-plugin.rs +++ b/src/test/run-pass-fulldeps/proc-macro/auxiliary/issue-40001-plugin.rs @@ -9,7 +9,6 @@ // except according to those terms. #![feature(box_syntax, plugin, plugin_registrar, rustc_private)] -#![feature(macro_at_most_once_rep)] #![crate_type = "dylib"] #[macro_use] diff --git a/src/test/run-pass/macros/macro-at-most-once-rep.rs b/src/test/run-pass/macros/macro-at-most-once-rep.rs index c7129423cb651..563fd01c11147 100644 --- a/src/test/run-pass/macros/macro-at-most-once-rep.rs +++ b/src/test/run-pass/macros/macro-at-most-once-rep.rs @@ -22,8 +22,6 @@ // edition:2018 -#![feature(macro_at_most_once_rep)] - macro_rules! foo { ($($a:ident)? ; $num:expr) => { { let mut x = 0; diff --git a/src/test/ui-fulldeps/auxiliary/lint_group_plugin_test.rs b/src/test/ui-fulldeps/auxiliary/lint_group_plugin_test.rs index 1057649d969d1..f697642f8431d 100644 --- a/src/test/ui-fulldeps/auxiliary/lint_group_plugin_test.rs +++ b/src/test/ui-fulldeps/auxiliary/lint_group_plugin_test.rs @@ -12,7 +12,6 @@ #![feature(plugin_registrar)] #![feature(box_syntax, rustc_private)] -#![feature(macro_at_most_once_rep)] // Load rustc as a plugin to get macros #[macro_use] diff --git a/src/test/ui-fulldeps/auxiliary/lint_plugin_test.rs b/src/test/ui-fulldeps/auxiliary/lint_plugin_test.rs index b0183a3c56bc4..8647797270f9a 100644 --- a/src/test/ui-fulldeps/auxiliary/lint_plugin_test.rs +++ b/src/test/ui-fulldeps/auxiliary/lint_plugin_test.rs @@ -12,7 +12,6 @@ #![feature(plugin_registrar)] #![feature(box_syntax, rustc_private)] -#![feature(macro_at_most_once_rep)] extern crate syntax; diff --git a/src/test/ui-fulldeps/auxiliary/lint_tool_test.rs b/src/test/ui-fulldeps/auxiliary/lint_tool_test.rs index 7d2acd7aa4c86..0a449e338bd06 100644 --- a/src/test/ui-fulldeps/auxiliary/lint_tool_test.rs +++ b/src/test/ui-fulldeps/auxiliary/lint_tool_test.rs @@ -10,7 +10,6 @@ #![feature(plugin_registrar)] #![feature(box_syntax, rustc_private)] -#![feature(macro_at_most_once_rep)] extern crate syntax; From aeede9eb468f373f2c3250899606b0a68e8b8a18 Mon Sep 17 00:00:00 2001 From: Mark Mansi Date: Sat, 24 Nov 2018 18:40:03 -0600 Subject: [PATCH 47/50] fix test --- src/test/ui/macros/macro-at-most-once-rep-2018.rs | 2 +- src/test/ui/macros/macro-at-most-once-rep-2018.stderr | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/ui/macros/macro-at-most-once-rep-2018.rs b/src/test/ui/macros/macro-at-most-once-rep-2018.rs index d8012c05acf8f..78bdf8ff71b88 100644 --- a/src/test/ui/macros/macro-at-most-once-rep-2018.rs +++ b/src/test/ui/macros/macro-at-most-once-rep-2018.rs @@ -39,7 +39,7 @@ pub fn main() { barplus!(a); //~ERROR unexpected end of macro invocation barplus!(a?); //~ ERROR no rules expected the token `?` barplus!(a?a); //~ ERROR no rules expected the token `?` - barplus!(a); + barplus!(a+); barplus!(+); barstar!(); //~ERROR unexpected end of macro invocation diff --git a/src/test/ui/macros/macro-at-most-once-rep-2018.stderr b/src/test/ui/macros/macro-at-most-once-rep-2018.stderr index efe0a2672c83c..43779078ebc83 100644 --- a/src/test/ui/macros/macro-at-most-once-rep-2018.stderr +++ b/src/test/ui/macros/macro-at-most-once-rep-2018.stderr @@ -1,7 +1,7 @@ error: the `?` macro repetition operator does not take a separator --> $DIR/macro-at-most-once-rep-2018.rs:20:10 | -LL | ($(a),?) => {} //~ERROR the `?` macro repetition operator +LL | ($(a),?) => {}; //~ERROR the `?` macro repetition operator | ^ error: no rules expected the token `?` From e63bd91895e640a5736ef37eb1d0dedc11fe3138 Mon Sep 17 00:00:00 2001 From: polyfloyd Date: Tue, 27 Nov 2018 22:33:46 +0100 Subject: [PATCH 48/50] Fix a typo in the documentation of std::ffi --- src/libstd/ffi/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libstd/ffi/mod.rs b/src/libstd/ffi/mod.rs index a3345df5e0d85..f1f3742996bda 100644 --- a/src/libstd/ffi/mod.rs +++ b/src/libstd/ffi/mod.rs @@ -112,12 +112,12 @@ //! ## On Unix //! //! On Unix, [`OsStr`] implements the -//! `std::os::unix:ffi::`[`OsStrExt`][unix.OsStrExt] trait, which +//! `std::os::unix::ffi::`[`OsStrExt`][unix.OsStrExt] trait, which //! augments it with two methods, [`from_bytes`] and [`as_bytes`]. //! These do inexpensive conversions from and to UTF-8 byte slices. //! //! Additionally, on Unix [`OsString`] implements the -//! `std::os::unix:ffi::`[`OsStringExt`][unix.OsStringExt] trait, +//! `std::os::unix::ffi::`[`OsStringExt`][unix.OsStringExt] trait, //! which provides [`from_vec`] and [`into_vec`] methods that consume //! their arguments, and take or produce vectors of [`u8`]. //! From d8190afbcb9b15eb8e04d3860a5bd018568a3980 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Wed, 28 Nov 2018 00:25:40 +0100 Subject: [PATCH 49/50] Fix alignment of stores to scalar pair The alignment for the second element of a scalar pair is not the same as for the first element. Make sure it is computed correctly based on the element size. --- src/librustc_codegen_ssa/mir/operand.rs | 20 +++++++++++++++----- src/test/codegen/issue-56267.rs | 18 ++++++++++++++++++ 2 files changed, 33 insertions(+), 5 deletions(-) create mode 100644 src/test/codegen/issue-56267.rs diff --git a/src/librustc_codegen_ssa/mir/operand.rs b/src/librustc_codegen_ssa/mir/operand.rs index 92d0219caf06b..fefbc14e4973c 100644 --- a/src/librustc_codegen_ssa/mir/operand.rs +++ b/src/librustc_codegen_ssa/mir/operand.rs @@ -331,11 +331,21 @@ impl<'a, 'tcx: 'a, V: CodegenObject> OperandValue { bx.store_with_flags(val, dest.llval, dest.align, flags); } OperandValue::Pair(a, b) => { - for (i, &x) in [a, b].iter().enumerate() { - let llptr = bx.struct_gep(dest.llval, i as u64); - let val = base::from_immediate(bx, x); - bx.store_with_flags(val, llptr, dest.align, flags); - } + let (a_scalar, b_scalar) = match dest.layout.abi { + layout::Abi::ScalarPair(ref a, ref b) => (a, b), + _ => bug!("store_with_flags: invalid ScalarPair layout: {:#?}", dest.layout) + }; + let b_offset = a_scalar.value.size(bx).align_to(b_scalar.value.align(bx).abi); + + let llptr = bx.struct_gep(dest.llval, 0); + let val = base::from_immediate(bx, a); + let align = dest.align; + bx.store_with_flags(val, llptr, align, flags); + + let llptr = bx.struct_gep(dest.llval, 1); + let val = base::from_immediate(bx, b); + let align = dest.align.restrict_for_offset(b_offset); + bx.store_with_flags(val, llptr, align, flags); } } } diff --git a/src/test/codegen/issue-56267.rs b/src/test/codegen/issue-56267.rs new file mode 100644 index 0000000000000..2c33f558931ed --- /dev/null +++ b/src/test/codegen/issue-56267.rs @@ -0,0 +1,18 @@ +// compile-flags: -C no-prepopulate-passes + +#![crate_type="rlib"] + +#[allow(dead_code)] +pub struct Foo { + foo: u64, + bar: T, +} + +// The store writing to bar.1 should have alignment 4. Not checking +// other stores here, as the alignment will be platform-dependent. + +// CHECK: store i32 [[TMP1:%.+]], i32* [[TMP2:%.+]], align 4 +#[no_mangle] +pub fn test(x: (i32, i32)) -> Foo<(i32, i32)> { + Foo { foo: 0, bar: x } +} From 5d7717360c8f343f70a33455029355f00e39dea2 Mon Sep 17 00:00:00 2001 From: Mark Mansi Date: Tue, 27 Nov 2018 18:21:10 -0600 Subject: [PATCH 50/50] fix test --- src/test/ui/macros/macro-at-most-once-rep-2018.stderr | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/ui/macros/macro-at-most-once-rep-2018.stderr b/src/test/ui/macros/macro-at-most-once-rep-2018.stderr index 43779078ebc83..da76d1ff1a721 100644 --- a/src/test/ui/macros/macro-at-most-once-rep-2018.stderr +++ b/src/test/ui/macros/macro-at-most-once-rep-2018.stderr @@ -41,7 +41,7 @@ LL | barplus!(); //~ERROR unexpected end of macro invocation | ^^^^^^^^^^^ missing tokens in macro arguments error: unexpected end of macro invocation - --> $DIR/macro-at-most-once-rep-2018.rs:41:15 + --> $DIR/macro-at-most-once-rep-2018.rs:39:15 | LL | macro_rules! barplus { | -------------------- when calling this macro @@ -77,7 +77,7 @@ LL | barstar!(); //~ERROR unexpected end of macro invocation | ^^^^^^^^^^^ missing tokens in macro arguments error: unexpected end of macro invocation - --> $DIR/macro-at-most-once-rep-2018.rs:46:14 + --> $DIR/macro-at-most-once-rep-2018.rs:46:15 | LL | macro_rules! barstar { | -------------------- when calling this macro