From 84b880d55e5b154d9649107ac583de7591a81823 Mon Sep 17 00:00:00 2001 From: Stefan Schindler Date: Thu, 15 Jun 2017 11:36:32 +0200 Subject: [PATCH 01/13] Add hint about the return code of panic! --- src/libcore/macros.rs | 2 +- src/libstd/macros.rs | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/libcore/macros.rs b/src/libcore/macros.rs index d68fad4972c68..537d925c8fa7c 100644 --- a/src/libcore/macros.rs +++ b/src/libcore/macros.rs @@ -456,7 +456,7 @@ macro_rules! writeln { /// /// # Panics /// -/// This will always panic. +/// This will always [panic!](macro.panic.html). /// /// # Examples /// diff --git a/src/libstd/macros.rs b/src/libstd/macros.rs index df3fce0da765d..547e840ffb7f3 100644 --- a/src/libstd/macros.rs +++ b/src/libstd/macros.rs @@ -24,6 +24,8 @@ /// The multi-argument form of this macro panics with a string and has the /// `format!` syntax for building a string. /// +/// If the main thread panics it will return with code `101`. +/// /// # Examples /// /// ```should_panic From 8205c348b4a793878a1cda06ebbc93860e9fea0c Mon Sep 17 00:00:00 2001 From: Yorwba Date: Thu, 22 Jun 2017 17:07:38 +0800 Subject: [PATCH 02/13] Note different versions of same crate when absolute paths of different types match. --- src/librustc/infer/error_reporting/mod.rs | 5 ++- .../type-mismatch-same-crate-name/Makefile | 19 ++++++++++ .../type-mismatch-same-crate-name/crateA.rs | 26 ++++++++++++++ .../type-mismatch-same-crate-name/crateB.rs | 14 ++++++++ .../type-mismatch-same-crate-name/crateC.rs | 35 +++++++++++++++++++ 5 files changed, 98 insertions(+), 1 deletion(-) create mode 100644 src/test/run-make/type-mismatch-same-crate-name/Makefile create mode 100644 src/test/run-make/type-mismatch-same-crate-name/crateA.rs create mode 100644 src/test/run-make/type-mismatch-same-crate-name/crateB.rs create mode 100644 src/test/run-make/type-mismatch-same-crate-name/crateC.rs diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs index 11bac21bc429e..2265c0c0a8c70 100644 --- a/src/librustc/infer/error_reporting/mod.rs +++ b/src/librustc/infer/error_reporting/mod.rs @@ -337,9 +337,12 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { if !(did1.is_local() || did2.is_local()) && did1.krate != did2.krate { let exp_path = self.tcx.item_path_str(did1); let found_path = self.tcx.item_path_str(did2); + let exp_abs_path = self.tcx.absolute_item_path_str(did1); + let found_abs_path = self.tcx.absolute_item_path_str(did2); // We compare strings because DefPath can be different // for imported and non-imported crates - if exp_path == found_path { + if exp_path == found_path + || exp_abs_path == found_abs_path { let crate_name = self.tcx.sess.cstore.crate_name(did1.krate); err.span_note(sp, &format!("Perhaps two different versions \ of crate `{}` are being used?", diff --git a/src/test/run-make/type-mismatch-same-crate-name/Makefile b/src/test/run-make/type-mismatch-same-crate-name/Makefile new file mode 100644 index 0000000000000..24ef203278a74 --- /dev/null +++ b/src/test/run-make/type-mismatch-same-crate-name/Makefile @@ -0,0 +1,19 @@ +-include ../tools.mk + +all: + # compile two different versions of crateA + $(RUSTC) --crate-type=rlib crateA.rs -C metadata=-1 -C extra-filename=-1 + $(RUSTC) --crate-type=rlib crateA.rs -C metadata=-2 -C extra-filename=-2 + # make crateB depend on version 1 of crateA + $(RUSTC) --crate-type=rlib crateB.rs --extern crateA=$(TMPDIR)/libcrateA-1.rlib + # make crateC depend on version 2 of crateA + $(RUSTC) crateC.rs --extern crateA=$(TMPDIR)/libcrateA-2.rlib 2>&1 | \ + grep -z \ + "mismatched types.*\ + crateB::try_foo(foo2);.*\ + expected struct \`crateA::foo::Foo\`, found struct \`crateA::Foo\`.*\ + different versions of crate \`crateA\`.*\ + mismatched types.*\ + crateB::try_bar(bar2);.*\ + expected trait \`crateA::bar::Bar\`, found trait \`crateA::Bar\`.*\ + different versions of crate \`crateA\`" diff --git a/src/test/run-make/type-mismatch-same-crate-name/crateA.rs b/src/test/run-make/type-mismatch-same-crate-name/crateA.rs new file mode 100644 index 0000000000000..e40266bb4cdaa --- /dev/null +++ b/src/test/run-make/type-mismatch-same-crate-name/crateA.rs @@ -0,0 +1,26 @@ +// Copyright 2017 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. + +mod foo { + pub struct Foo; +} + +mod bar { + pub trait Bar{} + + pub fn bar() -> Box { + unimplemented!() + } +} + +// This makes the publicly accessible path +// differ from the internal one. +pub use foo::Foo; +pub use bar::{Bar, bar}; diff --git a/src/test/run-make/type-mismatch-same-crate-name/crateB.rs b/src/test/run-make/type-mismatch-same-crate-name/crateB.rs new file mode 100644 index 0000000000000..da4ea1c9387e9 --- /dev/null +++ b/src/test/run-make/type-mismatch-same-crate-name/crateB.rs @@ -0,0 +1,14 @@ +// Copyright 2017 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. + +extern crate crateA; + +pub fn try_foo(x: crateA::Foo){} +pub fn try_bar(x: Box){} diff --git a/src/test/run-make/type-mismatch-same-crate-name/crateC.rs b/src/test/run-make/type-mismatch-same-crate-name/crateC.rs new file mode 100644 index 0000000000000..da869d2145fe1 --- /dev/null +++ b/src/test/run-make/type-mismatch-same-crate-name/crateC.rs @@ -0,0 +1,35 @@ +// Copyright 2017 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. + +// This tests the extra note reported when a type error deals with +// seemingly identical types. +// The main use case of this error is when there are two crates +// (generally different versions of the same crate) with the same name +// causing a type mismatch. + +// The test is nearly the same as the one in +// compile-fail/type-mismatch-same-crate-name.rs +// but deals with the case where one of the crates +// is only introduced as an indirect dependency. +// and the type is accessed via a reexport. +// This is similar to how the error can be introduced +// when using cargo's automatic dependency resolution. + +extern crate crateA; + +fn main() { + let foo2 = crateA::Foo; + let bar2 = crateA::bar(); + { + extern crate crateB; + crateB::try_foo(foo2); + crateB::try_bar(bar2); + } +} From 21bb60afc1d20399ceed73dcb7939432e05b5688 Mon Sep 17 00:00:00 2001 From: Yorwba Date: Thu, 29 Jun 2017 20:07:51 +0800 Subject: [PATCH 03/13] Replace `grep -z` by `tr -d '\r\n' | grep` for cross-compatibility --- src/test/run-make/type-mismatch-same-crate-name/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/run-make/type-mismatch-same-crate-name/Makefile b/src/test/run-make/type-mismatch-same-crate-name/Makefile index 24ef203278a74..1044d73fd1a36 100644 --- a/src/test/run-make/type-mismatch-same-crate-name/Makefile +++ b/src/test/run-make/type-mismatch-same-crate-name/Makefile @@ -8,7 +8,7 @@ all: $(RUSTC) --crate-type=rlib crateB.rs --extern crateA=$(TMPDIR)/libcrateA-1.rlib # make crateC depend on version 2 of crateA $(RUSTC) crateC.rs --extern crateA=$(TMPDIR)/libcrateA-2.rlib 2>&1 | \ - grep -z \ + tr -d '\r\n' | grep \ "mismatched types.*\ crateB::try_foo(foo2);.*\ expected struct \`crateA::foo::Foo\`, found struct \`crateA::Foo\`.*\ From 01b6c9459ca3f7857f211aa47f8fbf3b52ed1c47 Mon Sep 17 00:00:00 2001 From: Masaki Hara Date: Sun, 2 Jul 2017 08:41:39 +0900 Subject: [PATCH 04/13] Implement Eq/Hash/Debug etc. for unsized tuples. --- src/libcore/fmt/mod.rs | 9 +++++++-- src/libcore/hash/mod.rs | 7 ++++++- src/libcore/tuple.rs | 14 ++++++++++---- 3 files changed, 23 insertions(+), 7 deletions(-) diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs index bcc6d53c81d3b..750e86114c4bb 100644 --- a/src/libcore/fmt/mod.rs +++ b/src/libcore/fmt/mod.rs @@ -1627,13 +1627,13 @@ macro_rules! tuple { () => (); ( $($name:ident,)+ ) => ( #[stable(feature = "rust1", since = "1.0.0")] - impl<$($name:Debug),*> Debug for ($($name,)*) { + impl<$($name:Debug),*> Debug for ($($name,)*) where last_type!($($name,)+): ?Sized { #[allow(non_snake_case, unused_assignments, deprecated)] fn fmt(&self, f: &mut Formatter) -> Result { let mut builder = f.debug_tuple(""); let ($(ref $name,)*) = *self; $( - builder.field($name); + builder.field(&$name); )* builder.finish() @@ -1643,6 +1643,11 @@ macro_rules! tuple { ) } +macro_rules! last_type { + ($a:ident,) => { $a }; + ($a:ident, $($rest_a:ident,)+) => { last_type!($($rest_a,)+) }; +} + tuple! { T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, } #[stable(feature = "rust1", since = "1.0.0")] diff --git a/src/libcore/hash/mod.rs b/src/libcore/hash/mod.rs index 3b304f4c479a0..2000ba9146029 100644 --- a/src/libcore/hash/mod.rs +++ b/src/libcore/hash/mod.rs @@ -559,7 +559,7 @@ mod impls { ( $($name:ident)+) => ( #[stable(feature = "rust1", since = "1.0.0")] - impl<$($name: Hash),*> Hash for ($($name,)*) { + impl<$($name: Hash),*> Hash for ($($name,)*) where last_type!($($name,)+): ?Sized { #[allow(non_snake_case)] fn hash(&self, state: &mut S) { let ($(ref $name,)*) = *self; @@ -569,6 +569,11 @@ mod impls { ); } + macro_rules! last_type { + ($a:ident,) => { $a }; + ($a:ident, $($rest_a:ident,)+) => { last_type!($($rest_a,)+) }; + } + impl_hash_tuple! {} impl_hash_tuple! { A } impl_hash_tuple! { A B } diff --git a/src/libcore/tuple.rs b/src/libcore/tuple.rs index 55d55079ddc1b..47e9c7c903880 100644 --- a/src/libcore/tuple.rs +++ b/src/libcore/tuple.rs @@ -29,7 +29,7 @@ macro_rules! tuple_impls { } #[stable(feature = "rust1", since = "1.0.0")] - impl<$($T:PartialEq),+> PartialEq for ($($T,)+) { + impl<$($T:PartialEq),+> PartialEq for ($($T,)+) where last_type!($($T,)+): ?Sized { #[inline] fn eq(&self, other: &($($T,)+)) -> bool { $(self.$idx == other.$idx)&&+ @@ -41,10 +41,11 @@ macro_rules! tuple_impls { } #[stable(feature = "rust1", since = "1.0.0")] - impl<$($T:Eq),+> Eq for ($($T,)+) {} + impl<$($T:Eq),+> Eq for ($($T,)+) where last_type!($($T,)+): ?Sized {} #[stable(feature = "rust1", since = "1.0.0")] - impl<$($T:PartialOrd + PartialEq),+> PartialOrd for ($($T,)+) { + impl<$($T:PartialOrd + PartialEq),+> PartialOrd for ($($T,)+) + where last_type!($($T,)+): ?Sized { #[inline] fn partial_cmp(&self, other: &($($T,)+)) -> Option { lexical_partial_cmp!($(self.$idx, other.$idx),+) @@ -68,7 +69,7 @@ macro_rules! tuple_impls { } #[stable(feature = "rust1", since = "1.0.0")] - impl<$($T:Ord),+> Ord for ($($T,)+) { + impl<$($T:Ord),+> Ord for ($($T,)+) where last_type!($($T,)+): ?Sized { #[inline] fn cmp(&self, other: &($($T,)+)) -> Ordering { lexical_cmp!($(self.$idx, other.$idx),+) @@ -118,6 +119,11 @@ macro_rules! lexical_cmp { ($a:expr, $b:expr) => { ($a).cmp(&$b) }; } +macro_rules! last_type { + ($a:ident,) => { $a }; + ($a:ident, $($rest_a:ident,)+) => { last_type!($($rest_a,)+) }; +} + tuple_impls! { Tuple1 { (0) -> A From 728d26c8861265c15d997117be31ca2b9d3fa44b Mon Sep 17 00:00:00 2001 From: Masaki Hara Date: Tue, 4 Jul 2017 21:26:46 +0900 Subject: [PATCH 05/13] Add a test for unsized tuple impls. --- src/test/run-pass/unsized-tuple-impls.rs | 29 ++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 src/test/run-pass/unsized-tuple-impls.rs diff --git a/src/test/run-pass/unsized-tuple-impls.rs b/src/test/run-pass/unsized-tuple-impls.rs new file mode 100644 index 0000000000000..591b19f89e897 --- /dev/null +++ b/src/test/run-pass/unsized-tuple-impls.rs @@ -0,0 +1,29 @@ +// Copyright 2017 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(unsized_tuple_coercion)] + +use std::collections::HashSet; + +fn main() { + let x : &(i32, i32, [i32]) = &(0, 1, [2, 3]); + let y : &(i32, i32, [i32]) = &(0, 1, [2, 3, 4]); + let mut a = [y, x]; + a.sort(); + assert_eq!(a, [x, y]); + + assert_eq!(&format!("{:?}", a), "[(0, 1, [2, 3]), (0, 1, [2, 3, 4])]"); + + let mut h = HashSet::new(); + h.insert(x); + h.insert(y); + assert!(h.contains(x)); + assert!(h.contains(y)); +} From d5390573ba468d4f1d06bf4f3ba6d54ec26c98c5 Mon Sep 17 00:00:00 2001 From: Stefan Schindler Date: Wed, 5 Jul 2017 21:16:58 +0200 Subject: [PATCH 06/13] Insert current implementation header --- src/libcore/macros.rs | 2 +- src/libstd/macros.rs | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/libcore/macros.rs b/src/libcore/macros.rs index 537d925c8fa7c..ceaab1857167d 100644 --- a/src/libcore/macros.rs +++ b/src/libcore/macros.rs @@ -456,7 +456,7 @@ macro_rules! writeln { /// /// # Panics /// -/// This will always [panic!](macro.panic.html). +/// This will always [panic!](macro.panic.html) /// /// # Examples /// diff --git a/src/libstd/macros.rs b/src/libstd/macros.rs index 547e840ffb7f3..fbf2ba7f9a032 100644 --- a/src/libstd/macros.rs +++ b/src/libstd/macros.rs @@ -24,6 +24,8 @@ /// The multi-argument form of this macro panics with a string and has the /// `format!` syntax for building a string. /// +/// # Current implementation +/// /// If the main thread panics it will return with code `101`. /// /// # Examples From 9e001ce86522011ff716218f29dcd9dff082d20a Mon Sep 17 00:00:00 2001 From: Stefan Schindler Date: Wed, 5 Jul 2017 22:58:39 +0200 Subject: [PATCH 07/13] Be more specific about the implications of the panic! --- src/libstd/macros.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libstd/macros.rs b/src/libstd/macros.rs index fbf2ba7f9a032..a45d37b079297 100644 --- a/src/libstd/macros.rs +++ b/src/libstd/macros.rs @@ -26,7 +26,7 @@ /// /// # Current implementation /// -/// If the main thread panics it will return with code `101`. +/// If the main thread panics it will terminate all your threads and end your program with code `101`. /// /// # Examples /// From 05d352613226e890b7017b84edbc5b0ea4d6d147 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Fri, 30 Jun 2017 17:06:51 -0700 Subject: [PATCH 08/13] `rustc_on_unimplemented` supports referring to trait Add support to `rustc_on_unimplemented` to reference the full path of the annotated trait. For the following code: ```rust pub mod Bar { #[rustc_on_unimplemented = "test error `{Self}` with `{Bar}` `{Baz}` `{Quux}` in `{Foo}`"] pub trait Foo {} } ``` the error message will be: ``` test error `std::string::String` with `u8` `_` `u32` in `Bar::Foo` ``` --- src/librustc/traits/error_reporting.rs | 4 ++ src/librustc_typeck/check/mod.rs | 4 +- .../on-unimplemented/bad-annotation.rs | 0 .../ui/on-unimplemented/bad-annotation.stderr | 22 ++++++++ .../on-unimplemented/multiple-impls.rs | 0 .../ui/on-unimplemented/multiple-impls.stderr | 53 +++++++++++++++++++ .../on-unimplemented/on-impl.rs | 0 src/test/ui/on-unimplemented/on-impl.stderr | 19 +++++++ .../on-unimplemented/on-trait.rs | 9 ++-- src/test/ui/on-unimplemented/on-trait.stderr | 20 +++++++ .../on-unimplemented/slice-index.rs | 0 .../ui/on-unimplemented/slice-index.stderr | 20 +++++++ 12 files changed, 147 insertions(+), 4 deletions(-) rename src/test/{compile-fail => ui}/on-unimplemented/bad-annotation.rs (100%) create mode 100644 src/test/ui/on-unimplemented/bad-annotation.stderr rename src/test/{compile-fail => ui}/on-unimplemented/multiple-impls.rs (100%) create mode 100644 src/test/ui/on-unimplemented/multiple-impls.stderr rename src/test/{compile-fail => ui}/on-unimplemented/on-impl.rs (100%) create mode 100644 src/test/ui/on-unimplemented/on-impl.stderr rename src/test/{compile-fail => ui}/on-unimplemented/on-trait.rs (90%) create mode 100644 src/test/ui/on-unimplemented/on-trait.stderr rename src/test/{compile-fail => ui}/on-unimplemented/slice-index.rs (100%) create mode 100644 src/test/ui/on-unimplemented/slice-index.stderr diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index 0bf0e21baaf93..c02d1394f6bb5 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -330,6 +330,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { .filter(|a| a.check_name("rustc_on_unimplemented")) .next() { + let name = self.tcx.item_name(def_id).as_str(); let err_sp = item.span.substitute_dummy(span); let trait_str = self.tcx.item_path_str(trait_ref.def_id); if let Some(istring) = item.value_str() { @@ -347,6 +348,9 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { Piece::NextArgument(a) => match a.position { Position::ArgumentNamed(s) => match generic_map.get(s) { Some(val) => Some(val), + None if s == name => { + Some(&trait_str) + } None => { span_err!(self.tcx.sess, err_sp, E0272, "the #[rustc_on_unimplemented] attribute on trait \ diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 3241267bbc2e4..41edf8c2926ec 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -1166,6 +1166,7 @@ fn check_on_unimplemented<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, }) { if let Some(istring) = attr.value_str() { let istring = istring.as_str(); + let name = tcx.item_name(def_id).as_str(); let parser = Parser::new(&istring); let types = &generics.types; for token in parser { @@ -1174,13 +1175,14 @@ fn check_on_unimplemented<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, Piece::NextArgument(a) => match a.position { // `{Self}` is allowed Position::ArgumentNamed(s) if s == "Self" => (), + // `{ThisTraitsName}` is allowed + Position::ArgumentNamed(s) if s == name => (), // So is `{A}` if A is a type parameter Position::ArgumentNamed(s) => match types.iter().find(|t| { t.name == s }) { Some(_) => (), None => { - let name = tcx.item_name(def_id); span_err!(tcx.sess, attr.span, E0230, "there is no type parameter \ {} on trait {}", diff --git a/src/test/compile-fail/on-unimplemented/bad-annotation.rs b/src/test/ui/on-unimplemented/bad-annotation.rs similarity index 100% rename from src/test/compile-fail/on-unimplemented/bad-annotation.rs rename to src/test/ui/on-unimplemented/bad-annotation.rs diff --git a/src/test/ui/on-unimplemented/bad-annotation.stderr b/src/test/ui/on-unimplemented/bad-annotation.stderr new file mode 100644 index 0000000000000..8599477e8ed7e --- /dev/null +++ b/src/test/ui/on-unimplemented/bad-annotation.stderr @@ -0,0 +1,22 @@ +error[E0232]: this attribute must have a value + --> $DIR/bad-annotation.rs:26:1 + | +26 | #[rustc_on_unimplemented] //~ ERROR this attribute must have a value + | ^^^^^^^^^^^^^^^^^^^^^^^^^ attribute requires a value + | + = note: eg `#[rustc_on_unimplemented = "foo"]` + +error[E0230]: there is no type parameter C on trait BadAnnotation2 + --> $DIR/bad-annotation.rs:30:1 + | +30 | #[rustc_on_unimplemented = "Unimplemented trait error on `{Self}` with params `<{A},{B},{C}>`"] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0231]: only named substitution parameters are allowed + --> $DIR/bad-annotation.rs:35:1 + | +35 | #[rustc_on_unimplemented = "Unimplemented trait error on `{Self}` with params `<{A},{B},{}>`"] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 3 previous errors + diff --git a/src/test/compile-fail/on-unimplemented/multiple-impls.rs b/src/test/ui/on-unimplemented/multiple-impls.rs similarity index 100% rename from src/test/compile-fail/on-unimplemented/multiple-impls.rs rename to src/test/ui/on-unimplemented/multiple-impls.rs diff --git a/src/test/ui/on-unimplemented/multiple-impls.stderr b/src/test/ui/on-unimplemented/multiple-impls.stderr new file mode 100644 index 0000000000000..a1fa8b720a829 --- /dev/null +++ b/src/test/ui/on-unimplemented/multiple-impls.stderr @@ -0,0 +1,53 @@ +error[E0277]: the trait bound `[i32]: Index` is not satisfied + --> $DIR/multiple-impls.rs:43:5 + | +43 | Index::index(&[] as &[i32], 2u32); + | ^^^^^^^^^^^^ trait message + | + = help: the trait `Index` is not implemented for `[i32]` + = note: required by `Index::index` + +error[E0277]: the trait bound `[i32]: Index` is not satisfied + --> $DIR/multiple-impls.rs:43:5 + | +43 | Index::index(&[] as &[i32], 2u32); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait message + | + = help: the trait `Index` is not implemented for `[i32]` + +error[E0277]: the trait bound `[i32]: Index>` is not satisfied + --> $DIR/multiple-impls.rs:49:5 + | +49 | Index::index(&[] as &[i32], Foo(2u32)); + | ^^^^^^^^^^^^ on impl for Foo + | + = help: the trait `Index>` is not implemented for `[i32]` + = note: required by `Index::index` + +error[E0277]: the trait bound `[i32]: Index>` is not satisfied + --> $DIR/multiple-impls.rs:49:5 + | +49 | Index::index(&[] as &[i32], Foo(2u32)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ on impl for Foo + | + = help: the trait `Index>` is not implemented for `[i32]` + +error[E0277]: the trait bound `[i32]: Index>` is not satisfied + --> $DIR/multiple-impls.rs:55:5 + | +55 | Index::index(&[] as &[i32], Bar(2u32)); + | ^^^^^^^^^^^^ on impl for Bar + | + = help: the trait `Index>` is not implemented for `[i32]` + = note: required by `Index::index` + +error[E0277]: the trait bound `[i32]: Index>` is not satisfied + --> $DIR/multiple-impls.rs:55:5 + | +55 | Index::index(&[] as &[i32], Bar(2u32)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ on impl for Bar + | + = help: the trait `Index>` is not implemented for `[i32]` + +error: aborting due to 6 previous errors + diff --git a/src/test/compile-fail/on-unimplemented/on-impl.rs b/src/test/ui/on-unimplemented/on-impl.rs similarity index 100% rename from src/test/compile-fail/on-unimplemented/on-impl.rs rename to src/test/ui/on-unimplemented/on-impl.rs diff --git a/src/test/ui/on-unimplemented/on-impl.stderr b/src/test/ui/on-unimplemented/on-impl.stderr new file mode 100644 index 0000000000000..c8c06bf44fd6f --- /dev/null +++ b/src/test/ui/on-unimplemented/on-impl.stderr @@ -0,0 +1,19 @@ +error[E0277]: the trait bound `[i32]: Index` is not satisfied + --> $DIR/on-impl.rs:32:5 + | +32 | Index::::index(&[1, 2, 3] as &[i32], 2u32); + | ^^^^^^^^^^^^^^^^^^^ a usize is required to index into a slice + | + = help: the trait `Index` is not implemented for `[i32]` + = note: required by `Index::index` + +error[E0277]: the trait bound `[i32]: Index` is not satisfied + --> $DIR/on-impl.rs:32:5 + | +32 | Index::::index(&[1, 2, 3] as &[i32], 2u32); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ a usize is required to index into a slice + | + = help: the trait `Index` is not implemented for `[i32]` + +error: aborting due to 2 previous errors + diff --git a/src/test/compile-fail/on-unimplemented/on-trait.rs b/src/test/ui/on-unimplemented/on-trait.rs similarity index 90% rename from src/test/compile-fail/on-unimplemented/on-trait.rs rename to src/test/ui/on-unimplemented/on-trait.rs index a8daef356a5cc..ed7ec9b143689 100644 --- a/src/test/compile-fail/on-unimplemented/on-trait.rs +++ b/src/test/ui/on-unimplemented/on-trait.rs @@ -11,9 +11,12 @@ #![feature(on_unimplemented)] -#[rustc_on_unimplemented = "test error `{Self}` with `{Bar}` `{Baz}` `{Quux}`"] -trait Foo -{} +pub mod Bar { + #[rustc_on_unimplemented = "test error `{Self}` with `{Bar}` `{Baz}` `{Quux}` in `{Foo}`"] + pub trait Foo {} +} + +use Bar::Foo; fn foobar>() -> T { panic!() diff --git a/src/test/ui/on-unimplemented/on-trait.stderr b/src/test/ui/on-unimplemented/on-trait.stderr new file mode 100644 index 0000000000000..84986c1ecfdd3 --- /dev/null +++ b/src/test/ui/on-unimplemented/on-trait.stderr @@ -0,0 +1,20 @@ +error[E0277]: the trait bound `std::option::Option>: MyFromIterator<&u8>` is not satisfied + --> $DIR/on-trait.rs:37:30 + | +37 | let y: Option> = collect(x.iter()); // this should give approximately the same error for x.iter().collect() + | ^^^^^^^ a collection of type `std::option::Option>` cannot be built from an iterator over elements of type `&u8` + | + = help: the trait `MyFromIterator<&u8>` is not implemented for `std::option::Option>` + = note: required by `collect` + +error[E0277]: the trait bound `std::string::String: Bar::Foo` is not satisfied + --> $DIR/on-trait.rs:42:21 + | +42 | let x: String = foobar(); //~ ERROR + | ^^^^^^ test error `std::string::String` with `u8` `_` `u32` in `Bar::Foo` + | + = help: the trait `Bar::Foo` is not implemented for `std::string::String` + = note: required by `foobar` + +error: aborting due to 2 previous errors + diff --git a/src/test/compile-fail/on-unimplemented/slice-index.rs b/src/test/ui/on-unimplemented/slice-index.rs similarity index 100% rename from src/test/compile-fail/on-unimplemented/slice-index.rs rename to src/test/ui/on-unimplemented/slice-index.rs diff --git a/src/test/ui/on-unimplemented/slice-index.stderr b/src/test/ui/on-unimplemented/slice-index.stderr new file mode 100644 index 0000000000000..68789f77f750c --- /dev/null +++ b/src/test/ui/on-unimplemented/slice-index.stderr @@ -0,0 +1,20 @@ +error[E0277]: the trait bound `i32: std::slice::SliceIndex<[i32]>` is not satisfied + --> $DIR/slice-index.rs:21:5 + | +21 | x[1i32]; //~ ERROR E0277 + | ^^^^^^^ slice indices are of type `usize` or ranges of `usize` + | + = help: the trait `std::slice::SliceIndex<[i32]>` is not implemented for `i32` + = note: required because of the requirements on the impl of `std::ops::Index` for `[i32]` + +error[E0277]: the trait bound `std::ops::RangeTo: std::slice::SliceIndex<[i32]>` is not satisfied + --> $DIR/slice-index.rs:24:5 + | +24 | x[..1i32]; //~ ERROR E0277 + | ^^^^^^^^^ slice indices are of type `usize` or ranges of `usize` + | + = help: the trait `std::slice::SliceIndex<[i32]>` is not implemented for `std::ops::RangeTo` + = note: required because of the requirements on the impl of `std::ops::Index>` for `[i32]` + +error: aborting due to 2 previous errors + From 28ce2924f15983ad31c44cc432aa17f217c3a131 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Thu, 6 Jul 2017 15:20:01 -0700 Subject: [PATCH 09/13] Add `isize` and `usize` constructors to Literal This commit fills out the remaining integer literal constructors on the `proc_macro::Literal` type with `isize` and `usize`. (I think these were just left out by accident) --- src/libproc_macro/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libproc_macro/lib.rs b/src/libproc_macro/lib.rs index 06f9634d70613..357e2ab853cbb 100644 --- a/src/libproc_macro/lib.rs +++ b/src/libproc_macro/lib.rs @@ -303,7 +303,7 @@ impl Literal { Literal(token::Literal(token::Lit::Integer(Symbol::intern(&n.to_string())), None)) } - int_literals!(u8, i8, u16, i16, u32, i32, u64, i64); + int_literals!(u8, i8, u16, i16, u32, i32, u64, i64, usize, isize); fn typed_integer(n: i128, kind: &'static str) -> Literal { Literal(token::Literal(token::Lit::Integer(Symbol::intern(&n.to_string())), Some(Symbol::intern(kind)))) From 4d58b048a8b1ca9e2bd6907359ef9b4dc1f7382a Mon Sep 17 00:00:00 2001 From: Ian Douglas Scott Date: Thu, 6 Jul 2017 16:14:00 -0700 Subject: [PATCH 10/13] Redox: add stat methods(); support is_symlink() --- src/libstd/sys/redox/ext/fs.rs | 15 +++++++++++++++ src/libstd/sys/redox/fs.rs | 4 ++-- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/src/libstd/sys/redox/ext/fs.rs b/src/libstd/sys/redox/ext/fs.rs index 4437cf43920c5..9a0d1e06da327 100644 --- a/src/libstd/sys/redox/ext/fs.rs +++ b/src/libstd/sys/redox/ext/fs.rs @@ -177,6 +177,8 @@ pub trait MetadataExt { #[stable(feature = "metadata_ext", since = "1.1.0")] fn mode(&self) -> u32; #[stable(feature = "metadata_ext", since = "1.1.0")] + fn nlink(&self) -> u64; + #[stable(feature = "metadata_ext", since = "1.1.0")] fn uid(&self) -> u32; #[stable(feature = "metadata_ext", since = "1.1.0")] fn gid(&self) -> u32; @@ -194,6 +196,10 @@ pub trait MetadataExt { fn ctime(&self) -> i64; #[stable(feature = "metadata_ext", since = "1.1.0")] fn ctime_nsec(&self) -> i64; + #[stable(feature = "metadata_ext", since = "1.1.0")] + fn blksize(&self) -> u64; + #[stable(feature = "metadata_ext", since = "1.1.0")] + fn blocks(&self) -> u64; } #[stable(feature = "metadata_ext", since = "1.1.0")] @@ -207,6 +213,9 @@ impl MetadataExt for fs::Metadata { fn mode(&self) -> u32 { self.as_inner().as_inner().st_mode as u32 } + fn nlink(&self) -> u64 { + self.as_inner().as_inner().st_nlink as u64 + } fn uid(&self) -> u32 { self.as_inner().as_inner().st_uid as u32 } @@ -234,6 +243,12 @@ impl MetadataExt for fs::Metadata { fn ctime_nsec(&self) -> i64 { self.as_inner().as_inner().st_ctime_nsec as i64 } + fn blksize(&self) -> u64 { + self.as_inner().as_inner().st_blksize as u64 + } + fn blocks(&self) -> u64 { + self.as_inner().as_inner().st_blocks as u64 + } } /// Add special Redox types (block/char device, fifo and socket) diff --git a/src/libstd/sys/redox/fs.rs b/src/libstd/sys/redox/fs.rs index c5a19e8debe93..386ae24d9ea66 100644 --- a/src/libstd/sys/redox/fs.rs +++ b/src/libstd/sys/redox/fs.rs @@ -119,10 +119,10 @@ impl FilePermissions { impl FileType { pub fn is_dir(&self) -> bool { self.is(syscall::MODE_DIR) } pub fn is_file(&self) -> bool { self.is(syscall::MODE_FILE) } - pub fn is_symlink(&self) -> bool { false /*FIXME: Implement symlink mode*/ } + pub fn is_symlink(&self) -> bool { self.is(syscall::MODE_SYMLINK) } pub fn is(&self, mode: u16) -> bool { - self.mode & (syscall::MODE_DIR | syscall::MODE_FILE) == mode + self.mode & syscall::MODE_TYPE == mode } } From c6b280e0396780179a20776b55e3fa4cf4b1a513 Mon Sep 17 00:00:00 2001 From: John Gallagher Date: Sun, 9 Jul 2017 17:52:20 -0400 Subject: [PATCH 11/13] Add warning to BufWriter documentation --- src/libstd/io/buffered.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/libstd/io/buffered.rs b/src/libstd/io/buffered.rs index 296ee78aadb22..1b832453523fb 100644 --- a/src/libstd/io/buffered.rs +++ b/src/libstd/io/buffered.rs @@ -276,7 +276,10 @@ impl Seek for BufReader { /// `BufWriter` keeps an in-memory buffer of data and writes it to an underlying /// writer in large, infrequent batches. /// -/// The buffer will be written out when the writer is dropped. +/// When the `BufWriter` is dropped, the contents of its buffer will be written +/// out. However, any errors that happen in the process of flushing the buffer +/// when the writer is dropped will be ignored. Code that wishes to handle such +/// errors must manually call [`flush`] before the writer is dropped. /// /// # Examples /// @@ -316,6 +319,7 @@ impl Seek for BufReader { /// [`Write`]: ../../std/io/trait.Write.html /// [`Tcpstream::write`]: ../../std/net/struct.TcpStream.html#method.write /// [`TcpStream`]: ../../std/net/struct.TcpStream.html +/// [`flush`]: #method.flush #[stable(feature = "rust1", since = "1.0.0")] pub struct BufWriter { inner: Option, From f2566bbaebc4ea56bc3717ee8c04bee7d5c0a8d3 Mon Sep 17 00:00:00 2001 From: Oliver Middleton Date: Mon, 10 Jul 2017 02:07:29 +0100 Subject: [PATCH 12/13] Correct some stability attributes These show up in rustdoc so need to be correct. --- src/liballoc/boxed.rs | 4 ++-- src/libcore/cell.rs | 4 ++-- src/libcore/char.rs | 6 +++--- src/libstd/error.rs | 2 +- src/libstd/sync/mutex.rs | 2 +- src/libstd/sync/rwlock.rs | 4 ++-- src/libstd_unicode/char.rs | 2 +- 7 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs index 76cf10f0d55ea..94f5f4042e134 100644 --- a/src/liballoc/boxed.rs +++ b/src/liballoc/boxed.rs @@ -726,14 +726,14 @@ impl Clone for Box<[T]> { } } -#[stable(feature = "rust1", since = "1.0.0")] +#[stable(feature = "box_borrow", since = "1.1.0")] impl borrow::Borrow for Box { fn borrow(&self) -> &T { &**self } } -#[stable(feature = "rust1", since = "1.0.0")] +#[stable(feature = "box_borrow", since = "1.1.0")] impl borrow::BorrowMut for Box { fn borrow_mut(&mut self) -> &mut T { &mut **self diff --git a/src/libcore/cell.rs b/src/libcore/cell.rs index 1eebf67ad04cb..35744f3f16b39 100644 --- a/src/libcore/cell.rs +++ b/src/libcore/cell.rs @@ -942,7 +942,7 @@ impl<'b, T: ?Sized> Ref<'b, T> { #[unstable(feature = "coerce_unsized", issue = "27732")] impl<'b, T: ?Sized + Unsize, U: ?Sized> CoerceUnsized> for Ref<'b, T> {} -#[stable(feature = "std_guard_impls", since = "1.20")] +#[stable(feature = "std_guard_impls", since = "1.20.0")] impl<'a, T: ?Sized + fmt::Display> fmt::Display for Ref<'a, T> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { self.value.fmt(f) @@ -1041,7 +1041,7 @@ impl<'b, T: ?Sized> DerefMut for RefMut<'b, T> { #[unstable(feature = "coerce_unsized", issue = "27732")] impl<'b, T: ?Sized + Unsize, U: ?Sized> CoerceUnsized> for RefMut<'b, T> {} -#[stable(feature = "std_guard_impls", since = "1.20")] +#[stable(feature = "std_guard_impls", since = "1.20.0")] impl<'a, T: ?Sized + fmt::Display> fmt::Display for RefMut<'a, T> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { self.value.fmt(f) diff --git a/src/libcore/char.rs b/src/libcore/char.rs index 44f5fdbf4312b..bb4cb0ac3b215 100644 --- a/src/libcore/char.rs +++ b/src/libcore/char.rs @@ -210,7 +210,7 @@ impl From for char { /// An error which can be returned when parsing a char. -#[stable(feature = "char_from_str", since = "1.19.0")] +#[stable(feature = "char_from_str", since = "1.20.0")] #[derive(Clone, Debug)] pub struct ParseCharError { kind: CharErrorKind, @@ -237,7 +237,7 @@ enum CharErrorKind { TooManyChars, } -#[stable(feature = "char_from_str", since = "1.19.0")] +#[stable(feature = "char_from_str", since = "1.20.0")] impl fmt::Display for ParseCharError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { self.__description().fmt(f) @@ -245,7 +245,7 @@ impl fmt::Display for ParseCharError { } -#[stable(feature = "char_from_str", since = "1.19.0")] +#[stable(feature = "char_from_str", since = "1.20.0")] impl FromStr for char { type Err = ParseCharError; diff --git a/src/libstd/error.rs b/src/libstd/error.rs index d77f817659c56..d1c2bfb96b336 100644 --- a/src/libstd/error.rs +++ b/src/libstd/error.rs @@ -340,7 +340,7 @@ impl Error for char::CharTryFromError { } } -#[stable(feature = "char_from_str", since = "1.19.0")] +#[stable(feature = "char_from_str", since = "1.20.0")] impl Error for char::ParseCharError { fn description(&self) -> &str { self.__description() diff --git a/src/libstd/sync/mutex.rs b/src/libstd/sync/mutex.rs index fc6c7de9ef083..62d8de18f4b45 100644 --- a/src/libstd/sync/mutex.rs +++ b/src/libstd/sync/mutex.rs @@ -440,7 +440,7 @@ impl<'a, T: ?Sized + fmt::Debug> fmt::Debug for MutexGuard<'a, T> { } } -#[stable(feature = "std_guard_impls", since = "1.20")] +#[stable(feature = "std_guard_impls", since = "1.20.0")] impl<'a, T: ?Sized + fmt::Display> fmt::Display for MutexGuard<'a, T> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { (**self).fmt(f) diff --git a/src/libstd/sync/rwlock.rs b/src/libstd/sync/rwlock.rs index 944801e8a3bf0..5c5231f4e84a3 100644 --- a/src/libstd/sync/rwlock.rs +++ b/src/libstd/sync/rwlock.rs @@ -370,7 +370,7 @@ impl<'a, T: fmt::Debug> fmt::Debug for RwLockReadGuard<'a, T> { } } -#[stable(feature = "std_guard_impls", since = "1.20")] +#[stable(feature = "std_guard_impls", since = "1.20.0")] impl<'a, T: ?Sized + fmt::Display> fmt::Display for RwLockReadGuard<'a, T> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { (**self).fmt(f) @@ -386,7 +386,7 @@ impl<'a, T: fmt::Debug> fmt::Debug for RwLockWriteGuard<'a, T> { } } -#[stable(feature = "std_guard_impls", since = "1.20")] +#[stable(feature = "std_guard_impls", since = "1.20.0")] impl<'a, T: ?Sized + fmt::Display> fmt::Display for RwLockWriteGuard<'a, T> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { (**self).fmt(f) diff --git a/src/libstd_unicode/char.rs b/src/libstd_unicode/char.rs index d4d8993efb316..d6836418b4b5c 100644 --- a/src/libstd_unicode/char.rs +++ b/src/libstd_unicode/char.rs @@ -38,7 +38,7 @@ use tables::{conversions, derived_property, general_category, property}; pub use core::char::{MAX, from_digit, from_u32, from_u32_unchecked}; #[stable(feature = "rust1", since = "1.0.0")] pub use core::char::{EscapeDebug, EscapeDefault, EscapeUnicode}; -#[stable(feature = "char_from_str", since = "1.19.0")] +#[stable(feature = "char_from_str", since = "1.20.0")] pub use core::char::ParseCharError; // unstable reexports From 133c1bc9ac998d22a0028d2f2e15473f0d1d08ab Mon Sep 17 00:00:00 2001 From: Stefan Schindler Date: Tue, 11 Jul 2017 16:45:39 +0200 Subject: [PATCH 13/13] Wrap long line --- src/libstd/macros.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/libstd/macros.rs b/src/libstd/macros.rs index a45d37b079297..be0d1587aab56 100644 --- a/src/libstd/macros.rs +++ b/src/libstd/macros.rs @@ -26,7 +26,8 @@ /// /// # Current implementation /// -/// If the main thread panics it will terminate all your threads and end your program with code `101`. +/// If the main thread panics it will terminate all your threads and end your +/// program with code `101`. /// /// # Examples ///