1
Fork 0

Auto merge of #63319 - Centril:rollup-d89rmey, r=Centril

Rollup of 14 pull requests

Successful merges:

 - #61457 (Implement DoubleEndedIterator for iter::{StepBy, Peekable, Take})
 - #63017 (Remove special code-path for handing unknown tokens)
 - #63184 (Explaining the reason why validation is performed in to_str of path.rs)
 - #63230 (Make use of possibly uninitialized data [E0381] a hard error)
 - #63260 (fix UB in a test)
 - #63264 (Revert "Rollup merge of #62696 - chocol4te:fix_#62194, r=estebank")
 - #63272 (Some more libsyntax::attr cleanup)
 - #63285 (Remove leftover AwaitOrigin)
 - #63287 (Don't store &Span)
 - #63293 (Clarify align_to's requirements and obligations)
 - #63295 (improve align_offset docs)
 - #63299 (Make qualify consts in_projection use PlaceRef)
 - #63312 (doc: fix broken sentence)
 - #63315 (Fix #63313)

Failed merges:

r? @ghost
This commit is contained in:
bors 2019-08-06 08:21:32 +00:00
commit 8996328ebf
62 changed files with 808 additions and 330 deletions

View file

@ -485,6 +485,39 @@ impl<I> Iterator for StepBy<I> where I: Iterator {
}
}
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 @@ impl<I: Iterator> Iterator for Peekable<I> {
}
}
#[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 @@ impl<I> Iterator for Take<I> where I: Iterator{
}
}
#[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 {}

View file

@ -1606,10 +1606,12 @@ impl<T: ?Sized> *const T {
/// `align`.
///
/// If it is not possible to align the pointer, the implementation returns
/// `usize::max_value()`.
/// `usize::max_value()`. It is permissible for the implementation to *always*
/// return `usize::max_value()`. Only your algorithm's performance can depend
/// on getting a usable offset here, not its correctness.
///
/// The offset is expressed in number of `T` elements, and not bytes. The value returned can be
/// used with the `add` method.
/// used with the `wrapping_add` method.
///
/// There are no guarantees whatsoever that offsetting the pointer will not overflow or go
/// beyond the allocation that the pointer points into. It is up to the caller to ensure that
@ -2407,10 +2409,12 @@ impl<T: ?Sized> *mut T {
/// `align`.
///
/// If it is not possible to align the pointer, the implementation returns
/// `usize::max_value()`.
/// `usize::max_value()`. It is permissible for the implementation to *always*
/// return `usize::max_value()`. Only your algorithm's performance can depend
/// on getting a usable offset here, not its correctness.
///
/// The offset is expressed in number of `T` elements, and not bytes. The value returned can be
/// used with the `add` method.
/// used with the `wrapping_add` method.
///
/// There are no guarantees whatsoever that offsetting the pointer will not overflow or go
/// beyond the allocation that the pointer points into. It is up to the caller to ensure that

View file

@ -2308,9 +2308,10 @@ impl<T> [T] {
/// maintained.
///
/// This method splits the slice into three distinct slices: prefix, correctly aligned middle
/// slice of a new type, and the suffix slice. The method does a best effort to make the
/// middle slice the greatest length possible for a given type and input slice, but only
/// your algorithm's performance should depend on that, not its correctness.
/// slice of a new type, and the suffix slice. The method may make the middle slice the greatest
/// length possible for a given type and input slice, but only your algorithm's performance
/// should depend on that, not its correctness. It is permissible for all of the input data to
/// be returned as the prefix or suffix slice.
///
/// This method has no purpose when either input element `T` or output element `U` are
/// zero-sized and will return the original slice without splitting anything.
@ -2361,9 +2362,10 @@ impl<T> [T] {
/// maintained.
///
/// This method splits the slice into three distinct slices: prefix, correctly aligned middle
/// slice of a new type, and the suffix slice. The method does a best effort to make the
/// middle slice the greatest length possible for a given type and input slice, but only
/// your algorithm's performance should depend on that, not its correctness.
/// slice of a new type, and the suffix slice. The method may make the middle slice the greatest
/// length possible for a given type and input slice, but only your algorithm's performance
/// should depend on that, not its correctness. It is permissible for all of the input data to
/// be returned as the prefix or suffix slice.
///
/// This method has no purpose when either input element `T` or output element `U` are
/// zero-sized and will return the original slice without splitting anything.

View 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 test_iterator_step_by_nth_overflow() {
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]

View 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 [][..]));

View file

@ -5176,11 +5176,10 @@ impl<'a> LoweringContext<'a> {
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)
};

View file

@ -363,7 +363,8 @@ impl<'a> HashStable<StableHashingContext<'a>> for token::TokenKind {
}
token::DocComment(val) |
token::Shebang(val) => val.hash_stable(hcx, hasher),
token::Shebang(val) |
token::Unknown(val) => val.hash_stable(hcx, hasher),
}
}
}

