From 764e3668b05eeee92e8d81ac748cbb1c76de1a44 Mon Sep 17 00:00:00 2001 From: Stepan Koltsov Date: Mon, 15 Apr 2019 00:00:50 +0100 Subject: [PATCH 1/8] to_xe_bytes for isize and usize returns an array of different size ... on different platforms. Official rustdoc of [`usize::to_le_bytes`](https://doc.rust-lang.org/std/primitive.usize.html#method.to_le_bytes) displays signature ``` pub fn to_ne_bytes(self) -> [u8; 8] ``` which might be misleading: this function returns 4 bytes on 32-bit systems. --- src/libcore/num/mod.rs | 113 ++++++++++++++++++++++++++++++----------- 1 file changed, 83 insertions(+), 30 deletions(-) diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs index c1887a93490..562a7a4b3c7 100644 --- a/src/libcore/num/mod.rs +++ b/src/libcore/num/mod.rs @@ -214,11 +214,31 @@ pub mod diy_float; mod wrapping; +macro_rules! usize_isize_to_xe_bytes_doc { + () => {" + +**Note**: This function returns an array of length 2, 4 or 8 bytes +depending on the target pointer size. + +"} +} + + +macro_rules! usize_isize_from_xe_bytes_doc { + () => {" + +**Note**: This function takes an array of length 2, 4 or 8 bytes +depending on the target pointer size. + +"} +} + // `Int` + `SignedInt` implemented for signed integers macro_rules! int_impl { ($SelfT:ty, $ActualT:ident, $UnsignedT:ty, $BITS:expr, $Min:expr, $Max:expr, $Feature:expr, $EndFeature:expr, $rot:expr, $rot_op:expr, $rot_result:expr, $swap_op:expr, $swapped:expr, - $reversed:expr, $le_bytes:expr, $be_bytes:expr) => { + $reversed:expr, $le_bytes:expr, $be_bytes:expr, + $to_xe_bytes_doc:expr, $from_xe_bytes_doc:expr) => { doc_comment! { concat!("Returns the smallest value that can be represented by this integer type. @@ -2023,7 +2043,9 @@ $EndFeature, " doc_comment! { concat!("Return the memory representation of this integer as a byte array in big-endian (network) byte order. - +", +$to_xe_bytes_doc, +" # Examples ``` @@ -2041,7 +2063,9 @@ assert_eq!(bytes, ", $be_bytes, "); doc_comment! { concat!("Return the memory representation of this integer as a byte array in little-endian byte order. - +", +$to_xe_bytes_doc, +" # Examples ``` @@ -2064,7 +2088,9 @@ native byte order. As the target platform's native endianness is used, portable code should use [`to_be_bytes`] or [`to_le_bytes`], as appropriate, instead. - +", +$to_xe_bytes_doc, +" [`to_be_bytes`]: #method.to_be_bytes [`to_le_bytes`]: #method.to_le_bytes @@ -2089,7 +2115,9 @@ assert_eq!(bytes, if cfg!(target_endian = \"big\") { doc_comment! { concat!("Create an integer value from its representation as a byte array in big endian. - +", +$from_xe_bytes_doc, +" # Examples ``` @@ -2120,7 +2148,9 @@ doc_comment! { concat!(" Create an integer value from its representation as a byte array in little endian. - +", +$from_xe_bytes_doc, +" # Examples ``` @@ -2157,7 +2187,9 @@ appropriate instead. [`from_be_bytes`]: #method.from_be_bytes [`from_le_bytes`]: #method.from_le_bytes - +", +$from_xe_bytes_doc, +" # Examples ``` @@ -2193,20 +2225,20 @@ fn read_ne_", stringify!($SelfT), "(input: &mut &[u8]) -> ", stringify!($SelfT), #[lang = "i8"] impl i8 { int_impl! { i8, i8, u8, 8, -128, 127, "", "", 2, "-0x7e", "0xa", "0x12", "0x12", "0x48", - "[0x12]", "[0x12]" } + "[0x12]", "[0x12]", "", "" } } #[lang = "i16"] impl i16 { int_impl! { i16, i16, u16, 16, -32768, 32767, "", "", 4, "-0x5ffd", "0x3a", "0x1234", "0x3412", - "0x2c48", "[0x34, 0x12]", "[0x12, 0x34]" } + "0x2c48", "[0x34, 0x12]", "[0x12, 0x34]", "", "" } } #[lang = "i32"] impl i32 { int_impl! { i32, i32, u32, 32, -2147483648, 2147483647, "", "", 8, "0x10000b3", "0xb301", "0x12345678", "0x78563412", "0x1e6a2c48", "[0x78, 0x56, 0x34, 0x12]", - "[0x12, 0x34, 0x56, 0x78]" } + "[0x12, 0x34, 0x56, 0x78]", "", "" } } #[lang = "i64"] @@ -2214,7 +2246,7 @@ impl i64 { int_impl! { i64, i64, u64, 64, -9223372036854775808, 9223372036854775807, "", "", 12, "0xaa00000000006e1", "0x6e10aa", "0x1234567890123456", "0x5634129078563412", "0x6a2c48091e6a2c48", "[0x56, 0x34, 0x12, 0x90, 0x78, 0x56, 0x34, 0x12]", - "[0x12, 0x34, 0x56, 0x78, 0x90, 0x12, 0x34, 0x56]" } + "[0x12, 0x34, 0x56, 0x78, 0x90, 0x12, 0x34, 0x56]", "", "" } } #[lang = "i128"] @@ -2226,14 +2258,15 @@ impl i128 { "[0x12, 0x90, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78, \ 0x56, 0x34, 0x12, 0x90, 0x78, 0x56, 0x34, 0x12]", "[0x12, 0x34, 0x56, 0x78, 0x90, 0x12, 0x34, 0x56, \ - 0x78, 0x90, 0x12, 0x34, 0x56, 0x78, 0x90, 0x12]" } + 0x78, 0x90, 0x12, 0x34, 0x56, 0x78, 0x90, 0x12]", "", "" } } #[cfg(target_pointer_width = "16")] #[lang = "isize"] impl isize { int_impl! { isize, i16, u16, 16, -32768, 32767, "", "", 4, "-0x5ffd", "0x3a", "0x1234", - "0x3412", "0x2c48", "[0x34, 0x12]", "[0x12, 0x34]" } + "0x3412", "0x2c48", "[0x34, 0x12]", "[0x12, 0x34]", + usize_isize_to_xe_bytes_doc!(), usize_isize_from_xe_bytes_doc!() } } #[cfg(target_pointer_width = "32")] @@ -2241,7 +2274,8 @@ impl isize { impl isize { int_impl! { isize, i32, u32, 32, -2147483648, 2147483647, "", "", 8, "0x10000b3", "0xb301", "0x12345678", "0x78563412", "0x1e6a2c48", "[0x78, 0x56, 0x34, 0x12]", - "[0x12, 0x34, 0x56, 0x78]" } + "[0x12, 0x34, 0x56, 0x78]", + usize_isize_to_xe_bytes_doc!(), usize_isize_from_xe_bytes_doc!() } } #[cfg(target_pointer_width = "64")] @@ -2250,14 +2284,16 @@ impl isize { int_impl! { isize, i64, u64, 64, -9223372036854775808, 9223372036854775807, "", "", 12, "0xaa00000000006e1", "0x6e10aa", "0x1234567890123456", "0x5634129078563412", "0x6a2c48091e6a2c48", "[0x56, 0x34, 0x12, 0x90, 0x78, 0x56, 0x34, 0x12]", - "[0x12, 0x34, 0x56, 0x78, 0x90, 0x12, 0x34, 0x56]" } + "[0x12, 0x34, 0x56, 0x78, 0x90, 0x12, 0x34, 0x56]", + usize_isize_to_xe_bytes_doc!(), usize_isize_from_xe_bytes_doc!() } } // `Int` + `UnsignedInt` implemented for unsigned integers macro_rules! uint_impl { ($SelfT:ty, $ActualT:ty, $BITS:expr, $MaxV:expr, $Feature:expr, $EndFeature:expr, $rot:expr, $rot_op:expr, $rot_result:expr, $swap_op:expr, $swapped:expr, - $reversed:expr, $le_bytes:expr, $be_bytes:expr) => { + $reversed:expr, $le_bytes:expr, $be_bytes:expr, + $to_xe_bytes_doc:expr, $from_xe_bytes_doc:expr) => { doc_comment! { concat!("Returns the smallest value that can be represented by this integer type. @@ -3817,7 +3853,9 @@ $EndFeature, " doc_comment! { concat!("Return the memory representation of this integer as a byte array in big-endian (network) byte order. - +", +$to_xe_bytes_doc, +" # Examples ``` @@ -3835,7 +3873,9 @@ assert_eq!(bytes, ", $be_bytes, "); doc_comment! { concat!("Return the memory representation of this integer as a byte array in little-endian byte order. - +", +$to_xe_bytes_doc, +" # Examples ``` @@ -3858,7 +3898,9 @@ native byte order. As the target platform's native endianness is used, portable code should use [`to_be_bytes`] or [`to_le_bytes`], as appropriate, instead. - +", +$to_xe_bytes_doc, +" [`to_be_bytes`]: #method.to_be_bytes [`to_le_bytes`]: #method.to_le_bytes @@ -3883,7 +3925,9 @@ assert_eq!(bytes, if cfg!(target_endian = \"big\") { doc_comment! { concat!("Create an integer value from its representation as a byte array in big endian. - +", +$from_xe_bytes_doc, +" # Examples ``` @@ -3914,7 +3958,9 @@ fn read_be_", stringify!($SelfT), "(input: &mut &[u8]) -> ", stringify!($SelfT), concat!(" Create an integer value from its representation as a byte array in little endian. - +", +$from_xe_bytes_doc, +" # Examples ``` @@ -3951,7 +3997,9 @@ appropriate instead. [`from_be_bytes`]: #method.from_be_bytes [`from_le_bytes`]: #method.from_le_bytes - +", +$from_xe_bytes_doc, +" # Examples ``` @@ -3987,7 +4035,7 @@ fn read_ne_", stringify!($SelfT), "(input: &mut &[u8]) -> ", stringify!($SelfT), #[lang = "u8"] impl u8 { uint_impl! { u8, u8, 8, 255, "", "", 2, "0x82", "0xa", "0x12", "0x12", "0x48", "[0x12]", - "[0x12]" } + "[0x12]", "", "" } /// Checks if the value is within the ASCII range. @@ -4506,13 +4554,13 @@ impl u8 { #[lang = "u16"] impl u16 { uint_impl! { u16, u16, 16, 65535, "", "", 4, "0xa003", "0x3a", "0x1234", "0x3412", "0x2c48", - "[0x34, 0x12]", "[0x12, 0x34]" } + "[0x34, 0x12]", "[0x12, 0x34]", "", "" } } #[lang = "u32"] impl u32 { uint_impl! { u32, u32, 32, 4294967295, "", "", 8, "0x10000b3", "0xb301", "0x12345678", - "0x78563412", "0x1e6a2c48", "[0x78, 0x56, 0x34, 0x12]", "[0x12, 0x34, 0x56, 0x78]" } + "0x78563412", "0x1e6a2c48", "[0x78, 0x56, 0x34, 0x12]", "[0x12, 0x34, 0x56, 0x78]", "", "" } } #[lang = "u64"] @@ -4520,7 +4568,8 @@ impl u64 { uint_impl! { u64, u64, 64, 18446744073709551615, "", "", 12, "0xaa00000000006e1", "0x6e10aa", "0x1234567890123456", "0x5634129078563412", "0x6a2c48091e6a2c48", "[0x56, 0x34, 0x12, 0x90, 0x78, 0x56, 0x34, 0x12]", - "[0x12, 0x34, 0x56, 0x78, 0x90, 0x12, 0x34, 0x56]" } + "[0x12, 0x34, 0x56, 0x78, 0x90, 0x12, 0x34, 0x56]", + "", ""} } #[lang = "u128"] @@ -4531,20 +4580,23 @@ impl u128 { "[0x12, 0x90, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78, \ 0x56, 0x34, 0x12, 0x90, 0x78, 0x56, 0x34, 0x12]", "[0x12, 0x34, 0x56, 0x78, 0x90, 0x12, 0x34, 0x56, \ - 0x78, 0x90, 0x12, 0x34, 0x56, 0x78, 0x90, 0x12]" } + 0x78, 0x90, 0x12, 0x34, 0x56, 0x78, 0x90, 0x12]", + "", ""} } #[cfg(target_pointer_width = "16")] #[lang = "usize"] impl usize { uint_impl! { usize, u16, 16, 65535, "", "", 4, "0xa003", "0x3a", "0x1234", "0x3412", "0x2c48", - "[0x34, 0x12]", "[0x12, 0x34]" } + "[0x34, 0x12]", "[0x12, 0x34]", + usize_isize_to_xe_bytes_doc!(), usize_isize_from_xe_bytes_doc!() } } #[cfg(target_pointer_width = "32")] #[lang = "usize"] impl usize { uint_impl! { usize, u32, 32, 4294967295, "", "", 8, "0x10000b3", "0xb301", "0x12345678", - "0x78563412", "0x1e6a2c48", "[0x78, 0x56, 0x34, 0x12]", "[0x12, 0x34, 0x56, 0x78]" } + "0x78563412", "0x1e6a2c48", "[0x78, 0x56, 0x34, 0x12]", "[0x12, 0x34, 0x56, 0x78]", + usize_isize_to_xe_bytes_doc!(), usize_isize_from_xe_bytes_doc!() } } #[cfg(target_pointer_width = "64")] @@ -4553,7 +4605,8 @@ impl usize { uint_impl! { usize, u64, 64, 18446744073709551615, "", "", 12, "0xaa00000000006e1", "0x6e10aa", "0x1234567890123456", "0x5634129078563412", "0x6a2c48091e6a2c48", "[0x56, 0x34, 0x12, 0x90, 0x78, 0x56, 0x34, 0x12]", - "[0x12, 0x34, 0x56, 0x78, 0x90, 0x12, 0x34, 0x56]" } + "[0x12, 0x34, 0x56, 0x78, 0x90, 0x12, 0x34, 0x56]", + usize_isize_to_xe_bytes_doc!(), usize_isize_from_xe_bytes_doc!() } } /// A classification of floating point numbers. From 2e789b9f0dd4d288e09881c1152f30a9fb456f75 Mon Sep 17 00:00:00 2001 From: Tyler Mandry Date: Sun, 5 May 2019 17:23:47 -0700 Subject: [PATCH 2/8] Add test for #59972 --- src/test/run-pass/generator/issue-59972.rs | 23 ++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 src/test/run-pass/generator/issue-59972.rs diff --git a/src/test/run-pass/generator/issue-59972.rs b/src/test/run-pass/generator/issue-59972.rs new file mode 100644 index 00000000000..995da4fb3ff --- /dev/null +++ b/src/test/run-pass/generator/issue-59972.rs @@ -0,0 +1,23 @@ +// compile-flags: --edition=2018 + +#![feature(async_await, await_macro)] + +pub enum Uninhabited { } + +fn uninhabited_async() -> Uninhabited { + unreachable!() +} + +async fn noop() { } + +#[allow(unused)] +async fn contains_never() { + let error = uninhabited_async(); + await!(noop()); + let error2 = error; +} + +#[allow(unused_must_use)] +fn main() { + contains_never(); +} From bfa15f39888a514f1eb164e210cf5d85b33146e1 Mon Sep 17 00:00:00 2001 From: ben Date: Sun, 5 May 2019 08:41:39 +1200 Subject: [PATCH 3/8] Add tests for concrete const types --- .../concrete-const-as-fn-arg.rs | 14 +++++++++++ .../concrete-const-as-fn-arg.stderr | 6 +++++ .../concrete-const-impl-method.rs | 24 +++++++++++++++++++ .../concrete-const-impl-method.stderr | 6 +++++ 4 files changed, 50 insertions(+) create mode 100644 src/test/ui/const-generics/concrete-const-as-fn-arg.rs create mode 100644 src/test/ui/const-generics/concrete-const-as-fn-arg.stderr create mode 100644 src/test/ui/const-generics/concrete-const-impl-method.rs create mode 100644 src/test/ui/const-generics/concrete-const-impl-method.stderr diff --git a/src/test/ui/const-generics/concrete-const-as-fn-arg.rs b/src/test/ui/const-generics/concrete-const-as-fn-arg.rs new file mode 100644 index 00000000000..54981b77a2b --- /dev/null +++ b/src/test/ui/const-generics/concrete-const-as-fn-arg.rs @@ -0,0 +1,14 @@ +// Test that a concrete const type i.e. A<2>, can be used as an argument type in a function +// run-pass + +#![feature(const_generics)] +//~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash + +struct A; // ok + +fn with_concrete_const_arg(_: A<2>) -> u32 { 17 } + +fn main() { + let val: A<2> = A; + assert_eq!(with_concrete_const_arg(val), 17); +} diff --git a/src/test/ui/const-generics/concrete-const-as-fn-arg.stderr b/src/test/ui/const-generics/concrete-const-as-fn-arg.stderr new file mode 100644 index 00000000000..955b319d700 --- /dev/null +++ b/src/test/ui/const-generics/concrete-const-as-fn-arg.stderr @@ -0,0 +1,6 @@ +warning: the feature `const_generics` is incomplete and may cause the compiler to crash + --> $DIR/concrete-const-as-fn-arg.rs:4:12 + | +LL | #![feature(const_generics)] + | ^^^^^^^^^^^^^^ + diff --git a/src/test/ui/const-generics/concrete-const-impl-method.rs b/src/test/ui/const-generics/concrete-const-impl-method.rs new file mode 100644 index 00000000000..226ea415180 --- /dev/null +++ b/src/test/ui/const-generics/concrete-const-impl-method.rs @@ -0,0 +1,24 @@ +// Test that a method/associated non-method within an impl block of a concrete const type i.e. A<2>, +// is callable. +// run-pass + +#![feature(const_generics)] +//~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash + +pub struct A; + +impl A<2> { + fn impl_method(&self) -> u32 { + 17 + } + + fn associated_non_method() -> u32 { + 17 + } +} + +fn main() { + let val: A<2> = A; + assert_eq!(val.impl_method(), 17); + assert_eq!(A::<2>::associated_non_method(), 17); +} diff --git a/src/test/ui/const-generics/concrete-const-impl-method.stderr b/src/test/ui/const-generics/concrete-const-impl-method.stderr new file mode 100644 index 00000000000..3ce488c6275 --- /dev/null +++ b/src/test/ui/const-generics/concrete-const-impl-method.stderr @@ -0,0 +1,6 @@ +warning: the feature `const_generics` is incomplete and may cause the compiler to crash + --> $DIR/concrete-const-impl-method.rs:5:12 + | +LL | #![feature(const_generics)] + | ^^^^^^^^^^^^^^ + From c87d2ccf88f1b9ca039d18530fd474e5ad868bc4 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Wed, 8 May 2019 09:56:26 +0300 Subject: [PATCH 4/8] test for #50518 It was fixed somewhere between 1.28.0 and 1.31.1 closes #50518 --- src/test/ui/issues/issue-50518.rs | 40 +++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 src/test/ui/issues/issue-50518.rs diff --git a/src/test/ui/issues/issue-50518.rs b/src/test/ui/issues/issue-50518.rs new file mode 100644 index 00000000000..d776d181b62 --- /dev/null +++ b/src/test/ui/issues/issue-50518.rs @@ -0,0 +1,40 @@ +// compile-pass +use std::marker::PhantomData; + +struct Meta { + value: i32, + type_: PhantomData +} + +trait MetaTrait { + fn get_value(&self) -> i32; +} + +impl MetaTrait for Meta { + fn get_value(&self) -> i32 { self.value } +} + +trait Bar { + fn get_const(&self) -> &dyn MetaTrait; +} + +struct Foo { + _value: A +} + +impl Foo { + const CONST: &'static dyn MetaTrait = &Meta:: { + value: 10, + type_: PhantomData + }; +} + +impl Bar for Foo { + fn get_const(&self) -> &dyn MetaTrait { Self::CONST } +} + +fn main() { + let foo = Foo:: { _value: 10 }; + let bar: &dyn Bar = &foo; + println!("const {}", bar.get_const().get_value()); +} From 47768b2613393e39218c255ed990169665d69df9 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Wed, 8 May 2019 03:05:32 +0200 Subject: [PATCH 5/8] Document + Cleanup lang_items.rs --- src/librustc/middle/lang_items.rs | 97 +++++++++++++++++++------------ 1 file changed, 60 insertions(+), 37 deletions(-) diff --git a/src/librustc/middle/lang_items.rs b/src/librustc/middle/lang_items.rs index 5d809f14071..0e283ca6b1c 100644 --- a/src/librustc/middle/lang_items.rs +++ b/src/librustc/middle/lang_items.rs @@ -1,13 +1,13 @@ -// Detecting language items. -// -// Language items are items that represent concepts intrinsic to the language -// itself. Examples are: -// -// * Traits that specify "kinds"; e.g., "Sync", "Send". -// -// * Traits that represent operators; e.g., "Add", "Sub", "Index". -// -// * Functions called by the compiler itself. +//! Detecting language items. +//! +//! Language items are items that represent concepts intrinsic to the language +//! itself. Examples are: +//! +//! * Traits that specify "kinds"; e.g., "Sync", "Send". +//! +//! * Traits that represent operators; e.g., "Add", "Sub", "Index". +//! +//! * Functions called by the compiler itself. pub use self::LangItem::*; @@ -32,6 +32,7 @@ macro_rules! language_item_table { ) => { enum_from_u32! { + /// A representation of all the valid language items in Rust. #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)] pub enum LangItem { $($variant,)* @@ -39,6 +40,9 @@ enum_from_u32! { } impl LangItem { + /// Returns the `name` in `#[lang = "$name"]`. + /// For example, `LangItem::EqTraitLangItem`, + /// that is `#[lang = "eq"]` would result in `"eq"`. fn name(self) -> &'static str { match self { $( $variant => $name, )* @@ -48,28 +52,38 @@ impl LangItem { #[derive(HashStable)] pub struct LanguageItems { + /// Mappings from lang items to their possibly found `DefId`s. + /// The index corresponds to the order in `LangItem`. pub items: Vec>, + /// Lang items that were not found during collection. pub missing: Vec, } impl LanguageItems { - pub fn new() -> LanguageItems { - fn foo(_: LangItem) -> Option { None } + /// Construct an empty collection of lang items and no missing ones. + pub fn new() -> Self { + fn init_none(_: LangItem) -> Option { None } - LanguageItems { - items: vec![$(foo($variant)),*], + Self { + items: vec![$(init_none($variant)),*], missing: Vec::new(), } } + /// Returns the mappings to the possibly found `DefId`s for each lang item. pub fn items(&self) -> &[Option] { &*self.items } + /// Requires that a given `LangItem` was bound and returns the corresponding `DefId`. + /// If it wasn't bound, e.g. due to a missing `#[lang = ""]`, + /// returns an error message as a string. pub fn require(&self, it: LangItem) -> Result { self.items[it as usize].ok_or_else(|| format!("requires `{}` lang_item", it.name())) } + /// Returns the kind of closure that `id`, which is one of the `Fn*` traits, corresponds to. + /// If `id` is not one of the `Fn*` traits, `None` is returned. pub fn fn_trait_kind(&self, id: DefId) -> Option { match Some(id) { x if x == self.fn_trait() => Some(ty::ClosureKind::Fn), @@ -80,6 +94,9 @@ impl LanguageItems { } $( + /// Returns the corresponding `DefId` for the lang item + #[doc = $name] + /// if it exists. #[allow(dead_code)] pub fn $method(&self) -> Option { self.items[$variant as usize] @@ -90,6 +107,7 @@ impl LanguageItems { struct LanguageItemCollector<'a, 'tcx: 'a> { items: LanguageItems, tcx: TyCtxt<'a, 'tcx, 'tcx>, + /// A mapping from the name of the lang item to its order and the form it must be of. item_refs: FxHashMap<&'static str, (usize, Target)>, } @@ -105,32 +123,28 @@ impl<'a, 'v, 'tcx> ItemLikeVisitor<'v> for LanguageItemCollector<'a, 'tcx> { }, // Known lang item with attribute on incorrect target. Some((_, expected_target)) => { - let mut err = struct_span_err!( + struct_span_err!( self.tcx.sess, span, E0718, "`{}` language item must be applied to a {}", value, expected_target, - ); - err.span_label( + ).span_label( span, format!( "attribute should be applied to a {}, not a {}", expected_target, actual_target, ), - ); - err.emit(); + ).emit(); }, // Unknown lang item. _ => { - let mut err = struct_span_err!( + struct_span_err!( self.tcx.sess, span, E0522, "definition of an unknown language item: `{}`", value - ); - err.span_label( + ).span_label( span, format!("definition of unknown language item `{}`", value) - ); - err.emit(); + ).emit(); }, } } @@ -190,32 +204,39 @@ impl<'a, 'tcx> LanguageItemCollector<'a, 'tcx> { } } +/// Extract the first `lang = "$name"` out of a list of attributes. +/// The attributes `#[panic_handler]` and `#[alloc_error_handler]` +/// are also extracted out when found. pub fn extract(attrs: &[ast::Attribute]) -> Option<(Symbol, Span)> { - for attribute in attrs { - if attribute.check_name("lang") { - if let Some(value) = attribute.value_str() { - return Some((value, attribute.span)); - } - } else if attribute.check_name("panic_handler") { - return Some((Symbol::intern("panic_impl"), attribute.span)) - } else if attribute.check_name("alloc_error_handler") { - return Some((Symbol::intern("oom"), attribute.span)) - } - } - - None + attrs.iter().find_map(|attr| Some(match attr { + _ if attr.check_name("lang") => (attr.value_str()?, attr.span), + _ if attr.check_name("panic_handler") => (Symbol::intern("panic_impl"), attr.span), + _ if attr.check_name("alloc_error_handler") => (Symbol::intern("oom"), attr.span), + _ => return None, + })) } +/// Traverse and collect all the lang items in all crates. pub fn collect<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> LanguageItems { + // Initialize the collector. let mut collector = LanguageItemCollector::new(tcx); + + // Collect lang items in other crates. for &cnum in tcx.crates().iter() { for &(def_id, item_index) in tcx.defined_lang_items(cnum).iter() { collector.collect_item(item_index, def_id); } } + + // Collect lang items in this crate. tcx.hir().krate().visit_all_item_likes(&mut collector); + + // Extract out the found lang items. let LanguageItemCollector { mut items, .. } = collector; + + // Find all required but not-yet-defined lang items. weak_lang_items::check_crate(tcx, &mut items); + items } @@ -382,6 +403,8 @@ language_item_table! { } impl<'a, 'tcx, 'gcx> TyCtxt<'a, 'tcx, 'gcx> { + /// Returns the `DefId` for a given `LangItem`. + /// If not found, fatally abort compilation. pub fn require_lang_item(&self, lang_item: LangItem) -> DefId { self.lang_items().require(lang_item).unwrap_or_else(|msg| { self.sess.fatal(&msg) From 7e8035593d1900dc9db05b5aaf92d421d248eb22 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Thu, 2 May 2019 15:24:40 -0700 Subject: [PATCH 6/8] std: Update compiler-builtins crate Pulls in a fix for ensuring that wasm targets have code in compiler-builtins for `ldexp` which LLVM can generate references to. --- Cargo.lock | 34 +++++++++++++++++----------------- src/libstd/Cargo.toml | 2 +- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ff66b4a0372..0154b96751d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -17,7 +17,7 @@ dependencies = [ name = "alloc" version = "0.0.0" dependencies = [ - "compiler_builtins 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "compiler_builtins 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", "core 0.0.0", "rand 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "rand_xorshift 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -115,7 +115,7 @@ version = "0.1.27" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cc 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)", - "compiler_builtins 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "compiler_builtins 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-std-workspace-core 1.0.0", ] @@ -450,7 +450,7 @@ dependencies = [ [[package]] name = "compiler_builtins" -version = "0.1.10" +version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cc 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)", @@ -736,7 +736,7 @@ name = "dlmalloc" version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "compiler_builtins 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "compiler_builtins 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-std-workspace-core 1.0.0", ] @@ -902,7 +902,7 @@ name = "fortanix-sgx-abi" version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "compiler_builtins 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "compiler_builtins 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-std-workspace-core 1.0.0", ] @@ -1063,7 +1063,7 @@ name = "hashbrown" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "compiler_builtins 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "compiler_builtins 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-std-workspace-alloc 1.0.0", "rustc-std-workspace-core 1.0.0", ] @@ -1764,7 +1764,7 @@ dependencies = [ name = "panic_abort" version = "0.0.0" dependencies = [ - "compiler_builtins 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "compiler_builtins 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", "core 0.0.0", "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1774,7 +1774,7 @@ name = "panic_unwind" version = "0.0.0" dependencies = [ "alloc 0.0.0", - "compiler_builtins 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "compiler_builtins 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", "core 0.0.0", "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", "unwind 0.0.0", @@ -1959,7 +1959,7 @@ name = "profiler_builtins" version = "0.0.0" dependencies = [ "cc 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)", - "compiler_builtins 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "compiler_builtins 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", "core 0.0.0", ] @@ -2484,7 +2484,7 @@ name = "rustc-demangle" version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "compiler_builtins 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "compiler_builtins 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-std-workspace-core 1.0.0", ] @@ -2612,7 +2612,7 @@ dependencies = [ "alloc 0.0.0", "build_helper 0.1.0", "cmake 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)", - "compiler_builtins 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "compiler_builtins 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", "core 0.0.0", ] @@ -2842,7 +2842,7 @@ dependencies = [ "alloc 0.0.0", "build_helper 0.1.0", "cmake 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)", - "compiler_builtins 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "compiler_builtins 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", "core 0.0.0", ] @@ -2904,7 +2904,7 @@ dependencies = [ "alloc 0.0.0", "build_helper 0.1.0", "cmake 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)", - "compiler_builtins 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "compiler_builtins 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", "core 0.0.0", ] @@ -3021,7 +3021,7 @@ dependencies = [ "alloc 0.0.0", "build_helper 0.1.0", "cmake 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)", - "compiler_builtins 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "compiler_builtins 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", "core 0.0.0", ] @@ -3290,7 +3290,7 @@ dependencies = [ "alloc 0.0.0", "backtrace-sys 0.1.27 (registry+https://github.com/rust-lang/crates.io-index)", "cc 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)", - "compiler_builtins 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "compiler_builtins 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", "core 0.0.0", "dlmalloc 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "fortanix-sgx-abi 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3882,7 +3882,7 @@ name = "unwind" version = "0.0.0" dependencies = [ "cc 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)", - "compiler_builtins 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "compiler_builtins 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", "core 0.0.0", "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -4078,7 +4078,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum colored 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b0aa3473e85a3161b59845d6096b289bb577874cafeaf75ea1b1beaa6572c7fc" "checksum commoncrypto 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d056a8586ba25a1e4d61cb090900e495952c7886786fc55f909ab2f819b69007" "checksum commoncrypto-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1fed34f46747aa73dfaa578069fd8279d2818ade2b55f38f22a9401c7f4083e2" -"checksum compiler_builtins 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4ada53ac629568219809178f988ca2aac9889e9a847379588c097d30ce185145" +"checksum compiler_builtins 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "6549720ae78db799196d4af8f719facb4c7946710b4b64148482553e54b56d15" "checksum compiletest_rs 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)" = "f40ecc9332b68270998995c00f8051ee856121764a0d3230e64c9efd059d27b6" "checksum constant_time_eq 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8ff012e225ce166d4422e0e78419d901719760f62ae2b7969ca6b564d1b54a9e" "checksum core-foundation 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4e2640d6d0bf22e82bed1b73c6aef8d5dd31e5abe6666c57e6d45e2649f4f887" diff --git a/src/libstd/Cargo.toml b/src/libstd/Cargo.toml index ac1aff845d8..ad5d62f667a 100644 --- a/src/libstd/Cargo.toml +++ b/src/libstd/Cargo.toml @@ -19,7 +19,7 @@ panic_unwind = { path = "../libpanic_unwind", optional = true } panic_abort = { path = "../libpanic_abort" } core = { path = "../libcore" } libc = { version = "0.2.51", default-features = false, features = ['rustc-dep-of-std'] } -compiler_builtins = { version = "0.1.9" } +compiler_builtins = { version = "0.1.12" } profiler_builtins = { path = "../libprofiler_builtins", optional = true } unwind = { path = "../libunwind" } hashbrown = { version = "0.3.0", features = ['rustc-dep-of-std'] } From cc40f41ee5baefa0dc1845dd9d794abe90511161 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Wed, 8 May 2019 10:23:55 -0700 Subject: [PATCH 7/8] Instead of ICEing on incorrect pattern, use delay_span_bug --- src/librustc/middle/mem_categorization.rs | 12 ++++++++++-- src/test/ui/fn-in-pat.rs | 16 ++++++++++++++++ src/test/ui/fn-in-pat.stderr | 9 +++++++++ 3 files changed, 35 insertions(+), 2 deletions(-) create mode 100644 src/test/ui/fn-in-pat.rs create mode 100644 src/test/ui/fn-in-pat.stderr diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs index f6caf357b39..7edd5c5a9de 100644 --- a/src/librustc/middle/mem_categorization.rs +++ b/src/librustc/middle/mem_categorization.rs @@ -1300,8 +1300,16 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> { } } def => { - span_bug!(pat.span, "tuple struct pattern didn't resolve \ - to variant or struct {:?}", def); + debug!( + "tuple struct pattern didn't resolve to variant or struct {:?} at {:?}", + def, + pat.span, + ); + self.tcx.sess.delay_span_bug(pat.span, &format!( + "tuple struct pattern didn't resolve to variant or struct {:?}", + def, + )); + return Err(()); } }; diff --git a/src/test/ui/fn-in-pat.rs b/src/test/ui/fn-in-pat.rs new file mode 100644 index 00000000000..ed76b2c5db0 --- /dev/null +++ b/src/test/ui/fn-in-pat.rs @@ -0,0 +1,16 @@ +struct A {} + +impl A { + fn new() {} +} + +fn hof(_: F) where F: FnMut(()) {} + +fn ice() { + hof(|c| match c { + A::new() => (), //~ ERROR expected tuple struct/variant, found method + _ => () + }) +} + +fn main() {} diff --git a/src/test/ui/fn-in-pat.stderr b/src/test/ui/fn-in-pat.stderr new file mode 100644 index 00000000000..eee97fe9587 --- /dev/null +++ b/src/test/ui/fn-in-pat.stderr @@ -0,0 +1,9 @@ +error[E0164]: expected tuple struct/variant, found method `::new` + --> $DIR/fn-in-pat.rs:11:9 + | +LL | A::new() => (), + | ^^^^^^^^ not a tuple variant or struct + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0164`. From 0fce5c1bf0b5f12d4e3efe8d31b1df576d5abf45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Wed, 8 May 2019 11:42:47 -0700 Subject: [PATCH 8/8] Use `delay_span_bug` for "Failed to unify obligation" --- src/librustc/traits/project.rs | 15 ++++++++---- src/test/ui/issues/issue-60283.rs | 17 ++++++++++++++ src/test/ui/issues/issue-60283.stderr | 34 +++++++++++++++++++++++++++ 3 files changed, 61 insertions(+), 5 deletions(-) create mode 100644 src/test/ui/issues/issue-60283.rs create mode 100644 src/test/ui/issues/issue-60283.stderr diff --git a/src/librustc/traits/project.rs b/src/librustc/traits/project.rs index dabb8a72890..b5232e828c4 100644 --- a/src/librustc/traits/project.rs +++ b/src/librustc/traits/project.rs @@ -1454,13 +1454,18 @@ fn confirm_param_env_candidate<'cx, 'gcx, 'tcx>( } } Err(e) => { - span_bug!( - obligation.cause.span, - "Failed to unify obligation `{:?}` \ - with poly_projection `{:?}`: {:?}", + let msg = format!( + "Failed to unify obligation `{:?}` with poly_projection `{:?}`: {:?}", obligation, poly_cache_entry, - e); + e, + ); + debug!("confirm_param_env_candidate: {}", msg); + infcx.tcx.sess.delay_span_bug(obligation.cause.span, &msg); + Progress { + ty: infcx.tcx.types.err, + obligations: vec![], + } } } } diff --git a/src/test/ui/issues/issue-60283.rs b/src/test/ui/issues/issue-60283.rs new file mode 100644 index 00000000000..e5a9caa32fa --- /dev/null +++ b/src/test/ui/issues/issue-60283.rs @@ -0,0 +1,17 @@ +pub trait Trait<'a> { + type Item; +} + +impl<'a> Trait<'a> for () { + type Item = (); +} + +pub fn foo(_: T, _: F) +where T: for<'a> Trait<'a>, + F: for<'a> FnMut(>::Item) {} + +fn main() { + foo((), drop) + //~^ ERROR type mismatch in function arguments + //~| ERROR type mismatch resolving +} diff --git a/src/test/ui/issues/issue-60283.stderr b/src/test/ui/issues/issue-60283.stderr new file mode 100644 index 00000000000..a79b1959dca --- /dev/null +++ b/src/test/ui/issues/issue-60283.stderr @@ -0,0 +1,34 @@ +error[E0631]: type mismatch in function arguments + --> $DIR/issue-60283.rs:14:5 + | +LL | foo((), drop) + | ^^^ + | | + | expected signature of `for<'a> fn(<() as Trait<'a>>::Item) -> _` + | found signature of `fn(_) -> _` + | +note: required by `foo` + --> $DIR/issue-60283.rs:9:1 + | +LL | / pub fn foo(_: T, _: F) +LL | | where T: for<'a> Trait<'a>, +LL | | F: for<'a> FnMut(>::Item) {} + | |_________________________________________________^ + +error[E0271]: type mismatch resolving `for<'a> } as std::ops::FnOnce<(<() as Trait<'a>>::Item,)>>::Output == ()` + --> $DIR/issue-60283.rs:14:5 + | +LL | foo((), drop) + | ^^^ expected bound lifetime parameter 'a, found concrete lifetime + | +note: required by `foo` + --> $DIR/issue-60283.rs:9:1 + | +LL | / pub fn foo(_: T, _: F) +LL | | where T: for<'a> Trait<'a>, +LL | | F: for<'a> FnMut(>::Item) {} + | |_________________________________________________^ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0271`.