From 112a3473d046c7f2e677de2b71259649b9e4b9fd Mon Sep 17 00:00:00 2001 From: Kinrany Date: Sat, 20 Jul 2019 23:12:57 +0300 Subject: [PATCH 01/18] Fix theme picker blur handler: always hide instead of switching --- src/librustdoc/html/render.rs | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index 3cd520fd4b50b..c5cc04b9af555 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -874,15 +874,23 @@ fn write_shared( r#"var themes = document.getElementById("theme-choices"); var themePicker = document.getElementById("theme-picker"); +function showThemeButtonState() {{ + themes.style.display = "none"; + themePicker.style.borderBottomRightRadius = "3px"; + themePicker.style.borderBottomLeftRadius = "3px"; +}} + +function hideThemeButtonState() {{ + themes.style.display = "block"; + themePicker.style.borderBottomRightRadius = "0"; + themePicker.style.borderBottomLeftRadius = "0"; +}} + function switchThemeButtonState() {{ if (themes.style.display === "block") {{ - themes.style.display = "none"; - themePicker.style.borderBottomRightRadius = "3px"; - themePicker.style.borderBottomLeftRadius = "3px"; + showThemeButtonState(); }} else {{ - themes.style.display = "block"; - themePicker.style.borderBottomRightRadius = "0"; - themePicker.style.borderBottomLeftRadius = "0"; + hideThemeButtonState(); }} }}; @@ -895,7 +903,7 @@ function handleThemeButtonsBlur(e) {{ (!related || (related.id !== "themePicker" && (!related.parentNode || related.parentNode.id !== "theme-choices")))) {{ - switchThemeButtonState(); + hideThemeButtonState(); }} }} From 3e39ac718809c147141d4b6ed02b5db4a6779397 Mon Sep 17 00:00:00 2001 From: Kinrany Date: Sat, 20 Jul 2019 23:40:30 +0300 Subject: [PATCH 02/18] Update render.rs --- src/librustdoc/html/render.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index c5cc04b9af555..3234889ca7cda 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -885,7 +885,7 @@ function hideThemeButtonState() {{ themePicker.style.borderBottomRightRadius = "0"; themePicker.style.borderBottomLeftRadius = "0"; }} - + function switchThemeButtonState() {{ if (themes.style.display === "block") {{ showThemeButtonState(); From 2e41ba8742c341eaf1ec1b5954e089e4d2c02dd0 Mon Sep 17 00:00:00 2001 From: Tim Vermeulen Date: Sat, 6 Jul 2019 23:22:20 +0200 Subject: [PATCH 03/18] Use internal iteration in the Sum and Product impls of Result and Option --- src/libcore/iter/adapters/mod.rs | 146 ++++++++----------------------- src/libcore/iter/mod.rs | 2 +- src/libcore/iter/traits/accum.rs | 10 +-- src/libcore/option.rs | 7 +- src/libcore/result.rs | 4 +- src/libcore/tests/iter.rs | 17 ++++ 6 files changed, 67 insertions(+), 119 deletions(-) diff --git a/src/libcore/iter/adapters/mod.rs b/src/libcore/iter/adapters/mod.rs index 8eae52ffd3277..2a8286d29b80c 100644 --- a/src/libcore/iter/adapters/mod.rs +++ b/src/libcore/iter/adapters/mod.rs @@ -2063,137 +2063,65 @@ impl ExactSizeIterator for Inspect impl FusedIterator for Inspect where F: FnMut(&I::Item) {} -/// An iterator adapter that produces output as long as the underlying -/// iterator produces `Option::Some` values. -pub(crate) struct OptionShunt { - iter: I, - exited_early: bool, -} - -impl OptionShunt -where - I: Iterator>, -{ - /// Process the given iterator as if it yielded a `T` instead of a - /// `Option`. Any `None` value will stop the inner iterator and - /// the overall result will be a `None`. - pub fn process(iter: I, mut f: F) -> Option - where - F: FnMut(&mut Self) -> U, - { - let mut shunt = OptionShunt::new(iter); - let value = f(shunt.by_ref()); - shunt.reconstruct(value) - } - - fn new(iter: I) -> Self { - OptionShunt { - iter, - exited_early: false, - } - } - - /// Consume the adapter and rebuild a `Option` value. - fn reconstruct(self, val: U) -> Option { - if self.exited_early { - None - } else { - Some(val) - } - } -} - -impl Iterator for OptionShunt -where - I: Iterator>, -{ - type Item = T; - - fn next(&mut self) -> Option { - match self.iter.next() { - Some(Some(v)) => Some(v), - Some(None) => { - self.exited_early = true; - None - } - None => None, - } - } - - fn size_hint(&self) -> (usize, Option) { - if self.exited_early { - (0, Some(0)) - } else { - let (_, upper) = self.iter.size_hint(); - (0, upper) - } - } -} - /// An iterator adapter that produces output as long as the underlying /// iterator produces `Result::Ok` values. /// /// If an error is encountered, the iterator stops and the error is -/// stored. The error may be recovered later via `reconstruct`. -pub(crate) struct ResultShunt { +/// stored. +pub(crate) struct ResultShunt<'a, I, E> { iter: I, - error: Option, + error: &'a mut Result<(), E>, } -impl ResultShunt - where I: Iterator> +/// Process the given iterator as if it yielded a `T` instead of a +/// `Result`. Any errors will stop the inner iterator and +/// the overall result will be an error. +pub(crate) fn process_results(iter: I, mut f: F) -> Result +where + I: Iterator>, + for<'a> F: FnMut(ResultShunt<'a, I, E>) -> U, { - /// Process the given iterator as if it yielded a `T` instead of a - /// `Result`. Any errors will stop the inner iterator and - /// the overall result will be an error. - pub fn process(iter: I, mut f: F) -> Result - where F: FnMut(&mut Self) -> U - { - let mut shunt = ResultShunt::new(iter); - let value = f(shunt.by_ref()); - shunt.reconstruct(value) - } - - fn new(iter: I) -> Self { - ResultShunt { - iter, - error: None, - } - } - - /// Consume the adapter and rebuild a `Result` value. This should - /// *always* be called, otherwise any potential error would be - /// lost. - fn reconstruct(self, val: U) -> Result { - match self.error { - None => Ok(val), - Some(e) => Err(e), - } - } + let mut error = Ok(()); + let shunt = ResultShunt { + iter, + error: &mut error, + }; + let value = f(shunt); + error.map(|()| value) } -impl Iterator for ResultShunt +impl Iterator for ResultShunt<'_, I, E> where I: Iterator> { type Item = T; fn next(&mut self) -> Option { - match self.iter.next() { - Some(Ok(v)) => Some(v), - Some(Err(e)) => { - self.error = Some(e); - None - } - None => None, - } + self.find(|_| true) } fn size_hint(&self) -> (usize, Option) { - if self.error.is_some() { + if self.error.is_err() { (0, Some(0)) } else { let (_, upper) = self.iter.size_hint(); (0, upper) } } + + fn try_fold(&mut self, init: B, mut f: F) -> R + where + F: FnMut(B, Self::Item) -> R, + R: Try, + { + let error = &mut *self.error; + self.iter + .try_fold(init, |acc, x| match x { + Ok(x) => LoopState::from_try(f(acc, x)), + Err(e) => { + *error = Err(e); + LoopState::Break(Try::from_ok(acc)) + } + }) + .into_try() + } } diff --git a/src/libcore/iter/mod.rs b/src/libcore/iter/mod.rs index 4a7d7f96b9b04..aba8e84d58be5 100644 --- a/src/libcore/iter/mod.rs +++ b/src/libcore/iter/mod.rs @@ -360,7 +360,7 @@ pub use self::adapters::Flatten; #[stable(feature = "iter_copied", since = "1.36.0")] pub use self::adapters::Copied; -pub(crate) use self::adapters::{TrustedRandomAccess, OptionShunt, ResultShunt}; +pub(crate) use self::adapters::{TrustedRandomAccess, process_results}; mod range; mod sources; diff --git a/src/libcore/iter/traits/accum.rs b/src/libcore/iter/traits/accum.rs index 01b64fb08acf7..812463e77f976 100644 --- a/src/libcore/iter/traits/accum.rs +++ b/src/libcore/iter/traits/accum.rs @@ -1,6 +1,6 @@ use crate::ops::{Mul, Add}; use crate::num::Wrapping; -use crate::iter::adapters::{OptionShunt, ResultShunt}; +use crate::iter; /// Trait to represent types that can be created by summing up an iterator. /// @@ -139,7 +139,7 @@ impl Sum> for Result fn sum(iter: I) -> Result where I: Iterator>, { - ResultShunt::process(iter, |i| i.sum()) + iter::process_results(iter, |i| i.sum()) } } @@ -153,7 +153,7 @@ impl Product> for Result fn product(iter: I) -> Result where I: Iterator>, { - ResultShunt::process(iter, |i| i.product()) + iter::process_results(iter, |i| i.product()) } } @@ -180,7 +180,7 @@ where where I: Iterator>, { - OptionShunt::process(iter, |i| i.sum()) + iter.map(|x| x.ok_or(())).sum::>().ok() } } @@ -196,6 +196,6 @@ where where I: Iterator>, { - OptionShunt::process(iter, |i| i.product()) + iter.map(|x| x.ok_or(())).product::>().ok() } } diff --git a/src/libcore/option.rs b/src/libcore/option.rs index 70a87cfe5a78a..693ec0053223e 100644 --- a/src/libcore/option.rs +++ b/src/libcore/option.rs @@ -135,7 +135,7 @@ #![stable(feature = "rust1", since = "1.0.0")] -use crate::iter::{FromIterator, FusedIterator, TrustedLen, OptionShunt}; +use crate::iter::{FromIterator, FusedIterator, TrustedLen}; use crate::{convert, fmt, hint, mem, ops::{self, Deref, DerefMut}}; use crate::pin::Pin; @@ -1499,7 +1499,10 @@ impl> FromIterator> for Option { // FIXME(#11084): This could be replaced with Iterator::scan when this // performance bug is closed. - OptionShunt::process(iter.into_iter(), |i| i.collect()) + iter.into_iter() + .map(|x| x.ok_or(())) + .collect::>() + .ok() } } diff --git a/src/libcore/result.rs b/src/libcore/result.rs index 559877ddd5a1c..8c60a9c1b501d 100644 --- a/src/libcore/result.rs +++ b/src/libcore/result.rs @@ -231,7 +231,7 @@ #![stable(feature = "rust1", since = "1.0.0")] use crate::fmt; -use crate::iter::{FromIterator, FusedIterator, TrustedLen, ResultShunt}; +use crate::iter::{self, FromIterator, FusedIterator, TrustedLen}; use crate::ops::{self, Deref, DerefMut}; /// `Result` is a type that represents either success ([`Ok`]) or failure ([`Err`]). @@ -1343,7 +1343,7 @@ impl> FromIterator> for Result { // FIXME(#11084): This could be replaced with Iterator::scan when this // performance bug is closed. - ResultShunt::process(iter.into_iter(), |i| i.collect()) + iter::process_results(iter.into_iter(), |i| i.collect()) } } diff --git a/src/libcore/tests/iter.rs b/src/libcore/tests/iter.rs index b7b0849e2129b..31530cc2c94c4 100644 --- a/src/libcore/tests/iter.rs +++ b/src/libcore/tests/iter.rs @@ -1082,6 +1082,23 @@ fn test_iterator_sum_result() { assert_eq!(v.iter().cloned().sum::>(), Ok(10)); let v: &[Result] = &[Ok(1), Err(()), Ok(3), Ok(4)]; assert_eq!(v.iter().cloned().sum::>(), Err(())); + + #[derive(PartialEq, Debug)] + struct S(Result); + + impl Sum> for S { + fn sum>>(mut iter: I) -> Self { + // takes the sum by repeatedly calling `next` on `iter`, + // thus testing that repeated calls to `ResultShunt::try_fold` + // produce the expected results + Self(iter.by_ref().sum()) + } + } + + let v: &[Result] = &[Ok(1), Ok(2), Ok(3), Ok(4)]; + assert_eq!(v.iter().cloned().sum::(), S(Ok(10))); + let v: &[Result] = &[Ok(1), Err(()), Ok(3), Ok(4)]; + assert_eq!(v.iter().cloned().sum::(), S(Err(()))); } #[test] From 83b5eb961528972acaa13992a9bbbe9574458550 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Tue, 30 Jul 2019 17:46:46 -0700 Subject: [PATCH 04/18] Always error on `SizeOverflow` during mir evaluation --- src/librustc/mir/interpret/error.rs | 1 - src/test/ui/consts/issue-55878.rs | 4 ++++ src/test/ui/consts/issue-55878.stderr | 15 +++++++++++++++ src/test/ui/issues/issue-56762.rs | 2 ++ src/test/ui/issues/issue-56762.stderr | 15 +++++++++++++-- 5 files changed, 34 insertions(+), 3 deletions(-) create mode 100644 src/test/ui/consts/issue-55878.rs create mode 100644 src/test/ui/consts/issue-55878.stderr diff --git a/src/librustc/mir/interpret/error.rs b/src/librustc/mir/interpret/error.rs index 8d41b019c221a..7c1941196390a 100644 --- a/src/librustc/mir/interpret/error.rs +++ b/src/librustc/mir/interpret/error.rs @@ -141,7 +141,6 @@ impl<'tcx> ConstEvalErr<'tcx> { err_inval!(Layout(LayoutError::Unknown(_))) | err_inval!(TooGeneric) => return Err(ErrorHandled::TooGeneric), - err_inval!(Layout(LayoutError::SizeOverflow(_))) | err_inval!(TypeckError) => return Err(ErrorHandled::Reported), _ => {}, diff --git a/src/test/ui/consts/issue-55878.rs b/src/test/ui/consts/issue-55878.rs new file mode 100644 index 0000000000000..ce6c25742870e --- /dev/null +++ b/src/test/ui/consts/issue-55878.rs @@ -0,0 +1,4 @@ +// error-pattern: reaching this expression at runtime will panic or abort +fn main() { + println!("Size: {}", std::mem::size_of::<[u8; std::u64::MAX as usize]>()); +} diff --git a/src/test/ui/consts/issue-55878.stderr b/src/test/ui/consts/issue-55878.stderr new file mode 100644 index 0000000000000..03537ff20bf5e --- /dev/null +++ b/src/test/ui/consts/issue-55878.stderr @@ -0,0 +1,15 @@ +error: reaching this expression at runtime will panic or abort + --> $SRC_DIR/libcore/mem/mod.rs:LL:COL + | +LL | intrinsics::size_of::() + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ rustc layout computation failed: SizeOverflow([u8; 18446744073709551615]) + | + ::: $DIR/issue-55878.rs:3:26 + | +LL | println!("Size: {}", std::mem::size_of::<[u8; std::u64::MAX as usize]>()); + | --------------------------------------------------- + | + = note: `#[deny(const_err)]` on by default + +error: aborting due to previous error + diff --git a/src/test/ui/issues/issue-56762.rs b/src/test/ui/issues/issue-56762.rs index 8bb81b907c9a4..f12d0121a8f1a 100644 --- a/src/test/ui/issues/issue-56762.rs +++ b/src/test/ui/issues/issue-56762.rs @@ -17,6 +17,8 @@ impl TooBigArray { } static MY_TOO_BIG_ARRAY_1: TooBigArray = TooBigArray::new(); +//~^ ERROR could not evaluate static initializer static MY_TOO_BIG_ARRAY_2: [u8; HUGE_SIZE] = [0x00; HUGE_SIZE]; +//~^ ERROR could not evaluate static initializer fn main() { } diff --git a/src/test/ui/issues/issue-56762.stderr b/src/test/ui/issues/issue-56762.stderr index 83d5dc62e6161..fa7b9c71eb4a2 100644 --- a/src/test/ui/issues/issue-56762.stderr +++ b/src/test/ui/issues/issue-56762.stderr @@ -1,4 +1,15 @@ -error: the type `[u8; 2305843009213693951]` is too big for the current architecture +error[E0080]: could not evaluate static initializer + --> $DIR/issue-56762.rs:19:1 + | +LL | static MY_TOO_BIG_ARRAY_1: TooBigArray = TooBigArray::new(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ rustc layout computation failed: SizeOverflow([u8; 2305843009213693951]) -error: aborting due to previous error +error[E0080]: could not evaluate static initializer + --> $DIR/issue-56762.rs:21:1 + | +LL | static MY_TOO_BIG_ARRAY_2: [u8; HUGE_SIZE] = [0x00; HUGE_SIZE]; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ rustc layout computation failed: SizeOverflow([u8; 2305843009213693951]) +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0080`. From 58bd8786e891f69fcb7982938a635d4f8b16496b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Wed, 31 Jul 2019 14:10:33 -0700 Subject: [PATCH 05/18] Do not lint on SizeOverflow, always error --- src/librustc/mir/interpret/error.rs | 4 +++- src/test/ui/consts/issue-55878.stderr | 5 ++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/librustc/mir/interpret/error.rs b/src/librustc/mir/interpret/error.rs index 7c1941196390a..acdabd1e53d63 100644 --- a/src/librustc/mir/interpret/error.rs +++ b/src/librustc/mir/interpret/error.rs @@ -137,16 +137,18 @@ impl<'tcx> ConstEvalErr<'tcx> { message: &str, lint_root: Option, ) -> Result, ErrorHandled> { + let mut must_error = false; match self.error { err_inval!(Layout(LayoutError::Unknown(_))) | err_inval!(TooGeneric) => return Err(ErrorHandled::TooGeneric), err_inval!(TypeckError) => return Err(ErrorHandled::Reported), + err_inval!(LayoutError::SizeOverflow(_)) => must_error = true, _ => {}, } trace!("reporting const eval failure at {:?}", self.span); - let mut err = if let Some(lint_root) = lint_root { + let mut err = if let (Some(lint_root), false) = (lint_root, must_error) { let hir_id = self.stacktrace .iter() .rev() diff --git a/src/test/ui/consts/issue-55878.stderr b/src/test/ui/consts/issue-55878.stderr index 03537ff20bf5e..7ca7024912fbb 100644 --- a/src/test/ui/consts/issue-55878.stderr +++ b/src/test/ui/consts/issue-55878.stderr @@ -1,4 +1,4 @@ -error: reaching this expression at runtime will panic or abort +error[E0080]: reaching this expression at runtime will panic or abort --> $SRC_DIR/libcore/mem/mod.rs:LL:COL | LL | intrinsics::size_of::() @@ -8,8 +8,7 @@ LL | intrinsics::size_of::() | LL | println!("Size: {}", std::mem::size_of::<[u8; std::u64::MAX as usize]>()); | --------------------------------------------------- - | - = note: `#[deny(const_err)]` on by default error: aborting due to previous error +For more information about this error, try `rustc --explain E0080`. From d3da411a080fb19c9cba2b812a48fb0a57c03013 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Wed, 31 Jul 2019 16:22:34 -0700 Subject: [PATCH 06/18] Nicer labels for type layout errors --- src/librustc/mir/interpret/error.rs | 4 ++-- src/test/ui/consts/issue-55878.stderr | 2 +- src/test/ui/issues/issue-56762.stderr | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/librustc/mir/interpret/error.rs b/src/librustc/mir/interpret/error.rs index acdabd1e53d63..05978ae3c6f7a 100644 --- a/src/librustc/mir/interpret/error.rs +++ b/src/librustc/mir/interpret/error.rs @@ -144,7 +144,7 @@ impl<'tcx> ConstEvalErr<'tcx> { return Err(ErrorHandled::TooGeneric), err_inval!(TypeckError) => return Err(ErrorHandled::Reported), - err_inval!(LayoutError::SizeOverflow(_)) => must_error = true, + err_inval!(Layout(LayoutError::SizeOverflow(_))) => must_error = true, _ => {}, } trace!("reporting const eval failure at {:?}", self.span); @@ -336,7 +336,7 @@ impl fmt::Debug for InvalidProgramInfo<'tcx> { TypeckError => write!(f, "encountered constants with type errors, stopping evaluation"), Layout(ref err) => - write!(f, "rustc layout computation failed: {:?}", err), + write!(f, "{}", err), } } } diff --git a/src/test/ui/consts/issue-55878.stderr b/src/test/ui/consts/issue-55878.stderr index 7ca7024912fbb..adb272f4bed9c 100644 --- a/src/test/ui/consts/issue-55878.stderr +++ b/src/test/ui/consts/issue-55878.stderr @@ -2,7 +2,7 @@ error[E0080]: reaching this expression at runtime will panic or abort --> $SRC_DIR/libcore/mem/mod.rs:LL:COL | LL | intrinsics::size_of::() - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ rustc layout computation failed: SizeOverflow([u8; 18446744073709551615]) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ the type `[u8; 18446744073709551615]` is too big for the current architecture | ::: $DIR/issue-55878.rs:3:26 | diff --git a/src/test/ui/issues/issue-56762.stderr b/src/test/ui/issues/issue-56762.stderr index fa7b9c71eb4a2..bce95087c5ce4 100644 --- a/src/test/ui/issues/issue-56762.stderr +++ b/src/test/ui/issues/issue-56762.stderr @@ -2,13 +2,13 @@ error[E0080]: could not evaluate static initializer --> $DIR/issue-56762.rs:19:1 | LL | static MY_TOO_BIG_ARRAY_1: TooBigArray = TooBigArray::new(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ rustc layout computation failed: SizeOverflow([u8; 2305843009213693951]) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the type `[u8; 2305843009213693951]` is too big for the current architecture error[E0080]: could not evaluate static initializer --> $DIR/issue-56762.rs:21:1 | LL | static MY_TOO_BIG_ARRAY_2: [u8; HUGE_SIZE] = [0x00; HUGE_SIZE]; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ rustc layout computation failed: SizeOverflow([u8; 2305843009213693951]) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the type `[u8; 2305843009213693951]` is too big for the current architecture error: aborting due to 2 previous errors From 2c5684208c6f951b2cbe90df26a6691a95099e93 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sat, 3 Aug 2019 13:37:44 -0700 Subject: [PATCH 07/18] avoid mutable state and override main message --- src/librustc/mir/interpret/error.rs | 11 ++++++----- src/test/ui/consts/issue-55878.rs | 2 +- src/test/ui/consts/issue-55878.stderr | 2 +- src/test/ui/issues/issue-56762.rs | 4 ++-- src/test/ui/issues/issue-56762.stderr | 4 ++-- 5 files changed, 12 insertions(+), 11 deletions(-) diff --git a/src/librustc/mir/interpret/error.rs b/src/librustc/mir/interpret/error.rs index 05978ae3c6f7a..fb6f74397fc4c 100644 --- a/src/librustc/mir/interpret/error.rs +++ b/src/librustc/mir/interpret/error.rs @@ -137,16 +137,15 @@ impl<'tcx> ConstEvalErr<'tcx> { message: &str, lint_root: Option, ) -> Result, ErrorHandled> { - let mut must_error = false; - match self.error { + let must_error = match self.error { err_inval!(Layout(LayoutError::Unknown(_))) | err_inval!(TooGeneric) => return Err(ErrorHandled::TooGeneric), err_inval!(TypeckError) => return Err(ErrorHandled::Reported), - err_inval!(Layout(LayoutError::SizeOverflow(_))) => must_error = true, - _ => {}, - } + err_inval!(Layout(LayoutError::SizeOverflow(_))) => true, + _ => false, + }; trace!("reporting const eval failure at {:?}", self.span); let mut err = if let (Some(lint_root), false) = (lint_root, must_error) { let hir_id = self.stacktrace @@ -161,6 +160,8 @@ impl<'tcx> ConstEvalErr<'tcx> { tcx.span, message, ) + } else if must_error { + struct_error(tcx, &self.error.to_string()) } else { struct_error(tcx, message) }; diff --git a/src/test/ui/consts/issue-55878.rs b/src/test/ui/consts/issue-55878.rs index ce6c25742870e..6d8159e2fcdde 100644 --- a/src/test/ui/consts/issue-55878.rs +++ b/src/test/ui/consts/issue-55878.rs @@ -1,4 +1,4 @@ -// error-pattern: reaching this expression at runtime will panic or abort +// error-pattern: the type `[u8; 18446744073709551615]` is too big for the current architecture fn main() { println!("Size: {}", std::mem::size_of::<[u8; std::u64::MAX as usize]>()); } diff --git a/src/test/ui/consts/issue-55878.stderr b/src/test/ui/consts/issue-55878.stderr index adb272f4bed9c..184c6d0e29293 100644 --- a/src/test/ui/consts/issue-55878.stderr +++ b/src/test/ui/consts/issue-55878.stderr @@ -1,4 +1,4 @@ -error[E0080]: reaching this expression at runtime will panic or abort +error[E0080]: the type `[u8; 18446744073709551615]` is too big for the current architecture --> $SRC_DIR/libcore/mem/mod.rs:LL:COL | LL | intrinsics::size_of::() diff --git a/src/test/ui/issues/issue-56762.rs b/src/test/ui/issues/issue-56762.rs index f12d0121a8f1a..5ba5b9847d085 100644 --- a/src/test/ui/issues/issue-56762.rs +++ b/src/test/ui/issues/issue-56762.rs @@ -17,8 +17,8 @@ impl TooBigArray { } static MY_TOO_BIG_ARRAY_1: TooBigArray = TooBigArray::new(); -//~^ ERROR could not evaluate static initializer +//~^ ERROR the type `[u8; 2305843009213693951]` is too big for the current architecture static MY_TOO_BIG_ARRAY_2: [u8; HUGE_SIZE] = [0x00; HUGE_SIZE]; -//~^ ERROR could not evaluate static initializer +//~^ ERROR the type `[u8; 2305843009213693951]` is too big for the current architecture fn main() { } diff --git a/src/test/ui/issues/issue-56762.stderr b/src/test/ui/issues/issue-56762.stderr index bce95087c5ce4..e74904f1f6818 100644 --- a/src/test/ui/issues/issue-56762.stderr +++ b/src/test/ui/issues/issue-56762.stderr @@ -1,10 +1,10 @@ -error[E0080]: could not evaluate static initializer +error[E0080]: the type `[u8; 2305843009213693951]` is too big for the current architecture --> $DIR/issue-56762.rs:19:1 | LL | static MY_TOO_BIG_ARRAY_1: TooBigArray = TooBigArray::new(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the type `[u8; 2305843009213693951]` is too big for the current architecture -error[E0080]: could not evaluate static initializer +error[E0080]: the type `[u8; 2305843009213693951]` is too big for the current architecture --> $DIR/issue-56762.rs:21:1 | LL | static MY_TOO_BIG_ARRAY_2: [u8; HUGE_SIZE] = [0x00; HUGE_SIZE]; From db099fb491fa2e713047af4f22d4139a71a21dbc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sat, 3 Aug 2019 15:59:25 -0700 Subject: [PATCH 08/18] Point to local place span on "type too big" error --- src/librustc/lint/context.rs | 3 +++ src/librustc/ty/layout.rs | 8 +++++++- src/librustc_codegen_llvm/builder.rs | 4 ++++ src/librustc_codegen_llvm/context.rs | 10 +++++++++- src/librustc_codegen_ssa/mir/analyze.rs | 8 +++++++- src/librustc_codegen_ssa/mir/rvalue.rs | 14 ++++++++++---- src/librustc_mir/interpret/eval_context.rs | 3 +++ src/librustc_mir/transform/const_prop.rs | 3 +++ src/librustc_passes/layout_test.rs | 4 ++++ src/librustc_target/abi/mod.rs | 2 ++ src/test/ui/huge-array-simple.stderr | 4 ++++ src/test/ui/huge-array.rs | 3 +-- src/test/ui/huge-array.stderr | 4 ++++ src/test/ui/issues/issue-15919.stderr | 4 ++++ 14 files changed, 65 insertions(+), 9 deletions(-) diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs index de812410e8bd8..7d9653a9a55b1 100644 --- a/src/librustc/lint/context.rs +++ b/src/librustc/lint/context.rs @@ -901,6 +901,9 @@ impl<'a, 'tcx> LayoutOf for LateContext<'a, 'tcx> { fn layout_of(&self, ty: Ty<'tcx>) -> Self::TyLayout { self.tcx.layout_of(self.param_env.and(ty)) } + fn spanned_layout_of(&self, ty: Ty<'tcx>, _: Option) -> Self::TyLayout { + self.layout_of(ty) + } } impl<'a, 'tcx, T: LateLintPass<'a, 'tcx>> LateContextAndPass<'a, 'tcx, T> { diff --git a/src/librustc/ty/layout.rs b/src/librustc/ty/layout.rs index 3b4b814c92a90..14d35fd4ce891 100644 --- a/src/librustc/ty/layout.rs +++ b/src/librustc/ty/layout.rs @@ -3,7 +3,7 @@ use crate::ty::{self, Ty, TyCtxt, TypeFoldable, ReprOptions}; use syntax::ast::{self, Ident, IntTy, UintTy}; use syntax::attr; -use syntax_pos::DUMMY_SP; +use syntax_pos::{DUMMY_SP, Span}; use std::cmp; use std::fmt; @@ -1943,6 +1943,9 @@ impl<'tcx> LayoutOf for LayoutCx<'tcx, TyCtxt<'tcx>> { Ok(layout) } + fn spanned_layout_of(&self, ty: Ty<'tcx>, _: Option) -> Self::TyLayout { + self.layout_of(ty) + } } impl LayoutOf for LayoutCx<'tcx, ty::query::TyCtxtAt<'tcx>> { @@ -1974,6 +1977,9 @@ impl LayoutOf for LayoutCx<'tcx, ty::query::TyCtxtAt<'tcx>> { Ok(layout) } + fn spanned_layout_of(&self, ty: Ty<'tcx>, _: Option) -> Self::TyLayout { + self.layout_of(ty) + } } // Helper (inherent) `layout_of` methods to avoid pushing `LayoutCx` to users. diff --git a/src/librustc_codegen_llvm/builder.rs b/src/librustc_codegen_llvm/builder.rs index 894e5c2fd3d93..c01ba728034ce 100644 --- a/src/librustc_codegen_llvm/builder.rs +++ b/src/librustc_codegen_llvm/builder.rs @@ -6,6 +6,7 @@ use crate::type_::Type; use crate::type_of::LayoutLlvmExt; use crate::value::Value; use syntax::symbol::LocalInternedString; +use syntax::source_map::Span; use rustc_codegen_ssa::common::{IntPredicate, TypeKind, RealPredicate}; use rustc_codegen_ssa::MemFlags; use libc::{c_uint, c_char}; @@ -90,6 +91,9 @@ impl ty::layout::LayoutOf for Builder<'_, '_, 'tcx> { fn layout_of(&self, ty: Ty<'tcx>) -> Self::TyLayout { self.cx.layout_of(ty) } + fn spanned_layout_of(&self, ty: Ty<'tcx>, _: Option) -> Self::TyLayout { + self.cx.layout_of(ty) + } } impl Deref for Builder<'_, 'll, 'tcx> { diff --git a/src/librustc_codegen_llvm/context.rs b/src/librustc_codegen_llvm/context.rs index 2b68eb53a4ab9..18d82c27d8cc9 100644 --- a/src/librustc_codegen_llvm/context.rs +++ b/src/librustc_codegen_llvm/context.rs @@ -30,6 +30,7 @@ use std::iter; use std::str; use std::sync::Arc; use syntax::symbol::LocalInternedString; +use syntax::source_map::Span; use crate::abi::Abi; /// There is one `CodegenCx` per compilation unit. Each one has its own LLVM @@ -860,9 +861,16 @@ impl LayoutOf for CodegenCx<'ll, 'tcx> { type TyLayout = TyLayout<'tcx>; fn layout_of(&self, ty: Ty<'tcx>) -> Self::TyLayout { + self.spanned_layout_of(ty, None) + } + + fn spanned_layout_of(&self, ty: Ty<'tcx>, span: Option) -> Self::TyLayout { self.tcx.layout_of(ty::ParamEnv::reveal_all().and(ty)) .unwrap_or_else(|e| if let LayoutError::SizeOverflow(_) = e { - self.sess().fatal(&e.to_string()) + match span { + Some(span) => self.sess().span_fatal(span, &e.to_string()), + None => self.sess().fatal(&e.to_string()), + } } else { bug!("failed to get layout for `{}`: {}", ty, e) }) diff --git a/src/librustc_codegen_ssa/mir/analyze.rs b/src/librustc_codegen_ssa/mir/analyze.rs index 907689541f978..1ce3dbc4fe3b6 100644 --- a/src/librustc_codegen_ssa/mir/analyze.rs +++ b/src/librustc_codegen_ssa/mir/analyze.rs @@ -182,13 +182,19 @@ impl<'mir, 'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> Visitor<'tcx> rvalue: &mir::Rvalue<'tcx>, location: Location) { debug!("visit_assign(place={:?}, rvalue={:?})", place, rvalue); + let mut decl_span = None; + if let mir::PlaceBase::Local(local) = &place.base { + if let Some(decl) = self.fx.mir.local_decls.get(*local) { + decl_span = Some(decl.source_info.span); + } + } if let mir::Place { base: mir::PlaceBase::Local(index), projection: None, } = *place { self.assign(index, location); - if !self.fx.rvalue_creates_operand(rvalue) { + if !self.fx.rvalue_creates_operand(rvalue, decl_span) { self.not_ssa(index); } } else { diff --git a/src/librustc_codegen_ssa/mir/rvalue.rs b/src/librustc_codegen_ssa/mir/rvalue.rs index 202cf147f1fcb..56c76cdc026f7 100644 --- a/src/librustc_codegen_ssa/mir/rvalue.rs +++ b/src/librustc_codegen_ssa/mir/rvalue.rs @@ -6,6 +6,7 @@ use rustc::middle::lang_items::ExchangeMallocFnLangItem; use rustc_apfloat::{ieee, Float, Status, Round}; use std::{u128, i128}; use syntax::symbol::sym; +use syntax::source_map::Span; use crate::base; use crate::MemFlags; @@ -136,7 +137,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { } _ => { - assert!(self.rvalue_creates_operand(rvalue)); + assert!(self.rvalue_creates_operand(rvalue, None)); let (mut bx, temp) = self.codegen_rvalue_operand(bx, rvalue); temp.val.store(&mut bx, dest); bx @@ -169,7 +170,11 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { mut bx: Bx, rvalue: &mir::Rvalue<'tcx> ) -> (Bx, OperandRef<'tcx, Bx::Value>) { - assert!(self.rvalue_creates_operand(rvalue), "cannot codegen {:?} to operand", rvalue); + assert!( + self.rvalue_creates_operand(rvalue, None), + "cannot codegen {:?} to operand", + rvalue, + ); match *rvalue { mir::Rvalue::Cast(ref kind, ref source, mir_cast_ty) => { @@ -691,7 +696,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { } impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { - pub fn rvalue_creates_operand(&self, rvalue: &mir::Rvalue<'tcx>) -> bool { + pub fn rvalue_creates_operand(&self, rvalue: &mir::Rvalue<'tcx>, span: Option) -> bool { match *rvalue { mir::Rvalue::Ref(..) | mir::Rvalue::Len(..) | @@ -707,7 +712,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { mir::Rvalue::Aggregate(..) => { let ty = rvalue.ty(self.mir, self.cx.tcx()); let ty = self.monomorphize(&ty); - self.cx.layout_of(ty).is_zst() + self.cx.spanned_layout_of(ty, span).is_zst() + // self.cx.layout_of(ty).is_zst() } } diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs index f10d7fb965116..605afa7b36810 100644 --- a/src/librustc_mir/interpret/eval_context.rs +++ b/src/librustc_mir/interpret/eval_context.rs @@ -193,6 +193,9 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> LayoutOf for InterpCx<'mir, 'tcx, M> { .layout_of(self.param_env.and(ty)) .map_err(|layout| err_inval!(Layout(layout)).into()) } + fn spanned_layout_of(&self, ty: Ty<'tcx>, _: Option) -> Self::TyLayout { + self.layout_of(ty) + } } impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs index a450ec32e1a47..18b6f408fe12c 100644 --- a/src/librustc_mir/transform/const_prop.rs +++ b/src/librustc_mir/transform/const_prop.rs @@ -134,6 +134,9 @@ impl<'mir, 'tcx> LayoutOf for ConstPropagator<'mir, 'tcx> { fn layout_of(&self, ty: Ty<'tcx>) -> Self::TyLayout { self.tcx.layout_of(self.param_env.and(ty)) } + fn spanned_layout_of(&self, ty: Ty<'tcx>, _: Option) -> Self::TyLayout { + self.layout_of(ty) + } } impl<'mir, 'tcx> HasDataLayout for ConstPropagator<'mir, 'tcx> { diff --git a/src/librustc_passes/layout_test.rs b/src/librustc_passes/layout_test.rs index 95cb8de70675d..8c4635f3566ca 100644 --- a/src/librustc_passes/layout_test.rs +++ b/src/librustc_passes/layout_test.rs @@ -13,6 +13,7 @@ use rustc::ty::Ty; use rustc::ty::TyCtxt; use syntax::ast::Attribute; use syntax::symbol::sym; +use syntax::source_map::Span; pub fn test_layout(tcx: TyCtxt<'_>) { if tcx.features().rustc_attrs { @@ -116,6 +117,9 @@ impl LayoutOf for UnwrapLayoutCx<'tcx> { fn layout_of(&self, ty: Ty<'tcx>) -> Self::TyLayout { self.tcx.layout_of(self.param_env.and(ty)).unwrap() } + fn spanned_layout_of(&self, ty: Ty<'tcx>, _: Option) -> Self::TyLayout { + self.layout_of(ty) + } } impl HasTyCtxt<'tcx> for UnwrapLayoutCx<'tcx> { diff --git a/src/librustc_target/abi/mod.rs b/src/librustc_target/abi/mod.rs index 80fcb45d0b9bc..c4f38f4a7f4c3 100644 --- a/src/librustc_target/abi/mod.rs +++ b/src/librustc_target/abi/mod.rs @@ -9,6 +9,7 @@ use std::ops::{Add, Deref, Sub, Mul, AddAssign, Range, RangeInclusive}; use rustc_data_structures::newtype_index; use rustc_data_structures::indexed_vec::{Idx, IndexVec}; use syntax_pos::symbol::{sym, Symbol}; +use syntax_pos::Span; pub mod call; @@ -1012,6 +1013,7 @@ pub trait LayoutOf { type TyLayout; fn layout_of(&self, ty: Self::Ty) -> Self::TyLayout; + fn spanned_layout_of(&self, ty: Self::Ty, span: Option) -> Self::TyLayout; } #[derive(Copy, Clone, PartialEq, Eq)] diff --git a/src/test/ui/huge-array-simple.stderr b/src/test/ui/huge-array-simple.stderr index 3e9c86296cec2..71d3f62bbe53b 100644 --- a/src/test/ui/huge-array-simple.stderr +++ b/src/test/ui/huge-array-simple.stderr @@ -1,4 +1,8 @@ error: the type `[u8; N]` is too big for the current architecture + --> $DIR/huge-array-simple.rs:12:9 + | +LL | let _fat : [u8; (1<<61)+(1<<31)] = + | ^^^^ error: aborting due to previous error diff --git a/src/test/ui/huge-array.rs b/src/test/ui/huge-array.rs index f58dcd5806761..1ecf012e04be4 100644 --- a/src/test/ui/huge-array.rs +++ b/src/test/ui/huge-array.rs @@ -1,11 +1,10 @@ -// error-pattern:; 1518600000 - // FIXME https://github.com/rust-lang/rust/issues/59774 // normalize-stderr-test "thread.*panicked.*Metadata module not compiled.*\n" -> "" // normalize-stderr-test "note:.*RUST_BACKTRACE=1.*\n" -> "" fn generic(t: T) { let s: [T; 1518600000] = [t; 1518600000]; + //~^ ERROR the type `[[u8; 1518599999]; 1518600000]` is too big for the current architecture } fn main() { diff --git a/src/test/ui/huge-array.stderr b/src/test/ui/huge-array.stderr index 38d9effcfb527..823d974f4290e 100644 --- a/src/test/ui/huge-array.stderr +++ b/src/test/ui/huge-array.stderr @@ -1,4 +1,8 @@ error: the type `[[u8; 1518599999]; 1518600000]` is too big for the current architecture + --> $DIR/huge-array.rs:6:9 + | +LL | let s: [T; 1518600000] = [t; 1518600000]; + | ^ error: aborting due to previous error diff --git a/src/test/ui/issues/issue-15919.stderr b/src/test/ui/issues/issue-15919.stderr index e4e88cc47cfe7..66c768537843c 100644 --- a/src/test/ui/issues/issue-15919.stderr +++ b/src/test/ui/issues/issue-15919.stderr @@ -1,4 +1,8 @@ error: the type `[usize; N]` is too big for the current architecture + --> $DIR/issue-15919.rs:15:9 + | +LL | let x = [0usize; 0xffff_ffff_ffff_ffff]; + | ^ error: aborting due to previous error From 23400677d7efb82c396d37e01afc9d10698b3d3e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sat, 3 Aug 2019 22:04:39 -0700 Subject: [PATCH 09/18] Simplify change to layout_of --- src/librustc/lint/context.rs | 3 --- src/librustc/ty/layout.rs | 8 +------- src/librustc_codegen_llvm/builder.rs | 4 ---- src/librustc_codegen_ssa/mir/rvalue.rs | 1 - src/librustc_mir/interpret/eval_context.rs | 5 +---- src/librustc_mir/transform/const_prop.rs | 3 --- src/librustc_passes/layout_test.rs | 4 ---- src/librustc_target/abi/mod.rs | 4 +++- 8 files changed, 5 insertions(+), 27 deletions(-) diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs index 7d9653a9a55b1..de812410e8bd8 100644 --- a/src/librustc/lint/context.rs +++ b/src/librustc/lint/context.rs @@ -901,9 +901,6 @@ impl<'a, 'tcx> LayoutOf for LateContext<'a, 'tcx> { fn layout_of(&self, ty: Ty<'tcx>) -> Self::TyLayout { self.tcx.layout_of(self.param_env.and(ty)) } - fn spanned_layout_of(&self, ty: Ty<'tcx>, _: Option) -> Self::TyLayout { - self.layout_of(ty) - } } impl<'a, 'tcx, T: LateLintPass<'a, 'tcx>> LateContextAndPass<'a, 'tcx, T> { diff --git a/src/librustc/ty/layout.rs b/src/librustc/ty/layout.rs index 14d35fd4ce891..3b4b814c92a90 100644 --- a/src/librustc/ty/layout.rs +++ b/src/librustc/ty/layout.rs @@ -3,7 +3,7 @@ use crate::ty::{self, Ty, TyCtxt, TypeFoldable, ReprOptions}; use syntax::ast::{self, Ident, IntTy, UintTy}; use syntax::attr; -use syntax_pos::{DUMMY_SP, Span}; +use syntax_pos::DUMMY_SP; use std::cmp; use std::fmt; @@ -1943,9 +1943,6 @@ impl<'tcx> LayoutOf for LayoutCx<'tcx, TyCtxt<'tcx>> { Ok(layout) } - fn spanned_layout_of(&self, ty: Ty<'tcx>, _: Option) -> Self::TyLayout { - self.layout_of(ty) - } } impl LayoutOf for LayoutCx<'tcx, ty::query::TyCtxtAt<'tcx>> { @@ -1977,9 +1974,6 @@ impl LayoutOf for LayoutCx<'tcx, ty::query::TyCtxtAt<'tcx>> { Ok(layout) } - fn spanned_layout_of(&self, ty: Ty<'tcx>, _: Option) -> Self::TyLayout { - self.layout_of(ty) - } } // Helper (inherent) `layout_of` methods to avoid pushing `LayoutCx` to users. diff --git a/src/librustc_codegen_llvm/builder.rs b/src/librustc_codegen_llvm/builder.rs index c01ba728034ce..894e5c2fd3d93 100644 --- a/src/librustc_codegen_llvm/builder.rs +++ b/src/librustc_codegen_llvm/builder.rs @@ -6,7 +6,6 @@ use crate::type_::Type; use crate::type_of::LayoutLlvmExt; use crate::value::Value; use syntax::symbol::LocalInternedString; -use syntax::source_map::Span; use rustc_codegen_ssa::common::{IntPredicate, TypeKind, RealPredicate}; use rustc_codegen_ssa::MemFlags; use libc::{c_uint, c_char}; @@ -91,9 +90,6 @@ impl ty::layout::LayoutOf for Builder<'_, '_, 'tcx> { fn layout_of(&self, ty: Ty<'tcx>) -> Self::TyLayout { self.cx.layout_of(ty) } - fn spanned_layout_of(&self, ty: Ty<'tcx>, _: Option) -> Self::TyLayout { - self.cx.layout_of(ty) - } } impl Deref for Builder<'_, 'll, 'tcx> { diff --git a/src/librustc_codegen_ssa/mir/rvalue.rs b/src/librustc_codegen_ssa/mir/rvalue.rs index 56c76cdc026f7..4df45d1586086 100644 --- a/src/librustc_codegen_ssa/mir/rvalue.rs +++ b/src/librustc_codegen_ssa/mir/rvalue.rs @@ -713,7 +713,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let ty = rvalue.ty(self.mir, self.cx.tcx()); let ty = self.monomorphize(&ty); self.cx.spanned_layout_of(ty, span).is_zst() - // self.cx.layout_of(ty).is_zst() } } diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs index 605afa7b36810..1f23d8c017ccd 100644 --- a/src/librustc_mir/interpret/eval_context.rs +++ b/src/librustc_mir/interpret/eval_context.rs @@ -193,9 +193,6 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> LayoutOf for InterpCx<'mir, 'tcx, M> { .layout_of(self.param_env.and(ty)) .map_err(|layout| err_inval!(Layout(layout)).into()) } - fn spanned_layout_of(&self, ty: Ty<'tcx>, _: Option) -> Self::TyLayout { - self.layout_of(ty) - } } impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { @@ -509,7 +506,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { pub fn push_stack_frame( &mut self, instance: ty::Instance<'tcx>, - span: source_map::Span, + span: Span, body: &'mir mir::Body<'tcx>, return_place: Option>, return_to_block: StackPopCleanup, diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs index 18b6f408fe12c..a450ec32e1a47 100644 --- a/src/librustc_mir/transform/const_prop.rs +++ b/src/librustc_mir/transform/const_prop.rs @@ -134,9 +134,6 @@ impl<'mir, 'tcx> LayoutOf for ConstPropagator<'mir, 'tcx> { fn layout_of(&self, ty: Ty<'tcx>) -> Self::TyLayout { self.tcx.layout_of(self.param_env.and(ty)) } - fn spanned_layout_of(&self, ty: Ty<'tcx>, _: Option) -> Self::TyLayout { - self.layout_of(ty) - } } impl<'mir, 'tcx> HasDataLayout for ConstPropagator<'mir, 'tcx> { diff --git a/src/librustc_passes/layout_test.rs b/src/librustc_passes/layout_test.rs index 8c4635f3566ca..95cb8de70675d 100644 --- a/src/librustc_passes/layout_test.rs +++ b/src/librustc_passes/layout_test.rs @@ -13,7 +13,6 @@ use rustc::ty::Ty; use rustc::ty::TyCtxt; use syntax::ast::Attribute; use syntax::symbol::sym; -use syntax::source_map::Span; pub fn test_layout(tcx: TyCtxt<'_>) { if tcx.features().rustc_attrs { @@ -117,9 +116,6 @@ impl LayoutOf for UnwrapLayoutCx<'tcx> { fn layout_of(&self, ty: Ty<'tcx>) -> Self::TyLayout { self.tcx.layout_of(self.param_env.and(ty)).unwrap() } - fn spanned_layout_of(&self, ty: Ty<'tcx>, _: Option) -> Self::TyLayout { - self.layout_of(ty) - } } impl HasTyCtxt<'tcx> for UnwrapLayoutCx<'tcx> { diff --git a/src/librustc_target/abi/mod.rs b/src/librustc_target/abi/mod.rs index c4f38f4a7f4c3..4f53c7795c2be 100644 --- a/src/librustc_target/abi/mod.rs +++ b/src/librustc_target/abi/mod.rs @@ -1013,7 +1013,9 @@ pub trait LayoutOf { type TyLayout; fn layout_of(&self, ty: Self::Ty) -> Self::TyLayout; - fn spanned_layout_of(&self, ty: Self::Ty, span: Option) -> Self::TyLayout; + fn spanned_layout_of(&self, ty: Self::Ty, _span: Option) -> Self::TyLayout { + self.layout_of(ty) + } } #[derive(Copy, Clone, PartialEq, Eq)] From 387dcff796406eb55624c61e9f14a3b5c27ad5ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sun, 4 Aug 2019 09:44:06 -0700 Subject: [PATCH 10/18] review comments: clean up --- src/librustc_codegen_llvm/context.rs | 6 +++--- src/librustc_codegen_ssa/mir/analyze.rs | 7 +------ src/librustc_codegen_ssa/mir/rvalue.rs | 8 ++++---- src/librustc_target/abi/mod.rs | 2 +- 4 files changed, 9 insertions(+), 14 deletions(-) diff --git a/src/librustc_codegen_llvm/context.rs b/src/librustc_codegen_llvm/context.rs index 18d82c27d8cc9..ee8f1843c1a82 100644 --- a/src/librustc_codegen_llvm/context.rs +++ b/src/librustc_codegen_llvm/context.rs @@ -30,7 +30,7 @@ use std::iter; use std::str; use std::sync::Arc; use syntax::symbol::LocalInternedString; -use syntax::source_map::Span; +use syntax::source_map::{DUMMY_SP, Span}; use crate::abi::Abi; /// There is one `CodegenCx` per compilation unit. Each one has its own LLVM @@ -861,10 +861,10 @@ impl LayoutOf for CodegenCx<'ll, 'tcx> { type TyLayout = TyLayout<'tcx>; fn layout_of(&self, ty: Ty<'tcx>) -> Self::TyLayout { - self.spanned_layout_of(ty, None) + self.spanned_layout_of(ty, DUMMY_SP) } - fn spanned_layout_of(&self, ty: Ty<'tcx>, span: Option) -> Self::TyLayout { + fn spanned_layout_of(&self, ty: Ty<'tcx>, span: Span) -> Self::TyLayout { self.tcx.layout_of(ty::ParamEnv::reveal_all().and(ty)) .unwrap_or_else(|e| if let LayoutError::SizeOverflow(_) = e { match span { diff --git a/src/librustc_codegen_ssa/mir/analyze.rs b/src/librustc_codegen_ssa/mir/analyze.rs index 1ce3dbc4fe3b6..5dc050cbb3672 100644 --- a/src/librustc_codegen_ssa/mir/analyze.rs +++ b/src/librustc_codegen_ssa/mir/analyze.rs @@ -182,18 +182,13 @@ impl<'mir, 'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> Visitor<'tcx> rvalue: &mir::Rvalue<'tcx>, location: Location) { debug!("visit_assign(place={:?}, rvalue={:?})", place, rvalue); - let mut decl_span = None; - if let mir::PlaceBase::Local(local) = &place.base { - if let Some(decl) = self.fx.mir.local_decls.get(*local) { - decl_span = Some(decl.source_info.span); - } - } if let mir::Place { base: mir::PlaceBase::Local(index), projection: None, } = *place { self.assign(index, location); + let decl_span = self.fx.mir.local_decls[index].source_info.span; if !self.fx.rvalue_creates_operand(rvalue, decl_span) { self.not_ssa(index); } diff --git a/src/librustc_codegen_ssa/mir/rvalue.rs b/src/librustc_codegen_ssa/mir/rvalue.rs index 4df45d1586086..29a97894bdca9 100644 --- a/src/librustc_codegen_ssa/mir/rvalue.rs +++ b/src/librustc_codegen_ssa/mir/rvalue.rs @@ -6,7 +6,7 @@ use rustc::middle::lang_items::ExchangeMallocFnLangItem; use rustc_apfloat::{ieee, Float, Status, Round}; use std::{u128, i128}; use syntax::symbol::sym; -use syntax::source_map::Span; +use syntax::source_map::{DUMMY_SP, Span}; use crate::base; use crate::MemFlags; @@ -137,7 +137,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { } _ => { - assert!(self.rvalue_creates_operand(rvalue, None)); + assert!(self.rvalue_creates_operand(rvalue, DUMMY_SP)); let (mut bx, temp) = self.codegen_rvalue_operand(bx, rvalue); temp.val.store(&mut bx, dest); bx @@ -171,7 +171,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { rvalue: &mir::Rvalue<'tcx> ) -> (Bx, OperandRef<'tcx, Bx::Value>) { assert!( - self.rvalue_creates_operand(rvalue, None), + self.rvalue_creates_operand(rvalue, DUMMY_SP), "cannot codegen {:?} to operand", rvalue, ); @@ -696,7 +696,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { } impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { - pub fn rvalue_creates_operand(&self, rvalue: &mir::Rvalue<'tcx>, span: Option) -> bool { + pub fn rvalue_creates_operand(&self, rvalue: &mir::Rvalue<'tcx>, span: Span) -> bool { match *rvalue { mir::Rvalue::Ref(..) | mir::Rvalue::Len(..) | diff --git a/src/librustc_target/abi/mod.rs b/src/librustc_target/abi/mod.rs index 4f53c7795c2be..dd7ae742a63c6 100644 --- a/src/librustc_target/abi/mod.rs +++ b/src/librustc_target/abi/mod.rs @@ -1013,7 +1013,7 @@ pub trait LayoutOf { type TyLayout; fn layout_of(&self, ty: Self::Ty) -> Self::TyLayout; - fn spanned_layout_of(&self, ty: Self::Ty, _span: Option) -> Self::TyLayout { + fn spanned_layout_of(&self, ty: Self::Ty, _span: Span) -> Self::TyLayout { self.layout_of(ty) } } From bdd79b849e9db3024c8b5a0426e6a08af20edd2d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sun, 4 Aug 2019 12:23:05 -0700 Subject: [PATCH 11/18] tweak output and tests --- src/librustc/mir/interpret/error.rs | 4 +++- src/librustc_codegen_llvm/context.rs | 5 +---- src/librustc_codegen_ssa/mir/analyze.rs | 27 +++++++++++++++++-------- src/test/ui/consts/issue-55878.stderr | 2 +- src/test/ui/huge-enum.rs | 12 +++++------ src/test/ui/huge-enum.stderr | 6 +++++- src/test/ui/huge-struct.rs | 2 ++ src/test/ui/huge-struct.stderr | 4 ++++ src/test/ui/issues/issue-56762.stderr | 4 ++-- 9 files changed, 42 insertions(+), 24 deletions(-) diff --git a/src/librustc/mir/interpret/error.rs b/src/librustc/mir/interpret/error.rs index fb6f74397fc4c..b875977658794 100644 --- a/src/librustc/mir/interpret/error.rs +++ b/src/librustc/mir/interpret/error.rs @@ -165,7 +165,9 @@ impl<'tcx> ConstEvalErr<'tcx> { } else { struct_error(tcx, message) }; - err.span_label(self.span, self.error.to_string()); + if !must_error { + err.span_label(self.span, self.error.to_string()); + } // Skip the last, which is just the environment of the constant. The stacktrace // is sometimes empty because we create "fake" eval contexts in CTFE to do work // on constant values. diff --git a/src/librustc_codegen_llvm/context.rs b/src/librustc_codegen_llvm/context.rs index ee8f1843c1a82..a2aaaddf0931c 100644 --- a/src/librustc_codegen_llvm/context.rs +++ b/src/librustc_codegen_llvm/context.rs @@ -867,10 +867,7 @@ impl LayoutOf for CodegenCx<'ll, 'tcx> { fn spanned_layout_of(&self, ty: Ty<'tcx>, span: Span) -> Self::TyLayout { self.tcx.layout_of(ty::ParamEnv::reveal_all().and(ty)) .unwrap_or_else(|e| if let LayoutError::SizeOverflow(_) = e { - match span { - Some(span) => self.sess().span_fatal(span, &e.to_string()), - None => self.sess().fatal(&e.to_string()), - } + self.sess().span_fatal(span, &e.to_string()) } else { bug!("failed to get layout for `{}`: {}", ty, e) }) diff --git a/src/librustc_codegen_ssa/mir/analyze.rs b/src/librustc_codegen_ssa/mir/analyze.rs index 5dc050cbb3672..cc0c733c22410 100644 --- a/src/librustc_codegen_ssa/mir/analyze.rs +++ b/src/librustc_codegen_ssa/mir/analyze.rs @@ -9,6 +9,7 @@ use rustc::mir::visit::{Visitor, PlaceContext, MutatingUseContext, NonMutatingUs use rustc::mir::traversal; use rustc::ty; use rustc::ty::layout::{LayoutOf, HasTyCtxt}; +use syntax_pos::DUMMY_SP; use super::FunctionCx; use crate::traits::*; @@ -20,10 +21,13 @@ pub fn non_ssa_locals<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( analyzer.visit_body(mir); - for (index, ty) in mir.local_decls.iter().map(|l| l.ty).enumerate() { + for (index, (ty, span)) in mir.local_decls.iter() + .map(|l| (l.ty, l.source_info.span)) + .enumerate() + { let ty = fx.monomorphize(&ty); debug!("local {} has type {:?}", index, ty); - let layout = fx.cx.layout_of(ty); + let layout = fx.cx.spanned_layout_of(ty, span); if fx.cx.is_backend_immediate(layout) { // These sorts of types are immediates that we can store // in an Value without an alloca. @@ -93,10 +97,12 @@ impl> LocalAnalyzer<'mir, 'a, 'tcx, Bx> { } } - fn process_place(&mut self, - place_ref: &mir::PlaceRef<'_, 'tcx>, - context: PlaceContext, - location: Location) { + fn process_place( + &mut self, + place_ref: &mir::PlaceRef<'_, 'tcx>, + context: PlaceContext, + location: Location, + ) { let cx = self.fx.cx; if let Some(proj) = place_ref.projection { @@ -116,12 +122,17 @@ impl> LocalAnalyzer<'mir, 'a, 'tcx, Bx> { .projection_ty(cx.tcx(), &proj.elem) .ty; let elem_ty = self.fx.monomorphize(&elem_ty); - if cx.layout_of(elem_ty).is_zst() { + let span = if let mir::PlaceBase::Local(index) = place_ref.base { + self.fx.mir.local_decls[*index].source_info.span + } else { + DUMMY_SP + }; + if cx.spanned_layout_of(elem_ty, span).is_zst() { return; } if let mir::ProjectionElem::Field(..) = proj.elem { - let layout = cx.layout_of(base_ty.ty); + let layout = cx.spanned_layout_of(base_ty.ty, span); if cx.is_backend_immediate(layout) || cx.is_backend_scalar_pair(layout) { // Recurse with the same context, instead of `Projection`, // potentially stopping at non-operand projections, diff --git a/src/test/ui/consts/issue-55878.stderr b/src/test/ui/consts/issue-55878.stderr index 184c6d0e29293..aa4dfb719f905 100644 --- a/src/test/ui/consts/issue-55878.stderr +++ b/src/test/ui/consts/issue-55878.stderr @@ -2,7 +2,7 @@ error[E0080]: the type `[u8; 18446744073709551615]` is too big for the current a --> $SRC_DIR/libcore/mem/mod.rs:LL:COL | LL | intrinsics::size_of::() - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ the type `[u8; 18446744073709551615]` is too big for the current architecture + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | ::: $DIR/issue-55878.rs:3:26 | diff --git a/src/test/ui/huge-enum.rs b/src/test/ui/huge-enum.rs index 2492afbdc8f81..8ac15f3156bfd 100644 --- a/src/test/ui/huge-enum.rs +++ b/src/test/ui/huge-enum.rs @@ -1,16 +1,14 @@ -// normalize-stderr-test "std::option::Option<\[u32; \d+\]>" -> "TYPE" -// normalize-stderr-test "\[u32; \d+\]" -> "TYPE" - // FIXME https://github.com/rust-lang/rust/issues/59774 // normalize-stderr-test "thread.*panicked.*Metadata module not compiled.*\n" -> "" // normalize-stderr-test "note:.*RUST_BACKTRACE=1.*\n" -> "" #[cfg(target_pointer_width = "32")] -fn main() { - let big: Option<[u32; (1<<29)-1]> = None; -} +type BIG = Option<[u32; (1<<29)-1]>; #[cfg(target_pointer_width = "64")] +type BIG = Option<[u32; (1<<45)-1]>; + fn main() { - let big: Option<[u32; (1<<45)-1]> = None; + let big: BIG = None; + //~^ ERROR is too big for the current architecture } diff --git a/src/test/ui/huge-enum.stderr b/src/test/ui/huge-enum.stderr index 67cae3d52ed2d..94349f475e9be 100644 --- a/src/test/ui/huge-enum.stderr +++ b/src/test/ui/huge-enum.stderr @@ -1,4 +1,8 @@ -error: the type `TYPE` is too big for the current architecture +error: the type `std::option::Option<[u32; 35184372088831]>` is too big for the current architecture + --> $DIR/huge-enum.rs:12:9 + | +LL | let big: BIG = None; + | ^^^ error: aborting due to previous error diff --git a/src/test/ui/huge-struct.rs b/src/test/ui/huge-struct.rs index dc7d75a6f028e..e120cae7fdd14 100644 --- a/src/test/ui/huge-struct.rs +++ b/src/test/ui/huge-struct.rs @@ -47,4 +47,6 @@ struct S1M { val: S1k> } fn main() { let fat: Option>>> = None; + //~^ ERROR the type `S32>>` is too big for the current architecture + } diff --git a/src/test/ui/huge-struct.stderr b/src/test/ui/huge-struct.stderr index 06b084bdc3a39..5c2140df48126 100644 --- a/src/test/ui/huge-struct.stderr +++ b/src/test/ui/huge-struct.stderr @@ -1,4 +1,8 @@ error: the type `SXX>>` is too big for the current architecture + --> $DIR/huge-struct.rs:49:9 + | +LL | let fat: Option>>> = None; + | ^^^ error: aborting due to previous error diff --git a/src/test/ui/issues/issue-56762.stderr b/src/test/ui/issues/issue-56762.stderr index e74904f1f6818..69626d4bc7a9e 100644 --- a/src/test/ui/issues/issue-56762.stderr +++ b/src/test/ui/issues/issue-56762.stderr @@ -2,13 +2,13 @@ error[E0080]: the type `[u8; 2305843009213693951]` is too big for the current ar --> $DIR/issue-56762.rs:19:1 | LL | static MY_TOO_BIG_ARRAY_1: TooBigArray = TooBigArray::new(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the type `[u8; 2305843009213693951]` is too big for the current architecture + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0080]: the type `[u8; 2305843009213693951]` is too big for the current architecture --> $DIR/issue-56762.rs:21:1 | LL | static MY_TOO_BIG_ARRAY_2: [u8; HUGE_SIZE] = [0x00; HUGE_SIZE]; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the type `[u8; 2305843009213693951]` is too big for the current architecture + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 2 previous errors From f621f890a6e427b6074f0a8561fe1c95feff743d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sun, 4 Aug 2019 13:14:53 -0700 Subject: [PATCH 12/18] revert change to single test --- src/test/ui/huge-enum.rs | 3 +++ src/test/ui/huge-enum.stderr | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/test/ui/huge-enum.rs b/src/test/ui/huge-enum.rs index 8ac15f3156bfd..98d0ba6e15c09 100644 --- a/src/test/ui/huge-enum.rs +++ b/src/test/ui/huge-enum.rs @@ -1,3 +1,6 @@ +// normalize-stderr-test "std::option::Option<\[u32; \d+\]>" -> "TYPE" +// normalize-stderr-test "\[u32; \d+\]" -> "TYPE" + // FIXME https://github.com/rust-lang/rust/issues/59774 // normalize-stderr-test "thread.*panicked.*Metadata module not compiled.*\n" -> "" // normalize-stderr-test "note:.*RUST_BACKTRACE=1.*\n" -> "" diff --git a/src/test/ui/huge-enum.stderr b/src/test/ui/huge-enum.stderr index 94349f475e9be..1f16c81a8f45e 100644 --- a/src/test/ui/huge-enum.stderr +++ b/src/test/ui/huge-enum.stderr @@ -1,5 +1,5 @@ -error: the type `std::option::Option<[u32; 35184372088831]>` is too big for the current architecture - --> $DIR/huge-enum.rs:12:9 +error: the type `TYPE` is too big for the current architecture + --> $DIR/huge-enum.rs:15:9 | LL | let big: BIG = None; | ^^^ From 18130ef044cfa83af341c4a3500ab576f8cc4c38 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Mon, 5 Aug 2019 10:21:25 -0400 Subject: [PATCH 13/18] Replace error callback with Result --- src/librustc_resolve/lib.rs | 47 +++++++++++++++++++------------------ 1 file changed, 24 insertions(+), 23 deletions(-) diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 1a203e73f0a86..3dd1d7d274d5a 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -1771,8 +1771,13 @@ impl<'a> hir::lowering::Resolver for Resolver<'a> { path: &ast::Path, is_value: bool, ) -> Res { - self.resolve_ast_path_cb(path, is_value, - |resolver, span, error| resolve_error(resolver, span, error)) + match self.resolve_ast_path_inner(path, is_value) { + Ok(r) => r, + Err((span, error)) => { + resolve_error(self, span, error); + Res::Err + } + } } fn resolve_str_path( @@ -1833,8 +1838,6 @@ impl<'a> Resolver<'a> { /// just that an error occurred. pub fn resolve_str_path_error(&mut self, span: Span, path_str: &str, is_value: bool) -> Result<(ast::Path, Res), ()> { - let mut errored = false; - let path = if path_str.starts_with("::") { ast::Path { span, @@ -1855,24 +1858,24 @@ impl<'a> Resolver<'a> { .collect(), } }; - let res = self.resolve_ast_path_cb(&path, is_value, |_, _, _| errored = true); - if errored || res == def::Res::Err { - Err(()) - } else { - Ok((path, res)) + match self.resolve_ast_path_inner(&path, is_value) { + Ok(res) => { + if res == Res::Err { + Err(()) + } else { + Ok((path, res)) + } + } + Err(_) => Err(()), } } /// Like `resolve_ast_path`, but takes a callback in case there was an error. - // FIXME(eddyb) use `Result` or something instead of callbacks. - fn resolve_ast_path_cb( + fn resolve_ast_path_inner( &mut self, path: &ast::Path, is_value: bool, - error_callback: F, - ) -> Res - where F: for<'c, 'b> FnOnce(&'c mut Resolver<'_>, Span, ResolutionError<'b>) - { + ) -> Result)> { let namespace = if is_value { ValueNS } else { TypeNS }; let span = path.span; let path = Segment::from_path(&path); @@ -1880,23 +1883,21 @@ impl<'a> Resolver<'a> { match self.resolve_path_without_parent_scope(&path, Some(namespace), true, span, CrateLint::No) { PathResult::Module(ModuleOrUniformRoot::Module(module)) => - module.res().unwrap(), + Ok(module.res().unwrap()), PathResult::NonModule(path_res) if path_res.unresolved_segments() == 0 => - path_res.base_res(), + Ok(path_res.base_res()), PathResult::NonModule(..) => { - error_callback(self, span, ResolutionError::FailedToResolve { + Err((span, ResolutionError::FailedToResolve { label: String::from("type-relative paths are not supported in this context"), suggestion: None, - }); - Res::Err + })) } PathResult::Module(..) | PathResult::Indeterminate => unreachable!(), PathResult::Failed { span, label, suggestion, .. } => { - error_callback(self, span, ResolutionError::FailedToResolve { + Err((span, ResolutionError::FailedToResolve { label, suggestion, - }); - Res::Err + })) } } } From 3cd7f08ed1f801c2fa4983d9eef9162739922373 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Mon, 5 Aug 2019 12:25:32 -0400 Subject: [PATCH 14/18] Force callers of resolve_ast_path to deal with Res::Err correctly --- src/librustc_resolve/lib.rs | 12 ++---------- src/librustdoc/passes/collect_intra_doc_links.rs | 7 +++++++ 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 3dd1d7d274d5a..ba70355899879 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -1858,16 +1858,8 @@ impl<'a> Resolver<'a> { .collect(), } }; - match self.resolve_ast_path_inner(&path, is_value) { - Ok(res) => { - if res == Res::Err { - Err(()) - } else { - Ok((path, res)) - } - } - Err(_) => Err(()), - } + let res = self.resolve_ast_path_inner(&path, is_value).map_err(|_| ())?; + Ok((path, res)) } /// Like `resolve_ast_path`, but takes a callback in case there was an error. diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index 04de3374d0587..84cfdd790b733 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -71,6 +71,10 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> { resolver.resolve_str_path_error(DUMMY_SP, &path_str, ns == ValueNS) }) }); + let result = match result { + Ok((_, Res::Err)) => Err(()), + _ => result, + }; if let Ok((_, res)) = result { let res = res.map_id(|_| panic!("unexpected node_id")); @@ -134,6 +138,9 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> { let (_, ty_res) = cx.enter_resolver(|resolver| resolver.with_scope(node_id, |resolver| { resolver.resolve_str_path_error(DUMMY_SP, &path, false) }))?; + if let Res::Err = ty_res { + return Err(()); + } let ty_res = ty_res.map_id(|_| panic!("unexpected node_id")); match ty_res { Res::Def(DefKind::Struct, did) From e1875742d024c9ac52889d26881ca39a2a14cd8e Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Mon, 5 Aug 2019 20:13:59 +0200 Subject: [PATCH 15/18] assume_init: warn about valid != safe --- src/libcore/mem/maybe_uninit.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/libcore/mem/maybe_uninit.rs b/src/libcore/mem/maybe_uninit.rs index 64fdf504369f2..20367f724b6f3 100644 --- a/src/libcore/mem/maybe_uninit.rs +++ b/src/libcore/mem/maybe_uninit.rs @@ -402,6 +402,13 @@ impl MaybeUninit { /// /// [inv]: #initialization-invariant /// + /// On top of that, remember that most types have additional invariants beyond merely + /// being considered initialized at the type level. For example, a `1`-initialized [`Vec`] + /// is considered initialized because the only requirement the compiler knows about it + /// is that the data pointer must be non-null. Creating such a `Vec` does not cause + /// *immediate* undefined behavior, but will cause undefined behavior with most + /// safe operations (including dropping it). + /// /// # Examples /// /// Correct usage of this method: From ce8510a21445c1443d2657968c474dc658a0abf9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sun, 4 Aug 2019 21:18:05 -0700 Subject: [PATCH 16/18] fix tests --- src/test/ui/consts/issue-55878.rs | 5 ++++- src/test/ui/consts/issue-55878.stderr | 4 ++-- src/test/ui/huge-array-simple-32.rs | 11 +++++++++++ src/test/ui/huge-array-simple-32.stderr | 8 ++++++++ src/test/ui/huge-array-simple-64.rs | 11 +++++++++++ src/test/ui/huge-array-simple-64.stderr | 8 ++++++++ src/test/ui/huge-array-simple.rs | 20 -------------------- src/test/ui/huge-array-simple.stderr | 8 -------- src/test/ui/issues/issue-15919-32.rs | 9 +++++++++ src/test/ui/issues/issue-15919-32.stderr | 8 ++++++++ src/test/ui/issues/issue-15919-64.rs | 9 +++++++++ src/test/ui/issues/issue-15919-64.stderr | 8 ++++++++ src/test/ui/issues/issue-15919.rs | 16 ---------------- src/test/ui/issues/issue-15919.stderr | 8 -------- 14 files changed, 78 insertions(+), 55 deletions(-) create mode 100644 src/test/ui/huge-array-simple-32.rs create mode 100644 src/test/ui/huge-array-simple-32.stderr create mode 100644 src/test/ui/huge-array-simple-64.rs create mode 100644 src/test/ui/huge-array-simple-64.stderr delete mode 100644 src/test/ui/huge-array-simple.rs delete mode 100644 src/test/ui/huge-array-simple.stderr create mode 100644 src/test/ui/issues/issue-15919-32.rs create mode 100644 src/test/ui/issues/issue-15919-32.stderr create mode 100644 src/test/ui/issues/issue-15919-64.rs create mode 100644 src/test/ui/issues/issue-15919-64.stderr delete mode 100644 src/test/ui/issues/issue-15919.rs delete mode 100644 src/test/ui/issues/issue-15919.stderr diff --git a/src/test/ui/consts/issue-55878.rs b/src/test/ui/consts/issue-55878.rs index 6d8159e2fcdde..aa1dd58d2463d 100644 --- a/src/test/ui/consts/issue-55878.rs +++ b/src/test/ui/consts/issue-55878.rs @@ -1,4 +1,7 @@ -// error-pattern: the type `[u8; 18446744073709551615]` is too big for the current architecture +// normalize-stderr-64bit "18446744073709551615" -> "SIZE" +// normalize-stderr-32bit "4294967295" -> "SIZE" + +// error-pattern: is too big for the current architecture fn main() { println!("Size: {}", std::mem::size_of::<[u8; std::u64::MAX as usize]>()); } diff --git a/src/test/ui/consts/issue-55878.stderr b/src/test/ui/consts/issue-55878.stderr index aa4dfb719f905..4332c7f19dc11 100644 --- a/src/test/ui/consts/issue-55878.stderr +++ b/src/test/ui/consts/issue-55878.stderr @@ -1,10 +1,10 @@ -error[E0080]: the type `[u8; 18446744073709551615]` is too big for the current architecture +error[E0080]: the type `[u8; SIZE]` is too big for the current architecture --> $SRC_DIR/libcore/mem/mod.rs:LL:COL | LL | intrinsics::size_of::() | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | - ::: $DIR/issue-55878.rs:3:26 + ::: $DIR/issue-55878.rs:6:26 | LL | println!("Size: {}", std::mem::size_of::<[u8; std::u64::MAX as usize]>()); | --------------------------------------------------- diff --git a/src/test/ui/huge-array-simple-32.rs b/src/test/ui/huge-array-simple-32.rs new file mode 100644 index 0000000000000..f72d69ee747b8 --- /dev/null +++ b/src/test/ui/huge-array-simple-32.rs @@ -0,0 +1,11 @@ +// ignore-32bit + +// FIXME https://github.com/rust-lang/rust/issues/59774 +// normalize-stderr-test "thread.*panicked.*Metadata module not compiled.*\n" -> "" +// normalize-stderr-test "note:.*RUST_BACKTRACE=1.*\n" -> "" +#![allow(exceeding_bitshifts)] + +fn main() { + let _fat: [u8; (1<<61)+(1<<31)] = //~ ERROR too big for the current architecture + [0; (1u64<<61) as usize +(1u64<<31) as usize]; +} diff --git a/src/test/ui/huge-array-simple-32.stderr b/src/test/ui/huge-array-simple-32.stderr new file mode 100644 index 0000000000000..70d9194ea55c5 --- /dev/null +++ b/src/test/ui/huge-array-simple-32.stderr @@ -0,0 +1,8 @@ +error: the type `[u8; 2305843011361177600]` is too big for the current architecture + --> $DIR/huge-array-simple-32.rs:9:9 + | +LL | let _fat: [u8; (1<<61)+(1<<31)] = + | ^^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/huge-array-simple-64.rs b/src/test/ui/huge-array-simple-64.rs new file mode 100644 index 0000000000000..9f98f4d753190 --- /dev/null +++ b/src/test/ui/huge-array-simple-64.rs @@ -0,0 +1,11 @@ +// ignore-64bit + +// FIXME https://github.com/rust-lang/rust/issues/59774 +// normalize-stderr-test "thread.*panicked.*Metadata module not compiled.*\n" -> "" +// normalize-stderr-test "note:.*RUST_BACKTRACE=1.*\n" -> "" +#![allow(exceeding_bitshifts)] + +fn main() { + let _fat: [u8; (1<<31)+(1<<15)] = //~ ERROR too big for the current architecture + [0; (1u32<<31) as usize +(1u32<<15) as usize]; +} diff --git a/src/test/ui/huge-array-simple-64.stderr b/src/test/ui/huge-array-simple-64.stderr new file mode 100644 index 0000000000000..3f8e79e5b0b6e --- /dev/null +++ b/src/test/ui/huge-array-simple-64.stderr @@ -0,0 +1,8 @@ +error: the type `[u8; 2147516416]` is too big for the current architecture + --> $DIR/huge-array-simple-64.rs:9:9 + | +LL | let _fat: [u8; (1<<31)+(1<<15)] = + | ^^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/huge-array-simple.rs b/src/test/ui/huge-array-simple.rs deleted file mode 100644 index 0ff27168a7d86..0000000000000 --- a/src/test/ui/huge-array-simple.rs +++ /dev/null @@ -1,20 +0,0 @@ -// error-pattern: too big for the current architecture - -// normalize-stderr-test "; \d+]" -> "; N]" - -// FIXME https://github.com/rust-lang/rust/issues/59774 -// normalize-stderr-test "thread.*panicked.*Metadata module not compiled.*\n" -> "" -// normalize-stderr-test "note:.*RUST_BACKTRACE=1.*\n" -> "" -#![allow(exceeding_bitshifts)] - -#[cfg(target_pointer_width = "64")] -fn main() { - let _fat : [u8; (1<<61)+(1<<31)] = - [0; (1u64<<61) as usize +(1u64<<31) as usize]; -} - -#[cfg(target_pointer_width = "32")] -fn main() { - let _fat : [u8; (1<<31)+(1<<15)] = - [0; (1u32<<31) as usize +(1u32<<15) as usize]; -} diff --git a/src/test/ui/huge-array-simple.stderr b/src/test/ui/huge-array-simple.stderr deleted file mode 100644 index 71d3f62bbe53b..0000000000000 --- a/src/test/ui/huge-array-simple.stderr +++ /dev/null @@ -1,8 +0,0 @@ -error: the type `[u8; N]` is too big for the current architecture - --> $DIR/huge-array-simple.rs:12:9 - | -LL | let _fat : [u8; (1<<61)+(1<<31)] = - | ^^^^ - -error: aborting due to previous error - diff --git a/src/test/ui/issues/issue-15919-32.rs b/src/test/ui/issues/issue-15919-32.rs new file mode 100644 index 0000000000000..92394a4e54e9e --- /dev/null +++ b/src/test/ui/issues/issue-15919-32.rs @@ -0,0 +1,9 @@ +// ignore-64bit + +// FIXME https://github.com/rust-lang/rust/issues/59774 +// normalize-stderr-test "thread.*panicked.*Metadata module not compiled.*\n" -> "" +// normalize-stderr-test "note:.*RUST_BACKTRACE=1.*\n" -> "" + +fn main() { + let x = [0usize; 0xffff_ffff]; //~ ERROR too big +} diff --git a/src/test/ui/issues/issue-15919-32.stderr b/src/test/ui/issues/issue-15919-32.stderr new file mode 100644 index 0000000000000..7f5d9262d39a7 --- /dev/null +++ b/src/test/ui/issues/issue-15919-32.stderr @@ -0,0 +1,8 @@ +error: the type `[usize; 4294967295]` is too big for the current architecture + --> $DIR/issue-15919-32.rs:8:9 + | +LL | let x = [0usize; 0xffff_ffff]; + | ^ + +error: aborting due to previous error + diff --git a/src/test/ui/issues/issue-15919-64.rs b/src/test/ui/issues/issue-15919-64.rs new file mode 100644 index 0000000000000..938ee92e2f256 --- /dev/null +++ b/src/test/ui/issues/issue-15919-64.rs @@ -0,0 +1,9 @@ +// ignore-32bit + +// FIXME https://github.com/rust-lang/rust/issues/59774 +// normalize-stderr-test "thread.*panicked.*Metadata module not compiled.*\n" -> "" +// normalize-stderr-test "note:.*RUST_BACKTRACE=1.*\n" -> "" + +fn main() { + let x = [0usize; 0xffff_ffff_ffff_ffff]; //~ ERROR too big +} diff --git a/src/test/ui/issues/issue-15919-64.stderr b/src/test/ui/issues/issue-15919-64.stderr new file mode 100644 index 0000000000000..571b87d9961c0 --- /dev/null +++ b/src/test/ui/issues/issue-15919-64.stderr @@ -0,0 +1,8 @@ +error: the type `[usize; 18446744073709551615]` is too big for the current architecture + --> $DIR/issue-15919-64.rs:8:9 + | +LL | let x = [0usize; 0xffff_ffff_ffff_ffff]; + | ^ + +error: aborting due to previous error + diff --git a/src/test/ui/issues/issue-15919.rs b/src/test/ui/issues/issue-15919.rs deleted file mode 100644 index a7ac4802a12d5..0000000000000 --- a/src/test/ui/issues/issue-15919.rs +++ /dev/null @@ -1,16 +0,0 @@ -// error-pattern: too big for the current architecture -// normalize-stderr-test "\[usize; \d+\]" -> "[usize; N]" - -// FIXME https://github.com/rust-lang/rust/issues/59774 -// normalize-stderr-test "thread.*panicked.*Metadata module not compiled.*\n" -> "" -// normalize-stderr-test "note:.*RUST_BACKTRACE=1.*\n" -> "" - -#[cfg(target_pointer_width = "32")] -fn main() { - let x = [0usize; 0xffff_ffff]; -} - -#[cfg(target_pointer_width = "64")] -fn main() { - let x = [0usize; 0xffff_ffff_ffff_ffff]; -} diff --git a/src/test/ui/issues/issue-15919.stderr b/src/test/ui/issues/issue-15919.stderr deleted file mode 100644 index 66c768537843c..0000000000000 --- a/src/test/ui/issues/issue-15919.stderr +++ /dev/null @@ -1,8 +0,0 @@ -error: the type `[usize; N]` is too big for the current architecture - --> $DIR/issue-15919.rs:15:9 - | -LL | let x = [0usize; 0xffff_ffff_ffff_ffff]; - | ^ - -error: aborting due to previous error - From 1b9eb4ac4cb5ecc5a16a1ed781a88af4c65bfc2f Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Tue, 6 Aug 2019 09:47:42 +0200 Subject: [PATCH 17/18] be clear that 1-init Vec being valid (but not safe) is not a stable guarantee --- src/libcore/mem/maybe_uninit.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/libcore/mem/maybe_uninit.rs b/src/libcore/mem/maybe_uninit.rs index 20367f724b6f3..43c4b491ac89d 100644 --- a/src/libcore/mem/maybe_uninit.rs +++ b/src/libcore/mem/maybe_uninit.rs @@ -51,7 +51,8 @@ use crate::mem::ManuallyDrop; /// /// On top of that, remember that most types have additional invariants beyond merely /// being considered initialized at the type level. For example, a `1`-initialized [`Vec`] -/// is considered initialized because the only requirement the compiler knows about it +/// is considered initialized (under the current implementation, this does not constitute +/// a stable guarantee) because the only requirement the compiler knows about it /// is that the data pointer must be non-null. Creating such a `Vec` does not cause /// *immediate* undefined behavior, but will cause undefined behavior with most /// safe operations (including dropping it). @@ -404,7 +405,8 @@ impl MaybeUninit { /// /// On top of that, remember that most types have additional invariants beyond merely /// being considered initialized at the type level. For example, a `1`-initialized [`Vec`] - /// is considered initialized because the only requirement the compiler knows about it + /// is considered initialized (under the current implementation, this does not constitute + /// a stable guarantee) because the only requirement the compiler knows about it /// is that the data pointer must be non-null. Creating such a `Vec` does not cause /// *immediate* undefined behavior, but will cause undefined behavior with most /// safe operations (including dropping it). From 1821414b7bb496545ef147644cf5691db433ab5d Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Tue, 6 Aug 2019 10:41:48 +0200 Subject: [PATCH 18/18] clarify --- src/libcore/mem/maybe_uninit.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libcore/mem/maybe_uninit.rs b/src/libcore/mem/maybe_uninit.rs index 43c4b491ac89d..ff063759cba62 100644 --- a/src/libcore/mem/maybe_uninit.rs +++ b/src/libcore/mem/maybe_uninit.rs @@ -51,7 +51,7 @@ use crate::mem::ManuallyDrop; /// /// On top of that, remember that most types have additional invariants beyond merely /// being considered initialized at the type level. For example, a `1`-initialized [`Vec`] -/// is considered initialized (under the current implementation, this does not constitute +/// is considered initialized (under the current implementation; this does not constitute /// a stable guarantee) because the only requirement the compiler knows about it /// is that the data pointer must be non-null. Creating such a `Vec` does not cause /// *immediate* undefined behavior, but will cause undefined behavior with most @@ -405,7 +405,7 @@ impl MaybeUninit { /// /// On top of that, remember that most types have additional invariants beyond merely /// being considered initialized at the type level. For example, a `1`-initialized [`Vec`] - /// is considered initialized (under the current implementation, this does not constitute + /// is considered initialized (under the current implementation; this does not constitute /// a stable guarantee) because the only requirement the compiler knows about it /// is that the data pointer must be non-null. Creating such a `Vec` does not cause /// *immediate* undefined behavior, but will cause undefined behavior with most