]> git.lizzy.rs Git - rust.git/commitdiff
Rollup merge of #63285 - Mark-Simulacrum:rm-await-origin, r=Centril
authorMazdak Farrokhzad <twingoow@gmail.com>
Tue, 6 Aug 2019 06:17:44 +0000 (08:17 +0200)
committerGitHub <noreply@github.com>
Tue, 6 Aug 2019 06:17:44 +0000 (08:17 +0200)
Remove leftover AwaitOrigin

This was missed in PR #62293.

107 files changed:
src/libcore/iter/adapters/mod.rs
src/libcore/tests/iter.rs
src/libcore/tests/ptr.rs
src/librustc/hir/lowering.rs
src/librustc/ich/impls_syntax.rs
src/librustc/infer/combine.rs
src/librustc/infer/equate.rs
src/librustc/infer/glb.rs
src/librustc/infer/lub.rs
src/librustc/infer/nll_relate/mod.rs
src/librustc/infer/outlives/env.rs
src/librustc/infer/sub.rs
src/librustc/middle/expr_use_visitor.rs
src/librustc/middle/mem_categorization.rs
src/librustc/mir/tcx.rs
src/librustc/traits/error_reporting.rs
src/librustc/traits/select.rs
src/librustc/traits/specialize/mod.rs
src/librustc/ty/_match.rs
src/librustc/ty/error.rs
src/librustc/ty/inhabitedness/mod.rs
src/librustc/ty/layout.rs
src/librustc/ty/mod.rs
src/librustc/ty/print/obsolete.rs
src/librustc/ty/print/pretty.rs
src/librustc/ty/relate.rs
src/librustc/ty/sty.rs
src/librustc_codegen_llvm/debuginfo/metadata.rs
src/librustc_codegen_ssa/base.rs
src/librustc_codegen_ssa/debuginfo/type_names.rs
src/librustc_codegen_ssa/mir/constant.rs
src/librustc_codegen_ssa/mir/rvalue.rs
src/librustc_codegen_utils/symbol_names/v0.rs
src/librustc_lint/unused.rs
src/librustc_mir/borrow_check/conflict_errors.rs
src/librustc_mir/borrow_check/mod.rs
src/librustc_mir/borrow_check/nll/constraint_generation.rs
src/librustc_mir/borrow_check/nll/invalidation.rs
src/librustc_mir/borrow_check/nll/mod.rs
src/librustc_mir/borrow_check/nll/type_check/mod.rs
src/librustc_mir/borrow_check/path_utils.rs
src/librustc_mir/borrow_check/places_conflict.rs
src/librustc_mir/build/matches/test.rs
src/librustc_mir/dataflow/impls/borrows.rs
src/librustc_mir/hair/cx/expr.rs
src/librustc_mir/hair/pattern/_match.rs
src/librustc_mir/hair/pattern/mod.rs
src/librustc_mir/interpret/cast.rs
src/librustc_mir/interpret/intern.rs
src/librustc_mir/shim.rs
src/librustc_mir/transform/qualify_consts.rs
src/librustc_mir/transform/simplify_branches.rs
src/librustc_mir/transform/uniform_array_move_out.rs
src/librustc_mir/util/elaborate_drops.rs
src/librustc_traits/chalk_context/resolvent_ops.rs
src/librustc_typeck/check/_match.rs
src/librustc_typeck/check/expr.rs
src/librustc_typeck/check/regionck.rs
src/librustdoc/clean/cfg/tests.rs
src/librustdoc/html/highlight.rs
src/librustdoc/passes/check_code_block_syntax.rs
src/libstd/path.rs
src/libstd/thread/local.rs
src/libsyntax/attr/mod.rs
src/libsyntax/ext/build.rs
src/libsyntax/ext/expand.rs
src/libsyntax/ext/proc_macro_server.rs
src/libsyntax/parse/lexer/mod.rs
src/libsyntax/parse/lexer/tokentrees.rs
src/libsyntax/parse/token.rs
src/libsyntax/print/pprust.rs
src/libsyntax_ext/test_harness.rs
src/test/rustdoc-ui/invalid-syntax.stderr
src/test/ui/async-await/partial-initialization-across-await.rs [new file with mode: 0644]
src/test/ui/async-await/partial-initialization-across-await.stderr [new file with mode: 0644]
src/test/ui/borrowck/disallow-possibly-uninitialized.rs [new file with mode: 0644]
src/test/ui/borrowck/disallow-possibly-uninitialized.stderr [new file with mode: 0644]
src/test/ui/coherence/coherence-overlap-upstream.old.stderr
src/test/ui/coherence/coherence-overlap-upstream.re.stderr
src/test/ui/coherence/coherence_copy_like_err_fundamental_struct_tuple.old.stderr
src/test/ui/coherence/coherence_copy_like_err_fundamental_struct_tuple.re.stderr
src/test/ui/coherence/coherence_copy_like_err_struct.old.stderr
src/test/ui/coherence/coherence_copy_like_err_struct.re.stderr
src/test/ui/coherence/coherence_copy_like_err_tuple.old.stderr
src/test/ui/coherence/coherence_copy_like_err_tuple.re.stderr
src/test/ui/consts/const_let_refutable.nll.stderr [deleted file]
src/test/ui/consts/const_let_refutable.rs
src/test/ui/consts/const_let_refutable.stderr
src/test/ui/consts/self_normalization.rs [new file with mode: 0644]
src/test/ui/consts/self_normalization2.rs [new file with mode: 0644]
src/test/ui/empty/empty-never-array.nll.stderr [deleted file]
src/test/ui/empty/empty-never-array.rs
src/test/ui/empty/empty-never-array.stderr
src/test/ui/generator/partial-initialization-across-yield.rs [new file with mode: 0644]
src/test/ui/generator/partial-initialization-across-yield.stderr [new file with mode: 0644]
src/test/ui/issues/issue-15381.nll.stderr [deleted file]
src/test/ui/issues/issue-15381.rs
src/test/ui/issues/issue-15381.stderr
src/test/ui/issues/issue-48728.stderr
src/test/ui/parser/lex-bad-token.rs
src/test/ui/parser/lex-stray-backslash.rs
src/test/ui/parser/unicode-quote-chars.rs
src/test/ui/parser/unicode-quote-chars.stderr
src/test/ui/recursion/recursive-types-are-not-uninhabited.nll.stderr [deleted file]
src/test/ui/recursion/recursive-types-are-not-uninhabited.rs
src/test/ui/recursion/recursive-types-are-not-uninhabited.stderr
src/test/ui/specialization/issue-52050.stderr

index 8eae52ffd3277e43a2b44048a53b83be93a72b8d..af46e6df2942b21711a2e570470540732573464b 100644 (file)
@@ -485,6 +485,39 @@ fn nth(&mut self, mut n: usize) -> Option<Self::Item> {
     }
 }
 
+impl<I> StepBy<I> where I: ExactSizeIterator {
+    // The zero-based index starting from the end of the iterator of the
+    // last element. Used in the `DoubleEndedIterator` implementation.
+    fn next_back_index(&self) -> usize {
+        let rem = self.iter.len() % (self.step + 1);
+        if self.first_take {
+            if rem == 0 { self.step } else { rem - 1 }
+        } else {
+            rem
+        }
+    }
+}
+
+#[stable(feature = "double_ended_step_by_iterator", since = "1.38.0")]
+impl<I> DoubleEndedIterator for StepBy<I> where I: DoubleEndedIterator + ExactSizeIterator {
+    #[inline]
+    fn next_back(&mut self) -> Option<Self::Item> {
+        self.iter.nth_back(self.next_back_index())
+    }
+
+    #[inline]
+    fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
+        // `self.iter.nth_back(usize::MAX)` does the right thing here when `n`
+        // is out of bounds because the length of `self.iter` does not exceed
+        // `usize::MAX` (because `I: ExactSizeIterator`) and `nth_back` is
+        // zero-indexed
+        let n = n
+            .saturating_mul(self.step + 1)
+            .saturating_add(self.next_back_index());
+        self.iter.nth_back(n)
+    }
+}
+
 // StepBy can only make the iterator shorter, so the len will still fit.
 #[stable(feature = "iterator_step_by", since = "1.28.0")]
 impl<I> ExactSizeIterator for StepBy<I> where I: ExactSizeIterator {}
@@ -1158,6 +1191,45 @@ fn fold<Acc, Fold>(self, init: Acc, mut fold: Fold) -> Acc
     }
 }
 
+#[stable(feature = "double_ended_peek_iterator", since = "1.38.0")]
+impl<I> DoubleEndedIterator for Peekable<I> where I: DoubleEndedIterator {
+    #[inline]
+    fn next_back(&mut self) -> Option<Self::Item> {
+        self.iter.next_back().or_else(|| self.peeked.take().and_then(|x| x))
+    }
+
+    #[inline]
+    fn try_rfold<B, F, R>(&mut self, init: B, mut f: F) -> R where
+        Self: Sized, F: FnMut(B, Self::Item) -> R, R: Try<Ok=B>
+    {
+        match self.peeked.take() {
+            Some(None) => return Try::from_ok(init),
+            Some(Some(v)) => match self.iter.try_rfold(init, &mut f).into_result() {
+                Ok(acc) => f(acc, v),
+                Err(e) => {
+                    self.peeked = Some(Some(v));
+                    Try::from_error(e)
+                }
+            },
+            None => self.iter.try_rfold(init, f),
+        }
+    }
+
+    #[inline]
+    fn rfold<Acc, Fold>(self, init: Acc, mut fold: Fold) -> Acc
+        where Fold: FnMut(Acc, Self::Item) -> Acc,
+    {
+        match self.peeked {
+            Some(None) => return init,
+            Some(Some(v)) => {
+                let acc = self.iter.rfold(init, &mut fold);
+                fold(acc, v)
+            }
+            None => self.iter.rfold(init, fold),
+        }
+    }
+}
+
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<I: ExactSizeIterator> ExactSizeIterator for Peekable<I> {}
 
@@ -1627,6 +1699,51 @@ fn try_fold<Acc, Fold, R>(&mut self, init: Acc, mut fold: Fold) -> R where
     }
 }
 
+#[stable(feature = "double_ended_take_iterator", since = "1.38.0")]
+impl<I> DoubleEndedIterator for Take<I> where I: DoubleEndedIterator + ExactSizeIterator {
+    #[inline]
+    fn next_back(&mut self) -> Option<Self::Item> {
+        if self.n == 0 {
+            None
+        } else {
+            let n = self.n;
+            self.n -= 1;
+            self.iter.nth_back(self.iter.len().saturating_sub(n))
+        }
+    }
+
+    #[inline]
+    fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
+        let len = self.iter.len();
+        if self.n > n {
+            let m = len.saturating_sub(self.n) + n;
+            self.n -= n + 1;
+            self.iter.nth_back(m)
+        } else {
+            if len > 0 {
+                self.iter.nth_back(len - 1);
+            }
+            None
+        }
+    }
+
+    #[inline]
+    fn try_rfold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R where
+        Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try<Ok = Acc>
+    {
+        if self.n == 0 {
+            Try::from_ok(init)
+        } else {
+            let len = self.iter.len();
+            if len > self.n && self.iter.nth_back(len - self.n - 1).is_none() {
+                Try::from_ok(init)
+            } else {
+                self.iter.try_rfold(init, fold)
+            }
+        }
+    }
+}
+
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<I> ExactSizeIterator for Take<I> where I: ExactSizeIterator {}
 
index b7b0849e2129b65af0c1ab3c4e409f0fbb2c1f15..e27e1605607144f94b63a284015fab14e185bcac 100644 (file)
@@ -188,6 +188,19 @@ fn test_iterator_step_by() {
     assert_eq!(it.next(), Some(6));
     assert_eq!(it.next(), Some(9));
     assert_eq!(it.next(), None);
+
+    let mut it = (0..3).step_by(1);
+    assert_eq!(it.next_back(), Some(2));
+    assert_eq!(it.next_back(), Some(1));
+    assert_eq!(it.next_back(), Some(0));
+    assert_eq!(it.next_back(), None);
+
+    let mut it = (0..11).step_by(3);
+    assert_eq!(it.next_back(), Some(9));
+    assert_eq!(it.next_back(), Some(6));
+    assert_eq!(it.next_back(), Some(3));
+    assert_eq!(it.next_back(), Some(0));
+    assert_eq!(it.next_back(), None);
 }
 
 #[test]
@@ -252,6 +265,31 @@ fn nth(&mut self, n: usize) -> Option<Self::Item> {
     assert_eq!(it.0, (usize::MAX as Bigger) * 1);
 }
 
