From 612ef5f518198448c43959a6416b9da2964f9167 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Thu, 12 Sep 2019 17:04:32 -0400 Subject: [PATCH 01/15] add new tests for re_rebalance_coherence --- ...]-foreign[foreign[t],local]-for-foreign.rs | 14 +++++++++++++ ...pl[t]-foreign[local]-for-fundamental[t].rs | 21 +++++++++++++++++++ .../coherence/impl[t]-foreign[local]-for-t.rs | 16 ++++++++++++++ .../impl[t]-foreign[local]-for-t.stderr | 11 ++++++++++ .../coherence/re-rebalance-coherence-rpass.rs | 14 ------------- 5 files changed, 62 insertions(+), 14 deletions(-) create mode 100644 src/test/ui/coherence/impl[t]-foreign[foreign[t],local]-for-foreign.rs create mode 100644 src/test/ui/coherence/impl[t]-foreign[local]-for-fundamental[t].rs create mode 100644 src/test/ui/coherence/impl[t]-foreign[local]-for-t.rs create mode 100644 src/test/ui/coherence/impl[t]-foreign[local]-for-t.stderr delete mode 100644 src/test/ui/coherence/re-rebalance-coherence-rpass.rs diff --git a/src/test/ui/coherence/impl[t]-foreign[foreign[t],local]-for-foreign.rs b/src/test/ui/coherence/impl[t]-foreign[foreign[t],local]-for-foreign.rs new file mode 100644 index 0000000000000..61f2637c0c297 --- /dev/null +++ b/src/test/ui/coherence/impl[t]-foreign[foreign[t],local]-for-foreign.rs @@ -0,0 +1,14 @@ +#![feature(re_rebalance_coherence)] + +// run-pass +// compile-flags:--crate-name=test +// aux-build:coherence_lib.rs + +extern crate coherence_lib as lib; +use lib::*; +use std::rc::Rc; + +struct Local; +impl Remote2, Local> for usize { } + +fn main() {} diff --git a/src/test/ui/coherence/impl[t]-foreign[local]-for-fundamental[t].rs b/src/test/ui/coherence/impl[t]-foreign[local]-for-fundamental[t].rs new file mode 100644 index 0000000000000..586b8de9e95c9 --- /dev/null +++ b/src/test/ui/coherence/impl[t]-foreign[local]-for-fundamental[t].rs @@ -0,0 +1,21 @@ +#![feature(re_rebalance_coherence)] + +// compile-flags:--crate-name=test +// aux-build:coherence_lib.rs +// run-pass + +extern crate coherence_lib as lib; +use lib::*; +use std::rc::Rc; + +struct Local; + +impl Remote1 for Box { + // FIXME(#64412) -- this is expected to error +} + +impl Remote1 for &T { + // FIXME(#64412) -- this is expected to error +} + +fn main() {} diff --git a/src/test/ui/coherence/impl[t]-foreign[local]-for-t.rs b/src/test/ui/coherence/impl[t]-foreign[local]-for-t.rs new file mode 100644 index 0000000000000..6f35c6c9dbc88 --- /dev/null +++ b/src/test/ui/coherence/impl[t]-foreign[local]-for-t.rs @@ -0,0 +1,16 @@ +#![feature(re_rebalance_coherence)] + +// compile-flags:--crate-name=test +// aux-build:coherence_lib.rs + +extern crate coherence_lib as lib; +use lib::*; +use std::rc::Rc; + +struct Local; + +impl Remote1 for T { + //~^ ERROR type parameter `T` must be used as the type parameter for some local type +} + +fn main() {} diff --git a/src/test/ui/coherence/impl[t]-foreign[local]-for-t.stderr b/src/test/ui/coherence/impl[t]-foreign[local]-for-t.stderr new file mode 100644 index 0000000000000..be7de8cccb467 --- /dev/null +++ b/src/test/ui/coherence/impl[t]-foreign[local]-for-t.stderr @@ -0,0 +1,11 @@ +error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct`) + --> $DIR/impl[t]-foreign[local]-for-t.rs:12:1 + | +LL | impl Remote1 for T { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type parameter `T` must be used as the type parameter for some local type + | + = note: only traits defined in the current crate can be implemented for a type parameter + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0210`. diff --git a/src/test/ui/coherence/re-rebalance-coherence-rpass.rs b/src/test/ui/coherence/re-rebalance-coherence-rpass.rs deleted file mode 100644 index bacd3b89fad29..0000000000000 --- a/src/test/ui/coherence/re-rebalance-coherence-rpass.rs +++ /dev/null @@ -1,14 +0,0 @@ -#![allow(dead_code)] -#![feature(re_rebalance_coherence)] - -// run-pass -// aux-build:re_rebalance_coherence_lib.rs - -extern crate re_rebalance_coherence_lib as lib; -use lib::*; - -struct Oracle; -impl Backend for Oracle {} -impl<'a, T:'a, Tab> QueryFragment for BatchInsert<'a, T, Tab> {} - -fn main() {} From e69d1b67b6603e0635c553eff693a0606d282d75 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Fri, 13 Sep 2019 14:57:06 -0400 Subject: [PATCH 02/15] change to check-pass --- .../coherence/impl[t]-foreign[foreign[t],local]-for-foreign.rs | 2 +- .../ui/coherence/impl[t]-foreign[local]-for-fundamental[t].rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/ui/coherence/impl[t]-foreign[foreign[t],local]-for-foreign.rs b/src/test/ui/coherence/impl[t]-foreign[foreign[t],local]-for-foreign.rs index 61f2637c0c297..54d4bf04a583c 100644 --- a/src/test/ui/coherence/impl[t]-foreign[foreign[t],local]-for-foreign.rs +++ b/src/test/ui/coherence/impl[t]-foreign[foreign[t],local]-for-foreign.rs @@ -1,6 +1,6 @@ #![feature(re_rebalance_coherence)] -// run-pass +// check-pass // compile-flags:--crate-name=test // aux-build:coherence_lib.rs diff --git a/src/test/ui/coherence/impl[t]-foreign[local]-for-fundamental[t].rs b/src/test/ui/coherence/impl[t]-foreign[local]-for-fundamental[t].rs index 586b8de9e95c9..db671cb9bcaba 100644 --- a/src/test/ui/coherence/impl[t]-foreign[local]-for-fundamental[t].rs +++ b/src/test/ui/coherence/impl[t]-foreign[local]-for-fundamental[t].rs @@ -2,7 +2,7 @@ // compile-flags:--crate-name=test // aux-build:coherence_lib.rs -// run-pass +// check-pass extern crate coherence_lib as lib; use lib::*; From 6e5ada43bf84b15a8dd4d55f5bee3ba1a9939bfe Mon Sep 17 00:00:00 2001 From: Tim Vermeulen Date: Sat, 31 Aug 2019 23:00:15 +0200 Subject: [PATCH 03/15] Add cmp::{min_by, min_by_key, max_by, max_by_key} --- src/libcore/cmp.rs | 90 +++++++++++++++++++++++++++++++++++++++- src/libcore/tests/cmp.rs | 24 ++++++++++- src/libcore/tests/lib.rs | 1 + 3 files changed, 112 insertions(+), 3 deletions(-) diff --git a/src/libcore/cmp.rs b/src/libcore/cmp.rs index 7ec2295f97e36..4e2b1627e15ef 100644 --- a/src/libcore/cmp.rs +++ b/src/libcore/cmp.rs @@ -570,7 +570,7 @@ pub trait Ord: Eq + PartialOrd { #[inline] fn max(self, other: Self) -> Self where Self: Sized { - if other >= self { other } else { self } + max_by(self, other, Ord::cmp) } /// Compares and returns the minimum of two values. @@ -587,7 +587,7 @@ pub trait Ord: Eq + PartialOrd { #[inline] fn min(self, other: Self) -> Self where Self: Sized { - if self <= other { self } else { other } + min_by(self, other, Ord::cmp) } /// Restrict a value to a certain interval. @@ -898,6 +898,49 @@ pub fn min(v1: T, v2: T) -> T { v1.min(v2) } +/// Returns the minimum of two values with respect to the specified comparison function. +/// +/// Returns the first argument if the comparison determines them to be equal. +/// +/// # Examples +/// +/// ``` +/// #![feature(cmp_min_max_by)] +/// +/// use std::cmp; +/// +/// assert_eq!(cmp::min_by(-2, 1, |x: &i32, y: &i32| x.abs().cmp(&y.abs())), 1); +/// assert_eq!(cmp::min_by(-2, 2, |x: &i32, y: &i32| x.abs().cmp(&y.abs())), -2); +/// ``` +#[inline] +#[unstable(feature = "cmp_min_max_by", issue = "64460")] +pub fn min_by Ordering>(v1: T, v2: T, compare: F) -> T { + match compare(&v1, &v2) { + Ordering::Less | Ordering::Equal => v1, + Ordering::Greater => v2, + } +} + +/// Returns the element that gives the minimum value from the specified function. +/// +/// Returns the first argument if the comparison determines them to be equal. +/// +/// # Examples +/// +/// ``` +/// #![feature(cmp_min_max_by)] +/// +/// use std::cmp; +/// +/// assert_eq!(cmp::min_by_key(-2, 1, |x: &i32| x.abs()), 1); +/// assert_eq!(cmp::min_by_key(-2, 2, |x: &i32| x.abs()), -2); +/// ``` +#[inline] +#[unstable(feature = "cmp_min_max_by", issue = "64460")] +pub fn min_by_key K, K: Ord>(v1: T, v2: T, mut f: F) -> T { + min_by(v1, v2, |v1, v2| f(v1).cmp(&f(v2))) +} + /// Compares and returns the maximum of two values. /// /// Returns the second argument if the comparison determines them to be equal. @@ -918,6 +961,49 @@ pub fn max(v1: T, v2: T) -> T { v1.max(v2) } +/// Returns the maximum of two values with respect to the specified comparison function. +/// +/// Returns the second argument if the comparison determines them to be equal. +/// +/// # Examples +/// +/// ``` +/// #![feature(cmp_min_max_by)] +/// +/// use std::cmp; +/// +/// assert_eq!(cmp::max_by(-2, 1, |x: &i32, y: &i32| x.abs().cmp(&y.abs())), -2); +/// assert_eq!(cmp::max_by(-2, 2, |x: &i32, y: &i32| x.abs().cmp(&y.abs())), 2); +/// ``` +#[inline] +#[unstable(feature = "cmp_min_max_by", issue = "64460")] +pub fn max_by Ordering>(v1: T, v2: T, compare: F) -> T { + match compare(&v1, &v2) { + Ordering::Less | Ordering::Equal => v2, + Ordering::Greater => v1, + } +} + +/// Returns the element that gives the maximum value from the specified function. +/// +/// Returns the second argument if the comparison determines them to be equal. +/// +/// # Examples +/// +/// ``` +/// #![feature(cmp_min_max_by)] +/// +/// use std::cmp; +/// +/// assert_eq!(cmp::max_by_key(-2, 1, |x: &i32| x.abs()), -2); +/// assert_eq!(cmp::max_by_key(-2, 2, |x: &i32| x.abs()), 2); +/// ``` +#[inline] +#[unstable(feature = "cmp_min_max_by", issue = "64460")] +pub fn max_by_key K, K: Ord>(v1: T, v2: T, mut f: F) -> T { + max_by(v1, v2, |v1, v2| f(v1).cmp(&f(v2))) +} + // Implementation of PartialEq, Eq, PartialOrd and Ord for primitive types mod impls { use crate::cmp::Ordering::{self, Less, Greater, Equal}; diff --git a/src/libcore/tests/cmp.rs b/src/libcore/tests/cmp.rs index 4e624e5eb126e..5e6778e222a29 100644 --- a/src/libcore/tests/cmp.rs +++ b/src/libcore/tests/cmp.rs @@ -1,4 +1,4 @@ -use core::cmp::Ordering::{Less, Greater, Equal}; +use core::cmp::{self, Ordering::*}; #[test] fn test_int_totalord() { @@ -28,6 +28,28 @@ fn test_ord_max_min() { assert_eq!(1.min(1), 1); } +#[test] +fn test_ord_min_max_by() { + let f = |x: &i32, y: &i32| x.abs().cmp(&y.abs()); + assert_eq!(cmp::min_by(1, -1, f), 1); + assert_eq!(cmp::min_by(1, -2, f), 1); + assert_eq!(cmp::min_by(2, -1, f), -1); + assert_eq!(cmp::max_by(1, -1, f), -1); + assert_eq!(cmp::max_by(1, -2, f), -2); + assert_eq!(cmp::max_by(2, -1, f), 2); +} + +#[test] +fn test_ord_min_max_by_key() { + let f = |x: &i32| x.abs(); + assert_eq!(cmp::min_by_key(1, -1, f), 1); + assert_eq!(cmp::min_by_key(1, -2, f), 1); + assert_eq!(cmp::min_by_key(2, -1, f), -1); + assert_eq!(cmp::max_by_key(1, -1, f), -1); + assert_eq!(cmp::max_by_key(1, -2, f), -2); + assert_eq!(cmp::max_by_key(2, -1, f), 2); +} + #[test] fn test_ordering_reverse() { assert_eq!(Less.reverse(), Greater); diff --git a/src/libcore/tests/lib.rs b/src/libcore/tests/lib.rs index 050195cd2ef51..35661356028cb 100644 --- a/src/libcore/tests/lib.rs +++ b/src/libcore/tests/lib.rs @@ -34,6 +34,7 @@ #![feature(iter_partition_in_place)] #![feature(iter_is_partitioned)] #![feature(iter_order_by)] +#![feature(cmp_min_max_by)] extern crate test; From 72175915d6ae5abbc45cf2860a90508d2b4a38ea Mon Sep 17 00:00:00 2001 From: Tim Vermeulen Date: Sat, 14 Sep 2019 21:24:50 +0200 Subject: [PATCH 04/15] Simplify Iterator::{min_by, max_by} using cmp::{min_by, max_by} --- src/libcore/iter/traits/iterator.rs | 48 ++++++++++------------------- 1 file changed, 17 insertions(+), 31 deletions(-) diff --git a/src/libcore/iter/traits/iterator.rs b/src/libcore/iter/traits/iterator.rs index c09df3f7f22cb..da49223dfb285 100644 --- a/src/libcore/iter/traits/iterator.rs +++ b/src/libcore/iter/traits/iterator.rs @@ -1,4 +1,4 @@ -use crate::cmp::Ordering; +use crate::cmp::{self, Ordering}; use crate::ops::{Add, Try}; use super::super::LoopState; @@ -2223,13 +2223,12 @@ pub trait Iterator { move |x| (f(&x), x) } - // switch to y even if it is only equal, to preserve stability. #[inline] - fn select((x_p, _): &(B, T), (y_p, _): &(B, T)) -> bool { - x_p <= y_p + fn compare((x_p, _): &(B, T), (y_p, _): &(B, T)) -> Ordering { + x_p.cmp(y_p) } - let (_, x) = select_fold1(self.map(key(f)), select)?; + let (_, x) = self.map(key(f)).max_by(compare)?; Some(x) } @@ -2252,13 +2251,12 @@ pub trait Iterator { fn max_by(self, compare: F) -> Option where Self: Sized, F: FnMut(&Self::Item, &Self::Item) -> Ordering, { - // switch to y even if it is only equal, to preserve stability. #[inline] - fn select(mut compare: impl FnMut(&T, &T) -> Ordering) -> impl FnMut(&T, &T) -> bool { - move |x, y| compare(x, y) != Ordering::Greater + fn fold(mut compare: impl FnMut(&T, &T) -> Ordering) -> impl FnMut(T, T) -> T { + move |x, y| cmp::max_by(x, y, &mut compare) } - select_fold1(self, select(compare)) + fold1(self, fold(compare)) } /// Returns the element that gives the minimum value from the @@ -2285,13 +2283,12 @@ pub trait Iterator { move |x| (f(&x), x) } - // only switch to y if it is strictly smaller, to preserve stability. #[inline] - fn select((x_p, _): &(B, T), (y_p, _): &(B, T)) -> bool { - x_p > y_p + fn compare((x_p, _): &(B, T), (y_p, _): &(B, T)) -> Ordering { + x_p.cmp(y_p) } - let (_, x) = select_fold1(self.map(key(f)), select)?; + let (_, x) = self.map(key(f)).min_by(compare)?; Some(x) } @@ -2314,13 +2311,12 @@ pub trait Iterator { fn min_by(self, compare: F) -> Option where Self: Sized, F: FnMut(&Self::Item, &Self::Item) -> Ordering, { - // only switch to y if it is strictly smaller, to preserve stability. #[inline] - fn select(mut compare: impl FnMut(&T, &T) -> Ordering) -> impl FnMut(&T, &T) -> bool { - move |x, y| compare(x, y) == Ordering::Greater + fn fold(mut compare: impl FnMut(&T, &T) -> Ordering) -> impl FnMut(T, T) -> T { + move |x, y| cmp::min_by(x, y, &mut compare) } - select_fold1(self, select(compare)) + fold1(self, fold(compare)) } @@ -2958,28 +2954,18 @@ pub trait Iterator { } } -/// Select an element from an iterator based on the given "comparison" -/// function. -/// -/// This is an idiosyncratic helper to try to factor out the -/// commonalities of {max,min}{,_by}. In particular, this avoids -/// having to implement optimizations several times. +/// Fold an iterator without having to provide an initial value. #[inline] -fn select_fold1(mut it: I, f: F) -> Option +fn fold1(mut it: I, f: F) -> Option where I: Iterator, - F: FnMut(&I::Item, &I::Item) -> bool, + F: FnMut(I::Item, I::Item) -> I::Item, { - #[inline] - fn select(mut f: impl FnMut(&T, &T) -> bool) -> impl FnMut(T, T) -> T { - move |sel, x| if f(&sel, &x) { x } else { sel } - } - // start with the first element as our selection. This avoids // having to use `Option`s inside the loop, translating to a // sizeable performance gain (6x in one case). let first = it.next()?; - Some(it.fold(first, select(f))) + Some(it.fold(first, f)) } #[stable(feature = "rust1", since = "1.0.0")] From 194d357e03dcee73bfdb32a45175c97f4c3ce422 Mon Sep 17 00:00:00 2001 From: Charles Gleason Date: Tue, 3 Sep 2019 18:42:58 -0400 Subject: [PATCH 05/15] Document `From` trait for `LhsExpr` --- src/libsyntax/parse/parser/expr.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/libsyntax/parse/parser/expr.rs b/src/libsyntax/parse/parser/expr.rs index 5b9f0f1df6718..c38b134154d62 100644 --- a/src/libsyntax/parse/parser/expr.rs +++ b/src/libsyntax/parse/parser/expr.rs @@ -66,6 +66,10 @@ pub(super) enum LhsExpr { } impl From>> for LhsExpr { + /// Converts `Some(attrs)` into `LhsExpr::AttributesParsed(attrs)` + /// and `None` into `LhsExpr::NotYetParsed`. + /// + /// This conversion does not allocate. fn from(o: Option>) -> Self { if let Some(attrs) = o { LhsExpr::AttributesParsed(attrs) @@ -76,6 +80,9 @@ impl From>> for LhsExpr { } impl From> for LhsExpr { + /// Converts the `expr: P` into `LhsExpr::AlreadyParsed(expr)`. + /// + /// This conversion does not allocate. fn from(expr: P) -> Self { LhsExpr::AlreadyParsed(expr) } From 3f004a1bc44859857f05a9f692a578124b3f3e01 Mon Sep 17 00:00:00 2001 From: Georg Semmler Date: Tue, 17 Sep 2019 14:40:36 +0200 Subject: [PATCH 06/15] Fix re-rebalance coherence implementation for fundamental types Fixes #64412 --- src/librustc/traits/coherence.rs | 10 +++++++++- ...pl[t]-foreign[local]-for-fundamental[t].rs | 5 ++--- ...]-foreign[local]-for-fundamental[t].stderr | 19 +++++++++++++++++++ 3 files changed, 30 insertions(+), 4 deletions(-) create mode 100644 src/test/ui/coherence/impl[t]-foreign[local]-for-fundamental[t].stderr diff --git a/src/librustc/traits/coherence.rs b/src/librustc/traits/coherence.rs index b6f0addd77107..bc6bcb1f76f96 100644 --- a/src/librustc/traits/coherence.rs +++ b/src/librustc/traits/coherence.rs @@ -378,7 +378,15 @@ fn orphan_check_trait_ref<'tcx>( // Let Ti be the first such type. // - No uncovered type parameters P1..=Pn may appear in T0..Ti (excluding Ti) // - for input_ty in trait_ref.input_types() { + fn uncover_fundamental_ty(ty: Ty<'_>) -> Vec> { + if fundamental_ty(ty) { + ty.walk_shallow().flat_map(|ty| uncover_fundamental_ty(ty)).collect() + } else { + vec![ty] + } + } + + for input_ty in trait_ref.input_types().flat_map(uncover_fundamental_ty) { debug!("orphan_check_trait_ref: check ty `{:?}`", input_ty); if ty_is_local(tcx, input_ty, in_crate) { debug!("orphan_check_trait_ref: ty_is_local `{:?}`", input_ty); diff --git a/src/test/ui/coherence/impl[t]-foreign[local]-for-fundamental[t].rs b/src/test/ui/coherence/impl[t]-foreign[local]-for-fundamental[t].rs index db671cb9bcaba..54425b6d708aa 100644 --- a/src/test/ui/coherence/impl[t]-foreign[local]-for-fundamental[t].rs +++ b/src/test/ui/coherence/impl[t]-foreign[local]-for-fundamental[t].rs @@ -2,7 +2,6 @@ // compile-flags:--crate-name=test // aux-build:coherence_lib.rs -// check-pass extern crate coherence_lib as lib; use lib::*; @@ -11,11 +10,11 @@ use std::rc::Rc; struct Local; impl Remote1 for Box { - // FIXME(#64412) -- this is expected to error + //~^ ERROR type parameter `T` must be used as the type parameter for some local type } impl Remote1 for &T { - // FIXME(#64412) -- this is expected to error + //~^ ERROR type parameter `T` must be used as the type parameter for some local type } fn main() {} diff --git a/src/test/ui/coherence/impl[t]-foreign[local]-for-fundamental[t].stderr b/src/test/ui/coherence/impl[t]-foreign[local]-for-fundamental[t].stderr new file mode 100644 index 0000000000000..7859665a7bb58 --- /dev/null +++ b/src/test/ui/coherence/impl[t]-foreign[local]-for-fundamental[t].stderr @@ -0,0 +1,19 @@ +error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct`) + --> $DIR/impl[t]-foreign[local]-for-fundamental[t].rs:12:1 + | +LL | impl Remote1 for Box { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type parameter `T` must be used as the type parameter for some local type + | + = note: only traits defined in the current crate can be implemented for a type parameter + +error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct`) + --> $DIR/impl[t]-foreign[local]-for-fundamental[t].rs:16:1 + | +LL | impl Remote1 for &T { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type parameter `T` must be used as the type parameter for some local type + | + = note: only traits defined in the current crate can be implemented for a type parameter + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0210`. From a9c38d9d01bd50b5a264cd62fd32cec37f006ab9 Mon Sep 17 00:00:00 2001 From: Georg Semmler Date: Wed, 18 Sep 2019 22:14:33 +0200 Subject: [PATCH 07/15] Add more tests --- .../impl-foreign[foreign]-for-foreign.rs | 16 +++++++++++++++ .../impl-foreign[foreign]-for-foreign.stderr | 12 +++++++++++ .../impl-foreign[foreign]-for-local.rs | 16 +++++++++++++++ ...[t]-foreign[foreign]-for-fundamental[t].rs | 20 +++++++++++++++++++ ...foreign[foreign]-for-fundamental[t].stderr | 19 ++++++++++++++++++ .../impl[t]-foreign[foreign]-for-t.rs | 16 +++++++++++++++ .../impl[t]-foreign[foreign]-for-t.stderr | 11 ++++++++++ ...reign[fundamental[t],local]-for-foreign.rs | 20 +++++++++++++++++++ ...n[fundamental[t],local]-for-foreign.stderr | 19 ++++++++++++++++++ ...[t]-foreign[fundamental[t]]-for-foreign.rs | 20 +++++++++++++++++++ ...foreign[fundamental[t]]-for-foreign.stderr | 19 ++++++++++++++++++ ...eign[fundamental[t]]-for-fundamental[t].rs | 19 ++++++++++++++++++ ...[fundamental[t]]-for-fundamental[t].stderr | 19 ++++++++++++++++++ ...pl[t]-foreign[fundamental[t]]-for-local.rs | 17 ++++++++++++++++ .../impl[t]-foreign[fundamental[t]]-for-t.rs | 19 ++++++++++++++++++ ...pl[t]-foreign[fundamental[t]]-for-t.stderr | 19 ++++++++++++++++++ ...eign[local, fundamental[t]]-for-foreign.rs | 19 ++++++++++++++++++ .../impl[t]-foreign[local]-for-foreign.rs | 16 +++++++++++++++ .../impl[t]-foreign[local]-for-local.rs | 15 ++++++++++++++ .../impl[t]-foreign[t]-for-foreign.rs | 16 +++++++++++++++ .../impl[t]-foreign[t]-for-foreign.stderr | 11 ++++++++++ .../impl[t]-foreign[t]-for-fundamental.rs | 20 +++++++++++++++++++ .../impl[t]-foreign[t]-for-fundamental.stderr | 19 ++++++++++++++++++ .../coherence/impl[t]-foreign[t]-for-local.rs | 15 ++++++++++++++ .../ui/coherence/impl[t]-foreign[t]-for-t.rs | 16 +++++++++++++++ .../coherence/impl[t]-foreign[t]-for-t.stderr | 11 ++++++++++ 26 files changed, 439 insertions(+) create mode 100644 src/test/ui/coherence/impl-foreign[foreign]-for-foreign.rs create mode 100644 src/test/ui/coherence/impl-foreign[foreign]-for-foreign.stderr create mode 100644 src/test/ui/coherence/impl-foreign[foreign]-for-local.rs create mode 100644 src/test/ui/coherence/impl[t]-foreign[foreign]-for-fundamental[t].rs create mode 100644 src/test/ui/coherence/impl[t]-foreign[foreign]-for-fundamental[t].stderr create mode 100644 src/test/ui/coherence/impl[t]-foreign[foreign]-for-t.rs create mode 100644 src/test/ui/coherence/impl[t]-foreign[foreign]-for-t.stderr create mode 100644 src/test/ui/coherence/impl[t]-foreign[fundamental[t],local]-for-foreign.rs create mode 100644 src/test/ui/coherence/impl[t]-foreign[fundamental[t],local]-for-foreign.stderr create mode 100644 src/test/ui/coherence/impl[t]-foreign[fundamental[t]]-for-foreign.rs create mode 100644 src/test/ui/coherence/impl[t]-foreign[fundamental[t]]-for-foreign.stderr create mode 100644 src/test/ui/coherence/impl[t]-foreign[fundamental[t]]-for-fundamental[t].rs create mode 100644 src/test/ui/coherence/impl[t]-foreign[fundamental[t]]-for-fundamental[t].stderr create mode 100644 src/test/ui/coherence/impl[t]-foreign[fundamental[t]]-for-local.rs create mode 100644 src/test/ui/coherence/impl[t]-foreign[fundamental[t]]-for-t.rs create mode 100644 src/test/ui/coherence/impl[t]-foreign[fundamental[t]]-for-t.stderr create mode 100644 src/test/ui/coherence/impl[t]-foreign[local, fundamental[t]]-for-foreign.rs create mode 100644 src/test/ui/coherence/impl[t]-foreign[local]-for-foreign.rs create mode 100644 src/test/ui/coherence/impl[t]-foreign[local]-for-local.rs create mode 100644 src/test/ui/coherence/impl[t]-foreign[t]-for-foreign.rs create mode 100644 src/test/ui/coherence/impl[t]-foreign[t]-for-foreign.stderr create mode 100644 src/test/ui/coherence/impl[t]-foreign[t]-for-fundamental.rs create mode 100644 src/test/ui/coherence/impl[t]-foreign[t]-for-fundamental.stderr create mode 100644 src/test/ui/coherence/impl[t]-foreign[t]-for-local.rs create mode 100644 src/test/ui/coherence/impl[t]-foreign[t]-for-t.rs create mode 100644 src/test/ui/coherence/impl[t]-foreign[t]-for-t.stderr diff --git a/src/test/ui/coherence/impl-foreign[foreign]-for-foreign.rs b/src/test/ui/coherence/impl-foreign[foreign]-for-foreign.rs new file mode 100644 index 0000000000000..57738c64e3779 --- /dev/null +++ b/src/test/ui/coherence/impl-foreign[foreign]-for-foreign.rs @@ -0,0 +1,16 @@ +#![feature(re_rebalance_coherence)] + +// compile-flags:--crate-name=test +// aux-build:coherence_lib.rs + +extern crate coherence_lib as lib; +use lib::*; +use std::rc::Rc; + +struct Local; + +impl Remote1 for f64 { + //~^ ERROR only traits defined in the current crate can be implemented for arbitrary types [E0117] +} + +fn main() {} diff --git a/src/test/ui/coherence/impl-foreign[foreign]-for-foreign.stderr b/src/test/ui/coherence/impl-foreign[foreign]-for-foreign.stderr new file mode 100644 index 0000000000000..04e96f29230fb --- /dev/null +++ b/src/test/ui/coherence/impl-foreign[foreign]-for-foreign.stderr @@ -0,0 +1,12 @@ +error[E0117]: only traits defined in the current crate can be implemented for arbitrary types + --> $DIR/impl-foreign[foreign]-for-foreign.rs:12:1 + | +LL | impl Remote1 for f64 { + | ^^^^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate + | + = note: the impl does not reference only types defined in this crate + = note: define and implement a trait or new type instead + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0117`. diff --git a/src/test/ui/coherence/impl-foreign[foreign]-for-local.rs b/src/test/ui/coherence/impl-foreign[foreign]-for-local.rs new file mode 100644 index 0000000000000..33e85c164763e --- /dev/null +++ b/src/test/ui/coherence/impl-foreign[foreign]-for-local.rs @@ -0,0 +1,16 @@ +#![feature(re_rebalance_coherence)] + +// compile-flags:--crate-name=test +// aux-build:coherence_lib.rs +// check-pass + +extern crate coherence_lib as lib; +use lib::*; +use std::rc::Rc; + +struct Local; + +impl Remote1 for Local { +} + +fn main() {} diff --git a/src/test/ui/coherence/impl[t]-foreign[foreign]-for-fundamental[t].rs b/src/test/ui/coherence/impl[t]-foreign[foreign]-for-fundamental[t].rs new file mode 100644 index 0000000000000..66a4d9d273469 --- /dev/null +++ b/src/test/ui/coherence/impl[t]-foreign[foreign]-for-fundamental[t].rs @@ -0,0 +1,20 @@ +#![feature(re_rebalance_coherence)] + +// compile-flags:--crate-name=test +// aux-build:coherence_lib.rs + +extern crate coherence_lib as lib; +use lib::*; +use std::rc::Rc; + +struct Local; + +impl Remote1 for Box { + //~^ ERROR type parameter `T` must be used as the type parameter for some local type +} + +impl<'a, T> Remote1 for &'a T { + //~^ ERROR type parameter `T` must be used as the type parameter for some local type +} + +fn main() {} diff --git a/src/test/ui/coherence/impl[t]-foreign[foreign]-for-fundamental[t].stderr b/src/test/ui/coherence/impl[t]-foreign[foreign]-for-fundamental[t].stderr new file mode 100644 index 0000000000000..2467097b1a8b3 --- /dev/null +++ b/src/test/ui/coherence/impl[t]-foreign[foreign]-for-fundamental[t].stderr @@ -0,0 +1,19 @@ +error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct`) + --> $DIR/impl[t]-foreign[foreign]-for-fundamental[t].rs:12:1 + | +LL | impl Remote1 for Box { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type parameter `T` must be used as the type parameter for some local type + | + = note: only traits defined in the current crate can be implemented for a type parameter + +error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct`) + --> $DIR/impl[t]-foreign[foreign]-for-fundamental[t].rs:16:1 + | +LL | impl<'a, T> Remote1 for &'a T { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type parameter `T` must be used as the type parameter for some local type + | + = note: only traits defined in the current crate can be implemented for a type parameter + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0210`. diff --git a/src/test/ui/coherence/impl[t]-foreign[foreign]-for-t.rs b/src/test/ui/coherence/impl[t]-foreign[foreign]-for-t.rs new file mode 100644 index 0000000000000..0a67ebcbba44c --- /dev/null +++ b/src/test/ui/coherence/impl[t]-foreign[foreign]-for-t.rs @@ -0,0 +1,16 @@ +#![feature(re_rebalance_coherence)] + +// compile-flags:--crate-name=test +// aux-build:coherence_lib.rs + +extern crate coherence_lib as lib; +use lib::*; +use std::rc::Rc; + +struct Local; + +impl Remote1 for T { + //~^ ERROR type parameter `T` must be used as the type parameter for some local type +} + +fn main() {} diff --git a/src/test/ui/coherence/impl[t]-foreign[foreign]-for-t.stderr b/src/test/ui/coherence/impl[t]-foreign[foreign]-for-t.stderr new file mode 100644 index 0000000000000..5c28406f113fc --- /dev/null +++ b/src/test/ui/coherence/impl[t]-foreign[foreign]-for-t.stderr @@ -0,0 +1,11 @@ +error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct`) + --> $DIR/impl[t]-foreign[foreign]-for-t.rs:12:1 + | +LL | impl Remote1 for T { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ type parameter `T` must be used as the type parameter for some local type + | + = note: only traits defined in the current crate can be implemented for a type parameter + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0210`. diff --git a/src/test/ui/coherence/impl[t]-foreign[fundamental[t],local]-for-foreign.rs b/src/test/ui/coherence/impl[t]-foreign[fundamental[t],local]-for-foreign.rs new file mode 100644 index 0000000000000..24e0f309c4555 --- /dev/null +++ b/src/test/ui/coherence/impl[t]-foreign[fundamental[t],local]-for-foreign.rs @@ -0,0 +1,20 @@ +#![feature(re_rebalance_coherence)] + +// compile-flags:--crate-name=test +// aux-build:coherence_lib.rs + +extern crate coherence_lib as lib; +use lib::*; +use std::rc::Rc; + +struct Local; + +impl Remote2, Local> for u32 { + //~^ ERROR type parameter `T` must be used as the type parameter for some local type +} + +impl<'a, T> Remote2<&'a T, Local> for u32 { + //~^ ERROR type parameter `T` must be used as the type parameter for some local type +} + +fn main() {} diff --git a/src/test/ui/coherence/impl[t]-foreign[fundamental[t],local]-for-foreign.stderr b/src/test/ui/coherence/impl[t]-foreign[fundamental[t],local]-for-foreign.stderr new file mode 100644 index 0000000000000..da670bcfc3fc9 --- /dev/null +++ b/src/test/ui/coherence/impl[t]-foreign[fundamental[t],local]-for-foreign.stderr @@ -0,0 +1,19 @@ +error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct`) + --> $DIR/impl[t]-foreign[fundamental[t],local]-for-foreign.rs:12:1 + | +LL | impl Remote2, Local> for u32 { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type parameter `T` must be used as the type parameter for some local type + | + = note: only traits defined in the current crate can be implemented for a type parameter + +error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct`) + --> $DIR/impl[t]-foreign[fundamental[t],local]-for-foreign.rs:16:1 + | +LL | impl<'a, T> Remote2<&'a T, Local> for u32 { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type parameter `T` must be used as the type parameter for some local type + | + = note: only traits defined in the current crate can be implemented for a type parameter + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0210`. diff --git a/src/test/ui/coherence/impl[t]-foreign[fundamental[t]]-for-foreign.rs b/src/test/ui/coherence/impl[t]-foreign[fundamental[t]]-for-foreign.rs new file mode 100644 index 0000000000000..71598dae96ab3 --- /dev/null +++ b/src/test/ui/coherence/impl[t]-foreign[fundamental[t]]-for-foreign.rs @@ -0,0 +1,20 @@ +#![feature(re_rebalance_coherence)] + +// compile-flags:--crate-name=test +// aux-build:coherence_lib.rs + +extern crate coherence_lib as lib; +use lib::*; +use std::rc::Rc; + +struct Local; + +impl Remote1> for u32 { + //~^ ERROR type parameter `T` must be used as the type parameter for some local type +} + +impl<'a, T> Remote1<&'a T> for u32 { + //~^ ERROR type parameter `T` must be used as the type parameter for some local type +} + +fn main() {} diff --git a/src/test/ui/coherence/impl[t]-foreign[fundamental[t]]-for-foreign.stderr b/src/test/ui/coherence/impl[t]-foreign[fundamental[t]]-for-foreign.stderr new file mode 100644 index 0000000000000..dd9702650795e --- /dev/null +++ b/src/test/ui/coherence/impl[t]-foreign[fundamental[t]]-for-foreign.stderr @@ -0,0 +1,19 @@ +error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct`) + --> $DIR/impl[t]-foreign[fundamental[t]]-for-foreign.rs:12:1 + | +LL | impl Remote1> for u32 { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type parameter `T` must be used as the type parameter for some local type + | + = note: only traits defined in the current crate can be implemented for a type parameter + +error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct`) + --> $DIR/impl[t]-foreign[fundamental[t]]-for-foreign.rs:16:1 + | +LL | impl<'a, T> Remote1<&'a T> for u32 { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type parameter `T` must be used as the type parameter for some local type + | + = note: only traits defined in the current crate can be implemented for a type parameter + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0210`. diff --git a/src/test/ui/coherence/impl[t]-foreign[fundamental[t]]-for-fundamental[t].rs b/src/test/ui/coherence/impl[t]-foreign[fundamental[t]]-for-fundamental[t].rs new file mode 100644 index 0000000000000..7bf0306f29ba4 --- /dev/null +++ b/src/test/ui/coherence/impl[t]-foreign[fundamental[t]]-for-fundamental[t].rs @@ -0,0 +1,19 @@ +#![feature(re_rebalance_coherence)] + +// compile-flags:--crate-name=test +// aux-build:coherence_lib.rs + +extern crate coherence_lib as lib; +use lib::*; +use std::rc::Rc; + +struct Local; + +impl<'a, T> Remote1> for &'a T { + //~^ ERROR type parameter `T` must be used as the type parameter for some local type +} +impl<'a, T> Remote1<&'a T> for Box { + //~^ ERROR type parameter `T` must be used as the type parameter for some local type +} + +fn main() {} diff --git a/src/test/ui/coherence/impl[t]-foreign[fundamental[t]]-for-fundamental[t].stderr b/src/test/ui/coherence/impl[t]-foreign[fundamental[t]]-for-fundamental[t].stderr new file mode 100644 index 0000000000000..eec57fccea762 --- /dev/null +++ b/src/test/ui/coherence/impl[t]-foreign[fundamental[t]]-for-fundamental[t].stderr @@ -0,0 +1,19 @@ +error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct`) + --> $DIR/impl[t]-foreign[fundamental[t]]-for-fundamental[t].rs:12:1 + | +LL | impl<'a, T> Remote1> for &'a T { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type parameter `T` must be used as the type parameter for some local type + | + = note: only traits defined in the current crate can be implemented for a type parameter + +error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct`) + --> $DIR/impl[t]-foreign[fundamental[t]]-for-fundamental[t].rs:15:1 + | +LL | impl<'a, T> Remote1<&'a T> for Box { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type parameter `T` must be used as the type parameter for some local type + | + = note: only traits defined in the current crate can be implemented for a type parameter + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0210`. diff --git a/src/test/ui/coherence/impl[t]-foreign[fundamental[t]]-for-local.rs b/src/test/ui/coherence/impl[t]-foreign[fundamental[t]]-for-local.rs new file mode 100644 index 0000000000000..54d577c749248 --- /dev/null +++ b/src/test/ui/coherence/impl[t]-foreign[fundamental[t]]-for-local.rs @@ -0,0 +1,17 @@ +#![feature(re_rebalance_coherence)] + +// compile-flags:--crate-name=test +// aux-build:coherence_lib.rs +// check-pass + +extern crate coherence_lib as lib; +use lib::*; +use std::rc::Rc; + +struct Local; + +impl Remote1> for Local {} + +impl<'a, T> Remote1<&'a T> for Local {} + +fn main() {} diff --git a/src/test/ui/coherence/impl[t]-foreign[fundamental[t]]-for-t.rs b/src/test/ui/coherence/impl[t]-foreign[fundamental[t]]-for-t.rs new file mode 100644 index 0000000000000..7af929006ef7f --- /dev/null +++ b/src/test/ui/coherence/impl[t]-foreign[fundamental[t]]-for-t.rs @@ -0,0 +1,19 @@ +#![feature(re_rebalance_coherence)] + +// compile-flags:--crate-name=test +// aux-build:coherence_lib.rs + +extern crate coherence_lib as lib; +use lib::*; +use std::rc::Rc; + +struct Local; + +impl Remote1> for T { + //~^ ERROR type parameter `T` must be used as the type parameter for some local type +} +impl<'a, T> Remote1<&'a T> for T { + //~^ ERROR type parameter `T` must be used as the type parameter for some local type +} + +fn main() {} diff --git a/src/test/ui/coherence/impl[t]-foreign[fundamental[t]]-for-t.stderr b/src/test/ui/coherence/impl[t]-foreign[fundamental[t]]-for-t.stderr new file mode 100644 index 0000000000000..e017c3ffe6c05 --- /dev/null +++ b/src/test/ui/coherence/impl[t]-foreign[fundamental[t]]-for-t.stderr @@ -0,0 +1,19 @@ +error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct`) + --> $DIR/impl[t]-foreign[fundamental[t]]-for-t.rs:12:1 + | +LL | impl Remote1> for T { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type parameter `T` must be used as the type parameter for some local type + | + = note: only traits defined in the current crate can be implemented for a type parameter + +error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct`) + --> $DIR/impl[t]-foreign[fundamental[t]]-for-t.rs:15:1 + | +LL | impl<'a, T> Remote1<&'a T> for T { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type parameter `T` must be used as the type parameter for some local type + | + = note: only traits defined in the current crate can be implemented for a type parameter + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0210`. diff --git a/src/test/ui/coherence/impl[t]-foreign[local, fundamental[t]]-for-foreign.rs b/src/test/ui/coherence/impl[t]-foreign[local, fundamental[t]]-for-foreign.rs new file mode 100644 index 0000000000000..be0875d0110fd --- /dev/null +++ b/src/test/ui/coherence/impl[t]-foreign[local, fundamental[t]]-for-foreign.rs @@ -0,0 +1,19 @@ +#![feature(re_rebalance_coherence)] + +// compile-flags:--crate-name=test +// aux-build:coherence_lib.rs +// check-pass + +extern crate coherence_lib as lib; +use lib::*; +use std::rc::Rc; + +struct Local; +struct Local2(Rc); + +impl Remote2> for u32 {} +impl<'a, T> Remote2 for u32 {} +impl Remote2, Box> for u32 {} +impl<'a, T> Remote2, &'a T> for u32 {} + +fn main() {} diff --git a/src/test/ui/coherence/impl[t]-foreign[local]-for-foreign.rs b/src/test/ui/coherence/impl[t]-foreign[local]-for-foreign.rs new file mode 100644 index 0000000000000..81cf3c3f6eca9 --- /dev/null +++ b/src/test/ui/coherence/impl[t]-foreign[local]-for-foreign.rs @@ -0,0 +1,16 @@ +#![feature(re_rebalance_coherence)] + +// compile-flags:--crate-name=test +// aux-build:coherence_lib.rs +// check-pass + +extern crate coherence_lib as lib; +use lib::*; +use std::rc::Rc; + +struct Local; + +impl Remote1 for Rc {} +impl Remote1 for Vec> {} + +fn main() {} diff --git a/src/test/ui/coherence/impl[t]-foreign[local]-for-local.rs b/src/test/ui/coherence/impl[t]-foreign[local]-for-local.rs new file mode 100644 index 0000000000000..6b1d93cd94442 --- /dev/null +++ b/src/test/ui/coherence/impl[t]-foreign[local]-for-local.rs @@ -0,0 +1,15 @@ +#![feature(re_rebalance_coherence)] + +// compile-flags:--crate-name=test +// aux-build:coherence_lib.rs +// check-pass + +extern crate coherence_lib as lib; +use lib::*; +use std::rc::Rc; + +struct Local; + +impl Remote1 for Local {} + +fn main() {} diff --git a/src/test/ui/coherence/impl[t]-foreign[t]-for-foreign.rs b/src/test/ui/coherence/impl[t]-foreign[t]-for-foreign.rs new file mode 100644 index 0000000000000..5e89c2077330a --- /dev/null +++ b/src/test/ui/coherence/impl[t]-foreign[t]-for-foreign.rs @@ -0,0 +1,16 @@ +#![feature(re_rebalance_coherence)] + +// compile-flags:--crate-name=test +// aux-build:coherence_lib.rs + +extern crate coherence_lib as lib; +use lib::*; +use std::rc::Rc; + +struct Local; + +impl Remote1 for u32 { + //~^ ERROR type parameter `T` must be used as the type parameter for some local type +} + +fn main() {} diff --git a/src/test/ui/coherence/impl[t]-foreign[t]-for-foreign.stderr b/src/test/ui/coherence/impl[t]-foreign[t]-for-foreign.stderr new file mode 100644 index 0000000000000..5544729b5d640 --- /dev/null +++ b/src/test/ui/coherence/impl[t]-foreign[t]-for-foreign.stderr @@ -0,0 +1,11 @@ +error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct`) + --> $DIR/impl[t]-foreign[t]-for-foreign.rs:12:1 + | +LL | impl Remote1 for u32 { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ type parameter `T` must be used as the type parameter for some local type + | + = note: only traits defined in the current crate can be implemented for a type parameter + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0210`. diff --git a/src/test/ui/coherence/impl[t]-foreign[t]-for-fundamental.rs b/src/test/ui/coherence/impl[t]-foreign[t]-for-fundamental.rs new file mode 100644 index 0000000000000..300a2c4d48a9c --- /dev/null +++ b/src/test/ui/coherence/impl[t]-foreign[t]-for-fundamental.rs @@ -0,0 +1,20 @@ +#![feature(re_rebalance_coherence)] + +// compile-flags:--crate-name=test +// aux-build:coherence_lib.rs + +extern crate coherence_lib as lib; +use lib::*; +use std::rc::Rc; + +struct Local; + +impl Remote1 for Box { + //~^ ERROR type parameter `T` must be used as the type parameter for some local type +} + +impl<'a, A, B> Remote1 for &'a B { + //~^ ERROR type parameter `B` must be used as the type parameter for some local type +} + +fn main() {} diff --git a/src/test/ui/coherence/impl[t]-foreign[t]-for-fundamental.stderr b/src/test/ui/coherence/impl[t]-foreign[t]-for-fundamental.stderr new file mode 100644 index 0000000000000..be8cc29a6e5b0 --- /dev/null +++ b/src/test/ui/coherence/impl[t]-foreign[t]-for-fundamental.stderr @@ -0,0 +1,19 @@ +error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct`) + --> $DIR/impl[t]-foreign[t]-for-fundamental.rs:12:1 + | +LL | impl Remote1 for Box { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type parameter `T` must be used as the type parameter for some local type + | + = note: only traits defined in the current crate can be implemented for a type parameter + +error[E0210]: type parameter `B` must be used as the type parameter for some local type (e.g., `MyStruct`) + --> $DIR/impl[t]-foreign[t]-for-fundamental.rs:16:1 + | +LL | impl<'a, A, B> Remote1 for &'a B { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type parameter `B` must be used as the type parameter for some local type + | + = note: only traits defined in the current crate can be implemented for a type parameter + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0210`. diff --git a/src/test/ui/coherence/impl[t]-foreign[t]-for-local.rs b/src/test/ui/coherence/impl[t]-foreign[t]-for-local.rs new file mode 100644 index 0000000000000..769147ea7eabd --- /dev/null +++ b/src/test/ui/coherence/impl[t]-foreign[t]-for-local.rs @@ -0,0 +1,15 @@ +#![feature(re_rebalance_coherence)] + +// compile-flags:--crate-name=test +// aux-build:coherence_lib.rs +// check-pass + +extern crate coherence_lib as lib; +use lib::*; +use std::rc::Rc; + +struct Local; + +impl Remote1 for Local {} + +fn main() {} diff --git a/src/test/ui/coherence/impl[t]-foreign[t]-for-t.rs b/src/test/ui/coherence/impl[t]-foreign[t]-for-t.rs new file mode 100644 index 0000000000000..c8513380ff73e --- /dev/null +++ b/src/test/ui/coherence/impl[t]-foreign[t]-for-t.rs @@ -0,0 +1,16 @@ +#![feature(re_rebalance_coherence)] + +// compile-flags:--crate-name=test +// aux-build:coherence_lib.rs + +extern crate coherence_lib as lib; +use lib::*; +use std::rc::Rc; + +struct Local; + +impl Remote1 for T { + //~^ ERROR type parameter `T` must be used as the type parameter for some local type +} + +fn main() {} diff --git a/src/test/ui/coherence/impl[t]-foreign[t]-for-t.stderr b/src/test/ui/coherence/impl[t]-foreign[t]-for-t.stderr new file mode 100644 index 0000000000000..de857afd20b15 --- /dev/null +++ b/src/test/ui/coherence/impl[t]-foreign[t]-for-t.stderr @@ -0,0 +1,11 @@ +error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct`) + --> $DIR/impl[t]-foreign[t]-for-t.rs:12:1 + | +LL | impl Remote1 for T { + | ^^^^^^^^^^^^^^^^^^^^^^^^ type parameter `T` must be used as the type parameter for some local type + | + = note: only traits defined in the current crate can be implemented for a type parameter + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0210`. From 31b301219f534090690674e43e05c3cbfd2d5005 Mon Sep 17 00:00:00 2001 From: Georg Semmler Date: Wed, 18 Sep 2019 22:36:04 +0200 Subject: [PATCH 08/15] Split line to fix tidy --- src/test/ui/coherence/impl-foreign[foreign]-for-foreign.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/test/ui/coherence/impl-foreign[foreign]-for-foreign.rs b/src/test/ui/coherence/impl-foreign[foreign]-for-foreign.rs index 57738c64e3779..b08fedc5e11c2 100644 --- a/src/test/ui/coherence/impl-foreign[foreign]-for-foreign.rs +++ b/src/test/ui/coherence/impl-foreign[foreign]-for-foreign.rs @@ -10,7 +10,8 @@ use std::rc::Rc; struct Local; impl Remote1 for f64 { - //~^ ERROR only traits defined in the current crate can be implemented for arbitrary types [E0117] + //~^ ERROR only traits defined in the current crate + // | can be implemented for arbitrary types [E0117] } fn main() {} From 8112f71fc91bc7618d91bb3180fe80b8fafe1069 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Thu, 19 Sep 2019 09:24:42 -0700 Subject: [PATCH 09/15] rustbuild: Turn down compression on exe installers The Windows dist builders are the slowest builders right now, and the distribution phase of them is enormously slow clocking in at around 20 minutes to build all the related installers. This commit starts to optimize these by turning down the compression level in the `exe` installers. These aren't super heavily used so there's no great need for them to be so ultra-compressed, so let's dial back the compression parameters to get closer to the rest of our xz archives. This brings the installer in line with the gz tarball installer locally, and also brings the compression settings on par with the rest of our xz installers. --- src/etc/installer/exe/rust.iss | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/etc/installer/exe/rust.iss b/src/etc/installer/exe/rust.iss index c22d60b6c5df1..70648beac38b0 100644 --- a/src/etc/installer/exe/rust.iss +++ b/src/etc/installer/exe/rust.iss @@ -25,9 +25,9 @@ SourceDir=.\ OutputBaseFilename={#CFG_PACKAGE_NAME}-{#CFG_BUILD} DefaultDirName={sd}\Rust -Compression=lzma2/ultra -InternalCompressLevel=ultra -SolidCompression=true +Compression=lzma2/normal +InternalCompressLevel=normal +SolidCompression=no ChangesEnvironment=true ChangesAssociations=no From 1ab5593f951c07a6f0ed05fbbfe8f262863158a0 Mon Sep 17 00:00:00 2001 From: gaolei Date: Thu, 19 Sep 2019 15:13:40 +0800 Subject: [PATCH 10/15] factor out pluralisation remains after #64280 --- src/librustc/lint/builtin.rs | 4 ++-- src/librustc/middle/resolve_lifetime.rs | 4 ++-- src/librustc/traits/error_reporting.rs | 4 ++-- src/librustc/ty/error.rs | 2 +- src/librustc_lint/unused.rs | 22 ++++++++++++++------- src/librustc_resolve/check_unused.rs | 4 +++- src/librustc_resolve/resolve_imports.rs | 4 ++-- src/librustc_typeck/astconv.rs | 2 +- src/librustc_typeck/check/expr.rs | 4 ++-- src/librustc_typeck/check/method/suggest.rs | 4 ++-- src/librustc_typeck/check/mod.rs | 4 ++-- src/librustc_typeck/check/pat.rs | 14 ++++++------- src/libsyntax/ext/tt/transcribe.rs | 5 +++-- src/libsyntax/parse/diagnostics.rs | 8 ++++---- src/libsyntax/parse/parser/path.rs | 7 +++---- src/libsyntax/parse/parser/ty.rs | 6 +++--- src/libsyntax_ext/format.rs | 3 ++- 17 files changed, 56 insertions(+), 45 deletions(-) diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs index dd290572d7bb7..5906a6388a8bd 100644 --- a/src/librustc/lint/builtin.rs +++ b/src/librustc/lint/builtin.rs @@ -7,7 +7,7 @@ use crate::lint::{LintPass, LateLintPass, LintArray}; use crate::middle::stability; use crate::session::Session; -use errors::{Applicability, DiagnosticBuilder}; +use errors::{Applicability, DiagnosticBuilder, pluralise}; use syntax::ast; use syntax::source_map::Span; use syntax::symbol::Symbol; @@ -524,7 +524,7 @@ pub(crate) fn add_elided_lifetime_in_path_suggestion( }; db.span_suggestion( replace_span, - &format!("indicate the anonymous lifetime{}", if n >= 2 { "s" } else { "" }), + &format!("indicate the anonymous lifetime{}", pluralise!(n)), suggestion, Applicability::MachineApplicable ); diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs index 8836a632a7ca8..d833a34385b2d 100644 --- a/src/librustc/middle/resolve_lifetime.rs +++ b/src/librustc/middle/resolve_lifetime.rs @@ -17,7 +17,7 @@ use crate::ty::{self, DefIdTree, GenericParamDefKind, TyCtxt}; use crate::rustc::lint; use crate::session::Session; use crate::util::nodemap::{DefIdMap, FxHashMap, FxHashSet, HirIdMap, HirIdSet}; -use errors::{Applicability, DiagnosticBuilder}; +use errors::{Applicability, DiagnosticBuilder, pluralise}; use rustc_macros::HashStable; use std::borrow::Cow; use std::cell::Cell; @@ -3047,7 +3047,7 @@ pub fn report_missing_lifetime_specifiers( span, E0106, "missing lifetime specifier{}", - if count > 1 { "s" } else { "" } + pluralise!(count) ) } diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index 03cc00d87e3cd..0b06ec0703811 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -33,7 +33,7 @@ use crate::ty::subst::Subst; use crate::ty::SubtypePredicate; use crate::util::nodemap::{FxHashMap, FxHashSet}; -use errors::{Applicability, DiagnosticBuilder}; +use errors::{Applicability, DiagnosticBuilder, pluralise}; use std::fmt; use syntax::ast; use syntax::symbol::{sym, kw}; @@ -1186,7 +1186,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { _ => format!("{} {}argument{}", arg_length, if distinct && arg_length > 1 { "distinct " } else { "" }, - if arg_length == 1 { "" } else { "s" }), + pluralise!(arg_length)) } }; diff --git a/src/librustc/ty/error.rs b/src/librustc/ty/error.rs index 62910ec320494..5409cbc4129f0 100644 --- a/src/librustc/ty/error.rs +++ b/src/librustc/ty/error.rs @@ -196,7 +196,7 @@ impl<'tcx> ty::TyS<'tcx> { let n = tcx.lift_to_global(&n).unwrap(); match n.try_eval_usize(tcx, ty::ParamEnv::empty()) { Some(n) => { - format!("array of {} element{}", n, if n != 1 { "s" } else { "" }).into() + format!("array of {} element{}", n, pluralise!(n)).into() } None => "array".into(), } diff --git a/src/librustc_lint/unused.rs b/src/librustc_lint/unused.rs index c3975098351af..2d4af2f606a2c 100644 --- a/src/librustc_lint/unused.rs +++ b/src/librustc_lint/unused.rs @@ -9,7 +9,7 @@ use lint::{LintPass, EarlyLintPass, LateLintPass}; use syntax::ast; use syntax::attr; -use syntax::errors::Applicability; +use syntax::errors::{Applicability, pluralise}; use syntax::feature_gate::{AttributeType, BuiltinAttribute, BUILTIN_ATTRIBUTE_MAP}; use syntax::print::pprust; use syntax::symbol::{kw, sym}; @@ -48,7 +48,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedResults { } let ty = cx.tables.expr_ty(&expr); - let type_permits_lack_of_use = check_must_use_ty(cx, ty, &expr, s.span, "", "", false); + let type_permits_lack_of_use = check_must_use_ty(cx, ty, &expr, s.span, "", "", 1); let mut fn_warned = false; let mut op_warned = false; @@ -135,7 +135,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedResults { span: Span, descr_pre: &str, descr_post: &str, - plural: bool, + plural_len: usize, ) -> bool { if ty.is_unit() || cx.tcx.is_ty_uninhabited_from( cx.tcx.hir().get_module_parent(expr.hir_id), ty) @@ -143,13 +143,13 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedResults { return true; } - let plural_suffix = if plural { "s" } else { "" }; + let plural_suffix = pluralise!(plural_len); match ty.sty { ty::Adt(..) if ty.is_box() => { let boxed_ty = ty.boxed_ty(); let descr_pre = &format!("{}boxed ", descr_pre); - check_must_use_ty(cx, boxed_ty, expr, span, descr_pre, descr_post, plural) + check_must_use_ty(cx, boxed_ty, expr, span, descr_pre, descr_post, plural_len) } ty::Adt(def, _) => { check_must_use_def(cx, def.did, span, descr_pre, descr_post) @@ -202,7 +202,15 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedResults { for (i, ty) in tys.iter().map(|k| k.expect_ty()).enumerate() { let descr_post = &format!(" in tuple element {}", i); let span = *spans.get(i).unwrap_or(&span); - if check_must_use_ty(cx, ty, expr, span, descr_pre, descr_post, plural) { + if check_must_use_ty( + cx, + ty, + expr, + span, + descr_pre, + descr_post, + plural_len + ) { has_emitted = true; } } @@ -216,7 +224,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedResults { descr_pre, plural_suffix, ); - check_must_use_ty(cx, ty, expr, span, descr_pre, descr_post, true) + check_must_use_ty(cx, ty, expr, span, descr_pre, descr_post, n as usize + 1) } // Otherwise, we don't lint, to avoid false positives. _ => false, diff --git a/src/librustc_resolve/check_unused.rs b/src/librustc_resolve/check_unused.rs index 96d44b4b4c0dc..0d85be83e12e0 100644 --- a/src/librustc_resolve/check_unused.rs +++ b/src/librustc_resolve/check_unused.rs @@ -26,6 +26,8 @@ use crate::Resolver; use crate::resolve_imports::ImportDirectiveSubclass; +use errors::pluralise; + use rustc::util::nodemap::NodeMap; use rustc::{lint, ty}; use rustc_data_structures::fx::FxHashSet; @@ -295,7 +297,7 @@ impl Resolver<'_> { }).collect::>(); span_snippets.sort(); let msg = format!("unused import{}{}", - if len > 1 { "s" } else { "" }, + pluralise!(len), if !span_snippets.is_empty() { format!(": {}", span_snippets.join(", ")) } else { diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs index e77e8290f1faa..360343169bc3d 100644 --- a/src/librustc_resolve/resolve_imports.rs +++ b/src/librustc_resolve/resolve_imports.rs @@ -11,7 +11,7 @@ use crate::{Resolver, ResolutionError, Segment, ModuleKind}; use crate::{names_to_string, module_to_string}; use crate::diagnostics::Suggestion; -use errors::Applicability; +use errors::{Applicability, pluralise}; use rustc_data_structures::ptr_key::PtrKey; use rustc::ty; @@ -728,7 +728,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> { let msg = format!( "unresolved import{} {}", - if paths.len() > 1 { "s" } else { "" }, + pluralise!(paths.len()), paths.join(", "), ); diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 09e6b76900396..718d12484f741 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -1346,7 +1346,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { span, E0191, "the value of the associated type{} {} must be specified", - if associated_types.len() == 1 { "" } else { "s" }, + pluralise!(associated_types.len()), names, ); let (suggest, potential_assoc_types_spans) = diff --git a/src/librustc_typeck/check/expr.rs b/src/librustc_typeck/check/expr.rs index 56bd903040ab4..ef3f40dfdd987 100644 --- a/src/librustc_typeck/check/expr.rs +++ b/src/librustc_typeck/check/expr.rs @@ -17,7 +17,7 @@ use crate::util::common::ErrorReported; use crate::util::nodemap::FxHashMap; use crate::astconv::AstConv as _; -use errors::{Applicability, DiagnosticBuilder}; +use errors::{Applicability, DiagnosticBuilder, pluralise}; use syntax::ast; use syntax::symbol::{Symbol, kw, sym}; use syntax::source_map::Span; @@ -1178,7 +1178,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { struct_span_err!(tcx.sess, span, E0063, "missing field{} {}{} in initializer of `{}`", - if remaining_fields.len() == 1 { "" } else { "s" }, + pluralise!(remaining_fields.len()), remaining_fields_names, truncated_fields_error, adt_ty) diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs index 3e45b1e98d4ec..74e4f28255b16 100644 --- a/src/librustc_typeck/check/method/suggest.rs +++ b/src/librustc_typeck/check/method/suggest.rs @@ -5,7 +5,7 @@ use crate::check::FnCtxt; use crate::middle::lang_items::FnOnceTraitLangItem; use crate::namespace::Namespace; use crate::util::nodemap::FxHashSet; -use errors::{Applicability, DiagnosticBuilder}; +use errors::{Applicability, DiagnosticBuilder, pluralise}; use rustc::hir::{self, ExprKind, Node, QPath}; use rustc::hir::def::{Res, DefKind}; use rustc::hir::def_id::{CRATE_DEF_INDEX, LOCAL_CRATE, DefId}; @@ -560,7 +560,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let help = format!("{an}other candidate{s} {were} found in the following \ trait{s}, perhaps add a `use` for {one_of_them}:", an = if candidates.len() == 1 {"an" } else { "" }, - s = if candidates.len() == 1 { "" } else { "s" }, + s = pluralise!(candidates.len()), were = if candidates.len() == 1 { "was" } else { "were" }, one_of_them = if candidates.len() == 1 { "it" diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 1197160fa9501..bd6586aa0777e 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -88,7 +88,7 @@ pub mod intrinsic; mod op; use crate::astconv::{AstConv, PathSeg}; -use errors::{Applicability, DiagnosticBuilder, DiagnosticId}; +use errors::{Applicability, DiagnosticBuilder, DiagnosticId, pluralise}; use rustc::hir::{self, ExprKind, GenericArg, ItemKind, Node, PatKind, QPath}; use rustc::hir::def::{CtorOf, Res, DefKind}; use rustc::hir::def_id::{CrateNum, DefId, LOCAL_CRATE}; @@ -4843,5 +4843,5 @@ fn fatally_break_rust(sess: &Session) { } fn potentially_plural_count(count: usize, word: &str) -> String { - format!("{} {}{}", count, word, if count == 1 { "" } else { "s" }) + format!("{} {}{}", count, word, pluralise!(count)) } diff --git a/src/librustc_typeck/check/pat.rs b/src/librustc_typeck/check/pat.rs index 8502b89de1469..d93a4052cd393 100644 --- a/src/librustc_typeck/check/pat.rs +++ b/src/librustc_typeck/check/pat.rs @@ -1,6 +1,6 @@ use crate::check::FnCtxt; use crate::util::nodemap::FxHashMap; -use errors::{Applicability, DiagnosticBuilder}; +use errors::{Applicability, DiagnosticBuilder, pluralise}; use rustc::hir::{self, PatKind, Pat, HirId}; use rustc::hir::def::{Res, DefKind, CtorKind}; use rustc::hir::pat_util::EnumerateAndAdjustIterator; @@ -684,8 +684,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } fn e0023(&self, pat_span: Span, res: Res, subpats: &'tcx [P], fields: &[ty::FieldDef]) { - let subpats_ending = if subpats.len() == 1 { "" } else { "s" }; - let fields_ending = if fields.len() == 1 { "" } else { "s" }; + let subpats_ending = pluralise!(subpats.len()); + let fields_ending = pluralise!(fields.len()); let res_span = self.tcx.def_span(res.def_id()); struct_span_err!( self.tcx.sess, @@ -1103,10 +1103,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { E0527, "pattern requires {} element{} but array has {}", min_len, - if min_len != 1 { "s" } else { "" }, + pluralise!(min_len), size, ) - .span_label(span, format!("expected {} element{}", size, if size != 1 { "s" } else { "" })) + .span_label(span, format!("expected {} element{}", size, pluralise!(size))) .emit(); } @@ -1117,14 +1117,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { E0528, "pattern requires at least {} element{} but array has {}", min_len, - if min_len != 1 { "s" } else { "" }, + pluralise!(min_len), size, ).span_label( span, format!( "pattern cannot match array of {} element{}", size, - if size != 1 { "s" } else { "" }, + pluralise!(size), ), ).emit(); } diff --git a/src/libsyntax/ext/tt/transcribe.rs b/src/libsyntax/ext/tt/transcribe.rs index 23735727fe8cf..f9c07e3a2e4ff 100644 --- a/src/libsyntax/ext/tt/transcribe.rs +++ b/src/libsyntax/ext/tt/transcribe.rs @@ -8,6 +8,7 @@ use crate::tokenstream::{DelimSpan, TokenStream, TokenTree, TreeAndJoint}; use smallvec::{smallvec, SmallVec}; +use errors::pluralise; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::sync::Lrc; use syntax_pos::hygiene::{ExpnId, Transparency}; @@ -348,10 +349,10 @@ impl LockstepIterSize { "meta-variable `{}` repeats {} time{}, but `{}` repeats {} time{}", l_id, l_len, - if l_len != 1 { "s" } else { "" }, + pluralise!(l_len), r_id, r_len, - if r_len != 1 { "s" } else { "" }, + pluralise!(r_len), ); LockstepIterSize::Contradiction(msg) } diff --git a/src/libsyntax/parse/diagnostics.rs b/src/libsyntax/parse/diagnostics.rs index b74f2492c351f..2d7f4f71ca4ee 100644 --- a/src/libsyntax/parse/diagnostics.rs +++ b/src/libsyntax/parse/diagnostics.rs @@ -11,7 +11,7 @@ use crate::ptr::P; use crate::symbol::{kw, sym}; use crate::ThinVec; use crate::util::parser::AssocOp; -use errors::{Applicability, DiagnosticBuilder, DiagnosticId}; +use errors::{Applicability, DiagnosticBuilder, DiagnosticId, pluralise}; use rustc_data_structures::fx::FxHashSet; use syntax_pos::{Span, DUMMY_SP, MultiSpan, SpanSnippetError}; use log::{debug, trace}; @@ -532,15 +532,15 @@ impl<'a> Parser<'a> { self.eat_to_tokens(&[&end]); let span = lo.until(self.token.span); - let plural = number_of_gt > 1 || number_of_shr >= 1; + let total_num_of_gt = number_of_gt + number_of_shr * 2; self.diagnostic() .struct_span_err( span, - &format!("unmatched angle bracket{}", if plural { "s" } else { "" }), + &format!("unmatched angle bracket{}", pluralise!(total_num_of_gt)), ) .span_suggestion( span, - &format!("remove extra angle bracket{}", if plural { "s" } else { "" }), + &format!("remove extra angle bracket{}", pluralise!(total_num_of_gt)), String::new(), Applicability::MachineApplicable, ) diff --git a/src/libsyntax/parse/parser/path.rs b/src/libsyntax/parse/parser/path.rs index d4b13cc2e0121..dcd3c64801742 100644 --- a/src/libsyntax/parse/parser/path.rs +++ b/src/libsyntax/parse/parser/path.rs @@ -9,7 +9,7 @@ use crate::symbol::kw; use std::mem; use log::debug; -use errors::{Applicability}; +use errors::{Applicability, pluralise}; /// Specifies how to parse a path. #[derive(Copy, Clone, PartialEq)] @@ -347,20 +347,19 @@ impl<'a> Parser<'a> { let span = lo.with_hi( lo.lo() + BytePos(snapshot.unmatched_angle_bracket_count) ); - let plural = snapshot.unmatched_angle_bracket_count > 1; self.diagnostic() .struct_span_err( span, &format!( "unmatched angle bracket{}", - if plural { "s" } else { "" } + pluralise!(snapshot.unmatched_angle_bracket_count) ), ) .span_suggestion( span, &format!( "remove extra angle bracket{}", - if plural { "s" } else { "" } + pluralise!(snapshot.unmatched_angle_bracket_count) ), String::new(), Applicability::MachineApplicable, diff --git a/src/libsyntax/parse/parser/ty.rs b/src/libsyntax/parse/parser/ty.rs index 465e31ac57e64..5697edd8e4867 100644 --- a/src/libsyntax/parse/parser/ty.rs +++ b/src/libsyntax/parse/parser/ty.rs @@ -11,7 +11,7 @@ use crate::symbol::{kw}; use rustc_target::spec::abi::Abi; -use errors::{Applicability}; +use errors::{Applicability, pluralise}; /// Returns `true` if `IDENT t` can start a type -- `IDENT::a::b`, `IDENT`, /// `IDENT<::AssocTy>`. @@ -397,7 +397,7 @@ impl<'a> Parser<'a> { } if !negative_bounds.is_empty() || was_negative { - let plural = negative_bounds.len() > 1; + let negative_bounds_len = negative_bounds.len(); let last_span = negative_bounds.last().map(|sp| *sp); let mut err = self.struct_span_err( negative_bounds, @@ -420,7 +420,7 @@ impl<'a> Parser<'a> { } err.span_suggestion_hidden( bound_list, - &format!("remove the trait bound{}", if plural { "s" } else { "" }), + &format!("remove the trait bound{}", pluralise!(negative_bounds_len)), new_bound_list, Applicability::MachineApplicable, ); diff --git a/src/libsyntax_ext/format.rs b/src/libsyntax_ext/format.rs index 46c7cbb83de90..26455df17b896 100644 --- a/src/libsyntax_ext/format.rs +++ b/src/libsyntax_ext/format.rs @@ -5,6 +5,7 @@ use fmt_macros as parse; use errors::DiagnosticBuilder; use errors::Applicability; +use errors::pluralise; use syntax::ast; use syntax::ext::base::{self, *}; @@ -299,7 +300,7 @@ impl<'a, 'b> Context<'a, 'b> { &format!( "{} positional argument{} in format string, but {}", count, - if count != 1 { "s" } else { "" }, + pluralise!(count), self.describe_num_args(), ), ); From fde8cfe130db3826b88247318551d34d2bb63276 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Thu, 19 Sep 2019 09:24:42 -0700 Subject: [PATCH 11/15] rustbuild: Turn down compression on msi installers This is the same as #64615 except applied to our MSI installers. The same fix is applied effectively bringing these installers in line with the gz tarball installers, which are about 3x faster to produce locally and likely much faster to produce on CI. --- src/etc/installer/msi/rust.wxs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/etc/installer/msi/rust.wxs b/src/etc/installer/msi/rust.wxs index a471ccc6f5b48..a2e378f7b1db4 100644 --- a/src/etc/installer/msi/rust.wxs +++ b/src/etc/installer/msi/rust.wxs @@ -152,7 +152,7 @@ - + From 255dd3ff42aecdc36da800e5bbfe0c09e83fa066 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Thu, 19 Sep 2019 11:22:55 -0700 Subject: [PATCH 12/15] rustbuild: Improve output of `dist` step * Pass `/Q` to `iscc` on Windows to supress the thousands of lines of output about compressing documentation. * Print out what's happening before long steps * Use `timeit` to print out timing information for long-running installer assemblies. --- src/bootstrap/dist.rs | 66 ++++++++++++++++++++++++++++++------------- 1 file changed, 47 insertions(+), 19 deletions(-) diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index 076bcd878df71..50b20763c43d2 100644 --- a/src/bootstrap/dist.rs +++ b/src/bootstrap/dist.rs @@ -18,7 +18,7 @@ use build_helper::{output, t}; use crate::{Compiler, Mode, LLVM_TOOLS}; use crate::channel; -use crate::util::{is_dylib, exe}; +use crate::util::{is_dylib, exe, timeit}; use crate::builder::{Builder, RunConfig, ShouldRun, Step}; use crate::compile; use crate::tool::{self, Tool}; @@ -91,14 +91,15 @@ impl Step for Docs { let name = pkgname(builder, "rust-docs"); - builder.info(&format!("Dist docs ({})", host)); if !builder.config.docs { - builder.info("\tskipping - docs disabled"); return distdir(builder).join(format!("{}-{}.tar.gz", name, host)); } builder.default_doc(None); + builder.info(&format!("Dist docs ({})", host)); + let _time = timeit(builder); + let image = tmpdir(builder).join(format!("{}-{}-image", name, host)); let _ = fs::remove_dir_all(&image); @@ -151,9 +152,7 @@ impl Step for RustcDocs { let name = pkgname(builder, "rustc-docs"); - builder.info(&format!("Dist compiler docs ({})", host)); if !builder.config.compiler_docs { - builder.info("\tskipping - compiler docs disabled"); return distdir(builder).join(format!("{}-{}.tar.gz", name, host)); } @@ -179,6 +178,9 @@ impl Step for RustcDocs { .arg("--component-name=rustc-docs") .arg("--legacy-manifest-dirs=rustlib,cargo") .arg("--bulk-dirs=share/doc/rust/html"); + + builder.info(&format!("Dist compiler docs ({})", host)); + let _time = timeit(builder); builder.run(&mut cmd); builder.remove_dir(&image); @@ -350,6 +352,7 @@ impl Step for Mingw { } builder.info(&format!("Dist mingw ({})", host)); + let _time = timeit(builder); let name = pkgname(builder, "rust-mingw"); let image = tmpdir(builder).join(format!("{}-{}-image", name, host)); let _ = fs::remove_dir_all(&image); @@ -403,7 +406,6 @@ impl Step for Rustc { let compiler = self.compiler; let host = self.compiler.host; - builder.info(&format!("Dist rustc stage{} ({})", compiler.stage, host)); let name = pkgname(builder, "rustc"); let image = tmpdir(builder).join(format!("{}-{}-image", name, host)); let _ = fs::remove_dir_all(&image); @@ -460,6 +462,9 @@ impl Step for Rustc { .arg(format!("--package-name={}-{}", name, host)) .arg("--component-name=rustc") .arg("--legacy-manifest-dirs=rustlib,cargo"); + + builder.info(&format!("Dist rustc stage{} ({})", compiler.stage, host)); + let _time = timeit(builder); builder.run(&mut cmd); builder.remove_dir(&image); builder.remove_dir(&overlay); @@ -662,8 +667,6 @@ impl Step for Std { let target = self.target; let name = pkgname(builder, "rust-std"); - builder.info(&format!("Dist std stage{} ({} -> {})", - compiler.stage, &compiler.host, target)); // The only true set of target libraries came from the build triple, so // let's reduce redundant work by only producing archives from that host. @@ -714,6 +717,10 @@ impl Step for Std { .arg(format!("--package-name={}-{}", name, target)) .arg(format!("--component-name=rust-std-{}", target)) .arg("--legacy-manifest-dirs=rustlib,cargo"); + + builder.info(&format!("Dist std stage{} ({} -> {})", + compiler.stage, &compiler.host, target)); + let _time = timeit(builder); builder.run(&mut cmd); builder.remove_dir(&image); distdir(builder).join(format!("{}-{}.tar.gz", name, target)) @@ -754,11 +761,9 @@ impl Step for Analysis { let compiler = self.compiler; let target = self.target; assert!(builder.config.extended); - builder.info("Dist analysis"); let name = pkgname(builder, "rust-analysis"); if &compiler.host != builder.config.build { - builder.info("\tskipping, not a build host"); return distdir(builder).join(format!("{}-{}.tar.gz", name, target)); } @@ -786,6 +791,9 @@ impl Step for Analysis { .arg(format!("--package-name={}-{}", name, target)) .arg(format!("--component-name=rust-analysis-{}", target)) .arg("--legacy-manifest-dirs=rustlib,cargo"); + + builder.info("Dist analysis"); + let _time = timeit(builder); builder.run(&mut cmd); builder.remove_dir(&image); distdir(builder).join(format!("{}-{}.tar.gz", name, target)) @@ -874,8 +882,6 @@ impl Step for Src { /// Creates the `rust-src` installer component fn run(self, builder: &Builder<'_>) -> PathBuf { - builder.info("Dist src"); - let name = pkgname(builder, "rust-src"); let image = tmpdir(builder).join(format!("{}-image", name)); let _ = fs::remove_dir_all(&image); @@ -930,6 +936,9 @@ impl Step for Src { .arg(format!("--package-name={}", name)) .arg("--component-name=rust-src") .arg("--legacy-manifest-dirs=rustlib,cargo"); + + builder.info("Dist src"); + let _time = timeit(builder); builder.run(&mut cmd); builder.remove_dir(&image); @@ -957,8 +966,6 @@ impl Step for PlainSourceTarball { /// Creates the plain source tarball fn run(self, builder: &Builder<'_>) -> PathBuf { - builder.info("Create plain source tarball"); - // Make sure that the root folder of tarball has the correct name let plain_name = format!("{}-src", pkgname(builder, "rustc")); let plain_dst_src = tmpdir(builder).join(&plain_name); @@ -1020,6 +1027,9 @@ impl Step for PlainSourceTarball { .arg("--output").arg(&tarball) .arg("--work-dir=.") .current_dir(tmpdir(builder)); + + builder.info("Create plain source tarball"); + let _time = timeit(builder); builder.run(&mut cmd); distdir(builder).join(&format!("{}.tar.gz", plain_name)) } @@ -1073,7 +1083,6 @@ impl Step for Cargo { let compiler = self.compiler; let target = self.target; - builder.info(&format!("Dist cargo stage{} ({})", compiler.stage, target)); let src = builder.src.join("src/tools/cargo"); let etc = src.join("src/etc"); let release_num = builder.release_num("cargo"); @@ -1126,6 +1135,9 @@ impl Step for Cargo { .arg(format!("--package-name={}-{}", name, target)) .arg("--component-name=cargo") .arg("--legacy-manifest-dirs=rustlib,cargo"); + + builder.info(&format!("Dist cargo stage{} ({})", compiler.stage, target)); + let _time = timeit(builder); builder.run(&mut cmd); distdir(builder).join(format!("{}-{}.tar.gz", name, target)) } @@ -1161,7 +1173,6 @@ impl Step for Rls { let target = self.target; assert!(builder.config.extended); - builder.info(&format!("Dist RLS stage{} ({})", compiler.stage, target)); let src = builder.src.join("src/tools/rls"); let release_num = builder.release_num("rls"); let name = pkgname(builder, "rls"); @@ -1210,6 +1221,8 @@ impl Step for Rls { .arg("--legacy-manifest-dirs=rustlib,cargo") .arg("--component-name=rls-preview"); + builder.info(&format!("Dist RLS stage{} ({})", compiler.stage, target)); + let _time = timeit(builder); builder.run(&mut cmd); Some(distdir(builder).join(format!("{}-{}.tar.gz", name, target))) } @@ -1245,7 +1258,6 @@ impl Step for Clippy { let target = self.target; assert!(builder.config.extended); - builder.info(&format!("Dist clippy stage{} ({})", compiler.stage, target)); let src = builder.src.join("src/tools/clippy"); let release_num = builder.release_num("clippy"); let name = pkgname(builder, "clippy"); @@ -1299,6 +1311,8 @@ impl Step for Clippy { .arg("--legacy-manifest-dirs=rustlib,cargo") .arg("--component-name=clippy-preview"); + builder.info(&format!("Dist clippy stage{} ({})", compiler.stage, target)); + let _time = timeit(builder); builder.run(&mut cmd); Some(distdir(builder).join(format!("{}-{}.tar.gz", name, target))) } @@ -1334,7 +1348,6 @@ impl Step for Miri { let target = self.target; assert!(builder.config.extended); - builder.info(&format!("Dist miri stage{} ({})", compiler.stage, target)); let src = builder.src.join("src/tools/miri"); let release_num = builder.release_num("miri"); let name = pkgname(builder, "miri"); @@ -1389,6 +1402,8 @@ impl Step for Miri { .arg("--legacy-manifest-dirs=rustlib,cargo") .arg("--component-name=miri-preview"); + builder.info(&format!("Dist miri stage{} ({})", compiler.stage, target)); + let _time = timeit(builder); builder.run(&mut cmd); Some(distdir(builder).join(format!("{}-{}.tar.gz", name, target))) } @@ -1423,7 +1438,6 @@ impl Step for Rustfmt { let compiler = self.compiler; let target = self.target; - builder.info(&format!("Dist Rustfmt stage{} ({})", compiler.stage, target)); let src = builder.src.join("src/tools/rustfmt"); let release_num = builder.release_num("rustfmt"); let name = pkgname(builder, "rustfmt"); @@ -1476,6 +1490,8 @@ impl Step for Rustfmt { .arg("--legacy-manifest-dirs=rustlib,cargo") .arg("--component-name=rustfmt-preview"); + builder.info(&format!("Dist Rustfmt stage{} ({})", compiler.stage, target)); + let _time = timeit(builder); builder.run(&mut cmd); Some(distdir(builder).join(format!("{}-{}.tar.gz", name, target))) } @@ -1576,6 +1592,7 @@ impl Step for Extended { input_tarballs.push(tarball); } + builder.info("building combined installer"); let mut cmd = rust_installer(builder); cmd.arg("combine") .arg("--product-name=Rust") @@ -1587,7 +1604,9 @@ impl Step for Extended { .arg("--legacy-manifest-dirs=rustlib,cargo") .arg("--input-tarballs").arg(input_tarballs) .arg("--non-installed-overlay").arg(&overlay); + let time = timeit(&builder); builder.run(&mut cmd); + drop(time); let mut license = String::new(); license += &builder.read(&builder.src.join("COPYRIGHT")); @@ -1643,6 +1662,7 @@ impl Step for Extended { }; if target.contains("apple-darwin") { + builder.info("building pkg installer"); let pkg = tmp.join("pkg"); let _ = fs::remove_dir_all(&pkg); @@ -1692,6 +1712,7 @@ impl Step for Extended { pkgname(builder, "rust"), target))) .arg("--package-path").arg(&pkg); + let _time = timeit(builder); builder.run(&mut cmd); } @@ -1742,14 +1763,18 @@ impl Step for Extended { builder.create(&exe.join("LICENSE.txt"), &license); // Generate exe installer + builder.info("building `exe` installer with `iscc`"); let mut cmd = Command::new("iscc"); cmd.arg("rust.iss") + .arg("/Q") .current_dir(&exe); if target.contains("windows-gnu") { cmd.arg("/dMINGW"); } add_env(builder, &mut cmd, target); + let time = timeit(builder); builder.run(&mut cmd); + drop(time); builder.install(&exe.join(format!("{}-{}.exe", pkgname(builder, "rust"), target)), &distdir(builder), 0o755); @@ -1914,6 +1939,7 @@ impl Step for Extended { builder.install(&etc.join("gfx/banner.bmp"), &exe, 0o644); builder.install(&etc.join("gfx/dialogbg.bmp"), &exe, 0o644); + builder.info(&format!("building `msi` installer with {:?}", light)); let filename = format!("{}-{}.msi", pkgname(builder, "rust"), target); let mut cmd = Command::new(&light); cmd.arg("-nologo") @@ -1946,6 +1972,7 @@ impl Step for Extended { // ICE57 wrongly complains about the shortcuts cmd.arg("-sice:ICE57"); + let _time = timeit(builder); builder.run(&mut cmd); if !builder.config.dry_run { @@ -2114,6 +2141,7 @@ impl Step for LlvmTools { } builder.info(&format!("Dist LlvmTools ({})", target)); + let _time = timeit(builder); let src = builder.src.join("src/llvm-project/llvm"); let name = pkgname(builder, "llvm-tools"); From 3db2c13d893865e8e6929d5259bbac7d89a7ba06 Mon Sep 17 00:00:00 2001 From: Erin Power Date: Thu, 19 Sep 2019 21:53:40 +0200 Subject: [PATCH 13/15] Add Compatibility Notes to RELEASES.md for 1.38.0 --- RELEASES.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/RELEASES.md b/RELEASES.md index d634feba33ac5..ecf49278f4b52 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -68,6 +68,13 @@ Misc - [`rustc` will now warn about some incorrect uses of `mem::{uninitialized, zeroed}` that are known to cause undefined behaviour.][63346] +Compatibility Notes +------------------- +- Unfortunately the [`x86_64-unknown-uefi` platform can not be built][62785] + with rustc 1.39.0. +- The [`armv7-unknown-linux-gnueabihf` platform is also known to have + issues][62896] for certain crates such as libc. + [60260]: https://github.com/rust-lang/rust/pull/60260/ [61457]: https://github.com/rust-lang/rust/pull/61457/ [61491]: https://github.com/rust-lang/rust/pull/61491/ @@ -79,7 +86,9 @@ Misc [62735]: https://github.com/rust-lang/rust/pull/62735/ [62766]: https://github.com/rust-lang/rust/pull/62766/ [62784]: https://github.com/rust-lang/rust/pull/62784/ +[62785]: https://github.com/rust-lang/rust/issues/62785/ [62814]: https://github.com/rust-lang/rust/pull/62814/ +[62896]: https://github.com/rust-lang/rust/issues/62896/ [63000]: https://github.com/rust-lang/rust/pull/63000/ [63056]: https://github.com/rust-lang/rust/pull/63056/ [63107]: https://github.com/rust-lang/rust/pull/63107/ From c3140bae633b265657c0094f6df6edf630d1d917 Mon Sep 17 00:00:00 2001 From: guanqun Date: Sat, 21 Sep 2019 00:22:43 +0800 Subject: [PATCH 14/15] remove the extra comma after the match arm This would follow the same coding style as all the other match arms in this file. --- src/librustc_resolve/late/diagnostics.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc_resolve/late/diagnostics.rs b/src/librustc_resolve/late/diagnostics.rs index 0c86d8494fde8..df8bd3fa75e14 100644 --- a/src/librustc_resolve/late/diagnostics.rs +++ b/src/librustc_resolve/late/diagnostics.rs @@ -424,7 +424,7 @@ impl<'a> LateResolutionVisitor<'a, '_> { } else { err.note("did you mean to use one of the enum's variants?"); } - }, + } (Res::Def(DefKind::Struct, def_id), _) if ns == ValueNS => { if let Some((ctor_def, ctor_vis)) = self.r.struct_constructors.get(&def_id).cloned() { From 9f374da46781cfe2d297636fe97b2fd9647cb1d9 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Fri, 20 Sep 2019 15:39:34 -0700 Subject: [PATCH 15/15] Exempt extern "Rust" from improper_ctypes It should be fine for Rust ABIs to involve any Rust type. --- src/liballoc/alloc.rs | 2 +- src/libcore/panicking.rs | 2 +- src/librustc_lint/types.rs | 4 +++- src/test/ui/issues/issue-64593.rs | 12 ++++++++++++ 4 files changed, 17 insertions(+), 3 deletions(-) create mode 100644 src/test/ui/issues/issue-64593.rs diff --git a/src/liballoc/alloc.rs b/src/liballoc/alloc.rs index dc7fd1adc2958..a39fcd5ad4c58 100644 --- a/src/liballoc/alloc.rs +++ b/src/liballoc/alloc.rs @@ -240,7 +240,7 @@ pub(crate) unsafe fn box_free(ptr: Unique) { #[stable(feature = "global_alloc", since = "1.28.0")] #[rustc_allocator_nounwind] pub fn handle_alloc_error(layout: Layout) -> ! { - #[allow(improper_ctypes)] + #[cfg_attr(bootstrap, allow(improper_ctypes))] extern "Rust" { #[lang = "oom"] fn oom_impl(layout: Layout) -> !; diff --git a/src/libcore/panicking.rs b/src/libcore/panicking.rs index 15b7d69c58d24..3d2bc24bf24a5 100644 --- a/src/libcore/panicking.rs +++ b/src/libcore/panicking.rs @@ -71,7 +71,7 @@ pub fn panic_fmt(fmt: fmt::Arguments<'_>, file_line_col: &(&'static str, u32, u3 } // NOTE This function never crosses the FFI boundary; it's a Rust-to-Rust call - #[allow(improper_ctypes)] // PanicInfo contains a trait object which is not FFI safe + #[cfg_attr(boostrap_stdarch_ignore_this, allow(improper_ctypes))] extern "Rust" { #[lang = "panic_impl"] fn panic_impl(pi: &PanicInfo<'_>) -> !; diff --git a/src/librustc_lint/types.rs b/src/librustc_lint/types.rs index 3b8c06ba154c6..40261f6d13739 100644 --- a/src/librustc_lint/types.rs +++ b/src/librustc_lint/types.rs @@ -975,7 +975,9 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ImproperCTypes { fn check_foreign_item(&mut self, cx: &LateContext<'_, '_>, it: &hir::ForeignItem) { let mut vis = ImproperCTypesVisitor { cx }; let abi = cx.tcx.hir().get_foreign_abi(it.hir_id); - if abi != Abi::RustIntrinsic && abi != Abi::PlatformIntrinsic { + if let Abi::Rust | Abi::RustCall | Abi::RustIntrinsic | Abi::PlatformIntrinsic = abi { + // Don't worry about types in internal ABIs. + } else { match it.node { hir::ForeignItemKind::Fn(ref decl, _, _) => { vis.check_foreign_fn(it.hir_id, decl); diff --git a/src/test/ui/issues/issue-64593.rs b/src/test/ui/issues/issue-64593.rs new file mode 100644 index 0000000000000..9e787f638a998 --- /dev/null +++ b/src/test/ui/issues/issue-64593.rs @@ -0,0 +1,12 @@ +// check-pass +#![deny(improper_ctypes)] + +pub struct Error(std::num::NonZeroU32); + +extern "Rust" { + fn foo(dest: &mut [u8]) -> Result<(), Error>; +} + +fn main() { + let _ = unsafe { foo(&mut []) }; +}