View file

@ -6,7 +6,7 @@
> As of edition 2018, region inference is done using Non-lexical lifetimes,
> which is described in the guide and [this RFC].
[rustc guide]: https://rust-lang.github.io/rustc-guide/mir/borrowck.html
[rustc guide]: https://rust-lang.github.io/rustc-guide/borrow_check/region_inference.html
[this RFC]: https://github.com/rust-lang/rfcs/blob/master/text/2094-nll.md
## Terminology

View 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 {

View file

@ -105,6 +105,9 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
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) {

View file

@ -253,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(),
@ -364,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.
@ -481,6 +482,9 @@ crate struct MirBorrowckCtxt<'cx, 'tcx> {
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>,
@ -921,6 +925,12 @@ impl InitializationRequiringAction {
}
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

View file

@ -305,7 +305,7 @@ impl_stable_hash_for!(enum crate::interpret::eval_context::StackPopCleanup {
#[derive(Eq, PartialEq)]
struct FrameSnapshot<'a, 'tcx> {
instance: &'a ty::Instance<'tcx>,
span: &'a Span,
span: Span,
return_to_block: &'a StackPopCleanup,
return_place: Option<Place<(), AllocIdSnapshot<'a>>>,
locals: IndexVec<mir::Local, LocalValue<(), AllocIdSnapshot<'a>>>,
@ -345,7 +345,7 @@ impl<'a, 'mir, 'tcx, Ctx> Snapshot<'a, Ctx> for &'a Frame<'mir, 'tcx>
FrameSnapshot {
instance,
span,
span: *span,
return_to_block,
block,
stmt: *stmt,

View file

@ -182,16 +182,17 @@ trait Qualif {
fn in_projection_structurally(
cx: &ConstCx<'_, 'tcx>,
base: &PlaceBase<'tcx>,
proj: &Projection<'tcx>,
place: PlaceRef<'_, 'tcx>,
) -> bool {
let proj = place.projection.as_ref().unwrap();
let base_qualif = Self::in_place(cx, PlaceRef {
base,
base: place.base,
projection: &proj.base,
});
let qualif = base_qualif && Self::mask_for_ty(
cx,
Place::ty_from(&base, &proj.base, cx.body, cx.tcx)
Place::ty_from(place.base, &proj.base, cx.body, cx.tcx)
.projection_ty(cx.tcx, &proj.elem)
.ty,
);
@ -208,10 +209,9 @@ trait Qualif {
fn in_projection(
cx: &ConstCx<'_, 'tcx>,
base: &PlaceBase<'tcx>,
proj: &Projection<'tcx>,
place: PlaceRef<'_, 'tcx>,
) -> bool {
Self::in_projection_structurally(cx, base, proj)
Self::in_projection_structurally(cx, place)
}
fn in_place(cx: &ConstCx<'_, 'tcx>, place: PlaceRef<'_, 'tcx>) -> bool {
@ -234,9 +234,9 @@ trait Qualif {
Self::in_static(cx, static_)
},
PlaceRef {
base,
projection: Some(proj),
} => Self::in_projection(cx, base, proj),
base: _,
projection: Some(_),
} => Self::in_projection(cx, place),
}
}
@ -448,9 +448,10 @@ impl Qualif for IsNotPromotable {
fn in_projection(
cx: &ConstCx<'_, 'tcx>,
base: &PlaceBase<'tcx>,
proj: &Projection<'tcx>,
place: PlaceRef<'_, 'tcx>,
) -> bool {
let proj = place.projection.as_ref().unwrap();
match proj.elem {
ProjectionElem::Deref |
ProjectionElem::Downcast(..) => return true,
@ -461,7 +462,7 @@ impl Qualif for IsNotPromotable {
ProjectionElem::Field(..) => {
if cx.mode == Mode::NonConstFn {
let base_ty = Place::ty_from(base, &proj.base, cx.body, cx.tcx).ty;
let base_ty = Place::ty_from(place.base, &proj.base, cx.body, cx.tcx).ty;
if let Some(def) = base_ty.ty_adt_def() {
// No promotion of union field accesses.
if def.is_union() {
@ -472,7 +473,7 @@ impl Qualif for IsNotPromotable {
}
}
Self::in_projection_structurally(cx, base, proj)
Self::in_projection_structurally(cx, place)
}
fn in_rvalue(cx: &ConstCx<'_, 'tcx>, rvalue: &Rvalue<'tcx>) -> bool {

View file

@ -171,7 +171,7 @@ enum ResolutionError<'a> {
GenericParamsFromOuterFunction(Res),
/// Error E0403: the name is already used for a type or const parameter in this generic
/// parameter list.
NameAlreadyUsedInParameterList(Name, &'a Span),
NameAlreadyUsedInParameterList(Name, Span),
/// Error E0407: method is not a member of trait.
MethodNotMemberOfTrait(Name, &'a str),
/// Error E0437: type is not a member of trait.
@ -297,7 +297,7 @@ fn resolve_struct_error<'sess, 'a>(resolver: &'sess Resolver<'_>,
parameter in this list of generic parameters",
name);
err.span_label(span, "already used");
err.span_label(first_use_span.clone(), format!("first use of `{}`", name));
err.span_label(first_use_span, format!("first use of `{}`", name));
err
}
ResolutionError::MethodNotMemberOfTrait(method, trait_) => {
@ -2853,7 +2853,7 @@ impl<'a> Resolver<'a> {
let span = seen_bindings.get(&ident).unwrap();
let err = ResolutionError::NameAlreadyUsedInParameterList(
ident.name,
span,
*span,
);
resolve_error(self, param.ident.span, err);
}
@ -2875,7 +2875,7 @@ impl<'a> Resolver<'a> {
let span = seen_bindings.get(&ident).unwrap();
let err = ResolutionError::NameAlreadyUsedInParameterList(
ident.name,
span,
*span,
);
resolve_error(self, param.ident.span, err);
}

View 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,

View 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 @@ impl<'a> Classifier<'a> {
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 @@ impl<'a> Classifier<'a> {
return Ok(());
},
token::Whitespace => Class::None,
token::Whitespace | token::Unknown(..) => Class::None,
token::Comment => Class::Comment,
token::DocComment(..) => Class::DocComment,

View file

@ -32,24 +32,20 @@ impl<'a, 'tcx> SyntaxChecker<'a, 'tcx> {
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 @@ impl<'a, 'tcx> SyntaxChecker<'a, 'tcx> {
.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 @@ impl<'a, 'tcx> SyntaxChecker<'a, 'tcx> {
"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");
}

View file

@ -1819,6 +1819,8 @@ impl Path {
/// 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
///

View file

@ -1284,15 +1284,6 @@ pub enum Movability {
Movable,
}
/// Whether an `await` comes from `await!` or `.await` syntax.
/// FIXME: this should be removed when support for legacy `await!` is removed.
/// https://github.com/rust-lang/rust/issues/60610
#[derive(Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, Copy)]
pub enum AwaitOrigin {
FieldLike,
MacroLike,
}
pub type Mac = Spanned<Mac_>;
/// Represents a macro invocation. The `Path` indicates which macro

View file

@ -347,16 +347,17 @@ impl Attribute {
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;

View file

@ -879,13 +879,12 @@ impl<'a> ExtCtxt<'a> {
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,

View file

@ -1272,7 +1272,7 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
];
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 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
}
}
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,

View file

@ -184,7 +184,7 @@ impl FromInternal<(TreeAndJoint, &'_ ParseSess, &'_ mut Vec<Self>)>
}
OpenDelim(..) | CloseDelim(..) => unreachable!(),
Whitespace | Comment | Shebang(..) | Eof => unreachable!(),
Whitespace | Comment | Shebang(..) | Unknown(..) | Eof => unreachable!(),
}
}
}

View file

@ -3,7 +3,7 @@ use crate::parse::token::{self, Token, TokenKind};
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 @@ impl<'a> StringReader<'a> {
pos: source_file.start_pos,
end_src_index: src.len(),
src,
fatal_errs: Vec::new(),
override_span,
}
}
@ -89,29 +87,17 @@ impl<'a> StringReader<'a> {
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 @@ impl<'a> StringReader<'a> {
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 @@ impl<'a> StringReader<'a> {
// 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 @@ impl<'a> StringReader<'a> {
&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 @@ impl<'a> StringReader<'a> {
// 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(

View file

@ -217,7 +217,7 @@ impl<'a> TokenTreesReader<'a> {
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;
}
_ => {

View 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 @@ impl Token {
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)))

View file

@ -15,7 +15,7 @@ use crate::tokenstream::{self, TokenStream, TokenTree};
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),
}

View 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 {

View file

@ -1,4 +1,4 @@
# Compiler Test Documentation
Documentation the compiler testing framework has moved to
Documentation for the compiler testing framework can be found in
[the rustc guide](https://rust-lang.github.io/rustc-guide/tests/intro.html).

View 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__/
| ^

View file

@ -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();
}

View file

@ -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`.

View file

@ -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]
}

View file

@ -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`.

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View file

@ -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`.

View 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`
}

View 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`.

View file

@ -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`.

View 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() {

View 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`.

View file

@ -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();
}

View file

@ -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`.

View file

@ -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`.

View 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`
}
}

View 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`.

View 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

View file

@ -1 +1,3 @@
//~ ERROR: unknown start of token
fn main() {}

View file

@ -1 +1,3 @@
\ //~ ERROR: unknown start of token: \
fn main() {}

View 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: `,`
}

View 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

View file

@ -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`.

View 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() {

View 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`.

View 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