+#[test]
+fn test_iterator_step_by_nth_back() {
+    let mut it = (0..16).step_by(5);
+    assert_eq!(it.nth_back(0), Some(15));
+    assert_eq!(it.nth_back(0), Some(10));
+    assert_eq!(it.nth_back(0), Some(5));
+    assert_eq!(it.nth_back(0), Some(0));
+    assert_eq!(it.nth_back(0), None);
+
+    let mut it = (0..16).step_by(5);
+    assert_eq!(it.next(), Some(0)); // to set `first_take` to `false`
+    assert_eq!(it.nth_back(0), Some(15));
+    assert_eq!(it.nth_back(0), Some(10));
+    assert_eq!(it.nth_back(0), Some(5));
+    assert_eq!(it.nth_back(0), None);
+
+    let it = || (0..18).step_by(5);
+    assert_eq!(it().nth_back(0), Some(15));
+    assert_eq!(it().nth_back(1), Some(10));
+    assert_eq!(it().nth_back(2), Some(5));
+    assert_eq!(it().nth_back(3), Some(0));
+    assert_eq!(it().nth_back(4), None);
+    assert_eq!(it().nth_back(42), None);
+}
+
 #[test]
 #[should_panic]
 fn test_iterator_step_by_zero() {
@@ -465,8 +503,8 @@ fn test_iterator_filter_fold() {
 #[test]
 fn test_iterator_peekable() {
     let xs = vec![0, 1, 2, 3, 4, 5];
-    let mut it = xs.iter().cloned().peekable();
 
+    let mut it = xs.iter().cloned().peekable();
     assert_eq!(it.len(), 6);
     assert_eq!(it.peek().unwrap(), &0);
     assert_eq!(it.len(), 6);
@@ -492,6 +530,33 @@ fn test_iterator_peekable() {
     assert_eq!(it.len(), 0);
     assert!(it.next().is_none());
     assert_eq!(it.len(), 0);
+
+    let mut it = xs.iter().cloned().peekable();
+    assert_eq!(it.len(), 6);
+    assert_eq!(it.peek().unwrap(), &0);
+    assert_eq!(it.len(), 6);
+    assert_eq!(it.next_back().unwrap(), 5);
+    assert_eq!(it.len(), 5);
+    assert_eq!(it.next_back().unwrap(), 4);
+    assert_eq!(it.len(), 4);
+    assert_eq!(it.next_back().unwrap(), 3);
+    assert_eq!(it.len(), 3);
+    assert_eq!(it.peek().unwrap(), &0);
+    assert_eq!(it.len(), 3);
+    assert_eq!(it.peek().unwrap(), &0);
+    assert_eq!(it.len(), 3);
+    assert_eq!(it.next_back().unwrap(), 2);
+    assert_eq!(it.len(), 2);
+    assert_eq!(it.next_back().unwrap(), 1);
+    assert_eq!(it.len(), 1);
+    assert_eq!(it.peek().unwrap(), &0);
+    assert_eq!(it.len(), 1);
+    assert_eq!(it.next_back().unwrap(), 0);
+    assert_eq!(it.len(), 0);
+    assert!(it.peek().is_none());
+    assert_eq!(it.len(), 0);
+    assert!(it.next_back().is_none());
+    assert_eq!(it.len(), 0);
 }
 
 #[test]
@@ -564,6 +629,18 @@ fn test_iterator_peekable_fold() {
     assert_eq!(i, xs.len());
 }
 
+#[test]
+fn test_iterator_peekable_rfold() {
+    let xs = [0, 1, 2, 3, 4, 5];
+    let mut it = xs.iter().peekable();
+    assert_eq!(it.peek(), Some(&&0));
+    let i = it.rfold(0, |i, &x| {
+        assert_eq!(x, xs[xs.len() - 1 - i]);
+        i + 1
+    });
+    assert_eq!(i, xs.len());
+}
+
 /// This is an iterator that follows the Iterator contract,
 /// but it is not fused. After having returned None once, it will start
 /// producing elements if .next() is called again.
@@ -812,13 +889,25 @@ fn test_iterator_skip_fold() {
 fn test_iterator_take() {
     let xs = [0, 1, 2, 3, 5, 13, 15, 16, 17, 19];
     let ys = [0, 1, 2, 3, 5];
-    let mut it = xs.iter().take(5);
+
+    let mut it = xs.iter().take(ys.len());
     let mut i = 0;
-    assert_eq!(it.len(), 5);
+    assert_eq!(it.len(), ys.len());
     while let Some(&x) = it.next() {
         assert_eq!(x, ys[i]);
         i += 1;
-        assert_eq!(it.len(), 5-i);
+        assert_eq!(it.len(), ys.len() - i);
+    }
+    assert_eq!(i, ys.len());
+    assert_eq!(it.len(), 0);
+
+    let mut it = xs.iter().take(ys.len());
+    let mut i = 0;
+    assert_eq!(it.len(), ys.len());
+    while let Some(&x) = it.next_back() {
+        i += 1;
+        assert_eq!(x, ys[ys.len() - i]);
+        assert_eq!(it.len(), ys.len() - i);
     }
     assert_eq!(i, ys.len());
     assert_eq!(it.len(), 0);
@@ -848,19 +937,51 @@ fn test_iterator_take_nth() {
     }
 }
 
+#[test]
+fn test_iterator_take_nth_back() {
+    let xs = [0, 1, 2, 4, 5];
+    let mut it = xs.iter();
+    {
+        let mut take = it.by_ref().take(3);
+        let mut i = 0;
+        while let Some(&x) = take.nth_back(0) {
+            i += 1;
+            assert_eq!(x, 3 - i);
+        }
+    }
+    assert_eq!(it.nth_back(0), None);
+
+    let xs = [0, 1, 2, 3, 4];
+    let mut it = xs.iter().take(7);
+    assert_eq!(it.nth_back(1), Some(&3));
+    assert_eq!(it.nth_back(1), Some(&1));
+    assert_eq!(it.nth_back(1), None);
+}
+
 #[test]
 fn test_iterator_take_short() {
     let xs = [0, 1, 2, 3];
-    let ys = [0, 1, 2, 3];
+
     let mut it = xs.iter().take(5);
     let mut i = 0;
-    assert_eq!(it.len(), 4);
+    assert_eq!(it.len(), xs.len());
     while let Some(&x) = it.next() {
-        assert_eq!(x, ys[i]);
+        assert_eq!(x, xs[i]);
         i += 1;
-        assert_eq!(it.len(), 4-i);
+        assert_eq!(it.len(), xs.len() - i);
     }
-    assert_eq!(i, ys.len());
+    assert_eq!(i, xs.len());
+    assert_eq!(it.len(), 0);
+
+    let mut it = xs.iter().take(5);
+    let mut i = 0;
+    assert_eq!(it.len(), xs.len());
+    while let Some(&x) = it.next_back() {
+        i += 1;
+        assert_eq!(x, xs[xs.len() - i]);
+        assert_eq!(it.len(), xs.len() - i);
+    }
+    assert_eq!(i, xs.len());
     assert_eq!(it.len(), 0);
 }
 
@@ -2278,17 +2399,50 @@ fn test_enumerate_try_folds() {
 }
 
 #[test]
-fn test_peek_try_fold() {
+fn test_peek_try_folds() {
     let f = &|acc, x| i32::checked_add(2*acc, x);
+
     assert_eq!((1..20).peekable().try_fold(7, f), (1..20).try_fold(7, f));
+    assert_eq!((1..20).peekable().try_rfold(7, f), (1..20).try_rfold(7, f));
+
     let mut iter = (1..20).peekable();
     assert_eq!(iter.peek(), Some(&1));
     assert_eq!(iter.try_fold(7, f), (1..20).try_fold(7, f));
 
+    let mut iter = (1..20).peekable();
+    assert_eq!(iter.peek(), Some(&1));
+    assert_eq!(iter.try_rfold(7, f), (1..20).try_rfold(7, f));
+
     let mut iter = [100, 20, 30, 40, 50, 60, 70].iter().cloned().peekable();
     assert_eq!(iter.peek(), Some(&100));
     assert_eq!(iter.try_fold(0, i8::checked_add), None);
     assert_eq!(iter.peek(), Some(&40));
+
+    let mut iter = [100, 20, 30, 40, 50, 60, 70].iter().cloned().peekable();
+    assert_eq!(iter.peek(), Some(&100));
+    assert_eq!(iter.try_rfold(0, i8::checked_add), None);
+    assert_eq!(iter.peek(), Some(&100));
+    assert_eq!(iter.next_back(), Some(50));
+
+    let mut iter = (2..5).peekable();
+    assert_eq!(iter.peek(), Some(&2));
+    assert_eq!(iter.try_for_each(Err), Err(2));
+    assert_eq!(iter.peek(), Some(&3));
+    assert_eq!(iter.try_for_each(Err), Err(3));
+    assert_eq!(iter.peek(), Some(&4));
+    assert_eq!(iter.try_for_each(Err), Err(4));
+    assert_eq!(iter.peek(), None);
+    assert_eq!(iter.try_for_each(Err), Ok(()));
+
+    let mut iter = (2..5).peekable();
+    assert_eq!(iter.peek(), Some(&2));
+    assert_eq!(iter.try_rfold((), |(), x| Err(x)), Err(4));
+    assert_eq!(iter.peek(), Some(&2));
+    assert_eq!(iter.try_rfold((), |(), x| Err(x)), Err(3));
+    assert_eq!(iter.peek(), Some(&2));
+    assert_eq!(iter.try_rfold((), |(), x| Err(x)), Err(2));
+    assert_eq!(iter.peek(), None);
+    assert_eq!(iter.try_rfold((), |(), x| Err(x)), Ok(()));
 }
 
 #[test]
@@ -2371,13 +2525,25 @@ fn test_skip_nth_back() {
 fn test_take_try_folds() {
     let f = &|acc, x| i32::checked_add(2*acc, x);
     assert_eq!((10..30).take(10).try_fold(7, f), (10..20).try_fold(7, f));
-    //assert_eq!((10..30).take(10).try_rfold(7, f), (10..20).try_rfold(7, f));
+    assert_eq!((10..30).take(10).try_rfold(7, f), (10..20).try_rfold(7, f));
 
     let mut iter = (10..30).take(20);
     assert_eq!(iter.try_fold(0, i8::checked_add), None);
     assert_eq!(iter.next(), Some(20));
-    //assert_eq!(iter.try_rfold(0, i8::checked_add), None);
-    //assert_eq!(iter.next_back(), Some(24));
+    assert_eq!(iter.try_rfold(0, i8::checked_add), None);
+    assert_eq!(iter.next_back(), Some(24));
+
+    let mut iter = (2..20).take(3);
+    assert_eq!(iter.try_for_each(Err), Err(2));
+    assert_eq!(iter.try_for_each(Err), Err(3));
+    assert_eq!(iter.try_for_each(Err), Err(4));
+    assert_eq!(iter.try_for_each(Err), Ok(()));
+
+    let mut iter = (2..20).take(3).rev();
+    assert_eq!(iter.try_for_each(Err), Err(4));
+    assert_eq!(iter.try_for_each(Err), Err(3));
+    assert_eq!(iter.try_for_each(Err), Err(2));
+    assert_eq!(iter.try_for_each(Err), Ok(()));
 }
 
 #[test]
index 569b3197d09bd64576d7b3fcac10a619071a09c5..1a6be3a9bbd034558618281c4a325e762d1f6ac6 100644 (file)
@@ -145,7 +145,6 @@ fn test_as_ref() {
 }
 
 #[test]
-#[cfg(not(miri))] // This test is UB according to Stacked Borrows
 fn test_as_mut() {
     unsafe {
         let p: *mut isize = null_mut();
@@ -164,7 +163,7 @@ fn test_as_mut() {
         // Pointers to unsized types -- slices
         let s: &mut [u8] = &mut [1, 2, 3];
         let ms: *mut [u8] = s;
-        assert_eq!(ms.as_mut(), Some(s));
+        assert_eq!(ms.as_mut(), Some(&mut [1, 2, 3][..]));
 
         let mz: *mut [u8] = &mut [];
         assert_eq!(mz.as_mut(), Some(&mut [][..]));
index 5031e6dbd87d2a02441361afdf9970a80c430cdc..493083c680aad0f4585cde7b9a3fcaa89c50cbb2 100644 (file)
@@ -5176,11 +5176,10 @@ fn lower_expr(&mut self, e: &Expr) -> hir::Expr {
                 let attr = {
                     // `allow(unreachable_code)`
                     let allow = {
-                        let allow_ident = Ident::with_empty_ctxt(sym::allow).with_span_pos(e.span);
-                        let uc_ident = Ident::with_empty_ctxt(sym::unreachable_code)
-                            .with_span_pos(e.span);
+                        let allow_ident = Ident::new(sym::allow, e.span);
+                        let uc_ident = Ident::new(sym::unreachable_code, e.span);
                         let uc_nested = attr::mk_nested_word_item(uc_ident);
-                        attr::mk_list_item(e.span, allow_ident, vec![uc_nested])
+                        attr::mk_list_item(allow_ident, vec![uc_nested])
                     };
                     attr::mk_attr_outer(allow)
                 };
index 0c9c9adcf9da62bf459ef946b1d2d6ac138133f8..5cc8324b316065064a413867c538c8abe2ee6d46 100644 (file)
@@ -363,7 +363,8 @@ fn hash_stable<W: StableHasherResult>(&self,
             }
 
             token::DocComment(val) |
-            token::Shebang(val) => val.hash_stable(hcx, hasher),
+            token::Shebang(val) |
+            token::Unknown(val) => val.hash_stable(hcx, hasher),
         }
     }
 }
index e20b53455f49cf2ab6587743d1d77ccc62dfe560..4a9b68f24371d3da61eabe320b4a83898375f37d 100644 (file)
@@ -340,6 +340,7 @@ fn generalize(&self,
             ambient_variance,
             needs_wf: false,
             root_ty: ty,
+            param_env: self.param_env,
         };
 
         let ty = match generalize.relate(&ty, &ty) {
@@ -379,6 +380,8 @@ struct Generalizer<'cx, 'tcx> {
 
     /// The root type that we are generalizing. Used when reporting cycles.
     root_ty: Ty<'tcx>,
+
+    param_env: ty::ParamEnv<'tcx>,
 }
 
 /// Result from a generalization operation. This includes
@@ -419,6 +422,7 @@ impl TypeRelation<'tcx> for Generalizer<'_, 'tcx> {
     fn tcx(&self) -> TyCtxt<'tcx> {
         self.infcx.tcx
     }
+    fn param_env(&self) -> ty::ParamEnv<'tcx> { self.param_env }
 
     fn tag(&self) -> &'static str {
         "Generalizer"
index 5eebe9e78d3534e0c587df72c26647509b12124f..5dfa0d29daf1b7e5647bfd791e7ebaba4881eca5 100644 (file)
@@ -30,6 +30,8 @@ fn tag(&self) -> &'static str { "Equate" }
 
     fn tcx(&self) -> TyCtxt<'tcx> { self.fields.tcx() }
 
+    fn param_env(&self) -> ty::ParamEnv<'tcx> { self.fields.param_env }
+
     fn a_is_expected(&self) -> bool { self.a_is_expected }
 
     fn relate_item_substs(&mut self,
index 550213167470d537dd77ad9a4360c98a9acb852f..2cef521176269fb8f6c35e01e65f486819891674 100644 (file)
@@ -27,6 +27,8 @@ fn tag(&self) -> &'static str { "Glb" }
 
     fn tcx(&self) -> TyCtxt<'tcx> { self.fields.tcx() }
 
+    fn param_env(&self) -> ty::ParamEnv<'tcx> { self.fields.param_env }
+
     fn a_is_expected(&self) -> bool { self.a_is_expected }
 
     fn relate_with_variance<T: Relate<'tcx>>(&mut self,
index 156288b9e6afd899c386edef4311cfa3c84727ec..e20372f1513712359a007ba5af3a4c3e34c7c345 100644 (file)
@@ -27,6 +27,8 @@ fn tag(&self) -> &'static str { "Lub" }
 
     fn tcx(&self) -> TyCtxt<'tcx> { self.fields.tcx() }
 
+    fn param_env(&self) -> ty::ParamEnv<'tcx> { self.fields.param_env }
+
     fn a_is_expected(&self) -> bool { self.a_is_expected }
 
     fn relate_with_variance<T: Relate<'tcx>>(&mut self,
index a0621af053783865d46f234fea1e9aff97b8a0c2..5d521def65b0b91dc5e3ebee1ed97eba22765bc9 100644 (file)
@@ -502,6 +502,9 @@ fn tcx(&self) -> TyCtxt<'tcx> {
         self.infcx.tcx
     }
 
+    // FIXME(oli-obk): not sure how to get the correct ParamEnv
+    fn param_env(&self) -> ty::ParamEnv<'tcx> { ty::ParamEnv::empty() }
+
     fn tag(&self) -> &'static str {
         "nll::subtype"
     }
@@ -831,6 +834,9 @@ fn tcx(&self) -> TyCtxt<'tcx> {
         self.infcx.tcx
     }
 
+    // FIXME(oli-obk): not sure how to get the correct ParamEnv
+    fn param_env(&self) -> ty::ParamEnv<'tcx> { ty::ParamEnv::empty() }
+
     fn tag(&self) -> &'static str {
         "nll::generalizer"
     }
index d555886128598ebb602ade1f90e52d861439b8ba..e6155454d46f1fe9ffbc774f9e07bffa60f40246 100644 (file)
@@ -27,7 +27,7 @@
 /// interested in the `OutlivesEnvironment`. -nmatsakis
 #[derive(Clone)]
 pub struct OutlivesEnvironment<'tcx> {
-    param_env: ty::ParamEnv<'tcx>,
+    pub param_env: ty::ParamEnv<'tcx>,
     free_region_map: FreeRegionMap<'tcx>,
 
     // Contains, for each body B that we are checking (that is, the fn
index 1452a6dee5bc1a032b4274024d6f5f7252982967..cd1d206b5fca1282af18ff333f56c894678dfff0 100644 (file)
@@ -35,6 +35,9 @@ fn with_expected_switched<R, F: FnOnce(&mut Self) -> R>(&mut self, f: F) -> R {
 impl TypeRelation<'tcx> for Sub<'combine, 'infcx, 'tcx> {
     fn tag(&self) -> &'static str { "Sub" }
     fn tcx(&self) -> TyCtxt<'tcx> { self.fields.infcx.tcx }
+
+    fn param_env(&self) -> ty::ParamEnv<'tcx> { self.fields.param_env }
+
     fn a_is_expected(&self) -> bool { self.a_is_expected }
 
     fn with_cause<F,R>(&mut self, cause: Cause, f: F) -> R
index 2448db032b9654c39348188af6db5593e87a4c4e..a274d7bbee5f783fa395bdeb91222e97d3761e45 100644 (file)
@@ -277,6 +277,7 @@ pub fn new(
     ) -> Self {
         ExprUseVisitor {
             mc: mc::MemCategorizationContext::new(tcx,
+                                                  param_env,
                                                   body_owner,
                                                   region_scope_tree,
                                                   tables,
@@ -299,6 +300,7 @@ pub fn with_infer(
         ExprUseVisitor {
             mc: mc::MemCategorizationContext::with_infer(
                 infcx,
+                param_env,
                 body_owner,
                 region_scope_tree,
                 tables,
index 524d5ddf9290038b02a3195935b0e013bd2b9c2f..77d6f3932445b0eb5ccdafacd1b48ac24c2d40ee 100644 (file)
@@ -214,6 +214,7 @@ fn span(&self) -> Span { self.span }
 #[derive(Clone)]
 pub struct MemCategorizationContext<'a, 'tcx> {
     pub tcx: TyCtxt<'tcx>,
+    param_env: ty::ParamEnv<'tcx>,
     pub body_owner: DefId,
     pub upvars: Option<&'tcx FxIndexMap<hir::HirId, hir::Upvar>>,
     pub region_scope_tree: &'a region::ScopeTree,
@@ -330,6 +331,7 @@ pub fn to_user_str(&self) -> &'static str {
 impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> {
     pub fn new(
         tcx: TyCtxt<'tcx>,
+        param_env: ty::ParamEnv<'tcx>,
         body_owner: DefId,
         region_scope_tree: &'a region::ScopeTree,
         tables: &'a ty::TypeckTables<'tcx>,
@@ -342,7 +344,8 @@ pub fn new(
             region_scope_tree,
             tables,
             rvalue_promotable_map,
-            infcx: None
+            infcx: None,
+            param_env,
         }
     }
 }
@@ -359,6 +362,7 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> {
     ///   known, the results around upvar accesses may be incorrect.
     pub fn with_infer(
         infcx: &'a InferCtxt<'a, 'tcx>,
+        param_env: ty::ParamEnv<'tcx>,
         body_owner: DefId,
         region_scope_tree: &'a region::ScopeTree,
         tables: &'a ty::TypeckTables<'tcx>,
@@ -379,6 +383,7 @@ pub fn with_infer(
             tables,
             rvalue_promotable_map,
             infcx: Some(infcx),
+            param_env,
         }
     }
 
@@ -896,7 +901,7 @@ pub fn cat_rvalue_node(&self,
 
         // Always promote `[T; 0]` (even when e.g., borrowed mutably).
         let promotable = match expr_ty.sty {
-            ty::Array(_, len) if len.assert_usize(self.tcx) == Some(0) => true,
+            ty::Array(_, len) if len.try_eval_usize(self.tcx, self.param_env) == Some(0) => true,
             _ => promotable,
         };
 
index e2f5d192281a7e5153da64fd3f8a2f2ecb11dd74..f8889380b2abf9341ddb420215c4840b605bd766 100644 (file)
@@ -57,7 +57,7 @@ pub fn field_ty(self, tcx: TyCtxt<'tcx>, f: &Field) -> Ty<'tcx> {
     /// `PlaceElem`, where we can just use the `Ty` that is already
     /// stored inline on field projection elems.
     pub fn projection_ty(self, tcx: TyCtxt<'tcx>, elem: &PlaceElem<'tcx>) -> PlaceTy<'tcx> {
-        self.projection_ty_core(tcx, elem, |_, _, ty| ty)
+        self.projection_ty_core(tcx, ty::ParamEnv::empty(), elem, |_, _, ty| ty)
     }
 
     /// `place_ty.projection_ty_core(tcx, elem, |...| { ... })`
@@ -68,6 +68,7 @@ pub fn projection_ty(self, tcx: TyCtxt<'tcx>, elem: &PlaceElem<'tcx>) -> PlaceTy
     pub fn projection_ty_core<V, T>(
         self,
         tcx: TyCtxt<'tcx>,
+        param_env: ty::ParamEnv<'tcx>,
         elem: &ProjectionElem<V, T>,
         mut handle_field: impl FnMut(&Self, &Field, &T) -> Ty<'tcx>,
     ) -> PlaceTy<'tcx>
@@ -90,7 +91,7 @@ pub fn projection_ty_core<V, T>(
             ProjectionElem::Subslice { from, to } => {
                 PlaceTy::from_ty(match self.ty.sty {
                     ty::Array(inner, size) => {
-                        let size = size.unwrap_usize(tcx);
+                        let size = size.eval_usize(tcx, param_env);
                         let len = size - (from as u64) - (to as u64);
                         tcx.mk_array(inner, len)
                     }
index 14a288f5af1a02771ca2f07c61cff3710be1cb90..83bd5c56040e1f48c20ccc3fb6a84db41c6d89b3 100644 (file)
@@ -417,7 +417,7 @@ fn on_unimplemented_note(
                     Some(format!("[{}]", self.tcx.type_of(def.did).to_string())),
                 ));
                 let tcx = self.tcx;
-                if let Some(len) = len.assert_usize(tcx) {
+                if let Some(len) = len.try_eval_usize(tcx, ty::ParamEnv::empty()) {
                     flags.push((
                         sym::_Self,
                         Some(format!("[{}; {}]", self.tcx.type_of(def.did).to_string(), len)),
index 2486f29ab0f222606d5814d299ecff8df1468a48..da582c015e4ea4699deab770d0b5345913cea40f 100644 (file)
@@ -1082,7 +1082,8 @@ fn evaluate_stack<'o>(
         }
         if unbound_input_types && stack.iter().skip(1).any(|prev| {
             stack.obligation.param_env == prev.obligation.param_env
-                && self.match_fresh_trait_refs(&stack.fresh_trait_ref, &prev.fresh_trait_ref)
+                && self.match_fresh_trait_refs(
+                    &stack.fresh_trait_ref, &prev.fresh_trait_ref, prev.obligation.param_env)
         }) {
             debug!(
                 "evaluate_stack({:?}) --> unbound argument, recursive --> giving up",
@@ -3798,8 +3799,9 @@ fn match_fresh_trait_refs(
         &self,
         previous: &ty::PolyTraitRef<'tcx>,
         current: &ty::PolyTraitRef<'tcx>,
+        param_env: ty::ParamEnv<'tcx>,
     ) -> bool {
-        let mut matcher = ty::_match::Match::new(self.tcx());
+        let mut matcher = ty::_match::Match::new(self.tcx(), param_env);
         matcher.relate(previous, current).is_ok()
     }
 
index 8a84fca14380996cb0eb229a82843879e80cfdca..f0389bb037ac5b827aeb4e1e5bcc8e07f1d29d5a 100644 (file)
@@ -366,13 +366,8 @@ pub(super) fn specialization_graph_provider(
                     }
                 }
 
-                let access_levels = tcx.privacy_access_levels(impl_def_id.krate);
-                if let Some(id) = tcx.hir().as_local_hir_id(impl_def_id) {
-                    if access_levels.is_exported(id) || access_levels.is_public(id) {
-                        for cause in &overlap.intercrate_ambiguity_causes {
-                            cause.add_intercrate_ambiguity_hint(&mut err);
-                        }
-                    }
+                for cause in &overlap.intercrate_ambiguity_causes {
+                    cause.add_intercrate_ambiguity_hint(&mut err);
                 }
 
                 if overlap.involves_placeholder {
index 6e10dc03a2869e6a7b9e50d4c706ee1ad8aa7b84..f800a70e0becfadcb11fd8276e53a16fb4229c1f 100644 (file)
 /// affects any type variables or unification state.
 pub struct Match<'tcx> {
     tcx: TyCtxt<'tcx>,
+    param_env: ty::ParamEnv<'tcx>,
 }
 
 impl Match<'tcx> {
-    pub fn new(tcx: TyCtxt<'tcx>) -> Match<'tcx> {
-        Match { tcx }
+    pub fn new(tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>) -> Match<'tcx> {
+        Match { tcx, param_env }
     }
 }
 
 impl TypeRelation<'tcx> for Match<'tcx> {
     fn tag(&self) -> &'static str { "Match" }
     fn tcx(&self) -> TyCtxt<'tcx> { self.tcx }
+    fn param_env(&self) -> ty::ParamEnv<'tcx> { self.param_env }
     fn a_is_expected(&self) -> bool { true } // irrelevant
 
     fn relate_with_variance<T: Relate<'tcx>>(&mut self,
index b8bdde4a787380a4e110e8691c578107413fe821..4a72794b61a6471e4ee509c8863c3aa46b0cf450 100644 (file)
@@ -194,7 +194,7 @@ pub fn sort_string(&self, tcx: TyCtxt<'_>) -> Cow<'static, str> {
             ty::Foreign(def_id) => format!("extern type `{}`", tcx.def_path_str(def_id)).into(),
             ty::Array(_, n) => {
                 let n = tcx.lift_to_global(&n).unwrap();
-                match n.assert_usize(tcx) {
+                match n.try_eval_usize(tcx, ty::ParamEnv::empty()) {
                     Some(n) => format!("array of {} elements", n).into(),
                     None => "array".into(),
                 }
index 0d96e5ea625da9437b200d81a7fd6690814135a3..2b3291656653fc9ce3c44c132723822672ff5ca3 100644 (file)
@@ -3,6 +3,7 @@
 use crate::ty::{DefId, SubstsRef};
 use crate::ty::{AdtKind, Visibility};
 use crate::ty::TyKind::*;
+use crate::ty;
 
 pub use self::def_id_forest::DefIdForest;
 
@@ -190,7 +191,7 @@ fn uninhabited_from(&self, tcx: TyCtxt<'tcx>) -> DefIdForest {
                 }))
             }
 
-            Array(ty, len) => match len.assert_usize(tcx) {
+            Array(ty, len) => match len.try_eval_usize(tcx, ty::ParamEnv::empty()) {
                 // If the array is definitely non-empty, it's uninhabited if
                 // the type of its elements is uninhabited.
                 Some(n) if n != 0 => ty.uninhabited_from(tcx),
index e0e70f41abe6a1385e072913912115f4f0251202..a66a4ac66f3f5edf8d63833f6cd8fe85ea31b930 100644 (file)
@@ -594,7 +594,7 @@ fn layout_raw_uncached(&self, ty: Ty<'tcx>) -> Result<&'tcx LayoutDetails, Layou
                     }
                 }
 
-                let count = count.assert_usize(tcx).ok_or(LayoutError::Unknown(ty))?;
+                let count = count.try_eval_usize(tcx, param_env).ok_or(LayoutError::Unknown(ty))?;
                 let element = self.layout_of(element)?;
                 let size = element.size.checked_mul(count, dl)
                     .ok_or(LayoutError::SizeOverflow(ty))?;
index 8e170578227c0a624f36cf78b96c70b380949d69..5fec95e2a3b34f31f84dec3071becbf8fff1db6c 100644 (file)
@@ -2357,7 +2357,7 @@ pub fn variant_of_res(&self, res: Res) -> &VariantDef {
 
     #[inline]
     pub fn eval_explicit_discr(&self, tcx: TyCtxt<'tcx>, expr_did: DefId) -> Option<Discr<'tcx>> {
-        let param_env = ParamEnv::empty();
+        let param_env = tcx.param_env(expr_did);
         let repr_type = self.repr.discr_type();
         let substs = InternalSubsts::identity_for_item(tcx.global_tcx(), expr_did);
         let instance = ty::Instance::new(expr_did, substs);
@@ -2368,7 +2368,7 @@ pub fn eval_explicit_discr(&self, tcx: TyCtxt<'tcx>, expr_did: DefId) -> Option<
         match tcx.const_eval(param_env.and(cid)) {
             Ok(val) => {
                 // FIXME: Find the right type and use it instead of `val.ty` here
-                if let Some(b) = val.assert_bits(tcx.global_tcx(), param_env.and(val.ty)) {
+                if let Some(b) = val.try_eval_bits(tcx.global_tcx(), param_env, val.ty) {
                     trace!("discriminants: {} ({:?})", b, repr_type);
                     Some(Discr {
                         val: b,
index c12402a57cc3cfcd416779e4e0ddda45072ef012..b68e6a744872f4f3c786e5c59f8d64cd9008f0d9 100644 (file)
@@ -89,7 +89,8 @@ pub fn push_type_name(&self, t: Ty<'tcx>, output: &mut String, debug: bool) {
             ty::Array(inner_type, len) => {
                 output.push('[');
                 self.push_type_name(inner_type, output, debug);
-                write!(output, "; {}", len.unwrap_usize(self.tcx)).unwrap();
+                let len = len.eval_usize(self.tcx, ty::ParamEnv::reveal_all());
+                write!(output, "; {}", len).unwrap();
                 output.push(']');
             }
             ty::Slice(inner_type) => {
index e889f2edef2bbbd40455690c530e7cfd1aad5a28..017f67463c31be7240ff72b46acf3d74bd95426a 100644 (file)
@@ -696,7 +696,12 @@ fn pretty_print_type(
             },
             ty::Array(ty, sz) => {
                 p!(write("["), print(ty), write("; "));
-                if let Some(n) = sz.assert_usize(self.tcx()) {
+                if let ConstValue::Unevaluated(..) = sz.val {
+                    // do not try to evalute unevaluated constants. If we are const evaluating an
+                    // array length anon const, rustc will (with debug assertions) print the
+                    // constant's path. Which will end up here again.
+                    p!(write("_"));
+                } else if let Some(n) = sz.try_eval_usize(self.tcx(), ty::ParamEnv::empty()) {
                     p!(write("{}", n));
                 } else {
                     p!(write("_"));
@@ -915,7 +920,7 @@ fn pretty_print_const(
         if let ty::Ref(_, ref_ty, _) = ct.ty.sty {
             let byte_str = match (ct.val, &ref_ty.sty) {
                 (ConstValue::Scalar(Scalar::Ptr(ptr)), ty::Array(t, n)) if *t == u8 => {
-                    let n = n.unwrap_usize(self.tcx());
+                    let n = n.eval_usize(self.tcx(), ty::ParamEnv::empty());
                     Some(self.tcx()
                         .alloc_map.lock()
                         .unwrap_memory(ptr.alloc_id)
index ca54f63b83afe0c2acc30e6f38162a9cbf7dedb8..945e3e158eafb016c71bed74fdc8547e36e2db22 100644 (file)
@@ -25,6 +25,8 @@ pub enum Cause {
 pub trait TypeRelation<'tcx>: Sized {
     fn tcx(&self) -> TyCtxt<'tcx>;
 
+    fn param_env(&self) -> ty::ParamEnv<'tcx>;
+
     /// Returns a static string we can use for printouts.
     fn tag(&self) -> &'static str;
 
@@ -466,7 +468,9 @@ pub fn super_relate_tys<R: TypeRelation<'tcx>>(
                 Err(err) => {
                     // Check whether the lengths are both concrete/known values,
                     // but are unequal, for better diagnostics.
-                    match (sz_a.assert_usize(tcx), sz_b.assert_usize(tcx)) {
+                    let sz_a = sz_a.try_eval_usize(tcx, relation.param_env());
+                    let sz_b = sz_b.try_eval_usize(tcx, relation.param_env());
+                    match (sz_a, sz_b) {
                         (Some(sz_a_val), Some(sz_b_val)) => {
                             Err(TypeError::FixedArraySize(
                                 expected_found(relation, &sz_a_val, &sz_b_val)
index 2b14558de6916a2f783e40b01070b8221ad94dd6..769b6592b6fa80ceca715ddf2f05638f918819b6 100644 (file)
@@ -15,7 +15,7 @@
 use crate::ty::{List, TyS, ParamEnvAnd, ParamEnv};
 use crate::ty::layout::VariantIdx;
 use crate::util::captures::Captures;
-use crate::mir::interpret::{Scalar, Pointer};
+use crate::mir::interpret::{Scalar, GlobalId};
 
 use smallvec::SmallVec;
 use std::borrow::Cow;
@@ -1726,7 +1726,7 @@ pub fn conservative_is_privately_uninhabited(&self, tcx: TyCtxt<'tcx>) -> bool {
                 ty.expect_ty().conservative_is_privately_uninhabited(tcx)
             }),
             ty::Array(ty, len) => {
-                match len.assert_usize(tcx) {
+                match len.try_eval_usize(tcx, ParamEnv::empty()) {
                     // If the array is definitely non-empty, it's uninhabited if
                     // the type of its elements is uninhabited.
                     Some(n) if n != 0 => ty.conservative_is_privately_uninhabited(tcx),
@@ -2291,29 +2291,38 @@ pub fn from_usize(tcx: TyCtxt<'tcx>, n: u64) -> &'tcx Self {
     }
 
     #[inline]
-    pub fn to_bits(&self, tcx: TyCtxt<'tcx>, ty: ParamEnvAnd<'tcx, Ty<'tcx>>) -> Option<u128> {
-        if self.ty != ty.value {
-            return None;
+    pub fn try_eval_bits(
+        &self,
+        tcx: TyCtxt<'tcx>,
+        param_env: ParamEnv<'tcx>,
+        ty: Ty<'tcx>,
+    ) -> Option<u128> {
+        assert_eq!(self.ty, ty);
+        // if `ty` does not depend on generic parameters, use an empty param_env
+        let size = tcx.layout_of(param_env.with_reveal_all().and(ty)).ok()?.size;
+        match self.val {
+            // FIXME(const_generics): this doesn't work right now,
+            // because it tries to relate an `Infer` to a `Param`.
+            ConstValue::Unevaluated(did, substs) => {
+                // if `substs` has no unresolved components, use and empty param_env
+                let (param_env, substs) = param_env.with_reveal_all().and(substs).into_parts();
+                // try to resolve e.g. associated constants to their definition on an impl
+                let instance = ty::Instance::resolve(tcx, param_env, did, substs)?;
+                let gid = GlobalId {
+                    instance,
+                    promoted: None,
+                };
+                let evaluated = tcx.const_eval(param_env.and(gid)).ok()?;
+                evaluated.val.try_to_bits(size)
+            },
+            // otherwise just extract a `ConstValue`'s bits if possible
+            _ => self.val.try_to_bits(size),
         }
-        let size = tcx.layout_of(ty).ok()?.size;
-        self.val.try_to_bits(size)
-    }
-
-    #[inline]
-    pub fn to_ptr(&self) -> Option<Pointer> {
-        self.val.try_to_ptr()
-    }
-
-    #[inline]
-    pub fn assert_bits(&self, tcx: TyCtxt<'tcx>, ty: ParamEnvAnd<'tcx, Ty<'tcx>>) -> Option<u128> {
-        assert_eq!(self.ty, ty.value);
-        let size = tcx.layout_of(ty).ok()?.size;
-        self.val.try_to_bits(size)
     }
 
     #[inline]
-    pub fn assert_bool(&self, tcx: TyCtxt<'tcx>) -> Option<bool> {
-        self.assert_bits(tcx, ParamEnv::empty().and(tcx.types.bool)).and_then(|v| match v {
+    pub fn try_eval_bool(&self, tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>) -> Option<bool> {
+        self.try_eval_bits(tcx, param_env, tcx.types.bool).and_then(|v| match v {
             0 => Some(false),
             1 => Some(true),
             _ => None,
@@ -2321,20 +2330,19 @@ pub fn assert_bool(&self, tcx: TyCtxt<'tcx>) -> Option<bool> {
     }
 
     #[inline]
-    pub fn assert_usize(&self, tcx: TyCtxt<'tcx>) -> Option<u64> {
-        self.assert_bits(tcx, ParamEnv::empty().and(tcx.types.usize)).map(|v| v as u64)
+    pub fn try_eval_usize(&self, tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>) -> Option<u64> {
+        self.try_eval_bits(tcx, param_env, tcx.types.usize).map(|v| v as u64)
     }
 
     #[inline]
-    pub fn unwrap_bits(&self, tcx: TyCtxt<'tcx>, ty: ParamEnvAnd<'tcx, Ty<'tcx>>) -> u128 {
-        self.assert_bits(tcx, ty).unwrap_or_else(||
-            bug!("expected bits of {}, got {:#?}", ty.value, self))
+    pub fn eval_bits(&self, tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>, ty: Ty<'tcx>) -> u128 {
+        self.try_eval_bits(tcx, param_env, ty).unwrap_or_else(||
+            bug!("expected bits of {:#?}, got {:#?}", ty, self))
     }
 
     #[inline]
-    pub fn unwrap_usize(&self, tcx: TyCtxt<'tcx>) -> u64 {
-        self.assert_usize(tcx).unwrap_or_else(||
-            bug!("expected constant usize, got {:#?}", self))
+    pub fn eval_usize(&self, tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>) -> u64 {
+        self.eval_bits(tcx, param_env, tcx.types.usize) as u64
     }
 }
 
index f0bdb0018efe7f71fc415390eb4c7a6697640edd..3b7aee84862ce4743306caf49159e890e0aa761f 100644 (file)
@@ -341,7 +341,7 @@ fn fixed_vec_metadata(
     let (size, align) = cx.size_and_align_of(array_or_slice_type);
 
     let upper_bound = match array_or_slice_type.sty {
-        ty::Array(_, len) => len.unwrap_usize(cx.tcx) as c_longlong,
+        ty::Array(_, len) => len.eval_usize(cx.tcx, ty::ParamEnv::reveal_all()) as c_longlong,
         _ => -1
     };
 
index fc04976f511b38d065b6c0777e66028041fc066f..cdc54bb179ebf0f02b59485863efa5c7a54bea4a 100644 (file)
@@ -132,7 +132,7 @@ pub fn unsized_info<'tcx, Cx: CodegenMethods<'tcx>>(
         cx.tcx().struct_lockstep_tails_erasing_lifetimes(source, target, cx.param_env());
     match (&source.sty, &target.sty) {
         (&ty::Array(_, len), &ty::Slice(_)) => {
-            cx.const_usize(len.unwrap_usize(cx.tcx()))
+            cx.const_usize(len.eval_usize(cx.tcx(), ty::ParamEnv::reveal_all()))
         }
         (&ty::Dynamic(..), &ty::Dynamic(..)) => {
             // For now, upcasts are limited to changes in marker
index 8f0bb6ee1983730f9eabdb4d1c2cb0452a0455d0..ea39913d4b91ba6c6518485f8aaf186f72f2ce47 100644 (file)
@@ -89,7 +89,7 @@ pub fn push_debuginfo_type_name<'tcx>(
         ty::Array(inner_type, len) => {
             output.push('[');
             push_debuginfo_type_name(tcx, inner_type, true, output, visited);
-            output.push_str(&format!("; {}", len.unwrap_usize(tcx)));
+            output.push_str(&format!("; {}", len.eval_usize(tcx, ty::ParamEnv::reveal_all())));
             output.push(']');
         },
         ty::Slice(inner_type) => {
index d6951b923bf7d3c4ef4090e36fd707958b42a7d1..216e5a4645a462e01579877ebfd53c0f64ae32d6 100644 (file)
@@ -41,7 +41,7 @@ pub fn simd_shuffle_indices(
             .map(|c| {
                 let field_ty = c.ty.builtin_index().unwrap();
                 let fields = match c.ty.sty {
-                    ty::Array(_, n) => n.unwrap_usize(bx.tcx()),
+                    ty::Array(_, n) => n.eval_usize(bx.tcx(), ty::ParamEnv::reveal_all()),
                     _ => bug!("invalid simd shuffle type: {}", c.ty),
                 };
                 let values: Vec<_> = (0..fields).map(|field| {
index 202cf147f1fcbcefa8fce6fe83555acd4235399a..21cedb7a9b39487261b39007bf0278065c453cf2 100644 (file)
@@ -521,7 +521,7 @@ fn evaluate_array_len(
         } = *place {
             if let LocalRef::Operand(Some(op)) = self.locals[index] {
                 if let ty::Array(_, n) = op.layout.ty.sty {
-                    let n = n.unwrap_usize(bx.cx().tcx());
+                    let n = n.eval_usize(bx.cx().tcx(), ty::ParamEnv::reveal_all());
                     return bx.cx().const_usize(n);
                 }
             }
index 8a54fb6bbc4cae6cd6b1fe9b17a9e6ccd398354d..47601da8b7b23816643be91f9721d67a79d50435 100644 (file)
@@ -512,7 +512,7 @@ fn print_const(
         }
         self = ct.ty.print(self)?;
 
-        if let Some(bits) = ct.assert_bits(self.tcx, ty::ParamEnv::empty().and(ct.ty)) {
+        if let Some(bits) = ct.try_eval_bits(self.tcx, ty::ParamEnv::reveal_all(), ct.ty) {
             let _ = write!(self.out, "{:x}_", bits);
         } else {
             // NOTE(eddyb) despite having the path, we need to
index 4cccaa942b7429d929b640203b64527e1c50987d..23b5889202874883b044dde9f037d9f78885be0c 100644 (file)
@@ -208,7 +208,7 @@ fn check_must_use_ty<'tcx>(
                     }
                     has_emitted
                 }
-                ty::Array(ty, len) => match len.assert_usize(cx.tcx) {
+                ty::Array(ty, len) => match len.try_eval_usize(cx.tcx, cx.param_env) {
                     // If the array is definitely non-empty, we can do `#[must_use]` checking.
                     Some(n) if n != 0 => {
                         let descr_pre = &format!(
index 77e5ac2f865142d2615999739c729910b1ab8f34..4217a29bc663cbf4e7a7b663360552306d9a8997 100644 (file)
@@ -105,6 +105,9 @@ pub(super) fn report_use_of_moved_or_uninitialized(
                 format!("{} occurs due to use{}", desired_action.as_noun(), use_spans.describe()),
             );
 
+            // This error should not be downgraded to a warning,
+            // even in migrate mode.
+            self.disable_error_downgrading();
             err.buffer(&mut self.errors_buffer);
         } else {
             if let Some((reported_place, _)) = self.move_error_reported.get(&move_out_indices) {
index 9f22d7c51df6e6210fddc759e2db580ba4e6ee57..de27aec2b29902054420aae7cc6a8048d2b3e052 100644 (file)
@@ -206,7 +206,7 @@ fn do_mir_borrowck<'a, 'tcx>(
         def_id,
         &attributes,
         &dead_unwinds,
-        Borrows::new(tcx, body, regioncx.clone(), &borrow_set),
+        Borrows::new(tcx, body, param_env, regioncx.clone(), &borrow_set),
         |rs, i| DebugFormatted::new(&rs.location(i)),
     ));
     let flow_uninits = FlowAtLocation::new(do_dataflow(
@@ -242,6 +242,7 @@ fn do_mir_borrowck<'a, 'tcx>(
         infcx,
         body,
         mir_def_id: def_id,
+        param_env,
         move_data: &mdpe.move_data,
         location_table,
         movable_generator,
@@ -252,6 +253,7 @@ fn do_mir_borrowck<'a, 'tcx>(
         move_error_reported: BTreeMap::new(),
         uninitialized_error_reported: Default::default(),
         errors_buffer,
+        disable_error_downgrading: false,
         nonlexical_regioncx: regioncx,
         used_mut: Default::default(),
         used_mut_upvars: SmallVec::new(),
@@ -363,7 +365,7 @@ fn do_mir_borrowck<'a, 'tcx>(
     if !mbcx.errors_buffer.is_empty() {
         mbcx.errors_buffer.sort_by_key(|diag| diag.span.primary_span());
 
-        if tcx.migrate_borrowck() {
+        if !mbcx.disable_error_downgrading && tcx.migrate_borrowck() {
             // When borrowck=migrate, check if AST-borrowck would
             // error on the given code.
 
@@ -424,6 +426,7 @@ fn downgrade_if_error(diag: &mut Diagnostic) {
     crate infcx: &'cx InferCtxt<'cx, 'tcx>,
     body: &'cx Body<'tcx>,
     mir_def_id: DefId,
+    param_env: ty::ParamEnv<'tcx>,
     move_data: &'cx MoveData<'tcx>,
 
     /// Map from MIR `Location` to `LocationIndex`; created
@@ -479,6 +482,9 @@ fn downgrade_if_error(diag: &mut Diagnostic) {
     uninitialized_error_reported: FxHashSet<PlaceRef<'cx, 'tcx>>,
     /// Errors to be reported buffer
     errors_buffer: Vec<Diagnostic>,
+    /// If there are no errors reported by the HIR borrow checker, we downgrade
+    /// all NLL errors to warnings. Setting this flag disables downgrading.
+    disable_error_downgrading: bool,
     /// This field keeps track of all the local variables that are declared mut and are mutated.
     /// Used for the warning issued by an unused mutable local variable.
     used_mut: FxHashSet<Local>,
@@ -919,6 +925,12 @@ fn as_verb_in_past_tense(self) -> &'static str {
 }
 
 impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
+    /// If there are no errors reported by the HIR borrow checker, we downgrade
+    /// all NLL errors to warnings. Calling this disables downgrading.
+    crate fn disable_error_downgrading(&mut self)  {
+        self.disable_error_downgrading = true;
+    }
+
     /// Checks an access to the given place to see if it is allowed. Examines the set of borrows
     /// that are in scope, as well as which paths have been initialized, to ensure that (a) the
     /// place is initialized and (b) it is not borrowed in some way that would prevent this
@@ -1004,11 +1016,13 @@ fn check_access_for_conflict(
         let mut error_reported = false;
         let tcx = self.infcx.tcx;
         let body = self.body;
+        let param_env = self.param_env;
         let location_table = self.location_table.start_index(location);
         let borrow_set = self.borrow_set.clone();
         each_borrow_involving_path(
             self,
             tcx,
+            param_env,
             body,
             location,
             (sd, place_span.0),
@@ -1480,6 +1494,7 @@ fn check_for_invalidation_at_exit(
 
         if places_conflict::borrow_conflicts_with_place(
             self.infcx.tcx,
+            self.param_env,
             self.body,
             place,
             borrow.kind,
index 95c3299693b68eabbf5ffa4e96bf2427f11b4158..5c230913a0da3a443db3b3b91ccab52b2cf5b7e5 100644 (file)
@@ -18,6 +18,7 @@
 
 pub(super) fn generate_constraints<'cx, 'tcx>(
     infcx: &InferCtxt<'cx, 'tcx>,
+    param_env: ty::ParamEnv<'tcx>,
     liveness_constraints: &mut LivenessValues<RegionVid>,
     all_facts: &mut Option<AllFacts>,
     location_table: &LocationTable,
@@ -31,6 +32,7 @@ pub(super) fn generate_constraints<'cx, 'tcx>(
         location_table,
         all_facts,
         body,
+        param_env,
     };
 
     for (bb, data) in body.basic_blocks().iter_enumerated() {
@@ -41,6 +43,7 @@ pub(super) fn generate_constraints<'cx, 'tcx>(
 /// 'cg = the duration of the constraint generation process itself.
 struct ConstraintGeneration<'cg, 'cx, 'tcx> {
     infcx: &'cg InferCtxt<'cx, 'tcx>,
+    param_env: ty::ParamEnv<'tcx>,
     all_facts: &'cg mut Option<AllFacts>,
     location_table: &'cg LocationTable,
     liveness_constraints: &'cg mut LivenessValues<RegionVid>,
@@ -271,6 +274,7 @@ fn record_killed_borrows_for_place(&mut self, place: &Place<'tcx>, location: Loc
                         for &borrow_index in borrow_indices {
                             let places_conflict = places_conflict::places_conflict(
                                 self.infcx.tcx,
+                                self.param_env,
                                 self.body,
                                 &self.borrow_set.borrows[borrow_index].borrowed_place,
                                 place,
index 631a81421131c334290d06af2ef8ddcb157f5b2e..71106af767064683378eb16223a81fd01466ca34 100644 (file)
@@ -9,7 +9,7 @@
 use crate::borrow_check::nll::facts::AllFacts;
 use crate::borrow_check::path_utils::*;
 use crate::dataflow::indexes::BorrowIndex;
-use rustc::ty::TyCtxt;
+use rustc::ty::{self, TyCtxt};
 use rustc::mir::visit::Visitor;
 use rustc::mir::{BasicBlock, Location, Body, Place, Rvalue};
 use rustc::mir::{Statement, StatementKind};
@@ -19,6 +19,7 @@
 
 pub(super) fn generate_invalidates<'tcx>(
     tcx: TyCtxt<'tcx>,
+    param_env: ty::ParamEnv<'tcx>,
     all_facts: &mut Option<AllFacts>,
     location_table: &LocationTable,
     body: &Body<'tcx>,
@@ -34,6 +35,7 @@ pub(super) fn generate_invalidates<'tcx>(
         let mut ig = InvalidationGenerator {
             all_facts,
             borrow_set,
+            param_env,
             tcx,
             location_table,
             body,
@@ -45,6 +47,7 @@ pub(super) fn generate_invalidates<'tcx>(
 
 struct InvalidationGenerator<'cx, 'tcx> {
     tcx: TyCtxt<'tcx>,
+    param_env: ty::ParamEnv<'tcx>,
     all_facts: &'cx mut AllFacts,
     location_table: &'cx LocationTable,
     body: &'cx Body<'tcx>,
@@ -401,11 +404,13 @@ fn check_access_for_conflict(
         );
         let tcx = self.tcx;
         let body = self.body;
+        let param_env = self.param_env;
         let borrow_set = self.borrow_set.clone();
         let indices = self.borrow_set.borrows.indices();
         each_borrow_involving_path(
             self,
             tcx,
+            param_env,
             body,
             location,
             (sd, place),
index a2c5ad202e8c9d96404ae9240c271a34f52091e7..d65cdde303ca0a1ce278ee0cabcd0400b2e44210 100644 (file)
@@ -138,6 +138,7 @@ pub(in crate::borrow_check) fn compute_regions<'cx, 'tcx>(
 
     constraint_generation::generate_constraints(
         infcx,
+        param_env,
         &mut liveness_constraints,
         &mut all_facts,
         location_table,
@@ -162,6 +163,7 @@ pub(in crate::borrow_check) fn compute_regions<'cx, 'tcx>(
     // Generate various additional constraints.
     invalidation::generate_invalidates(
         infcx.tcx,
+        param_env,
         &mut all_facts,
         location_table,
         &body,
index b27be43dda2963bd3ac48a06f5b2e568d836bff6..70d6c15d8e2a792c9f2de420375872702f43f261 100644 (file)
@@ -669,7 +669,7 @@ fn sanitize_projection(
             ProjectionElem::Subslice { from, to } => PlaceTy::from_ty(
                 match base_ty.sty {
                     ty::Array(inner, size) => {
-                        let size = size.unwrap_usize(tcx);
+                        let size = size.eval_usize(tcx, self.cx.param_env);
                         let min_size = (from as u64) + (to as u64);
                         if let Some(rest_size) = size.checked_sub(min_size) {
                             tcx.mk_array(inner, rest_size)
@@ -1214,10 +1214,15 @@ fn relate_type_and_user_type(
         let tcx = self.infcx.tcx;
 
         for proj in &user_ty.projs {
-            let projected_ty = curr_projected_ty.projection_ty_core(tcx, proj, |this, field, &()| {
-                let ty = this.field_ty(tcx, field);
-                self.normalize(ty, locations)
-            });
+            let projected_ty = curr_projected_ty.projection_ty_core(
+                tcx,
+                self.param_env,
+                proj,
+                |this, field, &()| {
+                    let ty = this.field_ty(tcx, field);
+                    self.normalize(ty, locations)
+                },
+            );
             curr_projected_ty = projected_ty;
         }
         debug!("user_ty base: {:?} freshened: {:?} projs: {:?} yields: {:?}",
index da3f165482655a9ffea313041c0753bed4649bbc..43a012e1494f88e1df0a16c27cf7a4573f49510a 100644 (file)
@@ -4,7 +4,7 @@
 use crate::dataflow::indexes::BorrowIndex;
 use rustc::mir::{BasicBlock, Location, Body, Place, PlaceBase};
 use rustc::mir::{ProjectionElem, BorrowKind};
-use rustc::ty::TyCtxt;
+use rustc::ty::{self, TyCtxt};
 use rustc_data_structures::graph::dominators::Dominators;
 
 /// Returns `true` if the borrow represented by `kind` is
@@ -25,6 +25,7 @@ pub(super) enum Control {
 pub(super) fn each_borrow_involving_path<'tcx, F, I, S>(
     s: &mut S,
     tcx: TyCtxt<'tcx>,
+    param_env: ty::ParamEnv<'tcx>,
     body: &Body<'tcx>,
     _location: Location,
     access_place: (AccessDepth, &Place<'tcx>),
@@ -47,6 +48,7 @@ pub(super) fn each_borrow_involving_path<'tcx, F, I, S>(
 
         if places_conflict::borrow_conflicts_with_place(
             tcx,
+            param_env,
             body,
             &borrowed.borrowed_place,
             borrowed.kind,
index b2a03147ecf803dfd5ad567bb0949556da714afe..4dd2794f11301bb977fd1d00fefdb7a341490c6c 100644 (file)
@@ -26,6 +26,7 @@
 /// dataflow).
 crate fn places_conflict<'tcx>(
     tcx: TyCtxt<'tcx>,
+    param_env: ty::ParamEnv<'tcx>,
     body: &Body<'tcx>,
     borrow_place: &Place<'tcx>,
     access_place: &Place<'tcx>,
@@ -33,6 +34,7 @@
 ) -> bool {
     borrow_conflicts_with_place(
         tcx,
+        param_env,
         body,
         borrow_place,
         BorrowKind::Mut { allow_two_phase_borrow: true },
@@ -48,6 +50,7 @@
 /// order to make the conservative choice and preserve soundness.
 pub(super) fn borrow_conflicts_with_place<'tcx>(
     tcx: TyCtxt<'tcx>,
+    param_env: ty::ParamEnv<'tcx>,
     body: &Body<'tcx>,
     borrow_place: &Place<'tcx>,
     borrow_kind: BorrowKind,
@@ -78,6 +81,7 @@ pub(super) fn borrow_conflicts_with_place<'tcx>(
         access_place.iterate(|access_base, access_projections| {
             place_components_conflict(
                 tcx,
+                param_env,
                 body,
                 (borrow_base, borrow_projections),
                 borrow_kind,
@@ -91,6 +95,7 @@ pub(super) fn borrow_conflicts_with_place<'tcx>(
 
 fn place_components_conflict<'tcx>(
     tcx: TyCtxt<'tcx>,
+    param_env: ty::ParamEnv<'tcx>,
     body: &Body<'tcx>,
     borrow_projections: (&PlaceBase<'tcx>, ProjectionsIter<'_, 'tcx>),
     borrow_kind: BorrowKind,
@@ -143,7 +148,7 @@ fn place_components_conflict<'tcx>(
     let borrow_base = borrow_projections.0;
     let access_base = access_projections.0;
 
-    match place_base_conflict(tcx, borrow_base, access_base) {
+    match place_base_conflict(tcx, param_env, borrow_base, access_base) {
         Overlap::Arbitrary => {
             bug!("Two base can't return Arbitrary");
         }
@@ -306,6 +311,7 @@ fn place_components_conflict<'tcx>(
 // between `elem1` and `elem2`.
 fn place_base_conflict<'tcx>(
     tcx: TyCtxt<'tcx>,
+    param_env: ty::ParamEnv<'tcx>,
     elem1: &PlaceBase<'tcx>,
     elem2: &PlaceBase<'tcx>,
 ) -> Overlap {
@@ -339,7 +345,7 @@ fn place_base_conflict<'tcx>(
                 (StaticKind::Promoted(promoted_1), StaticKind::Promoted(promoted_2)) => {
                     if promoted_1 == promoted_2 {
                         if let ty::Array(_, len) = s1.ty.sty {
-                            if let Some(0) = len.assert_usize(tcx) {
+                            if let Some(0) = len.try_eval_usize(tcx, param_env) {
                                 // Ignore conflicts with promoted [T; 0].
                                 debug!("place_element_conflict: IGNORE-LEN-0-PROMOTED");
                                 return Overlap::Disjoint;
index 528dfbef6946a3d5546582bb77da17ae7cd8546e..1c93abd40ded25d70fb9234219bbbca520efa31e 100644 (file)
@@ -109,10 +109,11 @@ pub fn add_cases_to_switch<'pat>(&mut self,
 
         match *match_pair.pattern.kind {
             PatternKind::Constant { value } => {
-                let switch_ty = ty::ParamEnv::empty().and(switch_ty);
                 indices.entry(value)
                        .or_insert_with(|| {
-                           options.push(value.unwrap_bits(self.hir.tcx(), switch_ty));
+                           options.push(value.eval_bits(
+                               self.hir.tcx(), self.hir.param_env, switch_ty,
+                           ));
                            options.len() - 1
                        });
                 true
@@ -653,11 +654,10 @@ pub fn sort_candidate<'pat>(
                     use std::cmp::Ordering::*;
                     use rustc::hir::RangeEnd::*;
 
-                    let param_env = ty::ParamEnv::empty().and(test.ty);
                     let tcx = self.hir.tcx();
 
-                    let lo = compare_const_vals(tcx, test.lo, pat.hi, param_env)?;
-                    let hi = compare_const_vals(tcx, test.hi, pat.lo, param_env)?;
+                    let lo = compare_const_vals(tcx, test.lo, pat.hi, self.hir.param_env, test.ty)?;
+                    let hi = compare_const_vals(tcx, test.hi, pat.lo, self.hir.param_env, test.ty)?;
 
                     match (test.end, pat.end, lo, hi) {
                         // pat < test
@@ -772,11 +772,10 @@ fn const_range_contains(
     ) -> Option<bool> {
         use std::cmp::Ordering::*;
 
-        let param_env = ty::ParamEnv::empty().and(range.ty);
         let tcx = self.hir.tcx();
 
-        let a = compare_const_vals(tcx, range.lo, value, param_env)?;
-        let b = compare_const_vals(tcx, value, range.hi, param_env)?;
+        let a = compare_const_vals(tcx, range.lo, value, self.hir.param_env, range.ty)?;
+        let b = compare_const_vals(tcx, value, range.hi, self.hir.param_env, range.ty)?;
 
         match (b, range.end) {
             (Less, _) |
index 10c3e52b5255a62464fc30009c12259d021ddcea..018fd2e97b2645d44d7e571f3443e6a6260a35d3 100644 (file)
@@ -2,7 +2,7 @@
 use crate::borrow_check::place_ext::PlaceExt;
 
 use rustc::mir::{self, Location, Place, PlaceBase, Body};
-use rustc::ty::TyCtxt;
+use rustc::ty::{self, TyCtxt};
 use rustc::ty::RegionVid;
 
 use rustc_data_structures::bit_set::BitSet;
@@ -32,6 +32,7 @@ pub struct BorrowIndex {
 pub struct Borrows<'a, 'tcx> {
     tcx: TyCtxt<'tcx>,
     body: &'a Body<'tcx>,
+    param_env: ty::ParamEnv<'tcx>,
 
     borrow_set: Rc<BorrowSet<'tcx>>,
     borrows_out_of_scope_at_location: FxHashMap<Location, Vec<BorrowIndex>>,
@@ -137,6 +138,7 @@ impl<'a, 'tcx> Borrows<'a, 'tcx> {
     crate fn new(
         tcx: TyCtxt<'tcx>,
         body: &'a Body<'tcx>,
+        param_env: ty::ParamEnv<'tcx>,
         nonlexical_regioncx: Rc<RegionInferenceContext<'tcx>>,
         borrow_set: &Rc<BorrowSet<'tcx>>,
     ) -> Self {
@@ -153,6 +155,7 @@ impl<'a, 'tcx> Borrows<'a, 'tcx> {
         Borrows {
             tcx: tcx,
             body: body,
+            param_env,
             borrow_set: borrow_set.clone(),
             borrows_out_of_scope_at_location,
             _nonlexical_regioncx: nonlexical_regioncx,
@@ -218,6 +221,7 @@ fn kill_borrows_on_place(
                 .filter(|&&i| {
                     places_conflict::places_conflict(
                         self.tcx,
+                        self.param_env,
                         self.body,
                         &self.borrow_set.borrows[i].borrowed_place,
                         place,
index 242afcf5abb2e410f417562b95b00f6ee6381e67..1c6a743155ee48ef5e62f1d9f4814645e92a3a91 100644 (file)
@@ -556,7 +556,7 @@ fn make_mirror_unadjusted<'a, 'tcx>(
             };
             let span = cx.tcx.def_span(def_id);
             let count = match cx.tcx.at(span).const_eval(cx.param_env.and(global_id)) {
-                Ok(cv) => cv.unwrap_usize(cx.tcx),
+                Ok(cv) => cv.eval_usize(cx.tcx, cx.param_env),
                 Err(ErrorHandled::Reported) => 0,
                 Err(ErrorHandled::TooGeneric) => {
                     cx.tcx.sess.span_err(span, "array lengths can't depend on generic parameters");
index b1a317ee65f6f70bbd623fb60958bbe79a65a4c7..8a3d904e77579bdada62fcb53ffc545b5e9a1abe 100644 (file)
@@ -228,7 +228,7 @@ fn fold_const_value_deref(
                 ConstValue::Slice {
                     data: self.tcx.alloc_map.lock().unwrap_memory(p.alloc_id),
                     start: p.offset.bytes().try_into().unwrap(),
-                    end: n.unwrap_usize(self.tcx).try_into().unwrap(),
+                    end: n.eval_usize(self.tcx, ty::ParamEnv::empty()).try_into().unwrap(),
                 }
             },
             // fat pointers stay the same
@@ -646,8 +646,8 @@ fn all_constructors<'a, 'tcx>(
                 ConstantValue(ty::Const::from_bool(cx.tcx, b))
             }).collect()
         }
-        ty::Array(ref sub_ty, len) if len.assert_usize(cx.tcx).is_some() => {
-            let len = len.unwrap_usize(cx.tcx);
+        ty::Array(ref sub_ty, len) if len.try_eval_usize(cx.tcx, cx.param_env).is_some() => {
+            let len = len.eval_usize(cx.tcx, cx.param_env);
             if len != 0 && cx.is_uninhabited(sub_ty) {
                 vec![]
             } else {
@@ -789,7 +789,7 @@ fn max_slice_length<'p, 'a, 'tcx, I>(cx: &mut MatchCheckCtxt<'a, 'tcx>, patterns
                 match (value.val, &value.ty.sty) {
                     (_, ty::Array(_, n)) => max_fixed_len = cmp::max(
                         max_fixed_len,
-                        n.unwrap_usize(cx.tcx),
+                        n.eval_usize(cx.tcx, cx.param_env),
                     ),
                     (ConstValue::Slice{ start, end, .. }, ty::Slice(_)) => max_fixed_len = cmp::max(
                         max_fixed_len,
@@ -830,7 +830,11 @@ struct IntRange<'tcx> {
 }
 
 impl<'tcx> IntRange<'tcx> {
-    fn from_ctor(tcx: TyCtxt<'tcx>, ctor: &Constructor<'tcx>) -> Option<IntRange<'tcx>> {
+    fn from_ctor(
+        tcx: TyCtxt<'tcx>,
+        param_env: ty::ParamEnv<'tcx>,
+        ctor: &Constructor<'tcx>,
+    ) -> Option<IntRange<'tcx>> {
         // Floating-point ranges are permitted and we don't want
         // to consider them when constructing integer ranges.
         fn is_integral(ty: Ty<'_>) -> bool {
@@ -856,7 +860,7 @@ fn is_integral(ty: Ty<'_>) -> bool {
             }
             ConstantValue(val) if is_integral(val.ty) => {
                 let ty = val.ty;
-                if let Some(val) = val.assert_bits(tcx, ty::ParamEnv::empty().and(ty)) {
+                if let Some(val) = val.try_eval_bits(tcx, param_env, ty) {
                     let bias = IntRange::signed_bias(tcx, ty);
                     let val = val ^ bias;
                     Some(IntRange { range: val..=val, ty })
@@ -868,13 +872,17 @@ fn is_integral(ty: Ty<'_>) -> bool {
         }
     }
 
-    fn from_pat(tcx: TyCtxt<'tcx>, mut pat: &Pattern<'tcx>) -> Option<IntRange<'tcx>> {
+    fn from_pat(
+        tcx: TyCtxt<'tcx>,
+        param_env: ty::ParamEnv<'tcx>,
+        mut pat: &Pattern<'tcx>,
+    ) -> Option<IntRange<'tcx>> {
         let range = loop {
             match pat.kind {
                 box PatternKind::Constant { value } => break ConstantValue(value),
                 box PatternKind::Range(PatternRange { lo, hi, ty, end }) => break ConstantRange(
-                    lo.to_bits(tcx, ty::ParamEnv::empty().and(ty)).unwrap(),
-                    hi.to_bits(tcx, ty::ParamEnv::empty().and(ty)).unwrap(),
+                    lo.eval_bits(tcx, param_env, ty),
+                    hi.eval_bits(tcx, param_env, ty),
                     ty,
                     end,
                 ),
@@ -884,7 +892,7 @@ fn from_pat(tcx: TyCtxt<'tcx>, mut pat: &Pattern<'tcx>) -> Option<IntRange<'tcx>
                 _ => return None,
             }
         };
-        Self::from_ctor(tcx, &range)
+        Self::from_ctor(tcx, param_env, &range)
     }
 
     // The return value of `signed_bias` should be XORed with an endpoint to encode/decode it.
@@ -919,10 +927,11 @@ fn range_to_ctor(
     fn subtract_from(
         self,
         tcx: TyCtxt<'tcx>,
+        param_env: ty::ParamEnv<'tcx>,
         ranges: Vec<Constructor<'tcx>>,
     ) -> Vec<Constructor<'tcx>> {
         let ranges = ranges.into_iter().filter_map(|r| {
-            IntRange::from_ctor(tcx, &r).map(|i| i.range)
+            IntRange::from_ctor(tcx, param_env, &r).map(|i| i.range)
         });
         let mut remaining_ranges = vec![];
         let ty = self.ty;
@@ -989,6 +998,7 @@ enum MissingCtors<'tcx> {
 fn compute_missing_ctors<'tcx>(
     info: MissingCtorsInfo,
     tcx: TyCtxt<'tcx>,
+    param_env: ty::ParamEnv<'tcx>,
     all_ctors: &Vec<Constructor<'tcx>>,
     used_ctors: &Vec<Constructor<'tcx>>,
 ) -> MissingCtors<'tcx> {
@@ -1001,10 +1011,10 @@ fn compute_missing_ctors<'tcx>(
                 // If a constructor appears in a `match` arm, we can
                 // eliminate it straight away.
                 refined_ctors = vec![]
-            } else if let Some(interval) = IntRange::from_ctor(tcx, used_ctor) {
+            } else if let Some(interval) = IntRange::from_ctor(tcx, param_env, used_ctor) {
                 // Refine the required constructors for the type by subtracting
                 // the range defined by the current constructor pattern.
-                refined_ctors = interval.subtract_from(tcx, refined_ctors);
+                refined_ctors = interval.subtract_from(tcx, param_env, refined_ctors);
             }
 
             // If the constructor patterns that have been considered so far
@@ -1119,7 +1129,9 @@ pub fn is_useful<'p, 'a, 'tcx>(
         if is_declared_nonexhaustive {
             Useful
         } else {
-            split_grouped_constructors(cx.tcx, constructors, matrix, pcx.ty).into_iter().map(|c|
+            split_grouped_constructors(
+                cx.tcx, cx.param_env, constructors, matrix, pcx.ty,
+            ).into_iter().map(|c|
                 is_useful_specialized(cx, matrix, v, c, pcx.ty, witness)
             ).find(|result| result.is_useful()).unwrap_or(NotUseful)
         }
@@ -1158,8 +1170,9 @@ pub fn is_useful<'p, 'a, 'tcx>(
         // non-wildcard patterns in the current column. We always determine if
         // the set is empty, but we only fully construct them on-demand,
         // because they're rarely used and can be big.
-        let cheap_missing_ctors =
-            compute_missing_ctors(MissingCtorsInfo::Emptiness, cx.tcx, &all_ctors, &used_ctors);
+        let cheap_missing_ctors = compute_missing_ctors(
+            MissingCtorsInfo::Emptiness, cx.tcx, cx.param_env, &all_ctors, &used_ctors,
+        );
 
         let is_privately_empty = all_ctors.is_empty() && !cx.is_uninhabited(pcx.ty);
         let is_declared_nonexhaustive = cx.is_non_exhaustive_enum(pcx.ty) && !cx.is_local(pcx.ty);
@@ -1172,9 +1185,10 @@ pub fn is_useful<'p, 'a, 'tcx>(
             (pcx.ty.is_ptr_sized_integral() && !cx.tcx.features().precise_pointer_size_matching);
 
         if cheap_missing_ctors == MissingCtors::Empty && !is_non_exhaustive {
-            split_grouped_constructors(cx.tcx, all_ctors, matrix, pcx.ty).into_iter().map(|c| {
-                is_useful_specialized(cx, matrix, v, c, pcx.ty, witness)
-            }).find(|result| result.is_useful()).unwrap_or(NotUseful)
+            split_grouped_constructors(cx.tcx, cx.param_env, all_ctors, matrix, pcx.ty)
+                .into_iter().map(|c| is_useful_specialized(cx, matrix, v, c, pcx.ty, witness))
+                .find(|result| result.is_useful())
+                .unwrap_or(NotUseful)
         } else {
             let matrix = rows.iter().filter_map(|r| {
                 if r[0].is_wildcard() {
@@ -1242,9 +1256,9 @@ pub fn is_useful<'p, 'a, 'tcx>(
                             witness
                         }).collect()
                     } else {
-                        let expensive_missing_ctors =
-                            compute_missing_ctors(MissingCtorsInfo::Ctors, cx.tcx, &all_ctors,
-                                                  &used_ctors);
+                        let expensive_missing_ctors = compute_missing_ctors(
+                            MissingCtorsInfo::Ctors, cx.tcx, cx.param_env, &all_ctors, &used_ctors,
+                        );
                         if let MissingCtors::Ctors(missing_ctors) = expensive_missing_ctors {
                             pats.into_iter().flat_map(|witness| {
                                 missing_ctors.iter().map(move |ctor| {
@@ -1327,14 +1341,14 @@ fn pat_constructors<'tcx>(cx: &mut MatchCheckCtxt<'_, 'tcx>,
         PatternKind::Constant { value } => Some(vec![ConstantValue(value)]),
         PatternKind::Range(PatternRange { lo, hi, ty, end }) =>
             Some(vec![ConstantRange(
-                lo.to_bits(cx.tcx, ty::ParamEnv::empty().and(ty)).unwrap(),
-                hi.to_bits(cx.tcx, ty::ParamEnv::empty().and(ty)).unwrap(),
+                lo.eval_bits(cx.tcx, cx.param_env, ty),
+                hi.eval_bits(cx.tcx, cx.param_env, ty),
                 ty,
                 end,
             )]),
         PatternKind::Array { .. } => match pcx.ty.sty {
             ty::Array(_, length) => Some(vec![
-                Slice(length.unwrap_usize(cx.tcx))
+                Slice(length.eval_usize(cx.tcx, cx.param_env))
             ]),
             _ => span_bug!(pat.span, "bad ty {:?} for array pattern", pcx.ty)
         },
@@ -1402,7 +1416,8 @@ fn constructor_sub_pattern_tys<'a, 'tcx>(
                         match ty.sty {
                             // If the field type returned is an array of an unknown
                             // size return an TyErr.
-                            ty::Array(_, len) if len.assert_usize(cx.tcx).is_none() =>
+                            ty::Array(_, len)
+                                if len.try_eval_usize(cx.tcx, cx.param_env).is_none() =>
                                 cx.tcx.types.err,
                             _ => ty,
                         }
@@ -1432,11 +1447,12 @@ fn slice_pat_covered_by_const<'tcx>(
     prefix: &[Pattern<'tcx>],
     slice: &Option<Pattern<'tcx>>,
     suffix: &[Pattern<'tcx>],
+    param_env: ty::ParamEnv<'tcx>,
 ) -> Result<bool, ErrorReported> {
     let data: &[u8] = match (const_val.val, &const_val.ty.sty) {
         (ConstValue::ByRef { offset, alloc, .. }, ty::Array(t, n)) => {
             assert_eq!(*t, tcx.types.u8);
-            let n = n.assert_usize(tcx).unwrap();
+            let n = n.eval_usize(tcx, param_env);
             let ptr = Pointer::new(AllocId(0), offset);
             alloc.get_bytes(&tcx, ptr, Size::from_bytes(n)).unwrap()
         },
@@ -1464,7 +1480,7 @@ fn slice_pat_covered_by_const<'tcx>(
     {
         match pat.kind {
             box PatternKind::Constant { value } => {
-                let b = value.unwrap_bits(tcx, ty::ParamEnv::empty().and(pat.ty));
+                let b = value.eval_bits(tcx, param_env, pat.ty);
                 assert_eq!(b as u8 as u128, b);
                 if b as u8 != *ch {
                     return Ok(false);
@@ -1526,6 +1542,7 @@ fn should_treat_range_exhaustively(tcx: TyCtxt<'tcx>, ctor: &Constructor<'tcx>)
 /// merging operation depicted above.)
 fn split_grouped_constructors<'p, 'tcx>(
     tcx: TyCtxt<'tcx>,
+    param_env: ty::ParamEnv<'tcx>,
     ctors: Vec<Constructor<'tcx>>,
     &Matrix(ref m): &Matrix<'p, 'tcx>,
     ty: Ty<'tcx>,
@@ -1540,7 +1557,7 @@ fn split_grouped_constructors<'p, 'tcx>(
                 // We only care about finding all the subranges within the range of the constructor
                 // range. Anything else is irrelevant, because it is guaranteed to result in
                 // `NotUseful`, which is the default case anyway, and can be ignored.
-                let ctor_range = IntRange::from_ctor(tcx, &ctor).unwrap();
+                let ctor_range = IntRange::from_ctor(tcx, param_env, &ctor).unwrap();
 
                 /// Represents a border between 2 integers. Because the intervals spanning borders
                 /// must be able to cover every integer, we need to be able to represent
@@ -1565,7 +1582,7 @@ fn range_borders(r: IntRange<'_>) -> impl Iterator<Item = Border> {
                 // `borders` is the set of borders between equivalence classes: each equivalence
                 // class lies between 2 borders.
                 let row_borders = m.iter()
-                    .flat_map(|row| IntRange::from_pat(tcx, row[0]))
+                    .flat_map(|row| IntRange::from_pat(tcx, param_env, row[0]))
                     .flat_map(|range| ctor_range.intersection(&range))
                     .flat_map(|range| range_borders(range));
                 let ctor_borders = range_borders(ctor_range.clone());
@@ -1604,11 +1621,12 @@ fn range_borders(r: IntRange<'_>) -> impl Iterator<Item = Border> {
 /// Checks whether there exists any shared value in either `ctor` or `pat` by intersecting them.
 fn constructor_intersects_pattern<'p, 'tcx>(
     tcx: TyCtxt<'tcx>,
+    param_env: ty::ParamEnv<'tcx>,
     ctor: &Constructor<'tcx>,
     pat: &'p Pattern<'tcx>,
 ) -> Option<SmallVec<[&'p Pattern<'tcx>; 2]>> {
     if should_treat_range_exhaustively(tcx, ctor) {
-        match (IntRange::from_ctor(tcx, ctor), IntRange::from_pat(tcx, pat)) {
+        match (IntRange::from_ctor(tcx, param_env, ctor), IntRange::from_pat(tcx, param_env, pat)) {
             (Some(ctor), Some(pat)) => {
                 ctor.intersection(&pat).map(|_| {
                     let (pat_lo, pat_hi) = pat.range.into_inner();
@@ -1623,7 +1641,7 @@ fn constructor_intersects_pattern<'p, 'tcx>(
         // Fallback for non-ranges and ranges that involve floating-point numbers, which are not
         // conveniently handled by `IntRange`. For these cases, the constructor may not be a range
         // so intersection actually devolves into being covered by the pattern.
-        match constructor_covered_by_range(tcx, ctor, pat) {
+        match constructor_covered_by_range(tcx, param_env, ctor, pat) {
             Ok(true) => Some(smallvec![]),
             Ok(false) | Err(ErrorReported) => None,
         }
@@ -1632,6 +1650,7 @@ fn constructor_intersects_pattern<'p, 'tcx>(
 
 fn constructor_covered_by_range<'tcx>(
     tcx: TyCtxt<'tcx>,
+    param_env: ty::ParamEnv<'tcx>,
     ctor: &Constructor<'tcx>,
     pat: &Pattern<'tcx>,
 ) -> Result<bool, ErrorReported> {
@@ -1641,9 +1660,9 @@ fn constructor_covered_by_range<'tcx>(
         _ => bug!("`constructor_covered_by_range` called with {:?}", pat),
     };
     trace!("constructor_covered_by_range {:#?}, {:#?}, {:#?}, {}", ctor, from, to, ty);
-    let cmp_from = |c_from| compare_const_vals(tcx, c_from, from, ty::ParamEnv::empty().and(ty))
+    let cmp_from = |c_from| compare_const_vals(tcx, c_from, from, param_env, ty)
         .map(|res| res != Ordering::Less);
-    let cmp_to = |c_to| compare_const_vals(tcx, c_to, to, ty::ParamEnv::empty().and(ty));
+    let cmp_to = |c_to| compare_const_vals(tcx, c_to, to, param_env, ty);
     macro_rules! some_or_ok {
         ($e:expr) => {
             match $e {
@@ -1760,7 +1779,7 @@ fn specialize<'p, 'a: 'p, 'tcx>(
                                 ConstValue::ByRef { offset, alloc, .. } => (
                                     alloc,
                                     offset,
-                                    n.unwrap_usize(cx.tcx),
+                                    n.eval_usize(cx.tcx, cx.param_env),
                                     t,
                                 ),
                                 _ => span_bug!(
@@ -1821,7 +1840,7 @@ fn specialize<'p, 'a: 'p, 'tcx>(
                     // If the constructor is a:
                     //      Single value: add a row if the constructor equals the pattern.
                     //      Range: add a row if the constructor contains the pattern.
-                    constructor_intersects_pattern(cx.tcx, constructor, pat)
+                    constructor_intersects_pattern(cx.tcx, cx.param_env, constructor, pat)
                 }
             }
         }
@@ -1830,7 +1849,7 @@ fn specialize<'p, 'a: 'p, 'tcx>(
             // If the constructor is a:
             //      Single value: add a row if the pattern contains the constructor.
             //      Range: add a row if the constructor intersects the pattern.
-            constructor_intersects_pattern(cx.tcx, constructor, pat)
+            constructor_intersects_pattern(cx.tcx, cx.param_env, constructor, pat)
         }
 
         PatternKind::Array { ref prefix, ref slice, ref suffix } |
@@ -1854,7 +1873,9 @@ fn specialize<'p, 'a: 'p, 'tcx>(
                     }
                 }
                 ConstantValue(cv) => {
-                    match slice_pat_covered_by_const(cx.tcx, pat.span, cv, prefix, slice, suffix) {
+                    match slice_pat_covered_by_const(
+                        cx.tcx, pat.span, cv, prefix, slice, suffix, cx.param_env,
+                    ) {
                         Ok(true) => Some(smallvec![]),
                         Ok(false) => None,
                         Err(ErrorReported) => None
index f759ec7f219d12d68ec5b8cb80d79548111b7937..5ecfb84b632360d37eb79c3f57333c28b3df2d45 100644 (file)
@@ -446,7 +446,8 @@ fn lower_pattern_unadjusted(&mut self, pat: &'tcx hir::Pat) -> Pattern<'tcx> {
                             self.tcx,
                             lo,
                             hi,
-                            self.param_env.and(ty),
+                            self.param_env,
+                            ty,
                         );
                         match (end, cmp) {
                             (RangeEnd::Excluded, Some(Ordering::Less)) =>
@@ -728,7 +729,7 @@ fn slice_or_array_pattern(
 
             ty::Array(_, len) => {
                 // fixed-length array
-                let len = len.unwrap_usize(self.tcx);
+                let len = len.eval_usize(self.tcx, self.param_env);
                 assert!(len >= prefix.len() as u64 + suffix.len() as u64);
                 PatternKind::Array { prefix: prefix, slice: slice, suffix: suffix }
             }
@@ -1123,7 +1124,7 @@ fn const_to_pat_inner(
             }
             ty::Array(_, n) => {
                 PatternKind::Array {
-                    prefix: (0..n.unwrap_usize(self.tcx))
+                    prefix: (0..n.eval_usize(self.tcx, self.param_env))
                         .map(|i| adt_subpattern(i as usize, None))
                         .collect(),
                     slice: None,
@@ -1206,7 +1207,8 @@ fn visit_ty(&mut self, ty: Ty<'tcx>) -> bool {
                     // (But still tell caller to continue search.)
                     return false;
                 }
-                ty::Array(_, n) if n.assert_usize(self.tcx) == Some(0) => {
+                ty::Array(_, n) if n.try_eval_usize(self.tcx, ty::ParamEnv::reveal_all()) == Some(0)
+                => {
                     // rust-lang/rust#62336: ignore type of contents
                     // for empty array.
                     return false;
@@ -1451,7 +1453,8 @@ pub fn compare_const_vals<'tcx>(
     tcx: TyCtxt<'tcx>,
     a: &'tcx ty::Const<'tcx>,
     b: &'tcx ty::Const<'tcx>,
-    ty: ty::ParamEnvAnd<'tcx, Ty<'tcx>>,
+    param_env: ty::ParamEnv<'tcx>,
+    ty: Ty<'tcx>,
 ) -> Option<Ordering> {
     trace!("compare_const_vals: {:?}, {:?}", a, b);
 
@@ -1466,15 +1469,16 @@ pub fn compare_const_vals<'tcx>(
     let fallback = || from_bool(a == b);
 
     // Use the fallback if any type differs
-    if a.ty != b.ty || a.ty != ty.value {
+    if a.ty != b.ty || a.ty != ty {
         return fallback();
     }
 
-    // FIXME: This should use assert_bits(ty) instead of use_bits
-    // but triggers possibly bugs due to mismatching of arrays and slices
-    if let (Some(a), Some(b)) = (a.to_bits(tcx, ty), b.to_bits(tcx, ty)) {
+    let a_bits = a.try_eval_bits(tcx, param_env, ty);
+    let b_bits = b.try_eval_bits(tcx, param_env, ty);
+
+    if let (Some(a), Some(b)) = (a_bits, b_bits) {
         use ::rustc_apfloat::Float;
-        return match ty.value.sty {
+        return match ty.sty {
             ty::Float(ast::FloatTy::F32) => {
                 let l = ::rustc_apfloat::ieee::Single::from_bits(a);
                 let r = ::rustc_apfloat::ieee::Single::from_bits(b);
@@ -1497,7 +1501,7 @@ pub fn compare_const_vals<'tcx>(
         }
     }
 
-    if let ty::Str = ty.value.sty {
+    if let ty::Str = ty.sty {
         match (a.val, b.val) {
             (
                 ConstValue::Slice { data: alloc_a, start: offset_a, end: end_a },
index 8e3450656abfba31d61549aae24efaaf52340eff..26cfbfe53a35cdf856320174e6dd7012bb403de9 100644 (file)
@@ -253,7 +253,7 @@ fn unsize_into_ptr(
                 // u64 cast is from usize to u64, which is always good
                 let val = Immediate::new_slice(
                     ptr,
-                    length.unwrap_usize(self.tcx.tcx),
+                    length.eval_usize(self.tcx.tcx, self.param_env),
                     self,
                 );
                 self.write_immediate(val, dest)
index e9bba7889119a2f6a532f1d5bb0476640f8e7988..1074ab941a761acbfc5eb23b388ebd2570b78c45 100644 (file)
@@ -176,7 +176,8 @@ fn visit_primitive(&mut self, mplace: MPlaceTy<'tcx>) -> InterpResult<'tcx> {
                     (InternMode::ConstBase, hir::Mutability::MutMutable) |
                     (InternMode::Const, hir::Mutability::MutMutable) => {
                         match referenced_ty.sty {
-                            ty::Array(_, n) if n.unwrap_usize(self.ecx.tcx.tcx) == 0 => {}
+                            ty::Array(_, n)
+                                if n.eval_usize(self.ecx.tcx.tcx, self.param_env) == 0 => {}
                             ty::Slice(_)
                                 if value.to_meta().unwrap().unwrap().to_usize(self.ecx)? == 0 => {}
                             _ => bug!("const qualif failed to prevent mutable references"),
index 32b964dbadfa92ac3dcf5e4a5d0dab9f6844db46..42945c79ddf0edc73cce20b6c6d05d545e407b98 100644 (file)
@@ -304,8 +304,10 @@ fn array_subpath(&self, _path: Self::Path, _index: u32, _size: u32) -> Option<Se
 fn build_clone_shim<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, self_ty: Ty<'tcx>) -> Body<'tcx> {
     debug!("build_clone_shim(def_id={:?})", def_id);
 
+    let param_env = tcx.param_env(def_id);
+
     let mut builder = CloneShimBuilder::new(tcx, def_id, self_ty);
-    let is_copy = self_ty.is_copy_modulo_regions(tcx, tcx.param_env(def_id), builder.span);
+    let is_copy = self_ty.is_copy_modulo_regions(tcx, param_env, builder.span);
 
     let dest = Place::RETURN_PLACE;
     let src = Place::from(Local::new(1+0)).deref();
@@ -313,7 +315,7 @@ fn build_clone_shim<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, self_ty: Ty<'tcx>) -
     match self_ty.sty {
         _ if is_copy => builder.copy_shim(),
         ty::Array(ty, len) => {
-            let len = len.unwrap_usize(tcx);
+            let len = len.eval_usize(tcx, param_env);
             builder.array_shim(dest, src, ty, len)
         }
         ty::Closure(def_id, substs) => {
index ffeaf4e19c22a76008d1a6a3a92d8b8caf68565a..163d10b9bd5f399d950b2a9e110f127beeef112d 100644 (file)
@@ -367,7 +367,7 @@ fn in_rvalue(cx: &ConstCx<'_, 'tcx>, rvalue: &Rvalue<'tcx>) -> bool {
                     } else if let ty::Array(_, len) = ty.sty {
                         // FIXME(eddyb) the `cx.mode == Mode::NonConstFn` condition
                         // seems unnecessary, given that this is merely a ZST.
-                        match len.assert_usize(cx.tcx) {
+                        match len.try_eval_usize(cx.tcx, cx.param_env) {
                             Some(0) if cx.mode == Mode::NonConstFn => {},
                             _ => return true,
                         }
index f39c71ef42d71559c70bc6a04a5bd008ceb3ef03..9ffa3db4c2eb073df0dbe44c0b50e632f37f26a1 100644 (file)
@@ -1,6 +1,6 @@
 //! A pass that simplifies branches when their condition is known.
 
-use rustc::ty::{TyCtxt, ParamEnv};
+use rustc::ty::TyCtxt;
 use rustc::mir::*;
 use crate::transform::{MirPass, MirSource};
 
@@ -19,15 +19,15 @@ fn name(&self) -> Cow<'_, str> {
         Cow::Borrowed(&self.label)
     }
 
-    fn run_pass<'tcx>(&self, tcx: TyCtxt<'tcx>, _src: MirSource<'tcx>, body: &mut Body<'tcx>) {
+    fn run_pass<'tcx>(&self, tcx: TyCtxt<'tcx>, src: MirSource<'tcx>, body: &mut Body<'tcx>) {
+        let param_env = tcx.param_env(src.def_id());
         for block in body.basic_blocks_mut() {
             let terminator = block.terminator_mut();
             terminator.kind = match terminator.kind {
                 TerminatorKind::SwitchInt {
                     discr: Operand::Constant(ref c), switch_ty, ref values, ref targets, ..
                 } => {
-                    let switch_ty = ParamEnv::empty().and(switch_ty);
-                    let constant = c.literal.assert_bits(tcx, switch_ty);
+                    let constant = c.literal.try_eval_bits(tcx, param_env, switch_ty);
                     if let Some(constant) = constant {
                         let (otherwise, targets) = targets.split_last().unwrap();
                         let mut ret = TerminatorKind::Goto { target: *otherwise };
@@ -44,7 +44,7 @@ fn run_pass<'tcx>(&self, tcx: TyCtxt<'tcx>, _src: MirSource<'tcx>, body: &mut Bo
                 },
                 TerminatorKind::Assert {
                     target, cond: Operand::Constant(ref c), expected, ..
-                } if (c.literal.assert_bool(tcx) == Some(true)) == expected =>
+                } if (c.literal.try_eval_bool(tcx, param_env) == Some(true)) == expected =>
                     TerminatorKind::Goto { target },
                 TerminatorKind::FalseEdges { real_target, .. } => {
                     TerminatorKind::Goto { target: real_target }
index 6aceeebaea161ab88dd91203a47602330c922c7a..60489e7fa36688ab5718c0d6377e91f06b755724 100644 (file)
 pub struct UniformArrayMoveOut;
 
 impl MirPass for UniformArrayMoveOut {
-    fn run_pass<'tcx>(&self, tcx: TyCtxt<'tcx>, _src: MirSource<'tcx>, body: &mut Body<'tcx>) {
+    fn run_pass<'tcx>(&self, tcx: TyCtxt<'tcx>, src: MirSource<'tcx>, body: &mut Body<'tcx>) {
         let mut patch = MirPatch::new(body);
+        let param_env = tcx.param_env(src.def_id());
         {
-            let mut visitor = UniformArrayMoveOutVisitor{body, patch: &mut patch, tcx};
+            let mut visitor = UniformArrayMoveOutVisitor{body, patch: &mut patch, tcx, param_env};
             visitor.visit_body(body);
         }
         patch.apply(body);
@@ -51,6 +52,7 @@ struct UniformArrayMoveOutVisitor<'a, 'tcx> {
     body: &'a Body<'tcx>,
     patch: &'a mut MirPatch<'tcx>,
     tcx: TyCtxt<'tcx>,
+    param_env: ty::ParamEnv<'tcx>,
 }
 
 impl<'a, 'tcx> Visitor<'tcx> for UniformArrayMoveOutVisitor<'a, 'tcx> {
@@ -68,7 +70,7 @@ fn visit_assign(&mut self,
                     let place_ty =
                         Place::ty_from(&src_place.base, &proj.base, self.body, self.tcx).ty;
                     if let ty::Array(item_ty, const_size) = place_ty.sty {
-                        if let Some(size) = const_size.assert_usize(self.tcx) {
+                        if let Some(size) = const_size.try_eval_usize(self.tcx, self.param_env) {
                             assert!(size <= u32::max_value() as u64,
                                     "uniform array move out doesn't supported
                                      for array bigger then u32");
@@ -183,8 +185,9 @@ fn uniform(&mut self,
 pub struct RestoreSubsliceArrayMoveOut;
 
 impl MirPass for RestoreSubsliceArrayMoveOut {
-    fn run_pass<'tcx>(&self, tcx: TyCtxt<'tcx>, _src: MirSource<'tcx>, body: &mut Body<'tcx>) {
+    fn run_pass<'tcx>(&self, tcx: TyCtxt<'tcx>, src: MirSource<'tcx>, body: &mut Body<'tcx>) {
         let mut patch = MirPatch::new(body);
+        let param_env = tcx.param_env(src.def_id());
         {
             let mut visitor = RestoreDataCollector {
                 locals_use: IndexVec::from_elem(LocalUse::new(), &body.local_decls),
@@ -219,7 +222,7 @@ fn run_pass<'tcx>(&self, tcx: TyCtxt<'tcx>, _src: MirSource<'tcx>, body: &mut Bo
                             let src_ty =
                                 Place::ty_from(src_place.base, src_place.projection, body, tcx).ty;
                             if let ty::Array(_, ref size_o) = src_ty.sty {
-                                size_o.assert_usize(tcx)
+                                size_o.try_eval_usize(tcx, param_env)
                             } else {
                                 None
                             }
index 61ad2ba8f5737355c448af551cfb69b42214ad0d..d17dcaafc04f5b07d0a351da68d631b18ada1ddf 100644 (file)
@@ -821,7 +821,7 @@ fn open_drop(&mut self) -> BasicBlock {
                 self.complete_drop(Some(DropFlagMode::Deep), succ, unwind)
             }
             ty::Array(ety, size) => {
-                let size = size.assert_usize(self.tcx());
+                let size = size.try_eval_usize(self.tcx(), self.elaborator.param_env());
                 self.open_drop_for_array(ety, size)
             },
             ty::Slice(ety) => self.open_drop_for_array(ety, None),
index 59c01b8b1b7b19576806ffefeef29638d85d0f01..c7aa6fe105e54fcf8ff7ca2675c834d6b17a6577 100644 (file)
@@ -174,6 +174,11 @@ fn tcx(&self) -> TyCtxt<'tcx> {
         self.infcx.tcx
     }
 
+    fn param_env(&self) -> ty::ParamEnv<'tcx> {
+        // FIXME(oli-obk): learn chalk and create param envs
+        ty::ParamEnv::empty()
+    }
+
     fn tag(&self) -> &'static str {
         "chalk_context::answer_substitutor"
     }
index e4dda20c822bf26f8d996768d5ced26ac7da2501..3a43e764dd08e4e1bc022a9eb42fb8ee5c2ad22f 100644 (file)
@@ -423,7 +423,7 @@ pub fn check_pat_walk(
                 let expected_ty = self.structurally_resolved_type(pat.span, expected);
                 let (inner_ty, slice_ty) = match expected_ty.sty {
                     ty::Array(inner_ty, size) => {
-                        if let Some(size) = size.assert_usize(tcx) {
+                        if let Some(size) = size.try_eval_usize(tcx, self.param_env) {
                             let min_len = before.len() as u64 + after.len() as u64;
                             if slice.is_none() {
                                 if min_len != size {
index 8d2160c0ec7aa7c39cd52cac37ffa79b469d5b19..d825358beaade1e6022c2e99fc16dd08f9a4cb2d 100644 (file)
@@ -1386,7 +1386,7 @@ fn check_field(
                     }
                     ty::Array(_, len) => {
                         if let (Some(len), Ok(user_index)) = (
-                            len.assert_usize(self.tcx),
+                            len.try_eval_usize(self.tcx, self.param_env),
                             field.as_str().parse::<u64>()
                         ) {
                             let base = self.tcx.sess.source_map()
index fe6d91b0a6eba7f7ffbe658bf9ab6d29581d8099..3f9e662c6f412c900c3dab70c4507b8506848eed 100644 (file)
@@ -824,6 +824,7 @@ fn with_mc<F, R>(&self, f: F) -> R
     {
         f(mc::MemCategorizationContext::with_infer(
             &self.infcx,
+            self.outlives_environment.param_env,
             self.body_owner,
             &self.region_scope_tree,
             &self.tables.borrow(),
index d0df9f8f7e4101242b2e5ae4faf6ef2d679e047d..405144b444f09225b5eb5a09772b0b8a893aa20e 100644 (file)
@@ -211,7 +211,6 @@ fn test_parse_ok() {
 fn test_parse_err() {
     with_default_globals(|| {
         let mi = attr::mk_name_value_item(
-            DUMMY_SP,
             Ident::from_str("foo"),
             LitKind::Bool(false),
             DUMMY_SP,
index 8132074d6e0e7dd1fc307d6e61b929ec1a2de66e..5d86ee9721b75711aa73b12290c2493c15f82eac 100644 (file)
@@ -44,7 +44,7 @@ pub fn render_with_highlighting(
 
         let mut highlighted_source = vec![];
         if classifier.write_source(&mut highlighted_source).is_err() {
-            Err(classifier.lexer.buffer_fatal_errors())
+            Err(())
         } else {
             Ok(String::from_utf8_lossy(&highlighted_source).into_owned())
         }
@@ -59,14 +59,9 @@ pub fn render_with_highlighting(
             }
             write_footer(&mut out).unwrap();
         }
-        Err(errors) => {
-            // If errors are encountered while trying to highlight, cancel the errors and just emit
-            // the unhighlighted source. The errors will have already been reported in the
-            // `check-code-block-syntax` pass.
-            for mut error in errors {
-                error.cancel();
-            }
-
+        Err(()) => {
+            // If errors are encountered while trying to highlight, just emit
+            // the unhighlighted source.
             write!(out, "<pre><code>{}</code></pre>", src).unwrap();
         }
     }
@@ -192,14 +187,20 @@ fn try_next_token(&mut self) -> Result<Token, HighlightError> {
         if let Some(token) = self.peek_token.take() {
             return Ok(token);
         }
-        self.lexer.try_next_token().map_err(|()| HighlightError::LexError)
+        let token = self.lexer.next_token();
+        if let token::Unknown(..) = &token.kind {
+            return Err(HighlightError::LexError);
+        }
+        Ok(token)
     }
 
     fn peek(&mut self) -> Result<&Token, HighlightError> {
         if self.peek_token.is_none() {
-            self.peek_token = Some(
-                self.lexer.try_next_token().map_err(|()| HighlightError::LexError)?
-            );
+            let token = self.lexer.next_token();
+            if let token::Unknown(..) = &token.kind {
+                return Err(HighlightError::LexError);
+            }
+            self.peek_token = Some(token);
         }
         Ok(self.peek_token.as_ref().unwrap())
     }
@@ -237,7 +238,7 @@ fn write_token<W: Writer>(&mut self,
                 return Ok(());
             },
 
-            token::Whitespace => Class::None,
+            token::Whitespace | token::Unknown(..) => Class::None,
             token::Comment => Class::Comment,
             token::DocComment(..) => Class::DocComment,
 
index 0488153e7cb732e418d7a0ee36dab956d26c3a5c..357e17d2d1bc46c4c97cb79576f1cb668efd6ea8 100644 (file)
@@ -32,24 +32,20 @@ fn check_rust_syntax(&self, item: &clean::Item, dox: &str, code_block: RustCodeB
             dox[code_block.code].to_owned(),
         );
 
-        let errors = {
+        let has_errors = {
+            let mut has_errors = false;
             let mut lexer = Lexer::new(&sess, source_file, None);
-            while let Ok(token::Token { kind, .. }) = lexer.try_next_token() {
-                if kind == token::Eof {
-                    break;
+            loop  {
+                match lexer.next_token().kind {
+                    token::Eof => break,
+                    token::Unknown(..) => has_errors = true,
+                    _ => (),
                 }
             }
-
-            let errors = lexer.buffer_fatal_errors();
-
-            if !errors.is_empty() {
-                Err(errors)
-            } else {
-                Ok(())
-            }
+            has_errors
         };
 
-        if let Err(errors) = errors {
+        if has_errors {
             let mut diag = if let Some(sp) =
                 super::source_span_for_markdown_range(self.cx, &dox, &code_block.range, &item.attrs)
             {
@@ -58,11 +54,6 @@ fn check_rust_syntax(&self, item: &clean::Item, dox: &str, code_block: RustCodeB
                     .sess()
                     .struct_span_warn(sp, "could not parse code block as Rust code");
 
-                for mut err in errors {
-                    diag.note(&format!("error from rustc: {}", err.message()));
-                    err.cancel();
-                }
-
                 if code_block.syntax.is_none() && code_block.is_fenced {
                     let sp = sp.from_inner(InnerSpan::new(0, 3));
                     diag.span_suggestion(
@@ -82,11 +73,6 @@ fn check_rust_syntax(&self, item: &clean::Item, dox: &str, code_block: RustCodeB
                     "doc comment contains an invalid Rust code block",
                 );
 
-                for mut err in errors {
-                    // Don't bother reporting the error, because we can't show where it happened.
-                    err.cancel();
-                }
-
                 if code_block.syntax.is_none() && code_block.is_fenced {
                     diag.help("mark blocks that do not contain Rust code as text: ```text");
                 }
index 126bc3754dabcac134e18c713c3d967878439aa3..56fde77daac5808a01926caed2bac9d60653d986 100644 (file)
@@ -1819,6 +1819,8 @@ pub fn as_os_str(&self) -> &OsStr {
     /// Yields a [`&str`] slice if the `Path` is valid unicode.
     ///
     /// This conversion may entail doing a check for UTF-8 validity.
+    /// Note that validation is performed because non-UTF-8 strings are
+    /// perfectly valid for some OS.
     ///
     /// [`&str`]: ../primitive.str.html
     ///
index 9b355aa2023ff64d54912ef5fb0457054fd4225f..f85b5d632f16b59a410575a7735d8db0687718b1 100644 (file)
@@ -2,6 +2,7 @@
 
 #![unstable(feature = "thread_local_internals", issue = "0")]
 
+use crate::error::Error;
 use crate::fmt;
 
 /// A thread local storage key which owns its contents.
@@ -189,6 +190,7 @@ unsafe fn __getit() -> $crate::option::Option<&'static $t> {
 
 /// An error returned by [`LocalKey::try_with`](struct.LocalKey.html#method.try_with).
 #[stable(feature = "thread_local_try_with", since = "1.26.0")]
+#[derive(Clone, Copy, Eq, PartialEq)]
 pub struct AccessError {
     _private: (),
 }
@@ -207,6 +209,9 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
     }
 }
 
+#[stable(feature = "thread_local_try_with", since = "1.26.0")]
+impl Error for AccessError {}
+
 impl<T: 'static> LocalKey<T> {
     #[doc(hidden)]
     #[unstable(feature = "thread_local_internals",
index 3e56136b171083ad03ac51727090bf8cf9e1a74b..a9d3227b3a8f40d5732445de148e5622a0894345 100644 (file)
@@ -347,16 +347,17 @@ pub fn with_desugared_doc<T, F>(&self, f: F) -> T where
 
 pub fn mk_name_value_item_str(ident: Ident, value: Spanned<Symbol>) -> MetaItem {
     let lit_kind = LitKind::Str(value.node, ast::StrStyle::Cooked);
-    mk_name_value_item(ident.span.to(value.span), ident, lit_kind, value.span)
+    mk_name_value_item(ident, lit_kind, value.span)
 }
 
-pub fn mk_name_value_item(span: Span, ident: Ident, lit_kind: LitKind, lit_span: Span) -> MetaItem {
+pub fn mk_name_value_item(ident: Ident, lit_kind: LitKind, lit_span: Span) -> MetaItem {
     let lit = Lit::from_lit_kind(lit_kind, lit_span);
+    let span = ident.span.to(lit_span);
     MetaItem { path: Path::from_ident(ident), span, node: MetaItemKind::NameValue(lit) }
 }
 
-pub fn mk_list_item(span: Span, ident: Ident, items: Vec<NestedMetaItem>) -> MetaItem {
-    MetaItem { path: Path::from_ident(ident), span, node: MetaItemKind::List(items) }
+pub fn mk_list_item(ident: Ident, items: Vec<NestedMetaItem>) -> MetaItem {
+    MetaItem { path: Path::from_ident(ident), span: ident.span, node: MetaItemKind::List(items) }
 }
 
 pub fn mk_word_item(ident: Ident) -> MetaItem {
@@ -367,7 +368,7 @@ pub fn mk_nested_word_item(ident: Ident) -> NestedMetaItem {
     NestedMetaItem::MetaItem(mk_word_item(ident))
 }
 
-pub fn mk_attr_id() -> AttrId {
+crate fn mk_attr_id() -> AttrId {
     use std::sync::atomic::AtomicUsize;
     use std::sync::atomic::Ordering;
 
index 59e13fdc8f163a42d3dfd1c4391f363ad734e796..db562840e8d3bae41f2d847803ec431ba7ecbd2e 100644 (file)
@@ -879,13 +879,12 @@ pub fn meta_list_item_word(&self, sp: Span, w: ast::Name) -> ast::NestedMetaItem
 
     pub fn meta_list(&self, sp: Span, name: ast::Name, mis: Vec<ast::NestedMetaItem>)
                  -> ast::MetaItem {
-        attr::mk_list_item(sp, Ident::new(name, sp), mis)
+        attr::mk_list_item(Ident::new(name, sp), mis)
     }
 
     pub fn meta_name_value(&self, span: Span, name: ast::Name, lit_kind: ast::LitKind)
                        -> ast::MetaItem {
-        attr::mk_name_value_item(span, Ident::new(name, span),
-                                 lit_kind, span)
+        attr::mk_name_value_item(Ident::new(name, span), lit_kind, span)
     }
 
     pub fn item_use(&self, sp: Span,
index d2807e4a4b5fa1714eef74575c18cbf619a45971..964c81dd4664103743ca0cfd505acc6c3105acfa 100644 (file)
@@ -1272,7 +1272,7 @@ fn visit_attribute(&mut self, at: &mut ast::Attribute) {
                             ];
 
                             let include_ident = Ident::with_empty_ctxt(sym::include);
-                            let item = attr::mk_list_item(DUMMY_SP, include_ident, include_info);
+                            let item = attr::mk_list_item(include_ident, include_info);
                             items.push(ast::NestedMetaItem::MetaItem(item));
                         }
                         Err(e) => {
@@ -1333,7 +1333,7 @@ fn visit_attribute(&mut self, at: &mut ast::Attribute) {
                 }
             }
 
-            let meta = attr::mk_list_item(DUMMY_SP, Ident::with_empty_ctxt(sym::doc), items);
+            let meta = attr::mk_list_item(Ident::with_empty_ctxt(sym::doc), items);
             *at = attr::Attribute {
                 span: at.span,
                 id: at.id,
index 8d0023c9ab1eb986e57c69a8a6ef3e81b41e4758..36621ce7775107d77a76790c2a1d28f4099c8b9b 100644 (file)
@@ -184,7 +184,7 @@ macro_rules! op {
             }
 
             OpenDelim(..) | CloseDelim(..) => unreachable!(),
-            Whitespace | Comment | Shebang(..) | Eof => unreachable!(),
+            Whitespace | Comment | Shebang(..) | Unknown(..) | Eof => unreachable!(),
         }
     }
 }
index 950b1b2ff53404639abe034df636a5b1e1b1f900..e86d4c7fde683f39e6ba394e2f70a2deeb43db0b 100644 (file)
@@ -3,7 +3,7 @@
 use crate::symbol::{sym, Symbol};
 use crate::parse::unescape_error_reporting::{emit_unescape_error, push_escaped_char};
 
-use errors::{FatalError, Diagnostic, DiagnosticBuilder};
+use errors::{FatalError, DiagnosticBuilder};
 use syntax_pos::{BytePos, Pos, Span, NO_EXPANSION};
 use rustc_lexer::Base;
 use rustc_lexer::unescape;
@@ -39,7 +39,6 @@ pub struct StringReader<'a> {
     pos: BytePos,
     /// Stop reading src at this index.
     end_src_index: usize,
-    fatal_errs: Vec<DiagnosticBuilder<'a>>,
     /// Source text to tokenize.
     src: Lrc<String>,
     override_span: Option<Span>,
@@ -62,7 +61,6 @@ pub fn new(sess: &'a ParseSess,
             pos: source_file.start_pos,
             end_src_index: src.len(),
             src,
-            fatal_errs: Vec::new(),
             override_span,
         }
     }
@@ -89,29 +87,17 @@ fn mk_sp(&self, lo: BytePos, hi: BytePos) -> Span {
         self.override_span.unwrap_or_else(|| Span::new(lo, hi, NO_EXPANSION))
     }
 
-    fn unwrap_or_abort(&mut self, res: Result<Token, ()>) -> Token {
-        match res {
-            Ok(tok) => tok,
-            Err(_) => {
-                self.emit_fatal_errors();
-                FatalError.raise();
-            }
-        }
-    }
-
     /// Returns the next token, including trivia like whitespace or comments.
     ///
     /// `Err(())` means that some errors were encountered, which can be
     /// retrieved using `buffer_fatal_errors`.
-    pub fn try_next_token(&mut self) -> Result<Token, ()> {
-        assert!(self.fatal_errs.is_empty());
-
+    pub fn next_token(&mut self) -> Token {
         let start_src_index = self.src_index(self.pos);
         let text: &str = &self.src[start_src_index..self.end_src_index];
 
         if text.is_empty() {
             let span = self.mk_sp(self.pos, self.pos);
-            return Ok(Token::new(token::Eof, span));
+            return Token::new(token::Eof, span);
         }
 
         {
@@ -125,7 +111,7 @@ pub fn try_next_token(&mut self) -> Result<Token, ()> {
                     let kind = token::Shebang(sym);
 
                     let span = self.mk_sp(start, self.pos);
-                    return Ok(Token::new(kind, span));
+                    return Token::new(kind, span);
                 }
             }
         }
@@ -139,39 +125,10 @@ pub fn try_next_token(&mut self) -> Result<Token, ()> {
 
         // This could use `?`, but that makes code significantly (10-20%) slower.
         // https://github.com/rust-lang/rust/issues/37939
-        let kind = match self.cook_lexer_token(token.kind, start) {
-            Ok(it) => it,
-            Err(err) => return Err(self.fatal_errs.push(err)),
-        };
+        let kind = self.cook_lexer_token(token.kind, start);
 
         let span = self.mk_sp(start, self.pos);
-        Ok(Token::new(kind, span))
-    }
-
-    /// Returns the next token, including trivia like whitespace or comments.
-    ///
-    /// Aborts in case of an error.
-    pub fn next_token(&mut self) -> Token {
-        let res = self.try_next_token();
-        self.unwrap_or_abort(res)
-    }
-
-    fn emit_fatal_errors(&mut self) {
-        for err in &mut self.fatal_errs {
-            err.emit();
-        }
-
-        self.fatal_errs.clear();
-    }
-
-    pub fn buffer_fatal_errors(&mut self) -> Vec<Diagnostic> {
-        let mut buffer = Vec::new();
-
-        for err in self.fatal_errs.drain(..) {
-            err.buffer(&mut buffer);
-        }
-
-        buffer
+        Token::new(kind, span)
     }
 
     /// Report a fatal lexical error with a given span.
@@ -218,8 +175,8 @@ fn cook_lexer_token(
         &self,
         token: rustc_lexer::TokenKind,
         start: BytePos,
-    ) -> Result<TokenKind, DiagnosticBuilder<'a>> {
-        let kind = match token {
+    ) -> TokenKind {
+        match token {
             rustc_lexer::TokenKind::LineComment => {
                 let string = self.str_from(start);
                 // comments with only more "/"s are not doc comments
@@ -396,16 +353,12 @@ fn cook_lexer_token(
                 // this should be inside `rustc_lexer`. However, we should first remove compound
                 // tokens like `<<` from `rustc_lexer`, and then add fancier error recovery to it,
                 // as there will be less overall work to do this way.
-                return match unicode_chars::check_for_substitution(self, start, c, &mut err) {
-                    Some(token) => {
-                        err.emit();
-                        Ok(token)
-                    }
-                    None => Err(err),
-                }
+                let token = unicode_chars::check_for_substitution(self, start, c, &mut err)
+                    .unwrap_or_else(|| token::Unknown(self.symbol_from(start)));
+                err.emit();
+                token
             }
-        };
-        Ok(kind)
+        }
     }
 
     fn cook_lexer_literal(
index 830fbec58ded952c109184007741491d7a17aaa2..37e67a2729e6d36ac904727bb5ea7f6b4724689e 100644 (file)
@@ -217,7 +217,7 @@ fn real_token(&mut self) {
         loop {
             let token = self.string_reader.next_token();
             match token.kind {
-                token::Whitespace | token::Comment | token::Shebang(_) => {
+                token::Whitespace | token::Comment | token::Shebang(_) | token::Unknown(_) => {
                     self.joint_to_prev = NonJoint;
                 }
                 _ => {
index 73adb5c947c0b64ab777780c80a0e75bb1877df8..be800b4de66aff2153ec99c7fb06ef92473ceaf2 100644 (file)
@@ -255,6 +255,8 @@ pub enum TokenKind {
     /// A comment.
     Comment,
     Shebang(ast::Name),
+    /// A completely invalid token which should be skipped.
+    Unknown(ast::Name),
 
     Eof,
 }
@@ -603,7 +605,7 @@ pub fn is_reserved_ident(&self) -> bool {
             DotDotEq | Comma | Semi | ModSep | RArrow | LArrow | FatArrow | Pound | Dollar |
             Question | OpenDelim(..) | CloseDelim(..) |
             Literal(..) | Ident(..) | Lifetime(..) | Interpolated(..) | DocComment(..) |
-            Whitespace | Comment | Shebang(..) | Eof => return None,
+            Whitespace | Comment | Shebang(..) | Unknown(..) | Eof => return None,
         };
 
         Some(Token::new(kind, self.span.to(joint.span)))
index 2ef8a919b9c56e54408b7f0d917d659c289de1a6..bda761244d5ca09d4cac7ed844852a4f8162eaff 100644 (file)
@@ -15,7 +15,7 @@
 
 use rustc_target::spec::abi::{self, Abi};
 use syntax_pos::{self, BytePos};
-use syntax_pos::{DUMMY_SP, FileName, Span};
+use syntax_pos::{FileName, Span};
 
 use std::borrow::Cow;
 
@@ -124,8 +124,7 @@ pub fn print_crate<'a>(cm: &'a SourceMap,
 
         // #![feature(prelude_import)]
         let pi_nested = attr::mk_nested_word_item(ast::Ident::with_empty_ctxt(sym::prelude_import));
-        let list = attr::mk_list_item(
-            DUMMY_SP, ast::Ident::with_empty_ctxt(sym::feature), vec![pi_nested]);
+        let list = attr::mk_list_item(ast::Ident::with_empty_ctxt(sym::feature), vec![pi_nested]);
         let fake_attr = attr::mk_attr_inner(list);
         s.print_attribute(&fake_attr);
 
@@ -288,6 +287,7 @@ fn token_kind_to_string_ext(tok: &TokenKind, convert_dollar_crate: Option<Span>)
         token::Whitespace           => " ".to_string(),
         token::Comment              => "/* */".to_string(),
         token::Shebang(s)           => format!("/* shebang: {}*/", s),
+        token::Unknown(s)           => s.to_string(),
 
         token::Interpolated(ref nt) => nonterminal_to_string(nt),
     }
index 4b3903c7ad7d37a851430707c0e33ad029b028bd..eec8a3f802343f9a286a5ae65148218e86603f1b 100644 (file)
@@ -157,8 +157,7 @@ impl MutVisitor for EntryPointCleaner {
                 item.map(|ast::Item {id, ident, attrs, node, vis, span, tokens}| {
                     let allow_ident = Ident::with_empty_ctxt(sym::allow);
                     let dc_nested = attr::mk_nested_word_item(Ident::from_str("dead_code"));
-                    let allow_dead_code_item = attr::mk_list_item(DUMMY_SP, allow_ident,
-                                                                  vec![dc_nested]);
+                    let allow_dead_code_item = attr::mk_list_item(allow_ident, vec![dc_nested]);
                     let allow_dead_code = attr::mk_attr_outer(allow_dead_code_item);
 
                     ast::Item {
index b4ed747b44c817615aac7f67b384f5c8458603be..3bebbecb9dfcf5ad196f5a19657d24c8260fb637 100644 (file)
@@ -1,3 +1,21 @@
+error: unknown start of token: \
+ --> <doctest>:1:1
+  |
+1 | \__________pkt->size___________/          \_result->size_/ \__pkt->size__/
+  | ^
+
+error: unknown start of token: \
+ --> <doctest>:1:43
+  |
+1 | \__________pkt->size___________/          \_result->size_/ \__pkt->size__/
+  |                                           ^
+
+error: unknown start of token: \
+ --> <doctest>:1:60
+  |
+1 | \__________pkt->size___________/          \_result->size_/ \__pkt->size__/
+  |                                                            ^
+
 warning: could not parse code block as Rust code
   --> $DIR/invalid-syntax.rs:3:5
    |
@@ -6,13 +24,31 @@ LL |   /// ```
 LL | | /// \__________pkt->size___________/          \_result->size_/ \__pkt->size__/
 LL | | /// ```
    | |_______^
-   |
-   = note: error from rustc: unknown start of token: \
 help: mark blocks that do not contain Rust code as text
    |
 LL | /// ```text
    |     ^^^^^^^
 
+error: unknown start of token: `
+ --> <doctest>:3:30
+  |
+3 |    |     ^^^^^^ did you mean `baz::foobar`?
+  |                              ^
+help: Unicode character '`' (Grave Accent) looks like ''' (Single Quote), but it is not
+  |
+3 |    |     ^^^^^^ did you mean 'baz::foobar`?
+  |                              ^
+
+error: unknown start of token: `
+ --> <doctest>:3:42
+  |
+3 |    |     ^^^^^^ did you mean `baz::foobar`?
+  |                                          ^
+help: Unicode character '`' (Grave Accent) looks like ''' (Single Quote), but it is not
+  |
+3 |    |     ^^^^^^ did you mean `baz::foobar'?
+  |                                          ^
+
 warning: could not parse code block as Rust code
   --> $DIR/invalid-syntax.rs:8:5
    |
@@ -23,13 +59,17 @@ LL | | /// LL | use foobar::Baz;
 LL | | ///    |     ^^^^^^ did you mean `baz::foobar`?
 LL | | /// ```
    | |_______^
-   |
-   = note: error from rustc: unknown start of token: `
 help: mark blocks that do not contain Rust code as text
    |
 LL | /// ```text
    |     ^^^^^^^
 
+error: unknown start of token: \
+ --> <doctest>:1:1
+  |
+1 | \_
+  | ^
+
 warning: could not parse code block as Rust code
   --> $DIR/invalid-syntax.rs:19:5
    |
@@ -38,13 +78,17 @@ LL |   /// ```
 LL | | /// \_
 LL | | /// ```
    | |_______^
-   |
-   = note: error from rustc: unknown start of token: \
 help: mark blocks that do not contain Rust code as text
    |
 LL | /// ```text
    |     ^^^^^^^
 
+error: unknown start of token: \
+ --> <doctest>:1:1
+  |
+1 | \_
+  | ^
+
 warning: could not parse code block as Rust code
   --> $DIR/invalid-syntax.rs:32:5
    |
@@ -53,8 +97,12 @@ LL |   /// ```rust
 LL | | /// \_
 LL | | /// ```
    | |_______^
-   |
-   = note: error from rustc: unknown start of token: \
+
+error: unknown start of token: \
+ --> <doctest>:2:5
+  |
+2 |     \_
+  |     ^
 
 warning: could not parse code block as Rust code
   --> $DIR/invalid-syntax.rs:41:9
@@ -63,16 +111,48 @@ LL |   ///     code with bad syntax
    |  _________^
 LL | | ///     \_
    | |__________^
-   |
-   = note: error from rustc: unknown start of token: \
+
+error: unknown start of token: `
+ --> <doctest>:1:1
+  |
+1 | ```
+  | ^
+help: Unicode character '`' (Grave Accent) looks like ''' (Single Quote), but it is not
+  |
+1 | '``
+  | ^
+
+error: unknown start of token: `
+ --> <doctest>:1:2
+  |
+1 | ```
+  |  ^
+help: Unicode character '`' (Grave Accent) looks like ''' (Single Quote), but it is not
+  |
+1 | `'`
+  |  ^
+
+error: unknown start of token: `
+ --> <doctest>:1:3
+  |
+1 | ```
+  |   ^
+help: Unicode character '`' (Grave Accent) looks like ''' (Single Quote), but it is not
+  |
+1 | ``'
+  |   ^
 
 warning: could not parse code block as Rust code
   --> $DIR/invalid-syntax.rs:55:9
    |
 LL | ///     ```
    |         ^^^
-   |
-   = note: error from rustc: unknown start of token: `
+
+error: unknown start of token: \
+ --> <doctest>:1:1
+  |
+1 | \_
+  | ^
 
 warning: could not parse code block as Rust code
   --> $DIR/invalid-syntax.rs:58:5
@@ -82,8 +162,12 @@ LL |   /// ```edition2018
 LL | | /// \_
 LL | | /// ```
    | |_______^
-   |
-   = note: error from rustc: unknown start of token: \
+
+error: unknown start of token: \
+ --> <doctest>:1:1
+  |
+1 | \_
+  | ^
 
 warning: doc comment contains an invalid Rust code block
   --> $DIR/invalid-syntax.rs:63:1
@@ -95,3 +179,59 @@ LL | | #[doc = "```"]
    |
    = help: mark blocks that do not contain Rust code as text: ```text
 
+error: unknown start of token: \
+ --> <rustdoc-highlighting>:1:1
+  |
+1 | \_
+  | ^
+
+error: unknown start of token: \
+ --> <rustdoc-highlighting>:1:1
+  |
+1 | \_
+  | ^
+
+error: unknown start of token: `
+ --> <rustdoc-highlighting>:1:1
+  |
+1 | ```
+  | ^
+help: Unicode character '`' (Grave Accent) looks like ''' (Single Quote), but it is not
+  |
+1 | '``
+  | ^
+
+error: unknown start of token: \
+ --> <rustdoc-highlighting>:2:1
+  |
+2 | \_
+  | ^
+
+error: unknown start of token: \
+ --> <rustdoc-highlighting>:1:1
+  |
+1 | \_
+  | ^
+
+error: unknown start of token: \
+ --> <rustdoc-highlighting>:1:1
+  |
+1 | \_
+  | ^
+
+error: unknown start of token: `
+ --> <rustdoc-highlighting>:3:30
+  |
+3 |    |     ^^^^^^ did you mean `baz::foobar`?
+  |                              ^
+help: Unicode character '`' (Grave Accent) looks like ''' (Single Quote), but it is not
+  |
+3 |    |     ^^^^^^ did you mean 'baz::foobar`?
+  |                              ^
+
+error: unknown start of token: \
+ --> <rustdoc-highlighting>:1:1
+  |
+1 | \__________pkt->size___________/          \_result->size_/ \__pkt->size__/
+  | ^
+
diff --git a/src/test/ui/async-await/partial-initialization-across-await.rs b/src/test/ui/async-await/partial-initialization-across-await.rs
new file mode 100644 (file)
index 0000000..40f9f52
--- /dev/null
@@ -0,0 +1,44 @@
+// Test that we don't allow awaiting from an async fn while a local is partially
+// initialized.
+
+// edition:2018
+
+#![feature(async_await)]
+
+struct S { x: i32, y: i32 }
+struct T(i32, i32);
+
+async fn noop() {}
+
+async fn test_tuple() {
+    let mut t: (i32, i32);
+    t.0 = 42;
+    //~^ ERROR assign to part of possibly uninitialized variable: `t` [E0381]
+    noop().await;
+    t.1 = 88;
+    let _ = t;
+}
+
+async fn test_tuple_struct() {
+    let mut t: T;
+    t.0 = 42;
+    //~^ ERROR assign to part of possibly uninitialized variable: `t` [E0381]
+    noop().await;
+    t.1 = 88;
+    let _ = t;
+}
+
+async fn test_struct() {
+    let mut t: S;
+    t.x = 42;
+    //~^ ERROR assign to part of possibly uninitialized variable: `t` [E0381]
+    noop().await;
+    t.y = 88;
+    let _ = t;
+}
+
+fn main() {
+    let _ = test_tuple();
+    let _ = test_tuple_struct();
+    let _ = test_struct();
+}
diff --git a/src/test/ui/async-await/partial-initialization-across-await.stderr b/src/test/ui/async-await/partial-initialization-across-await.stderr
new file mode 100644 (file)
index 0000000..fe79eb0
--- /dev/null
@@ -0,0 +1,21 @@
+error[E0381]: assign to part of possibly uninitialized variable: `t`
+  --> $DIR/partial-initialization-across-await.rs:15:5
+   |
+LL |     t.0 = 42;
+   |     ^^^^^^^^ use of possibly uninitialized `t`
+
+error[E0381]: assign to part of possibly uninitialized variable: `t`
+  --> $DIR/partial-initialization-across-await.rs:24:5
+   |
+LL |     t.0 = 42;
+   |     ^^^^^^^^ use of possibly uninitialized `t`
+
+error[E0381]: assign to part of possibly uninitialized variable: `t`
+  --> $DIR/partial-initialization-across-await.rs:33:5
+   |
+LL |     t.x = 42;
+   |     ^^^^^^^^ use of possibly uninitialized `t`
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0381`.
diff --git a/src/test/ui/borrowck/disallow-possibly-uninitialized.rs b/src/test/ui/borrowck/disallow-possibly-uninitialized.rs
new file mode 100644 (file)
index 0000000..a987c00
--- /dev/null
@@ -0,0 +1,22 @@
+// Test that we don't allow partial initialization.
+// This may be relaxed in the future (see #54987).
+
+fn main() {
+    let mut t: (u64, u64);
+    t.0 = 1;
+    //~^ ERROR assign to part of possibly uninitialized variable: `t` [E0381]
+    t.1 = 1;
+
+    let mut t: (u64, u64);
+    t.1 = 1;
+    //~^ ERROR assign to part of possibly uninitialized variable: `t` [E0381]
+    t.0 = 1;
+
+    let mut t: (u64, u64);
+    t.0 = 1;
+    //~^ ERROR assign to part of possibly uninitialized variable: `t` [E0381]
+
+    let mut t: (u64,);
+    t.0 = 1;
+    //~^ ERROR assign to part of possibly uninitialized variable: `t` [E0381]
+}
diff --git a/src/test/ui/borrowck/disallow-possibly-uninitialized.stderr b/src/test/ui/borrowck/disallow-possibly-uninitialized.stderr
new file mode 100644 (file)
index 0000000..a32b17b
--- /dev/null
@@ -0,0 +1,27 @@
+error[E0381]: assign to part of possibly uninitialized variable: `t`
+  --> $DIR/disallow-possibly-uninitialized.rs:6:5
+   |
+LL |     t.0 = 1;
+   |     ^^^^^^^ use of possibly uninitialized `t`
+
+error[E0381]: assign to part of possibly uninitialized variable: `t`
+  --> $DIR/disallow-possibly-uninitialized.rs:11:5
+   |
+LL |     t.1 = 1;
+   |     ^^^^^^^ use of possibly uninitialized `t`
+
+error[E0381]: assign to part of possibly uninitialized variable: `t`
+  --> $DIR/disallow-possibly-uninitialized.rs:16:5
+   |
+LL |     t.0 = 1;
+   |     ^^^^^^^ use of possibly uninitialized `t`
+
+error[E0381]: assign to part of possibly uninitialized variable: `t`
+  --> $DIR/disallow-possibly-uninitialized.rs:20:5
+   |
+LL |     t.0 = 1;
+   |     ^^^^^^^ use of possibly uninitialized `t`
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0381`.
index dea948ff8abbb2f3d48439f34e8e8ae342b543ca..6c3484c2d8c4df3ca0ac3d9deee704c982ea70dc 100644 (file)
@@ -5,6 +5,8 @@ LL | impl<T> Foo for T where T: Remote {}
    | --------------------------------- first implementation here
 LL | impl Foo for i16 {}
    | ^^^^^^^^^^^^^^^^ conflicting implementation for `i16`
+   |
+   = note: upstream crates may add new impl of trait `coherence_lib::Remote` for type `i16` in future versions
 
 error: aborting due to previous error
 
index dea948ff8abbb2f3d48439f34e8e8ae342b543ca..6c3484c2d8c4df3ca0ac3d9deee704c982ea70dc 100644 (file)
@@ -5,6 +5,8 @@ LL | impl<T> Foo for T where T: Remote {}
    | --------------------------------- first implementation here
 LL | impl Foo for i16 {}
    | ^^^^^^^^^^^^^^^^ conflicting implementation for `i16`
+   |
+   = note: upstream crates may add new impl of trait `coherence_lib::Remote` for type `i16` in future versions
 
 error: aborting due to previous error
 
index 0ec4f0bb8e74dbb66a598cf1d4a99ca72f671069..12c7a1f977c3fefdd878d8b73309af7ee6b1077a 100644 (file)
@@ -6,6 +6,8 @@ LL | impl<T: lib::MyCopy> MyTrait for T { }
 ...
 LL | impl MyTrait for lib::MyFundamentalStruct<(MyType,)> { }
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `lib::MyFundamentalStruct<(MyType,)>`
+   |
+   = note: upstream crates may add new impl of trait `lib::MyCopy` for type `lib::MyFundamentalStruct<(MyType,)>` in future versions
 
 error: aborting due to previous error
 
index 0ec4f0bb8e74dbb66a598cf1d4a99ca72f671069..12c7a1f977c3fefdd878d8b73309af7ee6b1077a 100644 (file)
@@ -6,6 +6,8 @@ LL | impl<T: lib::MyCopy> MyTrait for T { }
 ...
 LL | impl MyTrait for lib::MyFundamentalStruct<(MyType,)> { }
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `lib::MyFundamentalStruct<(MyType,)>`
+   |
+   = note: upstream crates may add new impl of trait `lib::MyCopy` for type `lib::MyFundamentalStruct<(MyType,)>` in future versions
 
 error: aborting due to previous error
 
index e5862fdda7c58ffb08bdd15d35c9c413cc923599..1b6c62e9bf3a802b7c21b36102200be6eec0d172 100644 (file)
@@ -6,6 +6,8 @@ LL | impl<T: lib::MyCopy> MyTrait for T { }
 ...
 LL | impl MyTrait for lib::MyStruct<MyType> { }
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `lib::MyStruct<MyType>`
+   |
+   = note: upstream crates may add new impl of trait `lib::MyCopy` for type `lib::MyStruct<MyType>` in future versions
 
 error: aborting due to previous error
 
index e5862fdda7c58ffb08bdd15d35c9c413cc923599..1b6c62e9bf3a802b7c21b36102200be6eec0d172 100644 (file)
@@ -6,6 +6,8 @@ LL | impl<T: lib::MyCopy> MyTrait for T { }
 ...
 LL | impl MyTrait for lib::MyStruct<MyType> { }
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `lib::MyStruct<MyType>`
+   |
+   = note: upstream crates may add new impl of trait `lib::MyCopy` for type `lib::MyStruct<MyType>` in future versions
 
 error: aborting due to previous error
 
index a3c4ef8e105a2cfd62a4e3e89028c5ff64491d96..11bd788c761530cdedc7182762d1d4414e167a1e 100644 (file)
@@ -6,6 +6,8 @@ LL | impl<T: lib::MyCopy> MyTrait for T { }
 ...
 LL | impl MyTrait for (MyType,) { }
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(MyType,)`
+   |
+   = note: upstream crates may add new impl of trait `lib::MyCopy` for type `(MyType,)` in future versions
 
 error: aborting due to previous error
 
index a3c4ef8e105a2cfd62a4e3e89028c5ff64491d96..11bd788c761530cdedc7182762d1d4414e167a1e 100644 (file)
@@ -6,6 +6,8 @@ LL | impl<T: lib::MyCopy> MyTrait for T { }
 ...
 LL | impl MyTrait for (MyType,) { }
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(MyType,)`
+   |
+   = note: upstream crates may add new impl of trait `lib::MyCopy` for type `(MyType,)` in future versions
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/consts/const_let_refutable.nll.stderr b/src/test/ui/consts/const_let_refutable.nll.stderr
deleted file mode 100644 (file)
index a61c9b0..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-error[E0005]: refutable pattern in function argument: `&[]` not covered
-  --> $DIR/const_let_refutable.rs:3:16
-   |
-LL | const fn slice([a, b]: &[i32]) -> i32 {
-   |                ^^^^^^ pattern `&[]` not covered
-
-error[E0723]: can only call other `const fn` within a `const fn`, but `const <&i32 as std::ops::Add>::add` is not stable as `const fn`
-  --> $DIR/const_let_refutable.rs:4:5
-   |
-LL |     a + b
-   |     ^^^^^
-   |
-   = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563
-   = help: add `#![feature(const_fn)]` to the crate attributes to enable
-
-error[E0381]: use of possibly uninitialized variable: `a`
-  --> $DIR/const_let_refutable.rs:4:5
-   |
-LL |     a + b
-   |     ^ use of possibly uninitialized `a`
-
-error[E0381]: use of possibly uninitialized variable: `b`
-  --> $DIR/const_let_refutable.rs:4:9
-   |
-LL |     a + b
-   |         ^ use of possibly uninitialized `b`
-
-error: aborting due to 4 previous errors
-
-Some errors have detailed explanations: E0005, E0381, E0723.
-For more information about an error, try `rustc --explain E0005`.
index 322048c7fbf3f124aa1b77ad583e7d09992cfa07..7b3a591223025b85538db8d8f7e44d4646749370 100644 (file)
@@ -2,10 +2,6 @@ fn main() {}
 
 const fn slice([a, b]: &[i32]) -> i32 { //~ ERROR refutable pattern in function argument
     a + b //~ ERROR can only call other `const fn` within a `const fn`
-    //~^ WARN use of possibly uninitialized variable: `a`
-    //~| WARN this error has been downgraded to a warning for backwards compatibility
-    //~| WARN this represents potential undefined behavior in your code and this warning will
-    //~| WARN use of possibly uninitialized variable: `b`
-    //~| WARN this error has been downgraded to a warning for backwards compatibility
-    //~| WARN this represents potential undefined behavior in your code and this warning will
+    //~^ ERROR use of possibly uninitialized variable: `a`
+    //~| ERROR use of possibly uninitialized variable: `b`
 }
index a848b20ed98f5876d1761fdbfa1c1e2449f63756..a61c9b0c9fef9995daa1542852cf39603ac42417 100644 (file)
@@ -13,27 +13,19 @@ LL |     a + b
    = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563
    = help: add `#![feature(const_fn)]` to the crate attributes to enable
 
-warning[E0381]: use of possibly uninitialized variable: `a`
+error[E0381]: use of possibly uninitialized variable: `a`
   --> $DIR/const_let_refutable.rs:4:5
    |
 LL |     a + b
    |     ^ use of possibly uninitialized `a`
-   |
-   = warning: this error has been downgraded to a warning for backwards compatibility with previous releases
-   = warning: this represents potential undefined behavior in your code and this warning will become a hard error in the future
-   = note: for more information, try `rustc --explain E0729`
 
-warning[E0381]: use of possibly uninitialized variable: `b`
+error[E0381]: use of possibly uninitialized variable: `b`
   --> $DIR/const_let_refutable.rs:4:9
    |
 LL |     a + b
    |         ^ use of possibly uninitialized `b`
-   |
-   = warning: this error has been downgraded to a warning for backwards compatibility with previous releases
-   = warning: this represents potential undefined behavior in your code and this warning will become a hard error in the future
-   = note: for more information, try `rustc --explain E0729`
 
-error: aborting due to 2 previous errors
+error: aborting due to 4 previous errors
 
 Some errors have detailed explanations: E0005, E0381, E0723.
 For more information about an error, try `rustc --explain E0005`.
diff --git a/src/test/ui/consts/self_normalization.rs b/src/test/ui/consts/self_normalization.rs
new file mode 100644 (file)
index 0000000..b2a34f5
--- /dev/null
@@ -0,0 +1,16 @@
+// check-pass
+
+fn testfn(_arr: &mut [(); 0]) {}
+
+trait TestTrait {
+    fn method();
+}
+
+impl TestTrait for [(); 0] {
+    fn method() {
+        let mut arr: Self = [(); 0];
+        testfn(&mut arr);
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/consts/self_normalization2.rs b/src/test/ui/consts/self_normalization2.rs
new file mode 100644 (file)
index 0000000..4fca38c
--- /dev/null
@@ -0,0 +1,21 @@
+// check-pass
+
+trait Gen<T> {
+    fn gen(x: Self) -> T;
+}
+
+struct A;
+
+impl Gen<[(); 0]> for A {
+    fn gen(x: Self) -> [(); 0] {
+        []
+    }
+}
+
+fn array() -> impl Gen<[(); 0]> {
+    A
+}
+
+fn main() {
+    let [] = Gen::gen(array());
+}
diff --git a/src/test/ui/empty/empty-never-array.nll.stderr b/src/test/ui/empty/empty-never-array.nll.stderr
deleted file mode 100644 (file)
index 01ee1c3..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-error[E0005]: refutable pattern in local binding: `T(_, _)` not covered
-  --> $DIR/empty-never-array.rs:10:9
-   |
-LL | / enum Helper<T, U> {
-LL | |     T(T, [!; 0]),
-LL | |     #[allow(dead_code)]
-LL | |     U(U),
-LL | | }
-   | |_- `Helper<T, U>` defined here
-...
-LL |       let Helper::U(u) = Helper::T(t, []);
-   |           ^^^^^^^^^^^^ pattern `T(_, _)` not covered
-
-error[E0381]: use of possibly uninitialized variable: `u`
-  --> $DIR/empty-never-array.rs:12:5
-   |
-LL |     u
-   |     ^ use of possibly uninitialized `u`
-
-error: aborting due to 2 previous errors
-
-Some errors have detailed explanations: E0005, E0381.
-For more information about an error, try `rustc --explain E0005`.
index ce781da7d47e17a099e8d36349352f0af0f78979..ffd2545b291e269b561ad8a3f766128cd8659e4a 100644 (file)
@@ -10,9 +10,7 @@ fn transmute<T, U>(t: T) -> U {
     let Helper::U(u) = Helper::T(t, []);
     //~^ ERROR refutable pattern in local binding: `T(_, _)` not covered
     u
-    //~^ WARN use of possibly uninitialized variable: `u`
-    //~| WARN this error has been downgraded to a warning for backwards compatibility
-    //~| WARN this represents potential undefined behavior in your code and this warning will
+    //~^ ERROR use of possibly uninitialized variable: `u`
 }
 
 fn main() {
index 9911dd4683b6664a69b47d9e7b3a85fb6eb96194..01ee1c3a4d7fadbf7ec17219fcf79cff4a67648b 100644 (file)
@@ -11,17 +11,13 @@ LL | | }
 LL |       let Helper::U(u) = Helper::T(t, []);
    |           ^^^^^^^^^^^^ pattern `T(_, _)` not covered
 
-warning[E0381]: use of possibly uninitialized variable: `u`
+error[E0381]: use of possibly uninitialized variable: `u`
   --> $DIR/empty-never-array.rs:12:5
    |
 LL |     u
    |     ^ use of possibly uninitialized `u`
-   |
-   = warning: this error has been downgraded to a warning for backwards compatibility with previous releases
-   = warning: this represents potential undefined behavior in your code and this warning will become a hard error in the future
-   = note: for more information, try `rustc --explain E0729`
 
-error: aborting due to previous error
+error: aborting due to 2 previous errors
 
 Some errors have detailed explanations: E0005, E0381.
 For more information about an error, try `rustc --explain E0005`.
diff --git a/src/test/ui/generator/partial-initialization-across-yield.rs b/src/test/ui/generator/partial-initialization-across-yield.rs
new file mode 100644 (file)
index 0000000..1e45930
--- /dev/null
@@ -0,0 +1,46 @@
+// Test that we don't allow yielding from a generator while a local is partially
+// initialized.
+
+#![feature(generators)]
+
+struct S { x: i32, y: i32 }
+struct T(i32, i32);
+
+fn test_tuple() {
+    let _ = || {
+        let mut t: (i32, i32);
+        t.0 = 42;
+        //~^ ERROR assign to part of possibly uninitialized variable: `t` [E0381]
+        yield;
+        t.1 = 88;
+        let _ = t;
+    };
+}
+
+fn test_tuple_struct() {
+    let _ = || {
+        let mut t: T;
+        t.0 = 42;
+        //~^ ERROR assign to part of possibly uninitialized variable: `t` [E0381]
+        yield;
+        t.1 = 88;
+        let _ = t;
+    };
+}
+
+fn test_struct() {
+    let _ = || {
+        let mut t: S;
+        t.x = 42;
+        //~^ ERROR assign to part of possibly uninitialized variable: `t` [E0381]
+        yield;
+        t.y = 88;
+        let _ = t;
+    };
+}
+
+fn main() {
+    test_tuple();
+    test_tuple_struct();
+    test_struct();
+}
diff --git a/src/test/ui/generator/partial-initialization-across-yield.stderr b/src/test/ui/generator/partial-initialization-across-yield.stderr
new file mode 100644 (file)
index 0000000..8bf0037
--- /dev/null
@@ -0,0 +1,21 @@
+error[E0381]: assign to part of possibly uninitialized variable: `t`
+  --> $DIR/partial-initialization-across-yield.rs:12:9
+   |
+LL |         t.0 = 42;
+   |         ^^^^^^^^ use of possibly uninitialized `t`
+
+error[E0381]: assign to part of possibly uninitialized variable: `t`
+  --> $DIR/partial-initialization-across-yield.rs:23:9
+   |
+LL |         t.0 = 42;
+   |         ^^^^^^^^ use of possibly uninitialized `t`
+
+error[E0381]: assign to part of possibly uninitialized variable: `t`
+  --> $DIR/partial-initialization-across-yield.rs:34:9
+   |
+LL |         t.x = 42;
+   |         ^^^^^^^^ use of possibly uninitialized `t`
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0381`.
diff --git a/src/test/ui/issues/issue-15381.nll.stderr b/src/test/ui/issues/issue-15381.nll.stderr
deleted file mode 100644 (file)
index a849584..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-error[E0005]: refutable pattern in `for` loop binding: `&[]` not covered
-  --> $DIR/issue-15381.rs:4:9
-   |
-LL |     for &[x,y,z] in values.chunks(3).filter(|&xs| xs.len() == 3) {
-   |         ^^^^^^^^ pattern `&[]` not covered
-
-error[E0381]: borrow of possibly uninitialized variable: `y`
-  --> $DIR/issue-15381.rs:6:26
-   |
-LL |         println!("y={}", y);
-   |                          ^ use of possibly uninitialized `y`
-
-error: aborting due to 2 previous errors
-
-Some errors have detailed explanations: E0005, E0381.
-For more information about an error, try `rustc --explain E0005`.
index 3dbd4e717a0dbd2755cb07f4bcdeb9ad16496a94..d21c321b09399a79e9d7f5f365ccc3cb3db92fb4 100644 (file)
@@ -4,8 +4,6 @@ fn main() {
     for &[x,y,z] in values.chunks(3).filter(|&xs| xs.len() == 3) {
         //~^ ERROR refutable pattern in `for` loop binding: `&[]` not covered
         println!("y={}", y);
-        //~^ WARN borrow of possibly uninitialized variable: `y`
-        //~| WARN this error has been downgraded to a warning for backwards compatibility
-        //~| WARN this represents potential undefined behavior in your code and this warning will
+        //~^ ERROR borrow of possibly uninitialized variable: `y`
     }
 }
index 7b11d85ead8749fe86741c4ed9a3577e9c174e0a..a8495846b3610e544fd318ae296de9c89e3e4c8a 100644 (file)
@@ -4,17 +4,13 @@ error[E0005]: refutable pattern in `for` loop binding: `&[]` not covered
 LL |     for &[x,y,z] in values.chunks(3).filter(|&xs| xs.len() == 3) {
    |         ^^^^^^^^ pattern `&[]` not covered
 
-warning[E0381]: borrow of possibly uninitialized variable: `y`
+error[E0381]: borrow of possibly uninitialized variable: `y`
   --> $DIR/issue-15381.rs:6:26
    |
 LL |         println!("y={}", y);
    |                          ^ use of possibly uninitialized `y`
-   |
-   = warning: this error has been downgraded to a warning for backwards compatibility with previous releases
-   = warning: this represents potential undefined behavior in your code and this warning will become a hard error in the future
-   = note: for more information, try `rustc --explain E0729`
 
-error: aborting due to previous error
+error: aborting due to 2 previous errors
 
 Some errors have detailed explanations: E0005, E0381.
 For more information about an error, try `rustc --explain E0005`.
index 777e1fc9c27ea2f5f3cf263466213ad9464ec8ff..99a9bf9903e25702deef4acc6f25d4550ccf61af 100644 (file)
@@ -6,6 +6,8 @@ LL | #[derive(Clone)]
 ...
 LL | impl<T: Clone + ?Sized> Clone for Node<[T]> {
    | ------------------------------------------- first implementation here
+   |
+   = note: upstream crates may add new impl of trait `std::clone::Clone` for type `[_]` in future versions
 
 error: aborting due to previous error
 
index feb670c3d3dd0f6bbdb43fd5213b1ed6593ff3fa..9e4824611128d1d64fdc4234da5716a7758af2e5 100644 (file)
@@ -1 +1,3 @@
 ● //~ ERROR: unknown start of token
+
+fn main() {}
index 90d359231a6e727ff06d5bf0d230f5d2744eaa11..bb27f44c279f7ccf4c903c8f5e82a29e20b937b5 100644 (file)
@@ -1 +1,3 @@
 \ //~ ERROR: unknown start of token: \
+
+fn main() {}
index 69644211b8a11c750ed94a70c46a338f4a62a34a..1812dad81afc34b92c0f1a998d8447e86be5ba9c 100644 (file)
@@ -4,4 +4,7 @@ fn main() {
     println!(“hello world”);
     //~^ ERROR unknown start of token: \u{201c}
     //~^^ HELP Unicode characters '“' (Left Double Quotation Mark) and '”' (Right Double Quotation Mark) look like '"' (Quotation Mark), but are not
+    //~^^^ ERROR unknown start of token: \u{201d}
+    //~^^^^ HELP Unicode character '”' (Right Double Quotation Mark) looks like '"' (Quotation Mark), but it is not
+    //~^^^^^ ERROR expected token: `,`
 }
index 4a09ed75605e41463690662e51f50a1a9d4aa5cc..84e45ecd873a4852564cf35c13800b5e4299492d 100644 (file)
@@ -8,5 +8,21 @@ help: Unicode characters '“' (Left Double Quotation Mark) and '”' (Right Dou
 LL |     println!("hello world");
    |              ^^^^^^^^^^^^^
 
-error: aborting due to previous error
+error: unknown start of token: \u{201d}
+  --> $DIR/unicode-quote-chars.rs:4:26
+   |
+LL |     println!(“hello world”);
+   |                          ^
+help: Unicode character '”' (Right Double Quotation Mark) looks like '"' (Quotation Mark), but it is not
+   |
+LL |     println!(“hello world");
+   |                          ^
+
+error: expected token: `,`
+  --> $DIR/unicode-quote-chars.rs:4:21
+   |
+LL |     println!(“hello world”);
+   |                     ^^^^^ expected `,`
+
+error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/recursion/recursive-types-are-not-uninhabited.nll.stderr b/src/test/ui/recursion/recursive-types-are-not-uninhabited.nll.stderr
deleted file mode 100644 (file)
index eee331d..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-error[E0005]: refutable pattern in local binding: `Err(_)` not covered
-  --> $DIR/recursive-types-are-not-uninhabited.rs:6:9
-   |
-LL |     let Ok(x) = res;
-   |         ^^^^^ pattern `Err(_)` not covered
-
-error[E0381]: use of possibly uninitialized variable: `x`
-  --> $DIR/recursive-types-are-not-uninhabited.rs:8:5
-   |
-LL |     x
-   |     ^ use of possibly uninitialized `x`
-
-error: aborting due to 2 previous errors
-
-Some errors have detailed explanations: E0005, E0381.
-For more information about an error, try `rustc --explain E0005`.
index a618aba9413f025d3585eecb6c0e563ab7dc1966..45910c3c3a8c6dbc945baf39253f1e7328c08c2d 100644 (file)
@@ -6,9 +6,7 @@ fn foo(res: Result<u32, &R>) -> u32 {
     let Ok(x) = res;
     //~^ ERROR refutable pattern
     x
-    //~^ WARN use of possibly uninitialized variable: `x`
-    //~| WARN this error has been downgraded to a warning for backwards compatibility
-    //~| WARN this represents potential undefined behavior in your code and this warning will
+    //~^ ERROR use of possibly uninitialized variable: `x`
 }
 
 fn main() {
index 9203f893fdbf777bd4d2278d3265e4dc04c06517..eee331d95b9bc9c6f31a6241b21c2cd67d9290f2 100644 (file)
@@ -4,17 +4,13 @@ error[E0005]: refutable pattern in local binding: `Err(_)` not covered
 LL |     let Ok(x) = res;
    |         ^^^^^ pattern `Err(_)` not covered
 
-warning[E0381]: use of possibly uninitialized variable: `x`
+error[E0381]: use of possibly uninitialized variable: `x`
   --> $DIR/recursive-types-are-not-uninhabited.rs:8:5
    |
 LL |     x
    |     ^ use of possibly uninitialized `x`
-   |
-   = warning: this error has been downgraded to a warning for backwards compatibility with previous releases
-   = warning: this represents potential undefined behavior in your code and this warning will become a hard error in the future
-   = note: for more information, try `rustc --explain E0729`
 
-error: aborting due to previous error
+error: aborting due to 2 previous errors
 
 Some errors have detailed explanations: E0005, E0381.
 For more information about an error, try `rustc --explain E0005`.
index 583c580d341ba720ac98b2397bc44283f1bfa43d..dcb34f3ad4836518aad8be94b7fd533d51f91a47 100644 (file)
@@ -10,6 +10,8 @@ LL | | }
 LL | 
 LL |   impl IntoPyDictPointer for ()
    |   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `()`
+   |
+   = note: upstream crates may add new impl of trait `std::iter::Iterator` for type `()` in future versions
 
 error: aborting due to previous error