Auto merge of #62902 - Mark-Simulacrum:rollup-mxfk0mm, r=Mark-Simulacrum
Rollup of 14 pull requests Successful merges: - #60951 (more specific errors in src/librustc/mir/interpret/error.rs) - #62523 (Delay bug to resolve HRTB ICE) - #62656 (explain how to search in slice without owned data) - #62791 (Handle more cases of typos misinterpreted as type ascription) - #62804 (rustc_typeck: improve diagnostics for _ const/static declarations) - #62808 (Revert "Disable stack probing for gnux32.") - #62817 (Tweak span for variant not found error) - #62842 (Add tests for issue-58887) - #62851 (move unescape module to rustc_lexer) - #62859 (Place::as_place_ref is now Place::as_ref) - #62869 (add rustc_private as a proper language feature gate) - #62880 (normalize use of backticks in compiler messages for librustc_allocator) - #62885 (Change "OSX" to "macOS") - #62889 (Update stage0.txt) Failed merges: r? @ghost
This commit is contained in:
commit
a7f28678bb
97 changed files with 777 additions and 377 deletions
10
README.md
10
README.md
|
|
@ -200,11 +200,11 @@ fetch snapshots, and an OS that can execute the available snapshot binaries.
|
||||||
|
|
||||||
Snapshot binaries are currently built and tested on several platforms:
|
Snapshot binaries are currently built and tested on several platforms:
|
||||||
|
|
||||||
| Platform / Architecture | x86 | x86_64 |
|
| Platform / Architecture | x86 | x86_64 |
|
||||||
|--------------------------|-----|--------|
|
|----------------------------|-----|--------|
|
||||||
| Windows (7, 8, 10, ...) | ✓ | ✓ |
|
| Windows (7, 8, 10, ...) | ✓ | ✓ |
|
||||||
| Linux (2.6.18 or later) | ✓ | ✓ |
|
| Linux (2.6.18 or later) | ✓ | ✓ |
|
||||||
| OSX (10.7 Lion or later) | ✓ | ✓ |
|
| macOS (10.7 Lion or later) | ✓ | ✓ |
|
||||||
|
|
||||||
You may find that other platforms work, but these are our officially
|
You may find that other platforms work, but these are our officially
|
||||||
supported build environments that are most likely to work.
|
supported build environments that are most likely to work.
|
||||||
|
|
|
||||||
|
|
@ -553,10 +553,12 @@ impl char {
|
||||||
/// 'XID_Start' is a Unicode Derived Property specified in
|
/// 'XID_Start' is a Unicode Derived Property specified in
|
||||||
/// [UAX #31](http://unicode.org/reports/tr31/#NFKC_Modifications),
|
/// [UAX #31](http://unicode.org/reports/tr31/#NFKC_Modifications),
|
||||||
/// mostly similar to `ID_Start` but modified for closure under `NFKx`.
|
/// mostly similar to `ID_Start` but modified for closure under `NFKx`.
|
||||||
#[unstable(feature = "rustc_private",
|
#[cfg_attr(bootstrap,
|
||||||
reason = "mainly needed for compiler internals",
|
unstable(feature = "rustc_private",
|
||||||
issue = "27812")]
|
reason = "mainly needed for compiler internals",
|
||||||
#[inline]
|
issue = "27812"))]
|
||||||
|
#[cfg_attr(not(bootstrap),
|
||||||
|
unstable(feature = "unicode_internals", issue = "0"))]
|
||||||
pub fn is_xid_start(self) -> bool {
|
pub fn is_xid_start(self) -> bool {
|
||||||
derived_property::XID_Start(self)
|
derived_property::XID_Start(self)
|
||||||
}
|
}
|
||||||
|
|
@ -567,9 +569,12 @@ impl char {
|
||||||
/// 'XID_Continue' is a Unicode Derived Property specified in
|
/// 'XID_Continue' is a Unicode Derived Property specified in
|
||||||
/// [UAX #31](http://unicode.org/reports/tr31/#NFKC_Modifications),
|
/// [UAX #31](http://unicode.org/reports/tr31/#NFKC_Modifications),
|
||||||
/// mostly similar to 'ID_Continue' but modified for closure under NFKx.
|
/// mostly similar to 'ID_Continue' but modified for closure under NFKx.
|
||||||
#[unstable(feature = "rustc_private",
|
#[cfg_attr(bootstrap,
|
||||||
reason = "mainly needed for compiler internals",
|
unstable(feature = "rustc_private",
|
||||||
issue = "27812")]
|
reason = "mainly needed for compiler internals",
|
||||||
|
issue = "27812"))]
|
||||||
|
#[cfg_attr(not(bootstrap),
|
||||||
|
unstable(feature = "unicode_internals", issue = "0"))]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn is_xid_continue(self) -> bool {
|
pub fn is_xid_continue(self) -> bool {
|
||||||
derived_property::XID_Continue(self)
|
derived_property::XID_Continue(self)
|
||||||
|
|
|
||||||
|
|
@ -1263,6 +1263,15 @@ impl<T> [T] {
|
||||||
/// assert!(v.contains(&30));
|
/// assert!(v.contains(&30));
|
||||||
/// assert!(!v.contains(&50));
|
/// assert!(!v.contains(&50));
|
||||||
/// ```
|
/// ```
|
||||||
|
///
|
||||||
|
/// If you do not have an `&T`, but just an `&U` such that `T: Borrow<U>`
|
||||||
|
/// (e.g. `String: Borrow<str>`), you can use `iter().any`:
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// let v = [String::from("hello"), String::from("world")]; // slice of `String`
|
||||||
|
/// assert!(v.iter().any(|e| e == "hello")); // search with `&str`
|
||||||
|
/// assert!(!v.iter().any(|e| e == "hi"));
|
||||||
|
/// ```
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
pub fn contains(&self, x: &T) -> bool
|
pub fn contains(&self, x: &T) -> bool
|
||||||
where T: PartialEq
|
where T: PartialEq
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@
|
||||||
|
|
||||||
#![feature(nll)]
|
#![feature(nll)]
|
||||||
#![feature(rustc_private)]
|
#![feature(rustc_private)]
|
||||||
|
#![feature(unicode_internals)]
|
||||||
|
|
||||||
pub use Piece::*;
|
pub use Piece::*;
|
||||||
pub use Position::*;
|
pub use Position::*;
|
||||||
|
|
|
||||||
|
|
@ -764,16 +764,17 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
span_bug!(
|
// Errors in earlier passes can yield error variables without
|
||||||
|
// resolution errors here; delay ICE in favor of those errors.
|
||||||
|
self.tcx().sess.delay_span_bug(
|
||||||
self.var_infos[node_idx].origin.span(),
|
self.var_infos[node_idx].origin.span(),
|
||||||
"collect_error_for_expanding_node() could not find \
|
&format!("collect_error_for_expanding_node() could not find \
|
||||||
error for var {:?} in universe {:?}, lower_bounds={:#?}, \
|
error for var {:?} in universe {:?}, lower_bounds={:#?}, \
|
||||||
upper_bounds={:#?}",
|
upper_bounds={:#?}",
|
||||||
node_idx,
|
node_idx,
|
||||||
node_universe,
|
node_universe,
|
||||||
lower_bounds,
|
lower_bounds,
|
||||||
upper_bounds
|
upper_bounds));
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn collect_concrete_regions(
|
fn collect_concrete_regions(
|
||||||
|
|
|
||||||
|
|
@ -228,6 +228,24 @@ impl<'tcx> From<InterpError<'tcx, u64>> for InterpErrorInfo<'tcx> {
|
||||||
|
|
||||||
pub type AssertMessage<'tcx> = InterpError<'tcx, mir::Operand<'tcx>>;
|
pub type AssertMessage<'tcx> = InterpError<'tcx, mir::Operand<'tcx>>;
|
||||||
|
|
||||||
|
#[derive(Clone, RustcEncodable, RustcDecodable, HashStable)]
|
||||||
|
pub enum PanicMessage<O> {
|
||||||
|
Panic {
|
||||||
|
msg: Symbol,
|
||||||
|
line: u32,
|
||||||
|
col: u32,
|
||||||
|
file: Symbol,
|
||||||
|
},
|
||||||
|
BoundsCheck {
|
||||||
|
len: O,
|
||||||
|
index: O,
|
||||||
|
},
|
||||||
|
Overflow(mir::BinOp),
|
||||||
|
OverflowNeg,
|
||||||
|
DivisionByZero,
|
||||||
|
RemainderByZero,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, RustcEncodable, RustcDecodable, HashStable)]
|
#[derive(Clone, RustcEncodable, RustcDecodable, HashStable)]
|
||||||
pub enum InterpError<'tcx, O> {
|
pub enum InterpError<'tcx, O> {
|
||||||
/// This variant is used by machines to signal their own errors that do not
|
/// This variant is used by machines to signal their own errors that do not
|
||||||
|
|
@ -266,11 +284,6 @@ pub enum InterpError<'tcx, O> {
|
||||||
Unimplemented(String),
|
Unimplemented(String),
|
||||||
DerefFunctionPointer,
|
DerefFunctionPointer,
|
||||||
ExecuteMemory,
|
ExecuteMemory,
|
||||||
BoundsCheck { len: O, index: O },
|
|
||||||
Overflow(mir::BinOp),
|
|
||||||
OverflowNeg,
|
|
||||||
DivisionByZero,
|
|
||||||
RemainderByZero,
|
|
||||||
Intrinsic(String),
|
Intrinsic(String),
|
||||||
InvalidChar(u128),
|
InvalidChar(u128),
|
||||||
StackFrameLimitReached,
|
StackFrameLimitReached,
|
||||||
|
|
@ -298,12 +311,7 @@ pub enum InterpError<'tcx, O> {
|
||||||
HeapAllocZeroBytes,
|
HeapAllocZeroBytes,
|
||||||
HeapAllocNonPowerOfTwoAlignment(u64),
|
HeapAllocNonPowerOfTwoAlignment(u64),
|
||||||
Unreachable,
|
Unreachable,
|
||||||
Panic {
|
Panic(PanicMessage<O>),
|
||||||
msg: Symbol,
|
|
||||||
line: u32,
|
|
||||||
col: u32,
|
|
||||||
file: Symbol,
|
|
||||||
},
|
|
||||||
ReadFromReturnPointer,
|
ReadFromReturnPointer,
|
||||||
PathNotFound(Vec<String>),
|
PathNotFound(Vec<String>),
|
||||||
UnimplementedTraitSelection,
|
UnimplementedTraitSelection,
|
||||||
|
|
@ -369,8 +377,6 @@ impl<'tcx, O> InterpError<'tcx, O> {
|
||||||
"tried to dereference a function pointer",
|
"tried to dereference a function pointer",
|
||||||
ExecuteMemory =>
|
ExecuteMemory =>
|
||||||
"tried to treat a memory pointer as a function pointer",
|
"tried to treat a memory pointer as a function pointer",
|
||||||
BoundsCheck{..} =>
|
|
||||||
"array index out of bounds",
|
|
||||||
Intrinsic(..) =>
|
Intrinsic(..) =>
|
||||||
"intrinsic failed",
|
"intrinsic failed",
|
||||||
NoMirFor(..) =>
|
NoMirFor(..) =>
|
||||||
|
|
@ -422,8 +428,32 @@ impl<'tcx, O> InterpError<'tcx, O> {
|
||||||
two",
|
two",
|
||||||
Unreachable =>
|
Unreachable =>
|
||||||
"entered unreachable code",
|
"entered unreachable code",
|
||||||
Panic { .. } =>
|
Panic(PanicMessage::Panic{..}) =>
|
||||||
"the evaluated program panicked",
|
"the evaluated program panicked",
|
||||||
|
Panic(PanicMessage::BoundsCheck{..}) =>
|
||||||
|
"array index out of bounds",
|
||||||
|
Panic(PanicMessage::Overflow(mir::BinOp::Add)) =>
|
||||||
|
"attempt to add with overflow",
|
||||||
|
Panic(PanicMessage::Overflow(mir::BinOp::Sub)) =>
|
||||||
|
"attempt to subtract with overflow",
|
||||||
|
Panic(PanicMessage::Overflow(mir::BinOp::Mul)) =>
|
||||||
|
"attempt to multiply with overflow",
|
||||||
|
Panic(PanicMessage::Overflow(mir::BinOp::Div)) =>
|
||||||
|
"attempt to divide with overflow",
|
||||||
|
Panic(PanicMessage::Overflow(mir::BinOp::Rem)) =>
|
||||||
|
"attempt to calculate the remainder with overflow",
|
||||||
|
Panic(PanicMessage::OverflowNeg) =>
|
||||||
|
"attempt to negate with overflow",
|
||||||
|
Panic(PanicMessage::Overflow(mir::BinOp::Shr)) =>
|
||||||
|
"attempt to shift right with overflow",
|
||||||
|
Panic(PanicMessage::Overflow(mir::BinOp::Shl)) =>
|
||||||
|
"attempt to shift left with overflow",
|
||||||
|
Panic(PanicMessage::Overflow(op)) =>
|
||||||
|
bug!("{:?} cannot overflow", op),
|
||||||
|
Panic(PanicMessage::DivisionByZero) =>
|
||||||
|
"attempt to divide by zero",
|
||||||
|
Panic(PanicMessage::RemainderByZero) =>
|
||||||
|
"attempt to calculate the remainder with a divisor of zero",
|
||||||
ReadFromReturnPointer =>
|
ReadFromReturnPointer =>
|
||||||
"tried to read from the return pointer",
|
"tried to read from the return pointer",
|
||||||
PathNotFound(_) =>
|
PathNotFound(_) =>
|
||||||
|
|
@ -436,17 +466,6 @@ impl<'tcx, O> InterpError<'tcx, O> {
|
||||||
"encountered overly generic constant",
|
"encountered overly generic constant",
|
||||||
ReferencedConstant =>
|
ReferencedConstant =>
|
||||||
"referenced constant has errors",
|
"referenced constant has errors",
|
||||||
Overflow(mir::BinOp::Add) => "attempt to add with overflow",
|
|
||||||
Overflow(mir::BinOp::Sub) => "attempt to subtract with overflow",
|
|
||||||
Overflow(mir::BinOp::Mul) => "attempt to multiply with overflow",
|
|
||||||
Overflow(mir::BinOp::Div) => "attempt to divide with overflow",
|
|
||||||
Overflow(mir::BinOp::Rem) => "attempt to calculate the remainder with overflow",
|
|
||||||
OverflowNeg => "attempt to negate with overflow",
|
|
||||||
Overflow(mir::BinOp::Shr) => "attempt to shift right with overflow",
|
|
||||||
Overflow(mir::BinOp::Shl) => "attempt to shift left with overflow",
|
|
||||||
Overflow(op) => bug!("{:?} cannot overflow", op),
|
|
||||||
DivisionByZero => "attempt to divide by zero",
|
|
||||||
RemainderByZero => "attempt to calculate the remainder with a divisor of zero",
|
|
||||||
GeneratorResumedAfterReturn => "generator resumed after completion",
|
GeneratorResumedAfterReturn => "generator resumed after completion",
|
||||||
GeneratorResumedAfterPanic => "generator resumed after panicking",
|
GeneratorResumedAfterPanic => "generator resumed after panicking",
|
||||||
InfiniteLoop =>
|
InfiniteLoop =>
|
||||||
|
|
@ -493,8 +512,6 @@ impl<'tcx, O: fmt::Debug> fmt::Debug for InterpError<'tcx, O> {
|
||||||
callee_ty, caller_ty),
|
callee_ty, caller_ty),
|
||||||
FunctionArgCountMismatch =>
|
FunctionArgCountMismatch =>
|
||||||
write!(f, "tried to call a function with incorrect number of arguments"),
|
write!(f, "tried to call a function with incorrect number of arguments"),
|
||||||
BoundsCheck { ref len, ref index } =>
|
|
||||||
write!(f, "index out of bounds: the len is {:?} but the index is {:?}", len, index),
|
|
||||||
ReallocatedWrongMemoryKind(ref old, ref new) =>
|
ReallocatedWrongMemoryKind(ref old, ref new) =>
|
||||||
write!(f, "tried to reallocate memory from {} to {}", old, new),
|
write!(f, "tried to reallocate memory from {} to {}", old, new),
|
||||||
DeallocatedWrongMemoryKind(ref old, ref new) =>
|
DeallocatedWrongMemoryKind(ref old, ref new) =>
|
||||||
|
|
@ -518,8 +535,10 @@ impl<'tcx, O: fmt::Debug> fmt::Debug for InterpError<'tcx, O> {
|
||||||
write!(f, "incorrect alloc info: expected size {} and align {}, \
|
write!(f, "incorrect alloc info: expected size {} and align {}, \
|
||||||
got size {} and align {}",
|
got size {} and align {}",
|
||||||
size.bytes(), align.bytes(), size2.bytes(), align2.bytes()),
|
size.bytes(), align.bytes(), size2.bytes(), align2.bytes()),
|
||||||
Panic { ref msg, line, col, ref file } =>
|
Panic(PanicMessage::Panic { ref msg, line, col, ref file }) =>
|
||||||
write!(f, "the evaluated program panicked at '{}', {}:{}:{}", msg, file, line, col),
|
write!(f, "the evaluated program panicked at '{}', {}:{}:{}", msg, file, line, col),
|
||||||
|
Panic(PanicMessage::BoundsCheck { ref len, ref index }) =>
|
||||||
|
write!(f, "index out of bounds: the len is {:?} but the index is {:?}", len, index),
|
||||||
InvalidDiscriminant(val) =>
|
InvalidDiscriminant(val) =>
|
||||||
write!(f, "encountered invalid enum discriminant {}", val),
|
write!(f, "encountered invalid enum discriminant {}", val),
|
||||||
Exit(code) =>
|
Exit(code) =>
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ mod pointer;
|
||||||
|
|
||||||
pub use self::error::{
|
pub use self::error::{
|
||||||
InterpErrorInfo, InterpResult, InterpError, AssertMessage, ConstEvalErr, struct_error,
|
InterpErrorInfo, InterpResult, InterpError, AssertMessage, ConstEvalErr, struct_error,
|
||||||
FrameInfo, ConstEvalRawResult, ConstEvalResult, ErrorHandled,
|
FrameInfo, ConstEvalRawResult, ConstEvalResult, ErrorHandled, PanicMessage
|
||||||
};
|
};
|
||||||
|
|
||||||
pub use self::value::{Scalar, ScalarMaybeUndef, RawConst, ConstValue};
|
pub use self::value::{Scalar, ScalarMaybeUndef, RawConst, ConstValue};
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ use crate::ty::layout::{self, HasDataLayout, Size};
|
||||||
use rustc_macros::HashStable;
|
use rustc_macros::HashStable;
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
AllocId, InterpResult,
|
AllocId, InterpResult, PanicMessage
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Used by `check_in_alloc` to indicate context of check
|
/// Used by `check_in_alloc` to indicate context of check
|
||||||
|
|
@ -76,13 +76,13 @@ pub trait PointerArithmetic: layout::HasDataLayout {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn offset<'tcx>(&self, val: u64, i: u64) -> InterpResult<'tcx, u64> {
|
fn offset<'tcx>(&self, val: u64, i: u64) -> InterpResult<'tcx, u64> {
|
||||||
let (res, over) = self.overflowing_offset(val, i);
|
let (res, over) = self.overflowing_offset(val, i);
|
||||||
if over { err!(Overflow(mir::BinOp::Add)) } else { Ok(res) }
|
if over { err!(Panic(PanicMessage::Overflow(mir::BinOp::Add))) } else { Ok(res) }
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn signed_offset<'tcx>(&self, val: u64, i: i64) -> InterpResult<'tcx, u64> {
|
fn signed_offset<'tcx>(&self, val: u64, i: i64) -> InterpResult<'tcx, u64> {
|
||||||
let (res, over) = self.overflowing_signed_offset(val, i128::from(i));
|
let (res, over) = self.overflowing_signed_offset(val, i128::from(i));
|
||||||
if over { err!(Overflow(mir::BinOp::Add)) } else { Ok(res) }
|
if over { err!(Panic(PanicMessage::Overflow(mir::BinOp::Add))) } else { Ok(res) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@
|
||||||
use crate::hir::def::{CtorKind, Namespace};
|
use crate::hir::def::{CtorKind, Namespace};
|
||||||
use crate::hir::def_id::DefId;
|
use crate::hir::def_id::DefId;
|
||||||
use crate::hir::{self, InlineAsm as HirInlineAsm};
|
use crate::hir::{self, InlineAsm as HirInlineAsm};
|
||||||
use crate::mir::interpret::{ConstValue, InterpError, Scalar};
|
use crate::mir::interpret::{ConstValue, PanicMessage, InterpError::Panic, Scalar};
|
||||||
use crate::mir::visit::MirVisitable;
|
use crate::mir::visit::MirVisitable;
|
||||||
use crate::rustc_serialize as serialize;
|
use crate::rustc_serialize as serialize;
|
||||||
use crate::ty::adjustment::PointerCast;
|
use crate::ty::adjustment::PointerCast;
|
||||||
|
|
@ -1931,7 +1931,7 @@ impl<'tcx> Place<'tcx> {
|
||||||
iterate_over2(place_base, place_projection, &Projections::Empty, op)
|
iterate_over2(place_base, place_projection, &Projections::Empty, op)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn as_place_ref(&self) -> PlaceRef<'_, 'tcx> {
|
pub fn as_ref(&self) -> PlaceRef<'_, 'tcx> {
|
||||||
PlaceRef {
|
PlaceRef {
|
||||||
base: &self.base,
|
base: &self.base,
|
||||||
projection: &self.projection,
|
projection: &self.projection,
|
||||||
|
|
@ -3152,11 +3152,11 @@ impl<'tcx> TypeFoldable<'tcx> for Terminator<'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Assert { ref cond, expected, ref msg, target, cleanup } => {
|
Assert { ref cond, expected, ref msg, target, cleanup } => {
|
||||||
let msg = if let InterpError::BoundsCheck { ref len, ref index } = *msg {
|
let msg = if let Panic(PanicMessage::BoundsCheck { ref len, ref index }) = *msg {
|
||||||
InterpError::BoundsCheck {
|
Panic(PanicMessage::BoundsCheck {
|
||||||
len: len.fold_with(folder),
|
len: len.fold_with(folder),
|
||||||
index: index.fold_with(folder),
|
index: index.fold_with(folder),
|
||||||
}
|
})
|
||||||
} else {
|
} else {
|
||||||
msg.clone()
|
msg.clone()
|
||||||
};
|
};
|
||||||
|
|
@ -3197,7 +3197,7 @@ impl<'tcx> TypeFoldable<'tcx> for Terminator<'tcx> {
|
||||||
}
|
}
|
||||||
Assert { ref cond, ref msg, .. } => {
|
Assert { ref cond, ref msg, .. } => {
|
||||||
if cond.visit_with(visitor) {
|
if cond.visit_with(visitor) {
|
||||||
if let InterpError::BoundsCheck { ref len, ref index } = *msg {
|
if let Panic(PanicMessage::BoundsCheck { ref len, ref index }) = *msg {
|
||||||
len.visit_with(visitor) || index.visit_with(visitor)
|
len.visit_with(visitor) || index.visit_with(visitor)
|
||||||
} else {
|
} else {
|
||||||
false
|
false
|
||||||
|
|
|
||||||
|
|
@ -515,7 +515,8 @@ macro_rules! make_mir_visitor {
|
||||||
msg: & $($mutability)? AssertMessage<'tcx>,
|
msg: & $($mutability)? AssertMessage<'tcx>,
|
||||||
location: Location) {
|
location: Location) {
|
||||||
use crate::mir::interpret::InterpError::*;
|
use crate::mir::interpret::InterpError::*;
|
||||||
if let BoundsCheck { len, index } = msg {
|
use crate::mir::interpret::PanicMessage::BoundsCheck;
|
||||||
|
if let Panic(BoundsCheck { len, index }) = msg {
|
||||||
self.visit_operand(len, location);
|
self.visit_operand(len, location);
|
||||||
self.visit_operand(index, location);
|
self.visit_operand(index, location);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -79,7 +79,7 @@ impl MutVisitor for ExpandAllocatorDirectives<'_> {
|
||||||
|
|
||||||
if self.found {
|
if self.found {
|
||||||
self.handler
|
self.handler
|
||||||
.span_err(item.span, "cannot define more than one #[global_allocator]");
|
.span_err(item.span, "cannot define more than one `#[global_allocator]`");
|
||||||
return smallvec![item];
|
return smallvec![item];
|
||||||
}
|
}
|
||||||
self.found = true;
|
self.found = true;
|
||||||
|
|
@ -280,7 +280,7 @@ impl AllocFnFactory<'_> {
|
||||||
AllocatorTy::Unit => (self.cx.ty(self.span, TyKind::Tup(Vec::new())), expr),
|
AllocatorTy::Unit => (self.cx.ty(self.span, TyKind::Tup(Vec::new())), expr),
|
||||||
|
|
||||||
AllocatorTy::Layout | AllocatorTy::Usize | AllocatorTy::Ptr => {
|
AllocatorTy::Layout | AllocatorTy::Usize | AllocatorTy::Ptr => {
|
||||||
panic!("can't convert AllocatorTy to an output")
|
panic!("can't convert `AllocatorTy` to an output")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -238,7 +238,7 @@ impl<'mir, 'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> Visitor<'tcx>
|
||||||
context: PlaceContext,
|
context: PlaceContext,
|
||||||
location: Location) {
|
location: Location) {
|
||||||
debug!("visit_place(place={:?}, context={:?})", place, context);
|
debug!("visit_place(place={:?}, context={:?})", place, context);
|
||||||
self.process_place(&place.as_place_ref(), context, location);
|
self.process_place(&place.as_ref(), context, location);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_local(&mut self,
|
fn visit_local(&mut self,
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ use rustc::middle::lang_items;
|
||||||
use rustc::ty::{self, Ty, TypeFoldable, Instance};
|
use rustc::ty::{self, Ty, TypeFoldable, Instance};
|
||||||
use rustc::ty::layout::{self, LayoutOf, HasTyCtxt, FnTypeExt};
|
use rustc::ty::layout::{self, LayoutOf, HasTyCtxt, FnTypeExt};
|
||||||
use rustc::mir::{self, Place, PlaceBase, Static, StaticKind};
|
use rustc::mir::{self, Place, PlaceBase, Static, StaticKind};
|
||||||
use rustc::mir::interpret::InterpError;
|
use rustc::mir::interpret::{InterpError, PanicMessage};
|
||||||
use rustc_target::abi::call::{ArgType, FnType, PassMode, IgnoreMode};
|
use rustc_target::abi::call::{ArgType, FnType, PassMode, IgnoreMode};
|
||||||
use rustc_target::spec::abi::Abi;
|
use rustc_target::spec::abi::Abi;
|
||||||
use crate::base;
|
use crate::base;
|
||||||
|
|
@ -253,7 +253,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||||
|
|
||||||
PassMode::Direct(_) | PassMode::Pair(..) => {
|
PassMode::Direct(_) | PassMode::Pair(..) => {
|
||||||
let op =
|
let op =
|
||||||
self.codegen_consume(&mut bx, &mir::Place::RETURN_PLACE.as_place_ref());
|
self.codegen_consume(&mut bx, &mir::Place::RETURN_PLACE.as_ref());
|
||||||
if let Ref(llval, _, align) = op.val {
|
if let Ref(llval, _, align) = op.val {
|
||||||
bx.load(llval, align)
|
bx.load(llval, align)
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -314,7 +314,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
let place = self.codegen_place(&mut bx, &location.as_place_ref());
|
let place = self.codegen_place(&mut bx, &location.as_ref());
|
||||||
let (args1, args2);
|
let (args1, args2);
|
||||||
let mut args = if let Some(llextra) = place.llextra {
|
let mut args = if let Some(llextra) = place.llextra {
|
||||||
args2 = [place.llval, llextra];
|
args2 = [place.llval, llextra];
|
||||||
|
|
@ -368,7 +368,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||||
// checked operation, just a comparison with the minimum
|
// checked operation, just a comparison with the minimum
|
||||||
// value, so we have to check for the assert message.
|
// value, so we have to check for the assert message.
|
||||||
if !bx.check_overflow() {
|
if !bx.check_overflow() {
|
||||||
if let mir::interpret::InterpError::OverflowNeg = *msg {
|
if let InterpError::Panic(PanicMessage::OverflowNeg) = *msg {
|
||||||
const_cond = Some(expected);
|
const_cond = Some(expected);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -403,7 +403,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||||
|
|
||||||
// Put together the arguments to the panic entry point.
|
// Put together the arguments to the panic entry point.
|
||||||
let (lang_item, args) = match *msg {
|
let (lang_item, args) = match *msg {
|
||||||
InterpError::BoundsCheck { ref len, ref index } => {
|
InterpError::Panic(PanicMessage::BoundsCheck { ref len, ref index }) => {
|
||||||
let len = self.codegen_operand(&mut bx, len).immediate();
|
let len = self.codegen_operand(&mut bx, len).immediate();
|
||||||
let index = self.codegen_operand(&mut bx, index).immediate();
|
let index = self.codegen_operand(&mut bx, index).immediate();
|
||||||
|
|
||||||
|
|
@ -1171,7 +1171,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||||
LocalRef::Place(place) => self.codegen_transmute_into(bx, src, place),
|
LocalRef::Place(place) => self.codegen_transmute_into(bx, src, place),
|
||||||
LocalRef::UnsizedPlace(_) => bug!("transmute must not involve unsized locals"),
|
LocalRef::UnsizedPlace(_) => bug!("transmute must not involve unsized locals"),
|
||||||
LocalRef::Operand(None) => {
|
LocalRef::Operand(None) => {
|
||||||
let dst_layout = bx.layout_of(self.monomorphized_place_ty(&dst.as_place_ref()));
|
let dst_layout = bx.layout_of(self.monomorphized_place_ty(&dst.as_ref()));
|
||||||
assert!(!dst_layout.ty.has_erasable_regions());
|
assert!(!dst_layout.ty.has_erasable_regions());
|
||||||
let place = PlaceRef::alloca(bx, dst_layout, "transmute_temp");
|
let place = PlaceRef::alloca(bx, dst_layout, "transmute_temp");
|
||||||
place.storage_live(bx);
|
place.storage_live(bx);
|
||||||
|
|
@ -1186,7 +1186,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let dst = self.codegen_place(bx, &dst.as_place_ref());
|
let dst = self.codegen_place(bx, &dst.as_ref());
|
||||||
self.codegen_transmute_into(bx, src, dst);
|
self.codegen_transmute_into(bx, src, dst);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -462,7 +462,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||||
match *operand {
|
match *operand {
|
||||||
mir::Operand::Copy(ref place) |
|
mir::Operand::Copy(ref place) |
|
||||||
mir::Operand::Move(ref place) => {
|
mir::Operand::Move(ref place) => {
|
||||||
self.codegen_consume(bx, &place.as_place_ref())
|
self.codegen_consume(bx, &place.as_ref())
|
||||||
}
|
}
|
||||||
|
|
||||||
mir::Operand::Constant(ref constant) => {
|
mir::Operand::Constant(ref constant) => {
|
||||||
|
|
|
||||||
|
|
@ -355,7 +355,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
mir::Rvalue::Ref(_, bk, ref place) => {
|
mir::Rvalue::Ref(_, bk, ref place) => {
|
||||||
let cg_place = self.codegen_place(&mut bx, &place.as_place_ref());
|
let cg_place = self.codegen_place(&mut bx, &place.as_ref());
|
||||||
|
|
||||||
let ty = cg_place.layout.ty;
|
let ty = cg_place.layout.ty;
|
||||||
|
|
||||||
|
|
@ -446,7 +446,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||||
|
|
||||||
mir::Rvalue::Discriminant(ref place) => {
|
mir::Rvalue::Discriminant(ref place) => {
|
||||||
let discr_ty = rvalue.ty(&*self.mir, bx.tcx());
|
let discr_ty = rvalue.ty(&*self.mir, bx.tcx());
|
||||||
let discr = self.codegen_place(&mut bx, &place.as_place_ref())
|
let discr = self.codegen_place(&mut bx, &place.as_ref())
|
||||||
.codegen_get_discr(&mut bx, discr_ty);
|
.codegen_get_discr(&mut bx, discr_ty);
|
||||||
(bx, OperandRef {
|
(bx, OperandRef {
|
||||||
val: OperandValue::Immediate(discr),
|
val: OperandValue::Immediate(discr),
|
||||||
|
|
@ -527,7 +527,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// use common size calculation for non zero-sized types
|
// use common size calculation for non zero-sized types
|
||||||
let cg_value = self.codegen_place(bx, &place.as_place_ref());
|
let cg_value = self.codegen_place(bx, &place.as_ref());
|
||||||
cg_value.len(bx.cx())
|
cg_value.len(bx.cx())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -46,12 +46,12 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let cg_dest = self.codegen_place(&mut bx, &place.as_place_ref());
|
let cg_dest = self.codegen_place(&mut bx, &place.as_ref());
|
||||||
self.codegen_rvalue(bx, cg_dest, rvalue)
|
self.codegen_rvalue(bx, cg_dest, rvalue)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mir::StatementKind::SetDiscriminant{ref place, variant_index} => {
|
mir::StatementKind::SetDiscriminant{ref place, variant_index} => {
|
||||||
self.codegen_place(&mut bx, &place.as_place_ref())
|
self.codegen_place(&mut bx, &place.as_ref())
|
||||||
.codegen_set_discr(&mut bx, variant_index);
|
.codegen_set_discr(&mut bx, variant_index);
|
||||||
bx
|
bx
|
||||||
}
|
}
|
||||||
|
|
@ -73,7 +73,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||||
}
|
}
|
||||||
mir::StatementKind::InlineAsm(ref asm) => {
|
mir::StatementKind::InlineAsm(ref asm) => {
|
||||||
let outputs = asm.outputs.iter().map(|output| {
|
let outputs = asm.outputs.iter().map(|output| {
|
||||||
self.codegen_place(&mut bx, &output.as_place_ref())
|
self.codegen_place(&mut bx, &output.as_ref())
|
||||||
}).collect();
|
}).collect();
|
||||||
|
|
||||||
let input_vals = asm.inputs.iter()
|
let input_vals = asm.inputs.iter()
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
// We want to be able to build this crate with a stable compiler, so feature
|
// We want to be able to build this crate with a stable compiler, so feature
|
||||||
// flags should optional.
|
// flags should be optional.
|
||||||
#![cfg_attr(not(feature = "unicode-xid"), feature(rustc_private))]
|
|
||||||
#![cfg_attr(not(feature = "unicode-xid"), feature(unicode_internals))]
|
#![cfg_attr(not(feature = "unicode-xid"), feature(unicode_internals))]
|
||||||
|
|
||||||
mod cursor;
|
mod cursor;
|
||||||
|
pub mod unescape;
|
||||||
|
|
||||||
use crate::cursor::{Cursor, EOF_CHAR};
|
use crate::cursor::{Cursor, EOF_CHAR};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ use std::str::Chars;
|
||||||
use std::ops::Range;
|
use std::ops::Range;
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq)]
|
#[derive(Debug, PartialEq, Eq)]
|
||||||
pub(crate) enum EscapeError {
|
pub enum EscapeError {
|
||||||
ZeroChars,
|
ZeroChars,
|
||||||
MoreThanOneChar,
|
MoreThanOneChar,
|
||||||
|
|
||||||
|
|
@ -35,7 +35,7 @@ pub(crate) enum EscapeError {
|
||||||
|
|
||||||
/// Takes a contents of a char literal (without quotes), and returns an
|
/// Takes a contents of a char literal (without quotes), and returns an
|
||||||
/// unescaped char or an error
|
/// unescaped char or an error
|
||||||
pub(crate) fn unescape_char(literal_text: &str) -> Result<char, (usize, EscapeError)> {
|
pub fn unescape_char(literal_text: &str) -> Result<char, (usize, EscapeError)> {
|
||||||
let mut chars = literal_text.chars();
|
let mut chars = literal_text.chars();
|
||||||
unescape_char_or_byte(&mut chars, Mode::Char)
|
unescape_char_or_byte(&mut chars, Mode::Char)
|
||||||
.map_err(|err| (literal_text.len() - chars.as_str().len(), err))
|
.map_err(|err| (literal_text.len() - chars.as_str().len(), err))
|
||||||
|
|
@ -43,14 +43,14 @@ pub(crate) fn unescape_char(literal_text: &str) -> Result<char, (usize, EscapeEr
|
||||||
|
|
||||||
/// Takes a contents of a string literal (without quotes) and produces a
|
/// Takes a contents of a string literal (without quotes) and produces a
|
||||||
/// sequence of escaped characters or errors.
|
/// sequence of escaped characters or errors.
|
||||||
pub(crate) fn unescape_str<F>(literal_text: &str, callback: &mut F)
|
pub fn unescape_str<F>(literal_text: &str, callback: &mut F)
|
||||||
where
|
where
|
||||||
F: FnMut(Range<usize>, Result<char, EscapeError>),
|
F: FnMut(Range<usize>, Result<char, EscapeError>),
|
||||||
{
|
{
|
||||||
unescape_str_or_byte_str(literal_text, Mode::Str, callback)
|
unescape_str_or_byte_str(literal_text, Mode::Str, callback)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn unescape_byte(literal_text: &str) -> Result<u8, (usize, EscapeError)> {
|
pub fn unescape_byte(literal_text: &str) -> Result<u8, (usize, EscapeError)> {
|
||||||
let mut chars = literal_text.chars();
|
let mut chars = literal_text.chars();
|
||||||
unescape_char_or_byte(&mut chars, Mode::Byte)
|
unescape_char_or_byte(&mut chars, Mode::Byte)
|
||||||
.map(byte_from_char)
|
.map(byte_from_char)
|
||||||
|
|
@ -59,7 +59,7 @@ pub(crate) fn unescape_byte(literal_text: &str) -> Result<u8, (usize, EscapeErro
|
||||||
|
|
||||||
/// Takes a contents of a string literal (without quotes) and produces a
|
/// Takes a contents of a string literal (without quotes) and produces a
|
||||||
/// sequence of escaped characters or errors.
|
/// sequence of escaped characters or errors.
|
||||||
pub(crate) fn unescape_byte_str<F>(literal_text: &str, callback: &mut F)
|
pub fn unescape_byte_str<F>(literal_text: &str, callback: &mut F)
|
||||||
where
|
where
|
||||||
F: FnMut(Range<usize>, Result<u8, EscapeError>),
|
F: FnMut(Range<usize>, Result<u8, EscapeError>),
|
||||||
{
|
{
|
||||||
|
|
@ -72,7 +72,7 @@ where
|
||||||
/// sequence of characters or errors.
|
/// sequence of characters or errors.
|
||||||
/// NOTE: Raw strings do not perform any explicit character escaping, here we
|
/// NOTE: Raw strings do not perform any explicit character escaping, here we
|
||||||
/// only translate CRLF to LF and produce errors on bare CR.
|
/// only translate CRLF to LF and produce errors on bare CR.
|
||||||
pub(crate) fn unescape_raw_str<F>(literal_text: &str, callback: &mut F)
|
pub fn unescape_raw_str<F>(literal_text: &str, callback: &mut F)
|
||||||
where
|
where
|
||||||
F: FnMut(Range<usize>, Result<char, EscapeError>),
|
F: FnMut(Range<usize>, Result<char, EscapeError>),
|
||||||
{
|
{
|
||||||
|
|
@ -83,7 +83,7 @@ where
|
||||||
/// sequence of characters or errors.
|
/// sequence of characters or errors.
|
||||||
/// NOTE: Raw strings do not perform any explicit character escaping, here we
|
/// NOTE: Raw strings do not perform any explicit character escaping, here we
|
||||||
/// only translate CRLF to LF and produce errors on bare CR.
|
/// only translate CRLF to LF and produce errors on bare CR.
|
||||||
pub(crate) fn unescape_raw_byte_str<F>(literal_text: &str, callback: &mut F)
|
pub fn unescape_raw_byte_str<F>(literal_text: &str, callback: &mut F)
|
||||||
where
|
where
|
||||||
F: FnMut(Range<usize>, Result<u8, EscapeError>),
|
F: FnMut(Range<usize>, Result<u8, EscapeError>),
|
||||||
{
|
{
|
||||||
|
|
@ -93,7 +93,7 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
pub(crate) enum Mode {
|
pub enum Mode {
|
||||||
Char,
|
Char,
|
||||||
Str,
|
Str,
|
||||||
Byte,
|
Byte,
|
||||||
|
|
@ -101,18 +101,18 @@ pub(crate) enum Mode {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Mode {
|
impl Mode {
|
||||||
fn in_single_quotes(self) -> bool {
|
pub fn in_single_quotes(self) -> bool {
|
||||||
match self {
|
match self {
|
||||||
Mode::Char | Mode::Byte => true,
|
Mode::Char | Mode::Byte => true,
|
||||||
Mode::Str | Mode::ByteStr => false,
|
Mode::Str | Mode::ByteStr => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn in_double_quotes(self) -> bool {
|
pub fn in_double_quotes(self) -> bool {
|
||||||
!self.in_single_quotes()
|
!self.in_single_quotes()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn is_bytes(self) -> bool {
|
pub fn is_bytes(self) -> bool {
|
||||||
match self {
|
match self {
|
||||||
Mode::Byte | Mode::ByteStr => true,
|
Mode::Byte | Mode::ByteStr => true,
|
||||||
Mode::Char | Mode::Str => false,
|
Mode::Char | Mode::Str => false,
|
||||||
|
|
@ -139,14 +139,14 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||||
let is_partial_move = move_site_vec.iter().any(|move_site| {
|
let is_partial_move = move_site_vec.iter().any(|move_site| {
|
||||||
let move_out = self.move_data.moves[(*move_site).moi];
|
let move_out = self.move_data.moves[(*move_site).moi];
|
||||||
let moved_place = &self.move_data.move_paths[move_out.path].place;
|
let moved_place = &self.move_data.move_paths[move_out.path].place;
|
||||||
used_place != moved_place.as_place_ref()
|
used_place != moved_place.as_ref()
|
||||||
&& used_place.is_prefix_of(moved_place.as_place_ref())
|
&& used_place.is_prefix_of(moved_place.as_ref())
|
||||||
});
|
});
|
||||||
for move_site in &move_site_vec {
|
for move_site in &move_site_vec {
|
||||||
let move_out = self.move_data.moves[(*move_site).moi];
|
let move_out = self.move_data.moves[(*move_site).moi];
|
||||||
let moved_place = &self.move_data.move_paths[move_out.path].place;
|
let moved_place = &self.move_data.move_paths[move_out.path].place;
|
||||||
|
|
||||||
let move_spans = self.move_spans(moved_place.as_place_ref(), move_out.source);
|
let move_spans = self.move_spans(moved_place.as_ref(), move_out.source);
|
||||||
let move_span = move_spans.args_or_use();
|
let move_span = move_spans.args_or_use();
|
||||||
|
|
||||||
let move_msg = if move_spans.for_closure() {
|
let move_msg = if move_spans.for_closure() {
|
||||||
|
|
@ -223,7 +223,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||||
|
|
||||||
let ty = place.ty(self.body, self.infcx.tcx).ty;
|
let ty = place.ty(self.body, self.infcx.tcx).ty;
|
||||||
let opt_name =
|
let opt_name =
|
||||||
self.describe_place_with_options(place.as_place_ref(), IncludingDowncast(true));
|
self.describe_place_with_options(place.as_ref(), IncludingDowncast(true));
|
||||||
let note_msg = match opt_name {
|
let note_msg = match opt_name {
|
||||||
Some(ref name) => format!("`{}`", name),
|
Some(ref name) => format!("`{}`", name),
|
||||||
None => "value".to_owned(),
|
None => "value".to_owned(),
|
||||||
|
|
@ -275,11 +275,11 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||||
"report_move_out_while_borrowed: location={:?} place={:?} span={:?} borrow={:?}",
|
"report_move_out_while_borrowed: location={:?} place={:?} span={:?} borrow={:?}",
|
||||||
location, place, span, borrow
|
location, place, span, borrow
|
||||||
);
|
);
|
||||||
let value_msg = match self.describe_place(place.as_place_ref()) {
|
let value_msg = match self.describe_place(place.as_ref()) {
|
||||||
Some(name) => format!("`{}`", name),
|
Some(name) => format!("`{}`", name),
|
||||||
None => "value".to_owned(),
|
None => "value".to_owned(),
|
||||||
};
|
};
|
||||||
let borrow_msg = match self.describe_place(borrow.borrowed_place.as_place_ref()) {
|
let borrow_msg = match self.describe_place(borrow.borrowed_place.as_ref()) {
|
||||||
Some(name) => format!("`{}`", name),
|
Some(name) => format!("`{}`", name),
|
||||||
None => "value".to_owned(),
|
None => "value".to_owned(),
|
||||||
};
|
};
|
||||||
|
|
@ -287,12 +287,12 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||||
let borrow_spans = self.retrieve_borrow_spans(borrow);
|
let borrow_spans = self.retrieve_borrow_spans(borrow);
|
||||||
let borrow_span = borrow_spans.args_or_use();
|
let borrow_span = borrow_spans.args_or_use();
|
||||||
|
|
||||||
let move_spans = self.move_spans(place.as_place_ref(), location);
|
let move_spans = self.move_spans(place.as_ref(), location);
|
||||||
let span = move_spans.args_or_use();
|
let span = move_spans.args_or_use();
|
||||||
|
|
||||||
let mut err = self.cannot_move_when_borrowed(
|
let mut err = self.cannot_move_when_borrowed(
|
||||||
span,
|
span,
|
||||||
&self.describe_place(place.as_place_ref()).unwrap_or_else(|| "_".to_owned()),
|
&self.describe_place(place.as_ref()).unwrap_or_else(|| "_".to_owned()),
|
||||||
);
|
);
|
||||||
err.span_label(borrow_span, format!("borrow of {} occurs here", borrow_msg));
|
err.span_label(borrow_span, format!("borrow of {} occurs here", borrow_msg));
|
||||||
err.span_label(span, format!("move out of {} occurs here", value_msg));
|
err.span_label(span, format!("move out of {} occurs here", value_msg));
|
||||||
|
|
@ -326,21 +326,21 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||||
|
|
||||||
// Conflicting borrows are reported separately, so only check for move
|
// Conflicting borrows are reported separately, so only check for move
|
||||||
// captures.
|
// captures.
|
||||||
let use_spans = self.move_spans(place.as_place_ref(), location);
|
let use_spans = self.move_spans(place.as_ref(), location);
|
||||||
let span = use_spans.var_or_use();
|
let span = use_spans.var_or_use();
|
||||||
|
|
||||||
let mut err = self.cannot_use_when_mutably_borrowed(
|
let mut err = self.cannot_use_when_mutably_borrowed(
|
||||||
span,
|
span,
|
||||||
&self.describe_place(place.as_place_ref()).unwrap_or_else(|| "_".to_owned()),
|
&self.describe_place(place.as_ref()).unwrap_or_else(|| "_".to_owned()),
|
||||||
borrow_span,
|
borrow_span,
|
||||||
&self.describe_place(borrow.borrowed_place.as_place_ref())
|
&self.describe_place(borrow.borrowed_place.as_ref())
|
||||||
.unwrap_or_else(|| "_".to_owned()),
|
.unwrap_or_else(|| "_".to_owned()),
|
||||||
);
|
);
|
||||||
|
|
||||||
borrow_spans.var_span_label(&mut err, {
|
borrow_spans.var_span_label(&mut err, {
|
||||||
let place = &borrow.borrowed_place;
|
let place = &borrow.borrowed_place;
|
||||||
let desc_place =
|
let desc_place =
|
||||||
self.describe_place(place.as_place_ref()).unwrap_or_else(|| "_".to_owned());
|
self.describe_place(place.as_ref()).unwrap_or_else(|| "_".to_owned());
|
||||||
|
|
||||||
format!("borrow occurs due to use of `{}`{}", desc_place, borrow_spans.describe())
|
format!("borrow occurs due to use of `{}`{}", desc_place, borrow_spans.describe())
|
||||||
});
|
});
|
||||||
|
|
@ -517,7 +517,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
let borrow_place = &issued_borrow.borrowed_place;
|
let borrow_place = &issued_borrow.borrowed_place;
|
||||||
let borrow_place_desc = self.describe_place(borrow_place.as_place_ref())
|
let borrow_place_desc = self.describe_place(borrow_place.as_ref())
|
||||||
.unwrap_or_else(|| "_".to_owned());
|
.unwrap_or_else(|| "_".to_owned());
|
||||||
issued_spans.var_span_label(
|
issued_spans.var_span_label(
|
||||||
&mut err,
|
&mut err,
|
||||||
|
|
@ -650,8 +650,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||||
|
|
||||||
return Some((
|
return Some((
|
||||||
describe_base_place,
|
describe_base_place,
|
||||||
describe_place(first_borrowed_place.as_place_ref()),
|
describe_place(first_borrowed_place.as_ref()),
|
||||||
describe_place(second_borrowed_place.as_place_ref()),
|
describe_place(second_borrowed_place.as_ref()),
|
||||||
union_ty.to_string(),
|
union_ty.to_string(),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
@ -666,7 +666,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||||
// If we didn't find a field access into a union, or both places match, then
|
// If we didn't find a field access into a union, or both places match, then
|
||||||
// only return the description of the first place.
|
// only return the description of the first place.
|
||||||
(
|
(
|
||||||
describe_place(first_borrowed_place.as_place_ref()),
|
describe_place(first_borrowed_place.as_ref()),
|
||||||
"".to_string(),
|
"".to_string(),
|
||||||
"".to_string(),
|
"".to_string(),
|
||||||
"".to_string(),
|
"".to_string(),
|
||||||
|
|
@ -697,7 +697,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||||
);
|
);
|
||||||
|
|
||||||
let drop_span = place_span.1;
|
let drop_span = place_span.1;
|
||||||
let root_place = self.prefixes(borrow.borrowed_place.as_place_ref(), PrefixSet::All)
|
let root_place = self.prefixes(borrow.borrowed_place.as_ref(), PrefixSet::All)
|
||||||
.last()
|
.last()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
|
|
@ -730,13 +730,13 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||||
}, borrow_span));
|
}, borrow_span));
|
||||||
|
|
||||||
if let StorageDeadOrDrop::Destructor(dropped_ty) =
|
if let StorageDeadOrDrop::Destructor(dropped_ty) =
|
||||||
self.classify_drop_access_kind(borrow.borrowed_place.as_place_ref())
|
self.classify_drop_access_kind(borrow.borrowed_place.as_ref())
|
||||||
{
|
{
|
||||||
// If a borrow of path `B` conflicts with drop of `D` (and
|
// If a borrow of path `B` conflicts with drop of `D` (and
|
||||||
// we're not in the uninteresting case where `B` is a
|
// we're not in the uninteresting case where `B` is a
|
||||||
// prefix of `D`), then report this as a more interesting
|
// prefix of `D`), then report this as a more interesting
|
||||||
// destructor conflict.
|
// destructor conflict.
|
||||||
if !borrow.borrowed_place.as_place_ref().is_prefix_of(place_span.0.as_place_ref()) {
|
if !borrow.borrowed_place.as_ref().is_prefix_of(place_span.0.as_ref()) {
|
||||||
self.report_borrow_conflicts_with_destructor(
|
self.report_borrow_conflicts_with_destructor(
|
||||||
location, borrow, place_span, kind, dropped_ty,
|
location, borrow, place_span, kind, dropped_ty,
|
||||||
);
|
);
|
||||||
|
|
@ -744,7 +744,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let place_desc = self.describe_place(borrow.borrowed_place.as_place_ref());
|
let place_desc = self.describe_place(borrow.borrowed_place.as_ref());
|
||||||
|
|
||||||
let kind_place = kind.filter(|_| place_desc.is_some()).map(|k| (k, place_span.0));
|
let kind_place = kind.filter(|_| place_desc.is_some()).map(|k| (k, place_span.0));
|
||||||
let explanation = self.explain_why_borrow_contains_point(location, &borrow, kind_place);
|
let explanation = self.explain_why_borrow_contains_point(location, &borrow, kind_place);
|
||||||
|
|
@ -951,12 +951,12 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||||
|
|
||||||
let mut err = self.cannot_borrow_across_destructor(borrow_span);
|
let mut err = self.cannot_borrow_across_destructor(borrow_span);
|
||||||
|
|
||||||
let what_was_dropped = match self.describe_place(place.as_place_ref()) {
|
let what_was_dropped = match self.describe_place(place.as_ref()) {
|
||||||
Some(name) => format!("`{}`", name.as_str()),
|
Some(name) => format!("`{}`", name.as_str()),
|
||||||
None => String::from("temporary value"),
|
None => String::from("temporary value"),
|
||||||
};
|
};
|
||||||
|
|
||||||
let label = match self.describe_place(borrow.borrowed_place.as_place_ref()) {
|
let label = match self.describe_place(borrow.borrowed_place.as_ref()) {
|
||||||
Some(borrowed) => format!(
|
Some(borrowed) => format!(
|
||||||
"here, drop of {D} needs exclusive access to `{B}`, \
|
"here, drop of {D} needs exclusive access to `{B}`, \
|
||||||
because the type `{T}` implements the `Drop` trait",
|
because the type `{T}` implements the `Drop` trait",
|
||||||
|
|
@ -1127,7 +1127,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||||
format!("`{}` is borrowed here", place_desc),
|
format!("`{}` is borrowed here", place_desc),
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
let root_place = self.prefixes(borrow.borrowed_place.as_place_ref(),
|
let root_place = self.prefixes(borrow.borrowed_place.as_ref(),
|
||||||
PrefixSet::All)
|
PrefixSet::All)
|
||||||
.last()
|
.last()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
@ -1390,7 +1390,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||||
let mut err = self.cannot_mutate_in_match_guard(
|
let mut err = self.cannot_mutate_in_match_guard(
|
||||||
span,
|
span,
|
||||||
loan_span,
|
loan_span,
|
||||||
&self.describe_place(place.as_place_ref()).unwrap_or_else(|| "_".to_owned()),
|
&self.describe_place(place.as_ref()).unwrap_or_else(|| "_".to_owned()),
|
||||||
"assign",
|
"assign",
|
||||||
);
|
);
|
||||||
loan_spans.var_span_label(
|
loan_spans.var_span_label(
|
||||||
|
|
@ -1406,7 +1406,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||||
let mut err = self.cannot_assign_to_borrowed(
|
let mut err = self.cannot_assign_to_borrowed(
|
||||||
span,
|
span,
|
||||||
loan_span,
|
loan_span,
|
||||||
&self.describe_place(place.as_place_ref()).unwrap_or_else(|| "_".to_owned()),
|
&self.describe_place(place.as_ref()).unwrap_or_else(|| "_".to_owned()),
|
||||||
);
|
);
|
||||||
|
|
||||||
loan_spans.var_span_label(
|
loan_spans.var_span_label(
|
||||||
|
|
@ -1466,8 +1466,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||||
is_user_variable: None,
|
is_user_variable: None,
|
||||||
..
|
..
|
||||||
})
|
})
|
||||||
| None => (self.describe_place(place.as_place_ref()), assigned_span),
|
| None => (self.describe_place(place.as_ref()), assigned_span),
|
||||||
Some(decl) => (self.describe_place(err_place.as_place_ref()), decl.source_info.span),
|
Some(decl) => (self.describe_place(err_place.as_ref()), decl.source_info.span),
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut err = self.cannot_reassign_immutable(
|
let mut err = self.cannot_reassign_immutable(
|
||||||
|
|
|
||||||
|
|
@ -855,7 +855,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||||
def_id, is_generator, places
|
def_id, is_generator, places
|
||||||
);
|
);
|
||||||
if let Some((args_span, var_span)) = self.closure_span(
|
if let Some((args_span, var_span)) = self.closure_span(
|
||||||
*def_id, Place::from(target).as_place_ref(), places
|
*def_id, Place::from(target).as_ref(), places
|
||||||
) {
|
) {
|
||||||
return ClosureUse {
|
return ClosureUse {
|
||||||
is_generator,
|
is_generator,
|
||||||
|
|
@ -895,7 +895,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||||
for (upvar, place) in self.infcx.tcx.upvars(def_id)?.values().zip(places) {
|
for (upvar, place) in self.infcx.tcx.upvars(def_id)?.values().zip(places) {
|
||||||
match place {
|
match place {
|
||||||
Operand::Copy(place) |
|
Operand::Copy(place) |
|
||||||
Operand::Move(place) if target_place == place.as_place_ref() => {
|
Operand::Move(place) if target_place == place.as_ref() => {
|
||||||
debug!("closure_span: found captured local {:?}", place);
|
debug!("closure_span: found captured local {:?}", place);
|
||||||
return Some((*args_span, upvar.span));
|
return Some((*args_span, upvar.span));
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -560,7 +560,7 @@ impl<'cx, 'tcx> DataflowResultsConsumer<'cx, 'tcx> for MirBorrowckCtxt<'cx, 'tcx
|
||||||
self.check_if_path_or_subpath_is_moved(
|
self.check_if_path_or_subpath_is_moved(
|
||||||
location,
|
location,
|
||||||
InitializationRequiringAction::Use,
|
InitializationRequiringAction::Use,
|
||||||
(place.as_place_ref(), span),
|
(place.as_ref(), span),
|
||||||
flow_state,
|
flow_state,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -591,7 +591,7 @@ impl<'cx, 'tcx> DataflowResultsConsumer<'cx, 'tcx> for MirBorrowckCtxt<'cx, 'tcx
|
||||||
self.check_if_path_or_subpath_is_moved(
|
self.check_if_path_or_subpath_is_moved(
|
||||||
location,
|
location,
|
||||||
InitializationRequiringAction::Use,
|
InitializationRequiringAction::Use,
|
||||||
(output.as_place_ref(), o.span),
|
(output.as_ref(), o.span),
|
||||||
flow_state,
|
flow_state,
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -733,8 +733,8 @@ impl<'cx, 'tcx> DataflowResultsConsumer<'cx, 'tcx> for MirBorrowckCtxt<'cx, 'tcx
|
||||||
cleanup: _,
|
cleanup: _,
|
||||||
} => {
|
} => {
|
||||||
self.consume_operand(loc, (cond, span), flow_state);
|
self.consume_operand(loc, (cond, span), flow_state);
|
||||||
use rustc::mir::interpret::InterpError::BoundsCheck;
|
use rustc::mir::interpret::{InterpError::Panic, PanicMessage};
|
||||||
if let BoundsCheck { ref len, ref index } = *msg {
|
if let Panic(PanicMessage::BoundsCheck { ref len, ref index }) = *msg {
|
||||||
self.consume_operand(loc, (len, span), flow_state);
|
self.consume_operand(loc, (len, span), flow_state);
|
||||||
self.consume_operand(loc, (index, span), flow_state);
|
self.consume_operand(loc, (index, span), flow_state);
|
||||||
}
|
}
|
||||||
|
|
@ -1154,7 +1154,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||||
self.check_if_path_or_subpath_is_moved(
|
self.check_if_path_or_subpath_is_moved(
|
||||||
location,
|
location,
|
||||||
InitializationRequiringAction::Update,
|
InitializationRequiringAction::Update,
|
||||||
(place_span.0.as_place_ref(), place_span.1),
|
(place_span.0.as_ref(), place_span.1),
|
||||||
flow_state,
|
flow_state,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -1232,7 +1232,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||||
self.check_if_path_or_subpath_is_moved(
|
self.check_if_path_or_subpath_is_moved(
|
||||||
location,
|
location,
|
||||||
action,
|
action,
|
||||||
(place.as_place_ref(), span),
|
(place.as_ref(), span),
|
||||||
flow_state,
|
flow_state,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -1260,7 +1260,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||||
self.check_if_path_or_subpath_is_moved(
|
self.check_if_path_or_subpath_is_moved(
|
||||||
location,
|
location,
|
||||||
InitializationRequiringAction::Use,
|
InitializationRequiringAction::Use,
|
||||||
(place.as_place_ref(), span),
|
(place.as_ref(), span),
|
||||||
flow_state,
|
flow_state,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -1309,7 +1309,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||||
fn propagate_closure_used_mut_upvar(&mut self, operand: &Operand<'tcx>) {
|
fn propagate_closure_used_mut_upvar(&mut self, operand: &Operand<'tcx>) {
|
||||||
let propagate_closure_used_mut_place = |this: &mut Self, place: &Place<'tcx>| {
|
let propagate_closure_used_mut_place = |this: &mut Self, place: &Place<'tcx>| {
|
||||||
if place.projection.is_some() {
|
if place.projection.is_some() {
|
||||||
if let Some(field) = this.is_upvar_field_projection(place.as_place_ref()) {
|
if let Some(field) = this.is_upvar_field_projection(place.as_ref()) {
|
||||||
this.used_mut_upvars.push(field);
|
this.used_mut_upvars.push(field);
|
||||||
}
|
}
|
||||||
} else if let PlaceBase::Local(local) = place.base {
|
} else if let PlaceBase::Local(local) = place.base {
|
||||||
|
|
@ -1401,7 +1401,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||||
self.check_if_path_or_subpath_is_moved(
|
self.check_if_path_or_subpath_is_moved(
|
||||||
location,
|
location,
|
||||||
InitializationRequiringAction::Use,
|
InitializationRequiringAction::Use,
|
||||||
(place.as_place_ref(), span),
|
(place.as_ref(), span),
|
||||||
flow_state,
|
flow_state,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -1419,7 +1419,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||||
self.check_if_path_or_subpath_is_moved(
|
self.check_if_path_or_subpath_is_moved(
|
||||||
location,
|
location,
|
||||||
InitializationRequiringAction::Use,
|
InitializationRequiringAction::Use,
|
||||||
(place.as_place_ref(), span),
|
(place.as_ref(), span),
|
||||||
flow_state,
|
flow_state,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -1437,7 +1437,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||||
) {
|
) {
|
||||||
debug!("check_for_invalidation_at_exit({:?})", borrow);
|
debug!("check_for_invalidation_at_exit({:?})", borrow);
|
||||||
let place = &borrow.borrowed_place;
|
let place = &borrow.borrowed_place;
|
||||||
let root_place = self.prefixes(place.as_place_ref(), PrefixSet::All).last().unwrap();
|
let root_place = self.prefixes(place.as_ref(), PrefixSet::All).last().unwrap();
|
||||||
|
|
||||||
// FIXME(nll-rfc#40): do more precise destructor tracking here. For now
|
// FIXME(nll-rfc#40): do more precise destructor tracking here. For now
|
||||||
// we just know that all locals are dropped at function exit (otherwise
|
// we just know that all locals are dropped at function exit (otherwise
|
||||||
|
|
|
||||||
|
|
@ -131,7 +131,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let move_spans = self.move_spans(original_path.as_place_ref(), location);
|
let move_spans = self.move_spans(original_path.as_ref(), location);
|
||||||
grouped_errors.push(GroupedMoveError::OtherIllegalMove {
|
grouped_errors.push(GroupedMoveError::OtherIllegalMove {
|
||||||
use_spans: move_spans,
|
use_spans: move_spans,
|
||||||
original_path,
|
original_path,
|
||||||
|
|
@ -160,7 +160,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
||||||
let from_simple_let = match_place.is_none();
|
let from_simple_let = match_place.is_none();
|
||||||
let match_place = match_place.as_ref().unwrap_or(move_from);
|
let match_place = match_place.as_ref().unwrap_or(move_from);
|
||||||
|
|
||||||
match self.move_data.rev_lookup.find(match_place.as_place_ref()) {
|
match self.move_data.rev_lookup.find(match_place.as_ref()) {
|
||||||
// Error with the match place
|
// Error with the match place
|
||||||
LookupResult::Parent(_) => {
|
LookupResult::Parent(_) => {
|
||||||
for ge in &mut *grouped_errors {
|
for ge in &mut *grouped_errors {
|
||||||
|
|
@ -192,7 +192,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
// Error with the pattern
|
// Error with the pattern
|
||||||
LookupResult::Exact(_) => {
|
LookupResult::Exact(_) => {
|
||||||
let mpi = match self.move_data.rev_lookup.find(move_from.as_place_ref()) {
|
let mpi = match self.move_data.rev_lookup.find(move_from.as_ref()) {
|
||||||
LookupResult::Parent(Some(mpi)) => mpi,
|
LookupResult::Parent(Some(mpi)) => mpi,
|
||||||
// move_from should be a projection from match_place.
|
// move_from should be a projection from match_place.
|
||||||
_ => unreachable!("Probably not unreachable..."),
|
_ => unreachable!("Probably not unreachable..."),
|
||||||
|
|
@ -242,7 +242,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
||||||
};
|
};
|
||||||
debug!("report: original_path={:?} span={:?}, kind={:?} \
|
debug!("report: original_path={:?} span={:?}, kind={:?} \
|
||||||
original_path.is_upvar_field_projection={:?}", original_path, span, kind,
|
original_path.is_upvar_field_projection={:?}", original_path, span, kind,
|
||||||
self.is_upvar_field_projection(original_path.as_place_ref()));
|
self.is_upvar_field_projection(original_path.as_ref()));
|
||||||
(
|
(
|
||||||
match kind {
|
match kind {
|
||||||
IllegalMoveOriginKind::Static => {
|
IllegalMoveOriginKind::Static => {
|
||||||
|
|
@ -277,7 +277,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
||||||
span: Span
|
span: Span
|
||||||
) -> DiagnosticBuilder<'a> {
|
) -> DiagnosticBuilder<'a> {
|
||||||
let description = if place.projection.is_none() {
|
let description = if place.projection.is_none() {
|
||||||
format!("static item `{}`", self.describe_place(place.as_place_ref()).unwrap())
|
format!("static item `{}`", self.describe_place(place.as_ref()).unwrap())
|
||||||
} else {
|
} else {
|
||||||
let mut base_static = &place.projection;
|
let mut base_static = &place.projection;
|
||||||
while let Some(box Projection { base: Some(ref proj), .. }) = base_static {
|
while let Some(box Projection { base: Some(ref proj), .. }) = base_static {
|
||||||
|
|
@ -290,7 +290,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
||||||
|
|
||||||
format!(
|
format!(
|
||||||
"`{:?}` as `{:?}` is a static item",
|
"`{:?}` as `{:?}` is a static item",
|
||||||
self.describe_place(place.as_place_ref()).unwrap(),
|
self.describe_place(place.as_ref()).unwrap(),
|
||||||
self.describe_place(base_static).unwrap(),
|
self.describe_place(base_static).unwrap(),
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
|
@ -308,7 +308,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
||||||
// borrow to provide feedback about why this
|
// borrow to provide feedback about why this
|
||||||
// was a move rather than a copy.
|
// was a move rather than a copy.
|
||||||
let ty = deref_target_place.ty(self.body, self.infcx.tcx).ty;
|
let ty = deref_target_place.ty(self.body, self.infcx.tcx).ty;
|
||||||
let upvar_field = self.prefixes(move_place.as_place_ref(), PrefixSet::All)
|
let upvar_field = self.prefixes(move_place.as_ref(), PrefixSet::All)
|
||||||
.find_map(|p| self.is_upvar_field_projection(p));
|
.find_map(|p| self.is_upvar_field_projection(p));
|
||||||
|
|
||||||
let deref_base = match deref_target_place.projection {
|
let deref_base = match deref_target_place.projection {
|
||||||
|
|
@ -363,10 +363,10 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
||||||
let upvar_name = upvar.name;
|
let upvar_name = upvar.name;
|
||||||
let upvar_span = self.infcx.tcx.hir().span(upvar_hir_id);
|
let upvar_span = self.infcx.tcx.hir().span(upvar_hir_id);
|
||||||
|
|
||||||
let place_name = self.describe_place(move_place.as_place_ref()).unwrap();
|
let place_name = self.describe_place(move_place.as_ref()).unwrap();
|
||||||
|
|
||||||
let place_description = if self
|
let place_description = if self
|
||||||
.is_upvar_field_projection(move_place.as_place_ref())
|
.is_upvar_field_projection(move_place.as_ref())
|
||||||
.is_some()
|
.is_some()
|
||||||
{
|
{
|
||||||
format!("`{}`, a {}", place_name, capture_description)
|
format!("`{}`, a {}", place_name, capture_description)
|
||||||
|
|
@ -393,7 +393,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
||||||
_ => {
|
_ => {
|
||||||
let source = self.borrowed_content_source(deref_base);
|
let source = self.borrowed_content_source(deref_base);
|
||||||
match (
|
match (
|
||||||
self.describe_place(move_place.as_place_ref()),
|
self.describe_place(move_place.as_ref()),
|
||||||
source.describe_for_named_place(),
|
source.describe_for_named_place(),
|
||||||
) {
|
) {
|
||||||
(Some(place_desc), Some(source_desc)) => {
|
(Some(place_desc), Some(source_desc)) => {
|
||||||
|
|
@ -455,7 +455,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
||||||
|
|
||||||
if binds_to.is_empty() {
|
if binds_to.is_empty() {
|
||||||
let place_ty = move_from.ty(self.body, self.infcx.tcx).ty;
|
let place_ty = move_from.ty(self.body, self.infcx.tcx).ty;
|
||||||
let place_desc = match self.describe_place(move_from.as_place_ref()) {
|
let place_desc = match self.describe_place(move_from.as_ref()) {
|
||||||
Some(desc) => format!("`{}`", desc),
|
Some(desc) => format!("`{}`", desc),
|
||||||
None => format!("value"),
|
None => format!("value"),
|
||||||
};
|
};
|
||||||
|
|
@ -483,7 +483,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
||||||
GroupedMoveError::OtherIllegalMove { ref original_path, use_spans, .. } => {
|
GroupedMoveError::OtherIllegalMove { ref original_path, use_spans, .. } => {
|
||||||
let span = use_spans.var_or_use();
|
let span = use_spans.var_or_use();
|
||||||
let place_ty = original_path.ty(self.body, self.infcx.tcx).ty;
|
let place_ty = original_path.ty(self.body, self.infcx.tcx).ty;
|
||||||
let place_desc = match self.describe_place(original_path.as_place_ref()) {
|
let place_desc = match self.describe_place(original_path.as_ref()) {
|
||||||
Some(desc) => format!("`{}`", desc),
|
Some(desc) => format!("`{}`", desc),
|
||||||
None => format!("value"),
|
None => format!("value"),
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
||||||
let item_msg;
|
let item_msg;
|
||||||
let reason;
|
let reason;
|
||||||
let mut opt_source = None;
|
let mut opt_source = None;
|
||||||
let access_place_desc = self.describe_place(access_place.as_place_ref());
|
let access_place_desc = self.describe_place(access_place.as_ref());
|
||||||
debug!("report_mutability_error: access_place_desc={:?}", access_place_desc);
|
debug!("report_mutability_error: access_place_desc={:?}", access_place_desc);
|
||||||
|
|
||||||
match the_place_err {
|
match the_place_err {
|
||||||
|
|
@ -77,7 +77,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
||||||
));
|
));
|
||||||
|
|
||||||
item_msg = format!("`{}`", access_place_desc.unwrap());
|
item_msg = format!("`{}`", access_place_desc.unwrap());
|
||||||
if self.is_upvar_field_projection(access_place.as_place_ref()).is_some() {
|
if self.is_upvar_field_projection(access_place.as_ref()).is_some() {
|
||||||
reason = ", as it is not declared as mutable".to_string();
|
reason = ", as it is not declared as mutable".to_string();
|
||||||
} else {
|
} else {
|
||||||
let name = self.upvars[upvar_index.index()].name;
|
let name = self.upvars[upvar_index.index()].name;
|
||||||
|
|
@ -109,7 +109,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
||||||
));
|
));
|
||||||
|
|
||||||
reason =
|
reason =
|
||||||
if self.is_upvar_field_projection(access_place.as_place_ref()).is_some() {
|
if self.is_upvar_field_projection(access_place.as_ref()).is_some() {
|
||||||
", as it is a captured variable in a `Fn` closure".to_string()
|
", as it is a captured variable in a `Fn` closure".to_string()
|
||||||
} else {
|
} else {
|
||||||
", as `Fn` closures cannot mutate their captured variables".to_string()
|
", as `Fn` closures cannot mutate their captured variables".to_string()
|
||||||
|
|
@ -244,7 +244,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
||||||
format!(
|
format!(
|
||||||
"mutable borrow occurs due to use of `{}` in closure",
|
"mutable borrow occurs due to use of `{}` in closure",
|
||||||
// always Some() if the message is printed.
|
// always Some() if the message is printed.
|
||||||
self.describe_place(access_place.as_place_ref()).unwrap_or_default(),
|
self.describe_place(access_place.as_ref()).unwrap_or_default(),
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
borrow_span
|
borrow_span
|
||||||
|
|
|
||||||
|
|
@ -252,7 +252,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||||
Some(Cause::LiveVar(local, location)) => {
|
Some(Cause::LiveVar(local, location)) => {
|
||||||
let span = body.source_info(location).span;
|
let span = body.source_info(location).span;
|
||||||
let spans = self
|
let spans = self
|
||||||
.move_spans(Place::from(local).as_place_ref(), location)
|
.move_spans(Place::from(local).as_ref(), location)
|
||||||
.or_else(|| self.borrow_spans(span, location));
|
.or_else(|| self.borrow_spans(span, location));
|
||||||
|
|
||||||
let borrow_location = location;
|
let borrow_location = location;
|
||||||
|
|
@ -305,7 +305,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||||
);
|
);
|
||||||
if let Some(region_name) = region_name {
|
if let Some(region_name) = region_name {
|
||||||
let opt_place_desc =
|
let opt_place_desc =
|
||||||
self.describe_place(borrow.borrowed_place.as_place_ref());
|
self.describe_place(borrow.borrowed_place.as_ref());
|
||||||
BorrowExplanation::MustBeValidFor {
|
BorrowExplanation::MustBeValidFor {
|
||||||
category,
|
category,
|
||||||
from_closure,
|
from_closure,
|
||||||
|
|
|
||||||
|
|
@ -207,8 +207,8 @@ impl<'cx, 'tcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx> {
|
||||||
cleanup: _,
|
cleanup: _,
|
||||||
} => {
|
} => {
|
||||||
self.consume_operand(location, cond);
|
self.consume_operand(location, cond);
|
||||||
use rustc::mir::interpret::InterpError::BoundsCheck;
|
use rustc::mir::interpret::{InterpError::Panic, PanicMessage::BoundsCheck};
|
||||||
if let BoundsCheck { ref len, ref index } = *msg {
|
if let Panic(BoundsCheck { ref len, ref index }) = *msg {
|
||||||
self.consume_operand(location, len);
|
self.consume_operand(location, len);
|
||||||
self.consume_operand(location, index);
|
self.consume_operand(location, index);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@ use rustc::infer::canonical::QueryRegionConstraints;
|
||||||
use rustc::infer::outlives::env::RegionBoundPairs;
|
use rustc::infer::outlives::env::RegionBoundPairs;
|
||||||
use rustc::infer::{InferCtxt, InferOk, LateBoundRegionConversionTime, NLLRegionVariableOrigin};
|
use rustc::infer::{InferCtxt, InferOk, LateBoundRegionConversionTime, NLLRegionVariableOrigin};
|
||||||
use rustc::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
|
use rustc::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
|
||||||
use rustc::mir::interpret::{InterpError::BoundsCheck, ConstValue};
|
use rustc::mir::interpret::{InterpError::Panic, ConstValue, PanicMessage};
|
||||||
use rustc::mir::tcx::PlaceTy;
|
use rustc::mir::tcx::PlaceTy;
|
||||||
use rustc::mir::visit::{PlaceContext, Visitor, NonMutatingUseContext};
|
use rustc::mir::visit::{PlaceContext, Visitor, NonMutatingUseContext};
|
||||||
use rustc::mir::*;
|
use rustc::mir::*;
|
||||||
|
|
@ -1606,7 +1606,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||||
span_mirbug!(self, term, "bad Assert ({:?}, not bool", cond_ty);
|
span_mirbug!(self, term, "bad Assert ({:?}, not bool", cond_ty);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let BoundsCheck { ref len, ref index } = *msg {
|
if let Panic(PanicMessage::BoundsCheck { ref len, ref index }) = *msg {
|
||||||
if len.ty(body, tcx) != tcx.types.usize {
|
if len.ty(body, tcx) != tcx.types.usize {
|
||||||
span_mirbug!(self, len, "bounds-check length non-usize {:?}", len)
|
span_mirbug!(self, len, "bounds-check length non-usize {:?}", len)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -50,7 +50,7 @@ pub(super) fn each_borrow_involving_path<'tcx, F, I, S>(
|
||||||
body,
|
body,
|
||||||
&borrowed.borrowed_place,
|
&borrowed.borrowed_place,
|
||||||
borrowed.kind,
|
borrowed.kind,
|
||||||
place.as_place_ref(),
|
place.as_ref(),
|
||||||
access,
|
access,
|
||||||
places_conflict::PlaceConflictBias::Overlap,
|
places_conflict::PlaceConflictBias::Overlap,
|
||||||
) {
|
) {
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@ crate fn places_conflict<'tcx>(
|
||||||
body,
|
body,
|
||||||
borrow_place,
|
borrow_place,
|
||||||
BorrowKind::Mut { allow_two_phase_borrow: true },
|
BorrowKind::Mut { allow_two_phase_borrow: true },
|
||||||
access_place.as_place_ref(),
|
access_place.as_ref(),
|
||||||
AccessDepth::Deep,
|
AccessDepth::Deep,
|
||||||
bias,
|
bias,
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ use crate::build::expr::category::Category;
|
||||||
use crate::build::ForGuard::{OutsideGuard, RefWithinGuard};
|
use crate::build::ForGuard::{OutsideGuard, RefWithinGuard};
|
||||||
use crate::build::{BlockAnd, BlockAndExtension, Builder};
|
use crate::build::{BlockAnd, BlockAndExtension, Builder};
|
||||||
use crate::hair::*;
|
use crate::hair::*;
|
||||||
use rustc::mir::interpret::InterpError::BoundsCheck;
|
use rustc::mir::interpret::{InterpError::Panic, PanicMessage::BoundsCheck};
|
||||||
use rustc::mir::*;
|
use rustc::mir::*;
|
||||||
use rustc::ty::{CanonicalUserTypeAnnotation, Variance};
|
use rustc::ty::{CanonicalUserTypeAnnotation, Variance};
|
||||||
|
|
||||||
|
|
@ -105,10 +105,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
let msg = BoundsCheck {
|
let msg = Panic(BoundsCheck {
|
||||||
len: Operand::Move(len),
|
len: Operand::Move(len),
|
||||||
index: Operand::Copy(Place::from(idx)),
|
index: Operand::Copy(Place::from(idx)),
|
||||||
};
|
});
|
||||||
let success = this.assert(block, Operand::Move(lt), true, msg, expr_span);
|
let success = this.assert(block, Operand::Move(lt), true, msg, expr_span);
|
||||||
success.and(slice.index(idx))
|
success.and(slice.index(idx))
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ use crate::build::expr::category::{Category, RvalueFunc};
|
||||||
use crate::build::{BlockAnd, BlockAndExtension, Builder};
|
use crate::build::{BlockAnd, BlockAndExtension, Builder};
|
||||||
use crate::hair::*;
|
use crate::hair::*;
|
||||||
use rustc::middle::region;
|
use rustc::middle::region;
|
||||||
use rustc::mir::interpret::InterpError;
|
use rustc::mir::interpret::{InterpError::Panic, PanicMessage};
|
||||||
use rustc::mir::*;
|
use rustc::mir::*;
|
||||||
use rustc::ty::{self, CanonicalUserTypeAnnotation, Ty, UpvarSubsts};
|
use rustc::ty::{self, CanonicalUserTypeAnnotation, Ty, UpvarSubsts};
|
||||||
use syntax_pos::Span;
|
use syntax_pos::Span;
|
||||||
|
|
@ -101,7 +101,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||||
block,
|
block,
|
||||||
Operand::Move(is_min),
|
Operand::Move(is_min),
|
||||||
false,
|
false,
|
||||||
InterpError::OverflowNeg,
|
Panic(PanicMessage::OverflowNeg),
|
||||||
expr_span,
|
expr_span,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -401,7 +401,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||||
let val = result_value.clone().field(val_fld, ty);
|
let val = result_value.clone().field(val_fld, ty);
|
||||||
let of = result_value.field(of_fld, bool_ty);
|
let of = result_value.field(of_fld, bool_ty);
|
||||||
|
|
||||||
let err = InterpError::Overflow(op);
|
let err = Panic(PanicMessage::Overflow(op));
|
||||||
|
|
||||||
block = self.assert(block, Operand::Move(of), false, err, span);
|
block = self.assert(block, Operand::Move(of), false, err, span);
|
||||||
|
|
||||||
|
|
@ -412,9 +412,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||||
// and 2. there are two possible failure cases, divide-by-zero and overflow.
|
// and 2. there are two possible failure cases, divide-by-zero and overflow.
|
||||||
|
|
||||||
let (zero_err, overflow_err) = if op == BinOp::Div {
|
let (zero_err, overflow_err) = if op == BinOp::Div {
|
||||||
(InterpError::DivisionByZero, InterpError::Overflow(op))
|
(Panic(PanicMessage::DivisionByZero), Panic(PanicMessage::Overflow(op)))
|
||||||
} else {
|
} else {
|
||||||
(InterpError::RemainderByZero, InterpError::Overflow(op))
|
(Panic(PanicMessage::RemainderByZero), Panic(PanicMessage::Overflow(op)))
|
||||||
};
|
};
|
||||||
|
|
||||||
// Check for / 0
|
// Check for / 0
|
||||||
|
|
|
||||||
|
|
@ -1304,7 +1304,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||||
prefix_cursor = base;
|
prefix_cursor = base;
|
||||||
}
|
}
|
||||||
|
|
||||||
all_fake_borrows.push(place.as_place_ref());
|
all_fake_borrows.push(place.as_ref());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Deduplicate and ensure a deterministic order.
|
// Deduplicate and ensure a deterministic order.
|
||||||
|
|
|
||||||
|
|
@ -171,7 +171,7 @@ pub(crate) fn drop_flag_effects_for_function_entry<'tcx, F>(
|
||||||
let move_data = &ctxt.move_data;
|
let move_data = &ctxt.move_data;
|
||||||
for arg in body.args_iter() {
|
for arg in body.args_iter() {
|
||||||
let place = mir::Place::from(arg);
|
let place = mir::Place::from(arg);
|
||||||
let lookup_result = move_data.rev_lookup.find(place.as_place_ref());
|
let lookup_result = move_data.rev_lookup.find(place.as_ref());
|
||||||
on_lookup_result_bits(tcx, body, move_data,
|
on_lookup_result_bits(tcx, body, move_data,
|
||||||
lookup_result,
|
lookup_result,
|
||||||
|mpi| callback(mpi, DropFlagState::Present));
|
|mpi| callback(mpi, DropFlagState::Present));
|
||||||
|
|
|
||||||
|
|
@ -309,7 +309,7 @@ impl<'a, 'tcx> BitDenotation<'tcx> for MaybeInitializedPlaces<'a, 'tcx> {
|
||||||
// when a call returns successfully, that means we need to set
|
// when a call returns successfully, that means we need to set
|
||||||
// the bits for that dest_place to 1 (initialized).
|
// the bits for that dest_place to 1 (initialized).
|
||||||
on_lookup_result_bits(self.tcx, self.body, self.move_data(),
|
on_lookup_result_bits(self.tcx, self.body, self.move_data(),
|
||||||
self.move_data().rev_lookup.find(dest_place.as_place_ref()),
|
self.move_data().rev_lookup.find(dest_place.as_ref()),
|
||||||
|mpi| { in_out.insert(mpi); });
|
|mpi| { in_out.insert(mpi); });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -367,7 +367,7 @@ impl<'a, 'tcx> BitDenotation<'tcx> for MaybeUninitializedPlaces<'a, 'tcx> {
|
||||||
// when a call returns successfully, that means we need to set
|
// when a call returns successfully, that means we need to set
|
||||||
// the bits for that dest_place to 0 (initialized).
|
// the bits for that dest_place to 0 (initialized).
|
||||||
on_lookup_result_bits(self.tcx, self.body, self.move_data(),
|
on_lookup_result_bits(self.tcx, self.body, self.move_data(),
|
||||||
self.move_data().rev_lookup.find(dest_place.as_place_ref()),
|
self.move_data().rev_lookup.find(dest_place.as_ref()),
|
||||||
|mpi| { in_out.remove(mpi); });
|
|mpi| { in_out.remove(mpi); });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -423,7 +423,7 @@ impl<'a, 'tcx> BitDenotation<'tcx> for DefinitelyInitializedPlaces<'a, 'tcx> {
|
||||||
// when a call returns successfully, that means we need to set
|
// when a call returns successfully, that means we need to set
|
||||||
// the bits for that dest_place to 1 (initialized).
|
// the bits for that dest_place to 1 (initialized).
|
||||||
on_lookup_result_bits(self.tcx, self.body, self.move_data(),
|
on_lookup_result_bits(self.tcx, self.body, self.move_data(),
|
||||||
self.move_data().rev_lookup.find(dest_place.as_place_ref()),
|
self.move_data().rev_lookup.find(dest_place.as_ref()),
|
||||||
|mpi| { in_out.insert(mpi); });
|
|mpi| { in_out.insert(mpi); });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -274,9 +274,9 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
|
||||||
// move-path for the interior so it will be separate from
|
// move-path for the interior so it will be separate from
|
||||||
// the exterior.
|
// the exterior.
|
||||||
self.create_move_path(&place.clone().deref());
|
self.create_move_path(&place.clone().deref());
|
||||||
self.gather_init(place.as_place_ref(), InitKind::Shallow);
|
self.gather_init(place.as_ref(), InitKind::Shallow);
|
||||||
} else {
|
} else {
|
||||||
self.gather_init(place.as_place_ref(), InitKind::Deep);
|
self.gather_init(place.as_ref(), InitKind::Deep);
|
||||||
}
|
}
|
||||||
self.gather_rvalue(rval);
|
self.gather_rvalue(rval);
|
||||||
}
|
}
|
||||||
|
|
@ -286,7 +286,7 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
|
||||||
StatementKind::InlineAsm(ref asm) => {
|
StatementKind::InlineAsm(ref asm) => {
|
||||||
for (output, kind) in asm.outputs.iter().zip(&asm.asm.outputs) {
|
for (output, kind) in asm.outputs.iter().zip(&asm.asm.outputs) {
|
||||||
if !kind.is_indirect {
|
if !kind.is_indirect {
|
||||||
self.gather_init(output.as_place_ref(), InitKind::Deep);
|
self.gather_init(output.as_ref(), InitKind::Deep);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (_, input) in asm.inputs.iter() {
|
for (_, input) in asm.inputs.iter() {
|
||||||
|
|
@ -376,7 +376,7 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
|
||||||
TerminatorKind::DropAndReplace { ref location, ref value, .. } => {
|
TerminatorKind::DropAndReplace { ref location, ref value, .. } => {
|
||||||
self.create_move_path(location);
|
self.create_move_path(location);
|
||||||
self.gather_operand(value);
|
self.gather_operand(value);
|
||||||
self.gather_init(location.as_place_ref(), InitKind::Deep);
|
self.gather_init(location.as_ref(), InitKind::Deep);
|
||||||
}
|
}
|
||||||
TerminatorKind::Call {
|
TerminatorKind::Call {
|
||||||
ref func,
|
ref func,
|
||||||
|
|
@ -391,7 +391,7 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
|
||||||
}
|
}
|
||||||
if let Some((ref destination, _bb)) = *destination {
|
if let Some((ref destination, _bb)) = *destination {
|
||||||
self.create_move_path(destination);
|
self.create_move_path(destination);
|
||||||
self.gather_init(destination.as_place_ref(), InitKind::NonPanicPathOnly);
|
self.gather_init(destination.as_ref(), InitKind::NonPanicPathOnly);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ use rustc::ty;
|
||||||
use rustc::ty::layout::{LayoutOf, Primitive, Size};
|
use rustc::ty::layout::{LayoutOf, Primitive, Size};
|
||||||
use rustc::mir::BinOp;
|
use rustc::mir::BinOp;
|
||||||
use rustc::mir::interpret::{
|
use rustc::mir::interpret::{
|
||||||
InterpResult, InterpError, Scalar,
|
InterpResult, InterpError, Scalar, PanicMessage,
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
|
|
@ -261,7 +261,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||||
let file = Symbol::intern(self.read_str(file_place)?);
|
let file = Symbol::intern(self.read_str(file_place)?);
|
||||||
let line = self.read_scalar(line.into())?.to_u32()?;
|
let line = self.read_scalar(line.into())?.to_u32()?;
|
||||||
let col = self.read_scalar(col.into())?.to_u32()?;
|
let col = self.read_scalar(col.into())?.to_u32()?;
|
||||||
return Err(InterpError::Panic { msg, file, line, col }.into());
|
return Err(InterpError::Panic(PanicMessage::Panic { msg, file, line, col }).into());
|
||||||
} else if Some(def_id) == self.tcx.lang_items().begin_panic_fn() {
|
} else if Some(def_id) == self.tcx.lang_items().begin_panic_fn() {
|
||||||
assert!(args.len() == 2);
|
assert!(args.len() == 2);
|
||||||
// &'static str, &(&'static str, u32, u32)
|
// &'static str, &(&'static str, u32, u32)
|
||||||
|
|
@ -279,7 +279,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||||
let file = Symbol::intern(self.read_str(file_place)?);
|
let file = Symbol::intern(self.read_str(file_place)?);
|
||||||
let line = self.read_scalar(line.into())?.to_u32()?;
|
let line = self.read_scalar(line.into())?.to_u32()?;
|
||||||
let col = self.read_scalar(col.into())?.to_u32()?;
|
let col = self.read_scalar(col.into())?.to_u32()?;
|
||||||
return Err(InterpError::Panic { msg, file, line, col }.into());
|
return Err(InterpError::Panic(PanicMessage::Panic { msg, file, line, col }).into());
|
||||||
} else {
|
} else {
|
||||||
return Ok(false);
|
return Ok(false);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ use rustc::mir;
|
||||||
use rustc::ty::{self, layout::TyLayout};
|
use rustc::ty::{self, layout::TyLayout};
|
||||||
use syntax::ast::FloatTy;
|
use syntax::ast::FloatTy;
|
||||||
use rustc_apfloat::Float;
|
use rustc_apfloat::Float;
|
||||||
use rustc::mir::interpret::{InterpResult, Scalar};
|
use rustc::mir::interpret::{InterpResult, PanicMessage, Scalar};
|
||||||
|
|
||||||
use super::{InterpCx, PlaceTy, Immediate, Machine, ImmTy};
|
use super::{InterpCx, PlaceTy, Immediate, Machine, ImmTy};
|
||||||
|
|
||||||
|
|
@ -173,8 +173,8 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||||
return Ok((Scalar::from_bool(op(&l, &r)), false));
|
return Ok((Scalar::from_bool(op(&l, &r)), false));
|
||||||
}
|
}
|
||||||
let op: Option<fn(i128, i128) -> (i128, bool)> = match bin_op {
|
let op: Option<fn(i128, i128) -> (i128, bool)> = match bin_op {
|
||||||
Div if r == 0 => return err!(DivisionByZero),
|
Div if r == 0 => return err!(Panic(PanicMessage::DivisionByZero)),
|
||||||
Rem if r == 0 => return err!(RemainderByZero),
|
Rem if r == 0 => return err!(Panic(PanicMessage::RemainderByZero)),
|
||||||
Div => Some(i128::overflowing_div),
|
Div => Some(i128::overflowing_div),
|
||||||
Rem => Some(i128::overflowing_rem),
|
Rem => Some(i128::overflowing_rem),
|
||||||
Add => Some(i128::overflowing_add),
|
Add => Some(i128::overflowing_add),
|
||||||
|
|
@ -231,8 +231,8 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||||
Add => u128::overflowing_add,
|
Add => u128::overflowing_add,
|
||||||
Sub => u128::overflowing_sub,
|
Sub => u128::overflowing_sub,
|
||||||
Mul => u128::overflowing_mul,
|
Mul => u128::overflowing_mul,
|
||||||
Div if r == 0 => return err!(DivisionByZero),
|
Div if r == 0 => return err!(Panic(PanicMessage::DivisionByZero)),
|
||||||
Rem if r == 0 => return err!(RemainderByZero),
|
Rem if r == 0 => return err!(Panic(PanicMessage::RemainderByZero)),
|
||||||
Div => u128::overflowing_div,
|
Div => u128::overflowing_div,
|
||||||
Rem => u128::overflowing_rem,
|
Rem => u128::overflowing_rem,
|
||||||
_ => bug!(),
|
_ => bug!(),
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ use rustc::ty::TypeFoldable;
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
GlobalId, AllocId, Allocation, Scalar, InterpResult, Pointer, PointerArithmetic,
|
GlobalId, AllocId, Allocation, Scalar, InterpResult, Pointer, PointerArithmetic,
|
||||||
InterpCx, Machine, AllocMap, AllocationExtra,
|
InterpCx, Machine, AllocMap, AllocationExtra, PanicMessage,
|
||||||
RawConst, Immediate, ImmTy, ScalarMaybeUndef, Operand, OpTy, MemoryKind, LocalValue
|
RawConst, Immediate, ImmTy, ScalarMaybeUndef, Operand, OpTy, MemoryKind, LocalValue
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -356,7 +356,7 @@ where
|
||||||
// This can be violated because this runs during promotion on code where the
|
// This can be violated because this runs during promotion on code where the
|
||||||
// type system has not yet ensured that such things don't happen.
|
// type system has not yet ensured that such things don't happen.
|
||||||
debug!("tried to access element {} of array/slice with length {}", field, len);
|
debug!("tried to access element {} of array/slice with length {}", field, len);
|
||||||
return err!(BoundsCheck { len, index: field });
|
return err!(Panic(PanicMessage::BoundsCheck { len, index: field }));
|
||||||
}
|
}
|
||||||
stride * field
|
stride * field
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ use syntax::source_map::Span;
|
||||||
use rustc_target::spec::abi::Abi;
|
use rustc_target::spec::abi::Abi;
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
InterpResult, PointerArithmetic, InterpError, Scalar,
|
InterpResult, PointerArithmetic, InterpError, Scalar, PanicMessage,
|
||||||
InterpCx, Machine, Immediate, OpTy, ImmTy, PlaceTy, MPlaceTy, StackPopCleanup, FnVal,
|
InterpCx, Machine, Immediate, OpTy, ImmTy, PlaceTy, MPlaceTy, StackPopCleanup, FnVal,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -137,19 +137,23 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||||
// Compute error message
|
// Compute error message
|
||||||
use rustc::mir::interpret::InterpError::*;
|
use rustc::mir::interpret::InterpError::*;
|
||||||
return match *msg {
|
return match *msg {
|
||||||
BoundsCheck { ref len, ref index } => {
|
Panic(PanicMessage::BoundsCheck { ref len, ref index }) => {
|
||||||
let len = self.read_immediate(self.eval_operand(len, None)?)
|
let len = self.read_immediate(self.eval_operand(len, None)?)
|
||||||
.expect("can't eval len").to_scalar()?
|
.expect("can't eval len").to_scalar()?
|
||||||
.to_bits(self.memory().pointer_size())? as u64;
|
.to_bits(self.memory().pointer_size())? as u64;
|
||||||
let index = self.read_immediate(self.eval_operand(index, None)?)
|
let index = self.read_immediate(self.eval_operand(index, None)?)
|
||||||
.expect("can't eval index").to_scalar()?
|
.expect("can't eval index").to_scalar()?
|
||||||
.to_bits(self.memory().pointer_size())? as u64;
|
.to_bits(self.memory().pointer_size())? as u64;
|
||||||
err!(BoundsCheck { len, index })
|
err!(Panic(PanicMessage::BoundsCheck { len, index }))
|
||||||
}
|
}
|
||||||
Overflow(op) => Err(Overflow(op).into()),
|
Panic(PanicMessage::Overflow(op)) =>
|
||||||
OverflowNeg => Err(OverflowNeg.into()),
|
Err(Panic(PanicMessage::Overflow(op)).into()),
|
||||||
DivisionByZero => Err(DivisionByZero.into()),
|
Panic(PanicMessage::OverflowNeg) =>
|
||||||
RemainderByZero => Err(RemainderByZero.into()),
|
Err(Panic(PanicMessage::OverflowNeg).into()),
|
||||||
|
Panic(PanicMessage::DivisionByZero) =>
|
||||||
|
Err(Panic(PanicMessage::DivisionByZero).into()),
|
||||||
|
Panic(PanicMessage::RemainderByZero) =>
|
||||||
|
Err(Panic(PanicMessage::RemainderByZero).into()),
|
||||||
GeneratorResumedAfterReturn |
|
GeneratorResumedAfterReturn |
|
||||||
GeneratorResumedAfterPanic => unimplemented!(),
|
GeneratorResumedAfterPanic => unimplemented!(),
|
||||||
_ => bug!(),
|
_ => bug!(),
|
||||||
|
|
|
||||||
|
|
@ -79,7 +79,7 @@ impl MirPass for AddRetag {
|
||||||
let needs_retag = |place: &Place<'tcx>| {
|
let needs_retag = |place: &Place<'tcx>| {
|
||||||
// FIXME: Instead of giving up for unstable places, we should introduce
|
// FIXME: Instead of giving up for unstable places, we should introduce
|
||||||
// a temporary and retag on that.
|
// a temporary and retag on that.
|
||||||
is_stable(place.as_place_ref())
|
is_stable(place.as_ref())
|
||||||
&& may_have_reference(place.ty(&*local_decls, tcx).ty, tcx)
|
&& may_have_reference(place.ty(&*local_decls, tcx).ty, tcx)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ use rustc::mir::{
|
||||||
use rustc::mir::visit::{
|
use rustc::mir::visit::{
|
||||||
Visitor, PlaceContext, MutatingUseContext, MutVisitor, NonMutatingUseContext,
|
Visitor, PlaceContext, MutatingUseContext, MutVisitor, NonMutatingUseContext,
|
||||||
};
|
};
|
||||||
use rustc::mir::interpret::{InterpError, Scalar, GlobalId, InterpResult};
|
use rustc::mir::interpret::{InterpError::Panic, Scalar, GlobalId, InterpResult, PanicMessage};
|
||||||
use rustc::ty::{self, Instance, ParamEnv, Ty, TyCtxt};
|
use rustc::ty::{self, Instance, ParamEnv, Ty, TyCtxt};
|
||||||
use syntax_pos::{Span, DUMMY_SP};
|
use syntax_pos::{Span, DUMMY_SP};
|
||||||
use rustc::ty::subst::InternalSubsts;
|
use rustc::ty::subst::InternalSubsts;
|
||||||
|
|
@ -339,12 +339,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
|
||||||
// FIXME: implement
|
// FIXME: implement
|
||||||
=> {},
|
=> {},
|
||||||
|
|
||||||
| Panic { .. }
|
| Panic(_)
|
||||||
| BoundsCheck{..}
|
|
||||||
| Overflow(_)
|
|
||||||
| OverflowNeg
|
|
||||||
| DivisionByZero
|
|
||||||
| RemainderByZero
|
|
||||||
=> {
|
=> {
|
||||||
diagnostic.report_as_lint(
|
diagnostic.report_as_lint(
|
||||||
self.ecx.tcx,
|
self.ecx.tcx,
|
||||||
|
|
@ -522,7 +517,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
|
||||||
// Need to do overflow check here: For actual CTFE, MIR
|
// Need to do overflow check here: For actual CTFE, MIR
|
||||||
// generation emits code that does this before calling the op.
|
// generation emits code that does this before calling the op.
|
||||||
if prim.to_bits()? == (1 << (prim.layout.size.bits() - 1)) {
|
if prim.to_bits()? == (1 << (prim.layout.size.bits() - 1)) {
|
||||||
return err!(OverflowNeg);
|
return err!(Panic(PanicMessage::OverflowNeg));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
UnOp::Not => {
|
UnOp::Not => {
|
||||||
|
|
@ -600,7 +595,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
if overflow {
|
if overflow {
|
||||||
let err = InterpError::Overflow(op).into();
|
let err = Panic(PanicMessage::Overflow(op)).into();
|
||||||
let _: Option<()> = self.use_ecx(source_info, |_| Err(err));
|
let _: Option<()> = self.use_ecx(source_info, |_| Err(err));
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
@ -838,11 +833,11 @@ impl<'mir, 'tcx> MutVisitor<'tcx> for ConstPropagator<'mir, 'tcx> {
|
||||||
.expect("some part of a failing const eval must be local");
|
.expect("some part of a failing const eval must be local");
|
||||||
use rustc::mir::interpret::InterpError::*;
|
use rustc::mir::interpret::InterpError::*;
|
||||||
let msg = match msg {
|
let msg = match msg {
|
||||||
Overflow(_) |
|
Panic(PanicMessage::Overflow(_)) |
|
||||||
OverflowNeg |
|
Panic(PanicMessage::OverflowNeg) |
|
||||||
DivisionByZero |
|
Panic(PanicMessage::DivisionByZero) |
|
||||||
RemainderByZero => msg.description().to_owned(),
|
Panic(PanicMessage::RemainderByZero) => msg.description().to_owned(),
|
||||||
BoundsCheck { ref len, ref index } => {
|
Panic(PanicMessage::BoundsCheck { ref len, ref index }) => {
|
||||||
let len = self
|
let len = self
|
||||||
.eval_operand(len, source_info)
|
.eval_operand(len, source_info)
|
||||||
.expect("len must be const");
|
.expect("len must be const");
|
||||||
|
|
|
||||||
|
|
@ -105,7 +105,7 @@ fn find_dead_unwinds<'tcx>(
|
||||||
init_data.apply_location(tcx, body, env, loc);
|
init_data.apply_location(tcx, body, env, loc);
|
||||||
}
|
}
|
||||||
|
|
||||||
let path = match env.move_data.rev_lookup.find(location.as_place_ref()) {
|
let path = match env.move_data.rev_lookup.find(location.as_ref()) {
|
||||||
LookupResult::Exact(e) => e,
|
LookupResult::Exact(e) => e,
|
||||||
LookupResult::Parent(..) => {
|
LookupResult::Parent(..) => {
|
||||||
debug!("find_dead_unwinds: has parent; skipping");
|
debug!("find_dead_unwinds: has parent; skipping");
|
||||||
|
|
@ -360,7 +360,7 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
|
||||||
statement_index: data.statements.len()
|
statement_index: data.statements.len()
|
||||||
});
|
});
|
||||||
|
|
||||||
let path = self.move_data().rev_lookup.find(location.as_place_ref());
|
let path = self.move_data().rev_lookup.find(location.as_ref());
|
||||||
debug!("collect_drop_flags: {:?}, place {:?} ({:?})",
|
debug!("collect_drop_flags: {:?}, place {:?} ({:?})",
|
||||||
bb, location, path);
|
bb, location, path);
|
||||||
|
|
||||||
|
|
@ -399,7 +399,7 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
|
||||||
match terminator.kind {
|
match terminator.kind {
|
||||||
TerminatorKind::Drop { ref location, target, unwind } => {
|
TerminatorKind::Drop { ref location, target, unwind } => {
|
||||||
let init_data = self.initialization_data_at(loc);
|
let init_data = self.initialization_data_at(loc);
|
||||||
match self.move_data().rev_lookup.find(location.as_place_ref()) {
|
match self.move_data().rev_lookup.find(location.as_ref()) {
|
||||||
LookupResult::Exact(path) => {
|
LookupResult::Exact(path) => {
|
||||||
elaborate_drop(
|
elaborate_drop(
|
||||||
&mut Elaborator {
|
&mut Elaborator {
|
||||||
|
|
@ -488,7 +488,7 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
|
||||||
is_cleanup: false,
|
is_cleanup: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
match self.move_data().rev_lookup.find(location.as_place_ref()) {
|
match self.move_data().rev_lookup.find(location.as_ref()) {
|
||||||
LookupResult::Exact(path) => {
|
LookupResult::Exact(path) => {
|
||||||
debug!("elaborate_drop_and_replace({:?}) - tracked {:?}", terminator, path);
|
debug!("elaborate_drop_and_replace({:?}) - tracked {:?}", terminator, path);
|
||||||
let init_data = self.initialization_data_at(loc);
|
let init_data = self.initialization_data_at(loc);
|
||||||
|
|
@ -558,7 +558,7 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
|
||||||
assert!(!self.patch.is_patched(bb));
|
assert!(!self.patch.is_patched(bb));
|
||||||
|
|
||||||
let loc = Location { block: tgt, statement_index: 0 };
|
let loc = Location { block: tgt, statement_index: 0 };
|
||||||
let path = self.move_data().rev_lookup.find(place.as_place_ref());
|
let path = self.move_data().rev_lookup.find(place.as_ref());
|
||||||
on_lookup_result_bits(
|
on_lookup_result_bits(
|
||||||
self.tcx, self.body, self.move_data(), path,
|
self.tcx, self.body, self.move_data(), path,
|
||||||
|child| self.set_drop_flag(loc, child, DropFlagState::Present)
|
|child| self.set_drop_flag(loc, child, DropFlagState::Present)
|
||||||
|
|
@ -632,7 +632,7 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
|
||||||
assert!(!self.patch.is_patched(bb));
|
assert!(!self.patch.is_patched(bb));
|
||||||
|
|
||||||
let loc = Location { block: bb, statement_index: data.statements.len() };
|
let loc = Location { block: bb, statement_index: data.statements.len() };
|
||||||
let path = self.move_data().rev_lookup.find(place.as_place_ref());
|
let path = self.move_data().rev_lookup.find(place.as_ref());
|
||||||
on_lookup_result_bits(
|
on_lookup_result_bits(
|
||||||
self.tcx, self.body, self.move_data(), path,
|
self.tcx, self.body, self.move_data(), path,
|
||||||
|child| self.set_drop_flag(loc, child, DropFlagState::Present)
|
|child| self.set_drop_flag(loc, child, DropFlagState::Present)
|
||||||
|
|
|
||||||
|
|
@ -243,7 +243,7 @@ trait Qualif {
|
||||||
fn in_operand(cx: &ConstCx<'_, 'tcx>, operand: &Operand<'tcx>) -> bool {
|
fn in_operand(cx: &ConstCx<'_, 'tcx>, operand: &Operand<'tcx>) -> bool {
|
||||||
match *operand {
|
match *operand {
|
||||||
Operand::Copy(ref place) |
|
Operand::Copy(ref place) |
|
||||||
Operand::Move(ref place) => Self::in_place(cx, place.as_place_ref()),
|
Operand::Move(ref place) => Self::in_place(cx, place.as_ref()),
|
||||||
|
|
||||||
Operand::Constant(ref constant) => {
|
Operand::Constant(ref constant) => {
|
||||||
if let ConstValue::Unevaluated(def_id, _) = constant.literal.val {
|
if let ConstValue::Unevaluated(def_id, _) = constant.literal.val {
|
||||||
|
|
@ -272,7 +272,7 @@ trait Qualif {
|
||||||
Rvalue::NullaryOp(..) => false,
|
Rvalue::NullaryOp(..) => false,
|
||||||
|
|
||||||
Rvalue::Discriminant(ref place) |
|
Rvalue::Discriminant(ref place) |
|
||||||
Rvalue::Len(ref place) => Self::in_place(cx, place.as_place_ref()),
|
Rvalue::Len(ref place) => Self::in_place(cx, place.as_ref()),
|
||||||
|
|
||||||
Rvalue::Use(ref operand) |
|
Rvalue::Use(ref operand) |
|
||||||
Rvalue::Repeat(ref operand, _) |
|
Rvalue::Repeat(ref operand, _) |
|
||||||
|
|
@ -298,7 +298,7 @@ trait Qualif {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Self::in_place(cx, place.as_place_ref())
|
Self::in_place(cx, place.as_ref())
|
||||||
}
|
}
|
||||||
|
|
||||||
Rvalue::Aggregate(_, ref operands) => {
|
Rvalue::Aggregate(_, ref operands) => {
|
||||||
|
|
|
||||||
|
|
@ -168,7 +168,7 @@ fn each_block<'tcx, O>(
|
||||||
if place == peek_arg_place {
|
if place == peek_arg_place {
|
||||||
if let mir::Rvalue::Ref(_, mir::BorrowKind::Shared, ref peeking_at_place) = **rvalue {
|
if let mir::Rvalue::Ref(_, mir::BorrowKind::Shared, ref peeking_at_place) = **rvalue {
|
||||||
// Okay, our search is over.
|
// Okay, our search is over.
|
||||||
match move_data.rev_lookup.find(peeking_at_place.as_place_ref()) {
|
match move_data.rev_lookup.find(peeking_at_place.as_ref()) {
|
||||||
LookupResult::Exact(peek_mpi) => {
|
LookupResult::Exact(peek_mpi) => {
|
||||||
let bit_state = on_entry.contains(peek_mpi);
|
let bit_state = on_entry.contains(peek_mpi);
|
||||||
debug!("rustc_peek({:?} = &{:?}) bit_state: {}",
|
debug!("rustc_peek({:?} = &{:?}) bit_state: {}",
|
||||||
|
|
@ -192,7 +192,7 @@ fn each_block<'tcx, O>(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let lhs_mpi = move_data.rev_lookup.find(place.as_place_ref());
|
let lhs_mpi = move_data.rev_lookup.find(place.as_ref());
|
||||||
|
|
||||||
debug!("rustc_peek: computing effect on place: {:?} ({:?}) in stmt: {:?}",
|
debug!("rustc_peek: computing effect on place: {:?} ({:?}) in stmt: {:?}",
|
||||||
place, lhs_mpi, stmt);
|
place, lhs_mpi, stmt);
|
||||||
|
|
|
||||||
|
|
@ -5,8 +5,7 @@ pub fn target() -> TargetResult {
|
||||||
base.cpu = "x86-64".to_string();
|
base.cpu = "x86-64".to_string();
|
||||||
base.max_atomic_width = Some(64);
|
base.max_atomic_width = Some(64);
|
||||||
base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-mx32".to_string());
|
base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-mx32".to_string());
|
||||||
// BUG: temporarily workaround #59674
|
base.stack_probes = true;
|
||||||
base.stack_probes = false;
|
|
||||||
base.has_elf_tls = false;
|
base.has_elf_tls = false;
|
||||||
// BUG(GabrielMajeri): disabling the PLT on x86_64 Linux with x32 ABI
|
// BUG(GabrielMajeri): disabling the PLT on x86_64 Linux with x32 ABI
|
||||||
// breaks code gen. See LLVM bug 36743
|
// breaks code gen. See LLVM bug 36743
|
||||||
|
|
|
||||||
|
|
@ -1650,7 +1650,10 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
Applicability::MaybeIncorrect,
|
Applicability::MaybeIncorrect,
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
err.span_label(span, format!("variant not found in `{}`", qself_ty));
|
err.span_label(
|
||||||
|
assoc_ident.span,
|
||||||
|
format!("variant not found in `{}`", qself_ty),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(sp) = tcx.hir().span_if_local(adt_def.did) {
|
if let Some(sp) = tcx.hir().span_if_local(adt_def.did) {
|
||||||
|
|
|
||||||
|
|
@ -759,40 +759,40 @@ fn adt_destructor(tcx: TyCtxt<'_>, def_id: DefId) -> Option<ty::Destructor> {
|
||||||
fn primary_body_of(
|
fn primary_body_of(
|
||||||
tcx: TyCtxt<'_>,
|
tcx: TyCtxt<'_>,
|
||||||
id: hir::HirId,
|
id: hir::HirId,
|
||||||
) -> Option<(hir::BodyId, Option<&hir::FnHeader>, Option<&hir::FnDecl>)> {
|
) -> Option<(hir::BodyId, Option<&hir::Ty>, Option<&hir::FnHeader>, Option<&hir::FnDecl>)> {
|
||||||
match tcx.hir().get(id) {
|
match tcx.hir().get(id) {
|
||||||
Node::Item(item) => {
|
Node::Item(item) => {
|
||||||
match item.node {
|
match item.node {
|
||||||
hir::ItemKind::Const(_, body) |
|
hir::ItemKind::Const(ref ty, body) |
|
||||||
hir::ItemKind::Static(_, _, body) =>
|
hir::ItemKind::Static(ref ty, _, body) =>
|
||||||
Some((body, None, None)),
|
Some((body, Some(ty), None, None)),
|
||||||
hir::ItemKind::Fn(ref decl, ref header, .., body) =>
|
hir::ItemKind::Fn(ref decl, ref header, .., body) =>
|
||||||
Some((body, Some(header), Some(decl))),
|
Some((body, None, Some(header), Some(decl))),
|
||||||
_ =>
|
_ =>
|
||||||
None,
|
None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Node::TraitItem(item) => {
|
Node::TraitItem(item) => {
|
||||||
match item.node {
|
match item.node {
|
||||||
hir::TraitItemKind::Const(_, Some(body)) =>
|
hir::TraitItemKind::Const(ref ty, Some(body)) =>
|
||||||
Some((body, None, None)),
|
Some((body, Some(ty), None, None)),
|
||||||
hir::TraitItemKind::Method(ref sig, hir::TraitMethod::Provided(body)) =>
|
hir::TraitItemKind::Method(ref sig, hir::TraitMethod::Provided(body)) =>
|
||||||
Some((body, Some(&sig.header), Some(&sig.decl))),
|
Some((body, None, Some(&sig.header), Some(&sig.decl))),
|
||||||
_ =>
|
_ =>
|
||||||
None,
|
None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Node::ImplItem(item) => {
|
Node::ImplItem(item) => {
|
||||||
match item.node {
|
match item.node {
|
||||||
hir::ImplItemKind::Const(_, body) =>
|
hir::ImplItemKind::Const(ref ty, body) =>
|
||||||
Some((body, None, None)),
|
Some((body, Some(ty), None, None)),
|
||||||
hir::ImplItemKind::Method(ref sig, body) =>
|
hir::ImplItemKind::Method(ref sig, body) =>
|
||||||
Some((body, Some(&sig.header), Some(&sig.decl))),
|
Some((body, None, Some(&sig.header), Some(&sig.decl))),
|
||||||
_ =>
|
_ =>
|
||||||
None,
|
None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Node::AnonConst(constant) => Some((constant.body, None, None)),
|
Node::AnonConst(constant) => Some((constant.body, None, None, None)),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -825,7 +825,7 @@ fn typeck_tables_of(tcx: TyCtxt<'_>, def_id: DefId) -> &ty::TypeckTables<'_> {
|
||||||
let span = tcx.hir().span(id);
|
let span = tcx.hir().span(id);
|
||||||
|
|
||||||
// Figure out what primary body this item has.
|
// Figure out what primary body this item has.
|
||||||
let (body_id, fn_header, fn_decl) = primary_body_of(tcx, id)
|
let (body_id, body_ty, fn_header, fn_decl) = primary_body_of(tcx, id)
|
||||||
.unwrap_or_else(|| {
|
.unwrap_or_else(|| {
|
||||||
span_bug!(span, "can't type-check body of {:?}", def_id);
|
span_bug!(span, "can't type-check body of {:?}", def_id);
|
||||||
});
|
});
|
||||||
|
|
@ -856,7 +856,10 @@ fn typeck_tables_of(tcx: TyCtxt<'_>, def_id: DefId) -> &ty::TypeckTables<'_> {
|
||||||
fcx
|
fcx
|
||||||
} else {
|
} else {
|
||||||
let fcx = FnCtxt::new(&inh, param_env, body.value.hir_id);
|
let fcx = FnCtxt::new(&inh, param_env, body.value.hir_id);
|
||||||
let expected_type = tcx.type_of(def_id);
|
let expected_type = body_ty.and_then(|ty| match ty.node {
|
||||||
|
hir::TyKind::Infer => Some(AstConv::ast_ty_to_ty(&fcx, ty)),
|
||||||
|
_ => None
|
||||||
|
}).unwrap_or_else(|| tcx.type_of(def_id));
|
||||||
let expected_type = fcx.normalize_associated_types_in(body.value.span, &expected_type);
|
let expected_type = fcx.normalize_associated_types_in(body.value.span, &expected_type);
|
||||||
fcx.require_type_is_sized(expected_type, body.value.span, traits::ConstSized);
|
fcx.require_type_is_sized(expected_type, body.value.span, traits::ConstSized);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1135,6 +1135,26 @@ fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
|
||||||
checked_type_of(tcx, def_id, true).unwrap()
|
checked_type_of(tcx, def_id, true).unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn infer_placeholder_type(
|
||||||
|
tcx: TyCtxt<'_>,
|
||||||
|
def_id: DefId,
|
||||||
|
body_id: hir::BodyId,
|
||||||
|
span: Span,
|
||||||
|
) -> Ty<'_> {
|
||||||
|
let ty = tcx.typeck_tables_of(def_id).node_type(body_id.hir_id);
|
||||||
|
let mut diag = bad_placeholder_type(tcx, span);
|
||||||
|
if ty != tcx.types.err {
|
||||||
|
diag.span_suggestion(
|
||||||
|
span,
|
||||||
|
"replace `_` with the correct type",
|
||||||
|
ty.to_string(),
|
||||||
|
Applicability::MaybeIncorrect,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
diag.emit();
|
||||||
|
ty
|
||||||
|
}
|
||||||
|
|
||||||
/// Same as [`type_of`] but returns [`Option`] instead of failing.
|
/// Same as [`type_of`] but returns [`Option`] instead of failing.
|
||||||
///
|
///
|
||||||
/// If you want to fail anyway, you can set the `fail` parameter to true, but in this case,
|
/// If you want to fail anyway, you can set the `fail` parameter to true, but in this case,
|
||||||
|
|
@ -1160,7 +1180,16 @@ pub fn checked_type_of(tcx: TyCtxt<'_>, def_id: DefId, fail: bool) -> Option<Ty<
|
||||||
let substs = InternalSubsts::identity_for_item(tcx, def_id);
|
let substs = InternalSubsts::identity_for_item(tcx, def_id);
|
||||||
tcx.mk_fn_def(def_id, substs)
|
tcx.mk_fn_def(def_id, substs)
|
||||||
}
|
}
|
||||||
TraitItemKind::Const(ref ty, _) | TraitItemKind::Type(_, Some(ref ty)) => icx.to_ty(ty),
|
TraitItemKind::Const(ref ty, body_id) => {
|
||||||
|
body_id.and_then(|body_id| {
|
||||||
|
if let hir::TyKind::Infer = ty.node {
|
||||||
|
Some(infer_placeholder_type(tcx, def_id, body_id, ty.span))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}).unwrap_or_else(|| icx.to_ty(ty))
|
||||||
|
},
|
||||||
|
TraitItemKind::Type(_, Some(ref ty)) => icx.to_ty(ty),
|
||||||
TraitItemKind::Type(_, None) => {
|
TraitItemKind::Type(_, None) => {
|
||||||
if !fail {
|
if !fail {
|
||||||
return None;
|
return None;
|
||||||
|
|
@ -1174,7 +1203,13 @@ pub fn checked_type_of(tcx: TyCtxt<'_>, def_id: DefId, fail: bool) -> Option<Ty<
|
||||||
let substs = InternalSubsts::identity_for_item(tcx, def_id);
|
let substs = InternalSubsts::identity_for_item(tcx, def_id);
|
||||||
tcx.mk_fn_def(def_id, substs)
|
tcx.mk_fn_def(def_id, substs)
|
||||||
}
|
}
|
||||||
ImplItemKind::Const(ref ty, _) => icx.to_ty(ty),
|
ImplItemKind::Const(ref ty, body_id) => {
|
||||||
|
if let hir::TyKind::Infer = ty.node {
|
||||||
|
infer_placeholder_type(tcx, def_id, body_id, ty.span)
|
||||||
|
} else {
|
||||||
|
icx.to_ty(ty)
|
||||||
|
}
|
||||||
|
},
|
||||||
ImplItemKind::Existential(_) => {
|
ImplItemKind::Existential(_) => {
|
||||||
if tcx
|
if tcx
|
||||||
.impl_trait_ref(tcx.hir().get_parent_did(hir_id))
|
.impl_trait_ref(tcx.hir().get_parent_did(hir_id))
|
||||||
|
|
@ -1199,10 +1234,16 @@ pub fn checked_type_of(tcx: TyCtxt<'_>, def_id: DefId, fail: bool) -> Option<Ty<
|
||||||
|
|
||||||
Node::Item(item) => {
|
Node::Item(item) => {
|
||||||
match item.node {
|
match item.node {
|
||||||
ItemKind::Static(ref t, ..)
|
ItemKind::Static(ref ty, .., body_id)
|
||||||
| ItemKind::Const(ref t, _)
|
| ItemKind::Const(ref ty, body_id) => {
|
||||||
| ItemKind::Ty(ref t, _)
|
if let hir::TyKind::Infer = ty.node {
|
||||||
| ItemKind::Impl(.., ref t, _) => icx.to_ty(t),
|
infer_placeholder_type(tcx, def_id, body_id, ty.span)
|
||||||
|
} else {
|
||||||
|
icx.to_ty(ty)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
ItemKind::Ty(ref ty, _)
|
||||||
|
| ItemKind::Impl(.., ref ty, _) => icx.to_ty(ty),
|
||||||
ItemKind::Fn(..) => {
|
ItemKind::Fn(..) => {
|
||||||
let substs = InternalSubsts::identity_for_item(tcx, def_id);
|
let substs = InternalSubsts::identity_for_item(tcx, def_id);
|
||||||
tcx.mk_fn_def(def_id, substs)
|
tcx.mk_fn_def(def_id, substs)
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@
|
||||||
#![feature(inner_deref)]
|
#![feature(inner_deref)]
|
||||||
#![feature(never_type)]
|
#![feature(never_type)]
|
||||||
#![feature(mem_take)]
|
#![feature(mem_take)]
|
||||||
|
#![feature(unicode_internals)]
|
||||||
|
|
||||||
#![recursion_limit="256"]
|
#![recursion_limit="256"]
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -126,6 +126,9 @@ declare_features! (
|
||||||
|
|
||||||
// no-tracking-issue-start
|
// no-tracking-issue-start
|
||||||
|
|
||||||
|
// Allows using compiler's own crates.
|
||||||
|
(active, rustc_private, "1.0.0", Some(27812), None),
|
||||||
|
|
||||||
// Allows using the `rust-intrinsic`'s "ABI".
|
// Allows using the `rust-intrinsic`'s "ABI".
|
||||||
(active, intrinsics, "1.0.0", None, None),
|
(active, intrinsics, "1.0.0", None, None),
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ use crate::ast::{
|
||||||
self, Arg, BinOpKind, BindingMode, BlockCheckMode, Expr, ExprKind, Ident, Item, ItemKind,
|
self, Arg, BinOpKind, BindingMode, BlockCheckMode, Expr, ExprKind, Ident, Item, ItemKind,
|
||||||
Mutability, Pat, PatKind, PathSegment, QSelf, Ty, TyKind, VariantData,
|
Mutability, Pat, PatKind, PathSegment, QSelf, Ty, TyKind, VariantData,
|
||||||
};
|
};
|
||||||
|
use crate::feature_gate::{feature_err, UnstableFeatures};
|
||||||
use crate::parse::{SeqSep, PResult, Parser, ParseSess};
|
use crate::parse::{SeqSep, PResult, Parser, ParseSess};
|
||||||
use crate::parse::parser::{BlockMode, PathStyle, SemiColonMode, TokenType, TokenExpectType};
|
use crate::parse::parser::{BlockMode, PathStyle, SemiColonMode, TokenType, TokenExpectType};
|
||||||
use crate::parse::token::{self, TokenKind};
|
use crate::parse::token::{self, TokenKind};
|
||||||
|
|
@ -326,8 +327,8 @@ impl<'a> Parser<'a> {
|
||||||
self.token.is_keyword(kw::Return) ||
|
self.token.is_keyword(kw::Return) ||
|
||||||
self.token.is_keyword(kw::While)
|
self.token.is_keyword(kw::While)
|
||||||
);
|
);
|
||||||
let cm = self.sess.source_map();
|
let sm = self.sess.source_map();
|
||||||
match (cm.lookup_line(self.token.span.lo()), cm.lookup_line(sp.lo())) {
|
match (sm.lookup_line(self.token.span.lo()), sm.lookup_line(sp.lo())) {
|
||||||
(Ok(ref a), Ok(ref b)) if a.line != b.line && is_semi_suggestable => {
|
(Ok(ref a), Ok(ref b)) if a.line != b.line && is_semi_suggestable => {
|
||||||
// The spans are in different lines, expected `;` and found `let` or `return`.
|
// The spans are in different lines, expected `;` and found `let` or `return`.
|
||||||
// High likelihood that it is only a missing `;`.
|
// High likelihood that it is only a missing `;`.
|
||||||
|
|
@ -365,9 +366,53 @@ impl<'a> Parser<'a> {
|
||||||
err.span_label(self.token.span, "unexpected token");
|
err.span_label(self.token.span, "unexpected token");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
self.maybe_annotate_with_ascription(&mut err, false);
|
||||||
Err(err)
|
Err(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn maybe_annotate_with_ascription(
|
||||||
|
&self,
|
||||||
|
err: &mut DiagnosticBuilder<'_>,
|
||||||
|
maybe_expected_semicolon: bool,
|
||||||
|
) {
|
||||||
|
if let Some((sp, likely_path)) = self.last_type_ascription {
|
||||||
|
let sm = self.sess.source_map();
|
||||||
|
let next_pos = sm.lookup_char_pos(self.token.span.lo());
|
||||||
|
let op_pos = sm.lookup_char_pos(sp.hi());
|
||||||
|
|
||||||
|
if likely_path {
|
||||||
|
err.span_suggestion(
|
||||||
|
sp,
|
||||||
|
"maybe write a path separator here",
|
||||||
|
"::".to_string(),
|
||||||
|
match self.sess.unstable_features {
|
||||||
|
UnstableFeatures::Disallow => Applicability::MachineApplicable,
|
||||||
|
_ => Applicability::MaybeIncorrect,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
} else if op_pos.line != next_pos.line && maybe_expected_semicolon {
|
||||||
|
err.span_suggestion(
|
||||||
|
sp,
|
||||||
|
"try using a semicolon",
|
||||||
|
";".to_string(),
|
||||||
|
Applicability::MaybeIncorrect,
|
||||||
|
);
|
||||||
|
} else if let UnstableFeatures::Disallow = self.sess.unstable_features {
|
||||||
|
err.span_label(sp, "tried to parse a type due to this");
|
||||||
|
} else {
|
||||||
|
err.span_label(sp, "tried to parse a type due to this type ascription");
|
||||||
|
}
|
||||||
|
if let UnstableFeatures::Disallow = self.sess.unstable_features {
|
||||||
|
// Give extra information about type ascription only if it's a nightly compiler.
|
||||||
|
} else {
|
||||||
|
err.note("`#![feature(type_ascription)]` lets you annotate an expression with a \
|
||||||
|
type: `<expr>: <type>`");
|
||||||
|
err.note("for more information, see \
|
||||||
|
https://github.com/rust-lang/rust/issues/23416");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Eats and discards tokens until one of `kets` is encountered. Respects token trees,
|
/// Eats and discards tokens until one of `kets` is encountered. Respects token trees,
|
||||||
/// passes through any errors encountered. Used for error recovery.
|
/// passes through any errors encountered. Used for error recovery.
|
||||||
crate fn eat_to_tokens(&mut self, kets: &[&TokenKind]) {
|
crate fn eat_to_tokens(&mut self, kets: &[&TokenKind]) {
|
||||||
|
|
@ -556,7 +601,7 @@ impl<'a> Parser<'a> {
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
if !discriminant_spans.is_empty() && has_fields {
|
if !discriminant_spans.is_empty() && has_fields {
|
||||||
let mut err = crate::feature_gate::feature_err(
|
let mut err = feature_err(
|
||||||
sess,
|
sess,
|
||||||
sym::arbitrary_enum_discriminant,
|
sym::arbitrary_enum_discriminant,
|
||||||
discriminant_spans.clone(),
|
discriminant_spans.clone(),
|
||||||
|
|
@ -769,8 +814,8 @@ impl<'a> Parser<'a> {
|
||||||
return Ok(recovered);
|
return Ok(recovered);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let cm = self.sess.source_map();
|
let sm = self.sess.source_map();
|
||||||
match (cm.lookup_line(prev_sp.lo()), cm.lookup_line(sp.lo())) {
|
match (sm.lookup_line(prev_sp.lo()), sm.lookup_line(sp.lo())) {
|
||||||
(Ok(ref a), Ok(ref b)) if a.line == b.line => {
|
(Ok(ref a), Ok(ref b)) if a.line == b.line => {
|
||||||
// When the spans are in the same line, it means that the only content
|
// When the spans are in the same line, it means that the only content
|
||||||
// between them is whitespace, point only at the found token.
|
// between them is whitespace, point only at the found token.
|
||||||
|
|
@ -887,47 +932,9 @@ impl<'a> Parser<'a> {
|
||||||
self.look_ahead(2, |t| t.is_ident()) ||
|
self.look_ahead(2, |t| t.is_ident()) ||
|
||||||
self.look_ahead(1, |t| t == &token::Colon) && // `foo:bar:baz`
|
self.look_ahead(1, |t| t == &token::Colon) && // `foo:bar:baz`
|
||||||
self.look_ahead(2, |t| t.is_ident()) ||
|
self.look_ahead(2, |t| t.is_ident()) ||
|
||||||
self.look_ahead(1, |t| t == &token::ModSep) && // `foo:bar::baz`
|
self.look_ahead(1, |t| t == &token::ModSep) &&
|
||||||
self.look_ahead(2, |t| t.is_ident())
|
(self.look_ahead(2, |t| t.is_ident()) || // `foo:bar::baz`
|
||||||
}
|
self.look_ahead(2, |t| t == &token::Lt)) // `foo:bar::<baz>`
|
||||||
|
|
||||||
crate fn bad_type_ascription(
|
|
||||||
&self,
|
|
||||||
err: &mut DiagnosticBuilder<'a>,
|
|
||||||
lhs_span: Span,
|
|
||||||
cur_op_span: Span,
|
|
||||||
next_sp: Span,
|
|
||||||
maybe_path: bool,
|
|
||||||
) {
|
|
||||||
err.span_label(self.token.span, "expecting a type here because of type ascription");
|
|
||||||
let cm = self.sess.source_map();
|
|
||||||
let next_pos = cm.lookup_char_pos(next_sp.lo());
|
|
||||||
let op_pos = cm.lookup_char_pos(cur_op_span.hi());
|
|
||||||
if op_pos.line != next_pos.line {
|
|
||||||
err.span_suggestion(
|
|
||||||
cur_op_span,
|
|
||||||
"try using a semicolon",
|
|
||||||
";".to_string(),
|
|
||||||
Applicability::MaybeIncorrect,
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
if maybe_path {
|
|
||||||
err.span_suggestion(
|
|
||||||
cur_op_span,
|
|
||||||
"maybe you meant to write a path separator here",
|
|
||||||
"::".to_string(),
|
|
||||||
Applicability::MaybeIncorrect,
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
err.note("`#![feature(type_ascription)]` lets you annotate an \
|
|
||||||
expression with a type: `<expr>: <type>`")
|
|
||||||
.span_note(
|
|
||||||
lhs_span,
|
|
||||||
"this expression expects an ascribed type after the colon",
|
|
||||||
)
|
|
||||||
.help("this might be indicative of a syntax error elsewhere");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
crate fn recover_seq_parse_error(
|
crate fn recover_seq_parse_error(
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,12 @@
|
||||||
use crate::parse::ParseSess;
|
use crate::parse::ParseSess;
|
||||||
use crate::parse::token::{self, Token, TokenKind};
|
use crate::parse::token::{self, Token, TokenKind};
|
||||||
use crate::symbol::{sym, Symbol};
|
use crate::symbol::{sym, Symbol};
|
||||||
use crate::parse::unescape;
|
|
||||||
use crate::parse::unescape_error_reporting::{emit_unescape_error, push_escaped_char};
|
use crate::parse::unescape_error_reporting::{emit_unescape_error, push_escaped_char};
|
||||||
|
|
||||||
use errors::{FatalError, Diagnostic, DiagnosticBuilder};
|
use errors::{FatalError, Diagnostic, DiagnosticBuilder};
|
||||||
use syntax_pos::{BytePos, Pos, Span, NO_EXPANSION};
|
use syntax_pos::{BytePos, Pos, Span, NO_EXPANSION};
|
||||||
use rustc_lexer::Base;
|
use rustc_lexer::Base;
|
||||||
|
use rustc_lexer::unescape;
|
||||||
|
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
use std::char;
|
use std::char;
|
||||||
|
|
|
||||||
|
|
@ -4,9 +4,6 @@ use crate::ast::{self, Lit, LitKind};
|
||||||
use crate::parse::parser::Parser;
|
use crate::parse::parser::Parser;
|
||||||
use crate::parse::PResult;
|
use crate::parse::PResult;
|
||||||
use crate::parse::token::{self, Token, TokenKind};
|
use crate::parse::token::{self, Token, TokenKind};
|
||||||
use crate::parse::unescape::{unescape_char, unescape_byte};
|
|
||||||
use crate::parse::unescape::{unescape_str, unescape_byte_str};
|
|
||||||
use crate::parse::unescape::{unescape_raw_str, unescape_raw_byte_str};
|
|
||||||
use crate::print::pprust;
|
use crate::print::pprust;
|
||||||
use crate::symbol::{kw, sym, Symbol};
|
use crate::symbol::{kw, sym, Symbol};
|
||||||
use crate::tokenstream::{TokenStream, TokenTree};
|
use crate::tokenstream::{TokenStream, TokenTree};
|
||||||
|
|
@ -15,6 +12,9 @@ use errors::{Applicability, Handler};
|
||||||
use log::debug;
|
use log::debug;
|
||||||
use rustc_data_structures::sync::Lrc;
|
use rustc_data_structures::sync::Lrc;
|
||||||
use syntax_pos::Span;
|
use syntax_pos::Span;
|
||||||
|
use rustc_lexer::unescape::{unescape_char, unescape_byte};
|
||||||
|
use rustc_lexer::unescape::{unescape_str, unescape_byte_str};
|
||||||
|
use rustc_lexer::unescape::{unescape_raw_str, unescape_raw_byte_str};
|
||||||
|
|
||||||
use std::ascii;
|
use std::ascii;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,6 @@ pub mod token;
|
||||||
crate mod classify;
|
crate mod classify;
|
||||||
crate mod diagnostics;
|
crate mod diagnostics;
|
||||||
crate mod literal;
|
crate mod literal;
|
||||||
crate mod unescape;
|
|
||||||
crate mod unescape_error_reporting;
|
crate mod unescape_error_reporting;
|
||||||
|
|
||||||
/// Info about a parsing session.
|
/// Info about a parsing session.
|
||||||
|
|
|
||||||
|
|
@ -239,6 +239,7 @@ pub struct Parser<'a> {
|
||||||
/// error.
|
/// error.
|
||||||
crate unclosed_delims: Vec<UnmatchedBrace>,
|
crate unclosed_delims: Vec<UnmatchedBrace>,
|
||||||
crate last_unexpected_token_span: Option<Span>,
|
crate last_unexpected_token_span: Option<Span>,
|
||||||
|
crate last_type_ascription: Option<(Span, bool /* likely path typo */)>,
|
||||||
/// If present, this `Parser` is not parsing Rust code but rather a macro call.
|
/// If present, this `Parser` is not parsing Rust code but rather a macro call.
|
||||||
crate subparser_name: Option<&'static str>,
|
crate subparser_name: Option<&'static str>,
|
||||||
}
|
}
|
||||||
|
|
@ -502,6 +503,7 @@ impl<'a> Parser<'a> {
|
||||||
max_angle_bracket_count: 0,
|
max_angle_bracket_count: 0,
|
||||||
unclosed_delims: Vec::new(),
|
unclosed_delims: Vec::new(),
|
||||||
last_unexpected_token_span: None,
|
last_unexpected_token_span: None,
|
||||||
|
last_type_ascription: None,
|
||||||
subparser_name,
|
subparser_name,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -1422,7 +1424,10 @@ impl<'a> Parser<'a> {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let msg = format!("expected type, found {}", self.this_token_descr());
|
let msg = format!("expected type, found {}", self.this_token_descr());
|
||||||
return Err(self.fatal(&msg));
|
let mut err = self.fatal(&msg);
|
||||||
|
err.span_label(self.token.span, "expected type");
|
||||||
|
self.maybe_annotate_with_ascription(&mut err, true);
|
||||||
|
return Err(err);
|
||||||
};
|
};
|
||||||
|
|
||||||
let span = lo.to(self.prev_span);
|
let span = lo.to(self.prev_span);
|
||||||
|
|
@ -2823,10 +2828,11 @@ impl<'a> Parser<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parses an associative expression with operators of at least `min_prec` precedence.
|
/// Parses an associative expression with operators of at least `min_prec` precedence.
|
||||||
fn parse_assoc_expr_with(&mut self,
|
fn parse_assoc_expr_with(
|
||||||
min_prec: usize,
|
&mut self,
|
||||||
lhs: LhsExpr)
|
min_prec: usize,
|
||||||
-> PResult<'a, P<Expr>> {
|
lhs: LhsExpr,
|
||||||
|
) -> PResult<'a, P<Expr>> {
|
||||||
let mut lhs = if let LhsExpr::AlreadyParsed(expr) = lhs {
|
let mut lhs = if let LhsExpr::AlreadyParsed(expr) = lhs {
|
||||||
expr
|
expr
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -2840,9 +2846,11 @@ impl<'a> Parser<'a> {
|
||||||
self.parse_prefix_expr(attrs)?
|
self.parse_prefix_expr(attrs)?
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
let last_type_ascription_set = self.last_type_ascription.is_some();
|
||||||
|
|
||||||
match (self.expr_is_complete(&lhs), AssocOp::from_token(&self.token)) {
|
match (self.expr_is_complete(&lhs), AssocOp::from_token(&self.token)) {
|
||||||
(true, None) => {
|
(true, None) => {
|
||||||
|
self.last_type_ascription = None;
|
||||||
// Semi-statement forms are odd. See https://github.com/rust-lang/rust/issues/29071
|
// Semi-statement forms are odd. See https://github.com/rust-lang/rust/issues/29071
|
||||||
return Ok(lhs);
|
return Ok(lhs);
|
||||||
}
|
}
|
||||||
|
|
@ -2857,12 +2865,14 @@ impl<'a> Parser<'a> {
|
||||||
// If the next token is a keyword, then the tokens above *are* unambiguously incorrect:
|
// If the next token is a keyword, then the tokens above *are* unambiguously incorrect:
|
||||||
// `if x { a } else { b } && if y { c } else { d }`
|
// `if x { a } else { b } && if y { c } else { d }`
|
||||||
if !self.look_ahead(1, |t| t.is_reserved_ident()) => {
|
if !self.look_ahead(1, |t| t.is_reserved_ident()) => {
|
||||||
|
self.last_type_ascription = None;
|
||||||
// These cases are ambiguous and can't be identified in the parser alone
|
// These cases are ambiguous and can't be identified in the parser alone
|
||||||
let sp = self.sess.source_map().start_point(self.token.span);
|
let sp = self.sess.source_map().start_point(self.token.span);
|
||||||
self.sess.ambiguous_block_expr_parse.borrow_mut().insert(sp, lhs.span);
|
self.sess.ambiguous_block_expr_parse.borrow_mut().insert(sp, lhs.span);
|
||||||
return Ok(lhs);
|
return Ok(lhs);
|
||||||
}
|
}
|
||||||
(true, Some(ref op)) if !op.can_continue_expr_unambiguously() => {
|
(true, Some(ref op)) if !op.can_continue_expr_unambiguously() => {
|
||||||
|
self.last_type_ascription = None;
|
||||||
return Ok(lhs);
|
return Ok(lhs);
|
||||||
}
|
}
|
||||||
(true, Some(_)) => {
|
(true, Some(_)) => {
|
||||||
|
|
@ -2921,21 +2931,9 @@ impl<'a> Parser<'a> {
|
||||||
continue
|
continue
|
||||||
} else if op == AssocOp::Colon {
|
} else if op == AssocOp::Colon {
|
||||||
let maybe_path = self.could_ascription_be_path(&lhs.node);
|
let maybe_path = self.could_ascription_be_path(&lhs.node);
|
||||||
let next_sp = self.token.span;
|
self.last_type_ascription = Some((self.prev_span, maybe_path));
|
||||||
|
|
||||||
lhs = match self.parse_assoc_op_cast(lhs, lhs_span, ExprKind::Type) {
|
lhs = self.parse_assoc_op_cast(lhs, lhs_span, ExprKind::Type)?;
|
||||||
Ok(lhs) => lhs,
|
|
||||||
Err(mut err) => {
|
|
||||||
self.bad_type_ascription(
|
|
||||||
&mut err,
|
|
||||||
lhs_span,
|
|
||||||
cur_op_span,
|
|
||||||
next_sp,
|
|
||||||
maybe_path,
|
|
||||||
);
|
|
||||||
return Err(err);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
continue
|
continue
|
||||||
} else if op == AssocOp::DotDot || op == AssocOp::DotDotEq {
|
} else if op == AssocOp::DotDot || op == AssocOp::DotDotEq {
|
||||||
// If we didn’t have to handle `x..`/`x..=`, it would be pretty easy to
|
// If we didn’t have to handle `x..`/`x..=`, it would be pretty easy to
|
||||||
|
|
@ -3020,6 +3018,9 @@ impl<'a> Parser<'a> {
|
||||||
|
|
||||||
if let Fixity::None = fixity { break }
|
if let Fixity::None = fixity { break }
|
||||||
}
|
}
|
||||||
|
if last_type_ascription_set {
|
||||||
|
self.last_type_ascription = None;
|
||||||
|
}
|
||||||
Ok(lhs)
|
Ok(lhs)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,12 +3,11 @@
|
||||||
use std::ops::Range;
|
use std::ops::Range;
|
||||||
use std::iter::once;
|
use std::iter::once;
|
||||||
|
|
||||||
|
use rustc_lexer::unescape::{EscapeError, Mode};
|
||||||
use syntax_pos::{Span, BytePos};
|
use syntax_pos::{Span, BytePos};
|
||||||
|
|
||||||
use crate::errors::{Handler, Applicability};
|
use crate::errors::{Handler, Applicability};
|
||||||
|
|
||||||
use super::unescape::{EscapeError, Mode};
|
|
||||||
|
|
||||||
pub(crate) fn emit_unescape_error(
|
pub(crate) fn emit_unescape_error(
|
||||||
handler: &Handler,
|
handler: &Handler,
|
||||||
// interior part of the literal, without quotes
|
// interior part of the literal, without quotes
|
||||||
|
|
|
||||||
|
|
@ -141,7 +141,10 @@ fn parse_args<'a>(
|
||||||
|
|
||||||
while p.token != token::Eof {
|
while p.token != token::Eof {
|
||||||
if !p.eat(&token::Comma) {
|
if !p.eat(&token::Comma) {
|
||||||
return Err(ecx.struct_span_err(p.token.span, "expected token: `,`"));
|
let mut err = ecx.struct_span_err(p.token.span, "expected token: `,`");
|
||||||
|
err.span_label(p.token.span, "expected `,`");
|
||||||
|
p.maybe_annotate_with_ascription(&mut err, false);
|
||||||
|
return Err(err);
|
||||||
}
|
}
|
||||||
if p.token == token::Eof {
|
if p.token == token::Eof {
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@
|
||||||
#![feature(decl_macro)]
|
#![feature(decl_macro)]
|
||||||
#![feature(nll)]
|
#![feature(nll)]
|
||||||
#![feature(rustc_diagnostic_macros)]
|
#![feature(rustc_diagnostic_macros)]
|
||||||
|
#![feature(unicode_internals)]
|
||||||
|
|
||||||
#![recursion_limit="256"]
|
#![recursion_limit="256"]
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -25,9 +25,9 @@ cargo: beta
|
||||||
#
|
#
|
||||||
# This means that there's a small window of time (a few days) where artifacts
|
# This means that there's a small window of time (a few days) where artifacts
|
||||||
# are downloaded from dev-static.rust-lang.org instead of static.rust-lang.org.
|
# are downloaded from dev-static.rust-lang.org instead of static.rust-lang.org.
|
||||||
# In order to ease this transition we have an extra key is in this configuration
|
# In order to ease this transition we have an extra key which is in the
|
||||||
# file below. When uncommented this will instruct the bootstrap.py script to
|
# configuration file below. When uncommented this will instruct the bootstrap.py
|
||||||
# download from dev-static.rust-lang.org.
|
# script to download from dev-static.rust-lang.org.
|
||||||
#
|
#
|
||||||
# This key is typically commented out at all times. If you're looking at a
|
# This key is typically commented out at all times. If you're looking at a
|
||||||
# stable release tarball it should *definitely* be commented out. If you're
|
# stable release tarball it should *definitely* be commented out. If you're
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,6 @@ use std::alloc::System;
|
||||||
static A: System = System;
|
static A: System = System;
|
||||||
#[global_allocator]
|
#[global_allocator]
|
||||||
static B: System = System;
|
static B: System = System;
|
||||||
//~^ ERROR: cannot define more than one #[global_allocator]
|
//~^ ERROR: cannot define more than one `#[global_allocator]`
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
error: cannot define more than one #[global_allocator]
|
error: cannot define more than one `#[global_allocator]`
|
||||||
--> $DIR/two-allocators.rs:6:1
|
--> $DIR/two-allocators.rs:6:1
|
||||||
|
|
|
|
||||||
LL | static B: System = System;
|
LL | static B: System = System;
|
||||||
|
|
|
||||||
|
|
@ -10,13 +10,13 @@ error: expected token: `,`
|
||||||
--> $DIR/bad-format-args.rs:3:16
|
--> $DIR/bad-format-args.rs:3:16
|
||||||
|
|
|
|
||||||
LL | format!("" 1);
|
LL | format!("" 1);
|
||||||
| ^
|
| ^ expected `,`
|
||||||
|
|
||||||
error: expected token: `,`
|
error: expected token: `,`
|
||||||
--> $DIR/bad-format-args.rs:4:19
|
--> $DIR/bad-format-args.rs:4:19
|
||||||
|
|
|
|
||||||
LL | format!("", 1 1);
|
LL | format!("", 1 1);
|
||||||
| ^
|
| ^ expected `,`
|
||||||
|
|
||||||
error: aborting due to 3 previous errors
|
error: aborting due to 3 previous errors
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,10 @@ error[E0121]: the type placeholder `_` is not allowed within types on item signa
|
||||||
--> $DIR/E0121.rs:3:13
|
--> $DIR/E0121.rs:3:13
|
||||||
|
|
|
|
||||||
LL | static BAR: _ = "test";
|
LL | static BAR: _ = "test";
|
||||||
| ^ not allowed in type signatures
|
| ^
|
||||||
|
| |
|
||||||
|
| not allowed in type signatures
|
||||||
|
| help: replace `_` with the correct type: `&'static str`
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
|
|
||||||
23
src/test/ui/existential-type/issue-58887.rs
Normal file
23
src/test/ui/existential-type/issue-58887.rs
Normal file
|
|
@ -0,0 +1,23 @@
|
||||||
|
#![feature(existential_type)]
|
||||||
|
|
||||||
|
trait UnwrapItemsExt {
|
||||||
|
type Iter;
|
||||||
|
fn unwrap_items(self) -> Self::Iter;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<I, T, E> UnwrapItemsExt for I
|
||||||
|
where
|
||||||
|
I: Iterator<Item = Result<T, E>>,
|
||||||
|
E: std::fmt::Debug,
|
||||||
|
{
|
||||||
|
existential type Iter: Iterator<Item = T>;
|
||||||
|
//~^ ERROR: could not find defining uses
|
||||||
|
|
||||||
|
fn unwrap_items(self) -> Self::Iter {
|
||||||
|
//~^ ERROR: type parameter `T` is part of concrete type
|
||||||
|
//~| ERROR: type parameter `E` is part of concrete type
|
||||||
|
self.map(|x| x.unwrap())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
||||||
30
src/test/ui/existential-type/issue-58887.stderr
Normal file
30
src/test/ui/existential-type/issue-58887.stderr
Normal file
|
|
@ -0,0 +1,30 @@
|
||||||
|
error: type parameter `T` is part of concrete type but not used in parameter list for existential type
|
||||||
|
--> $DIR/issue-58887.rs:16:41
|
||||||
|
|
|
||||||
|
LL | fn unwrap_items(self) -> Self::Iter {
|
||||||
|
| _________________________________________^
|
||||||
|
LL | |
|
||||||
|
LL | |
|
||||||
|
LL | | self.map(|x| x.unwrap())
|
||||||
|
LL | | }
|
||||||
|
| |_____^
|
||||||
|
|
||||||
|
error: type parameter `E` is part of concrete type but not used in parameter list for existential type
|
||||||
|
--> $DIR/issue-58887.rs:16:41
|
||||||
|
|
|
||||||
|
LL | fn unwrap_items(self) -> Self::Iter {
|
||||||
|
| _________________________________________^
|
||||||
|
LL | |
|
||||||
|
LL | |
|
||||||
|
LL | | self.map(|x| x.unwrap())
|
||||||
|
LL | | }
|
||||||
|
| |_____^
|
||||||
|
|
||||||
|
error: could not find defining uses
|
||||||
|
--> $DIR/issue-58887.rs:13:5
|
||||||
|
|
|
||||||
|
LL | existential type Iter: Iterator<Item = T>;
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: aborting due to 3 previous errors
|
||||||
|
|
||||||
5
src/test/ui/feature-gate/rustc-private.rs
Normal file
5
src/test/ui/feature-gate/rustc-private.rs
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
// gate-test-rustc_private
|
||||||
|
|
||||||
|
extern crate libc; //~ ERROR use of unstable library feature 'rustc_private'
|
||||||
|
|
||||||
|
fn main() {}
|
||||||
12
src/test/ui/feature-gate/rustc-private.stderr
Normal file
12
src/test/ui/feature-gate/rustc-private.stderr
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
error[E0658]: use of unstable library feature 'rustc_private': this crate is being loaded from the sysroot, an unstable location; did you mean to load this crate from crates.io via `Cargo.toml` instead?
|
||||||
|
--> $DIR/rustc-private.rs:3:1
|
||||||
|
|
|
||||||
|
LL | extern crate libc;
|
||||||
|
| ^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: for more information, see https://github.com/rust-lang/rust/issues/27812
|
||||||
|
= help: add `#![feature(rustc_private)]` to the crate attributes to enable
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0658`.
|
||||||
50
src/test/ui/hrtb/issue-62203-hrtb-ice.rs
Normal file
50
src/test/ui/hrtb/issue-62203-hrtb-ice.rs
Normal file
|
|
@ -0,0 +1,50 @@
|
||||||
|
trait T0<'a, A> {
|
||||||
|
type O;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct L<T> {
|
||||||
|
f: T,
|
||||||
|
}
|
||||||
|
|
||||||
|
// explicitly named variants of what one would normally denote by the
|
||||||
|
// unit type `()`. Why do this? So that we can differentiate them in
|
||||||
|
// the diagnostic output.
|
||||||
|
struct Unit1;
|
||||||
|
struct Unit2;
|
||||||
|
struct Unit3;
|
||||||
|
struct Unit4;
|
||||||
|
|
||||||
|
impl<'a, A, T> T0<'a, A> for L<T>
|
||||||
|
where
|
||||||
|
T: FnMut(A) -> Unit3,
|
||||||
|
{
|
||||||
|
type O = T::Output;
|
||||||
|
}
|
||||||
|
|
||||||
|
trait T1: for<'r> Ty<'r> {
|
||||||
|
fn m<'a, B: Ty<'a>, F>(&self, f: F) -> Unit1
|
||||||
|
where
|
||||||
|
F: for<'r> T0<'r, (<Self as Ty<'r>>::V,), O = <B as Ty<'r>>::V>,
|
||||||
|
{
|
||||||
|
unimplemented!();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
trait Ty<'a> {
|
||||||
|
type V;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let v = Unit2.m(
|
||||||
|
//~^ ERROR type mismatch
|
||||||
|
//~| ERROR type mismatch
|
||||||
|
L {
|
||||||
|
f : |x| { drop(x); Unit4 }
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Ty<'a> for Unit2 {
|
||||||
|
type V = &'a u8;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl T1 for Unit2 {}
|
||||||
22
src/test/ui/hrtb/issue-62203-hrtb-ice.stderr
Normal file
22
src/test/ui/hrtb/issue-62203-hrtb-ice.stderr
Normal file
|
|
@ -0,0 +1,22 @@
|
||||||
|
error[E0271]: type mismatch resolving `for<'r> <L<[closure@$DIR/issue-62203-hrtb-ice.rs:42:17: 42:39]> as T0<'r, (<Unit2 as Ty<'r>>::V,)>>::O == <_ as Ty<'r>>::V`
|
||||||
|
--> $DIR/issue-62203-hrtb-ice.rs:38:19
|
||||||
|
|
|
||||||
|
LL | let v = Unit2.m(
|
||||||
|
| ^ expected struct `Unit4`, found associated type
|
||||||
|
|
|
||||||
|
= note: expected type `Unit4`
|
||||||
|
found type `<_ as Ty<'_>>::V`
|
||||||
|
|
||||||
|
error[E0271]: type mismatch resolving `<[closure@$DIR/issue-62203-hrtb-ice.rs:42:17: 42:39] as std::ops::FnOnce<((&u8,),)>>::Output == Unit3`
|
||||||
|
--> $DIR/issue-62203-hrtb-ice.rs:38:19
|
||||||
|
|
|
||||||
|
LL | let v = Unit2.m(
|
||||||
|
| ^ expected struct `Unit4`, found struct `Unit3`
|
||||||
|
|
|
||||||
|
= note: expected type `Unit4`
|
||||||
|
found type `Unit3`
|
||||||
|
= note: required because of the requirements on the impl of `for<'r> T0<'r, (<Unit2 as Ty<'r>>::V,)>` for `L<[closure@$DIR/issue-62203-hrtb-ice.rs:42:17: 42:39]>`
|
||||||
|
|
||||||
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0271`.
|
||||||
|
|
@ -87,15 +87,12 @@ error: expected type, found `4`
|
||||||
--> $DIR/issue-22644.rs:34:28
|
--> $DIR/issue-22644.rs:34:28
|
||||||
|
|
|
|
||||||
LL | println!("{}", a: &mut 4);
|
LL | println!("{}", a: &mut 4);
|
||||||
| ^ expecting a type here because of type ascription
|
| - ^ expected type
|
||||||
|
| |
|
||||||
|
| tried to parse a type due to this type ascription
|
||||||
|
|
|
|
||||||
= note: `#![feature(type_ascription)]` lets you annotate an expression with a type: `<expr>: <type>`
|
= note: `#![feature(type_ascription)]` lets you annotate an expression with a type: `<expr>: <type>`
|
||||||
note: this expression expects an ascribed type after the colon
|
= note: for more information, see https://github.com/rust-lang/rust/issues/23416
|
||||||
--> $DIR/issue-22644.rs:34:20
|
|
||||||
|
|
|
||||||
LL | println!("{}", a: &mut 4);
|
|
||||||
| ^
|
|
||||||
= help: this might be indicative of a syntax error elsewhere
|
|
||||||
|
|
||||||
error: aborting due to 9 previous errors
|
error: aborting due to 9 previous errors
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,15 +2,12 @@ error: expected type, found `42`
|
||||||
--> $DIR/issue-34255-1.rs:8:24
|
--> $DIR/issue-34255-1.rs:8:24
|
||||||
|
|
|
|
||||||
LL | Test::Drill(field: 42);
|
LL | Test::Drill(field: 42);
|
||||||
| ^^ expecting a type here because of type ascription
|
| - ^^ expected type
|
||||||
|
| |
|
||||||
|
| tried to parse a type due to this type ascription
|
||||||
|
|
|
|
||||||
= note: `#![feature(type_ascription)]` lets you annotate an expression with a type: `<expr>: <type>`
|
= note: `#![feature(type_ascription)]` lets you annotate an expression with a type: `<expr>: <type>`
|
||||||
note: this expression expects an ascribed type after the colon
|
= note: for more information, see https://github.com/rust-lang/rust/issues/23416
|
||||||
--> $DIR/issue-34255-1.rs:8:17
|
|
||||||
|
|
|
||||||
LL | Test::Drill(field: 42);
|
|
||||||
| ^^^^^
|
|
||||||
= help: this might be indicative of a syntax error elsewhere
|
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ error: expected type, found `0`
|
||||||
--> $DIR/issue-39616.rs:1:12
|
--> $DIR/issue-39616.rs:1:12
|
||||||
|
|
|
|
||||||
LL | fn foo(a: [0; 1]) {}
|
LL | fn foo(a: [0; 1]) {}
|
||||||
| ^
|
| ^ expected type
|
||||||
|
|
||||||
error: expected one of `)`, `,`, `->`, `where`, or `{`, found `]`
|
error: expected one of `)`, `,`, `->`, `where`, or `{`, found `]`
|
||||||
--> $DIR/issue-39616.rs:1:16
|
--> $DIR/issue-39616.rs:1:16
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,10 @@ LL | bar(baz: $rest)
|
||||||
| - help: try using a semicolon: `;`
|
| - help: try using a semicolon: `;`
|
||||||
...
|
...
|
||||||
LL | foo!(true);
|
LL | foo!(true);
|
||||||
| ^^^^ expecting a type here because of type ascription
|
| ^^^^ expected type
|
||||||
|
|
|
||||||
|
= note: `#![feature(type_ascription)]` lets you annotate an expression with a type: `<expr>: <type>`
|
||||||
|
= note: for more information, see https://github.com/rust-lang/rust/issues/23416
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -12,15 +12,12 @@ error: expected type, found keyword `loop`
|
||||||
--> $DIR/lifetime_starts_expressions.rs:6:26
|
--> $DIR/lifetime_starts_expressions.rs:6:26
|
||||||
|
|
|
|
||||||
LL | loop { break 'label: loop { break 'label 42; }; }
|
LL | loop { break 'label: loop { break 'label 42; }; }
|
||||||
| ^^^^ expecting a type here because of type ascription
|
| - ^^^^ expected type
|
||||||
|
| |
|
||||||
|
| tried to parse a type due to this type ascription
|
||||||
|
|
|
|
||||||
= note: `#![feature(type_ascription)]` lets you annotate an expression with a type: `<expr>: <type>`
|
= note: `#![feature(type_ascription)]` lets you annotate an expression with a type: `<expr>: <type>`
|
||||||
note: this expression expects an ascribed type after the colon
|
= note: for more information, see https://github.com/rust-lang/rust/issues/23416
|
||||||
--> $DIR/lifetime_starts_expressions.rs:6:12
|
|
||||||
|
|
|
||||||
LL | loop { break 'label: loop { break 'label 42; }; }
|
|
||||||
| ^^^^^^^^^^^^
|
|
||||||
= help: this might be indicative of a syntax error elsewhere
|
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ error: expected token: `,`
|
||||||
--> $DIR/missing-comma.rs:19:19
|
--> $DIR/missing-comma.rs:19:19
|
||||||
|
|
|
|
||||||
LL | println!("{}" a);
|
LL | println!("{}" a);
|
||||||
| ^
|
| ^ expected `,`
|
||||||
|
|
||||||
error: no rules expected the token `b`
|
error: no rules expected the token `b`
|
||||||
--> $DIR/missing-comma.rs:21:12
|
--> $DIR/missing-comma.rs:21:12
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ error: expected type, found `{`
|
||||||
--> $DIR/issue-33262.rs:4:22
|
--> $DIR/issue-33262.rs:4:22
|
||||||
|
|
|
|
||||||
LL | for i in 0..a as { }
|
LL | for i in 0..a as { }
|
||||||
| ^
|
| ^ expected type
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ error: expected type, found `'static`
|
||||||
--> $DIR/trait-object-macro-matcher.rs:9:8
|
--> $DIR/trait-object-macro-matcher.rs:9:8
|
||||||
|
|
|
|
||||||
LL | m!('static);
|
LL | m!('static);
|
||||||
| ^^^^^^^
|
| ^^^^^^^ expected type
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ error: expected type, found `{`
|
||||||
--> $DIR/recover-enum2.rs:6:18
|
--> $DIR/recover-enum2.rs:6:18
|
||||||
|
|
|
|
||||||
LL | abc: {},
|
LL | abc: {},
|
||||||
| ^
|
| ^ expected type
|
||||||
|
|
||||||
error: expected one of `!`, `(`, `)`, `+`, `,`, `::`, or `<`, found `{`
|
error: expected one of `!`, `(`, `)`, `+`, `,`, `::`, or `<`, found `{`
|
||||||
--> $DIR/recover-enum2.rs:25:22
|
--> $DIR/recover-enum2.rs:25:22
|
||||||
|
|
|
||||||
|
|
@ -2,15 +2,12 @@ error: expected type, found `3`
|
||||||
--> $DIR/recover-from-bad-variant.rs:7:26
|
--> $DIR/recover-from-bad-variant.rs:7:26
|
||||||
|
|
|
|
||||||
LL | let x = Enum::Foo(a: 3, b: 4);
|
LL | let x = Enum::Foo(a: 3, b: 4);
|
||||||
| ^ expecting a type here because of type ascription
|
| - ^ expected type
|
||||||
|
| |
|
||||||
|
| tried to parse a type due to this type ascription
|
||||||
|
|
|
|
||||||
= note: `#![feature(type_ascription)]` lets you annotate an expression with a type: `<expr>: <type>`
|
= note: `#![feature(type_ascription)]` lets you annotate an expression with a type: `<expr>: <type>`
|
||||||
note: this expression expects an ascribed type after the colon
|
= note: for more information, see https://github.com/rust-lang/rust/issues/23416
|
||||||
--> $DIR/recover-from-bad-variant.rs:7:23
|
|
||||||
|
|
|
||||||
LL | let x = Enum::Foo(a: 3, b: 4);
|
|
||||||
| ^
|
|
||||||
= help: this might be indicative of a syntax error elsewhere
|
|
||||||
|
|
||||||
error[E0532]: expected tuple struct/variant, found struct variant `Enum::Foo`
|
error[E0532]: expected tuple struct/variant, found struct variant `Enum::Foo`
|
||||||
--> $DIR/recover-from-bad-variant.rs:10:9
|
--> $DIR/recover-from-bad-variant.rs:10:9
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ error: expected type, found keyword `mut`
|
||||||
--> $DIR/removed-syntax-mut-vec-ty.rs:1:11
|
--> $DIR/removed-syntax-mut-vec-ty.rs:1:11
|
||||||
|
|
|
|
||||||
LL | type v = [mut isize];
|
LL | type v = [mut isize];
|
||||||
| ^^^
|
| ^^^ expected type
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ error: expected type, found `{`
|
||||||
--> $DIR/removed-syntax-record.rs:1:10
|
--> $DIR/removed-syntax-record.rs:1:10
|
||||||
|
|
|
|
||||||
LL | type t = { f: () };
|
LL | type t = { f: () };
|
||||||
| ^
|
| ^ expected type
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@ error: expected type, found `'a`
|
||||||
--> $DIR/trait-object-lifetime-parens.rs:9:17
|
--> $DIR/trait-object-lifetime-parens.rs:9:17
|
||||||
|
|
|
|
||||||
LL | let _: Box<('a) + Trait>;
|
LL | let _: Box<('a) + Trait>;
|
||||||
| - ^^
|
| - ^^ expected type
|
||||||
| |
|
| |
|
||||||
| while parsing the type for `_`
|
| while parsing the type for `_`
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -23,9 +23,7 @@ LL | enum Shape {
|
||||||
| ---------- variant `Rombus` not found here
|
| ---------- variant `Rombus` not found here
|
||||||
...
|
...
|
||||||
LL | println!("My shape is {:?}", Shape::Rombus{ size: 5});
|
LL | println!("My shape is {:?}", Shape::Rombus{ size: 5});
|
||||||
| -------^^^^^^
|
| ^^^^^^ variant not found in `Shape`
|
||||||
| |
|
|
||||||
| variant not found in `Shape`
|
|
||||||
|
|
||||||
error[E0599]: no variant or associated item named `Squareee` found for type `Shape` in the current scope
|
error[E0599]: no variant or associated item named `Squareee` found for type `Shape` in the current scope
|
||||||
--> $DIR/suggest-variants.rs:15:12
|
--> $DIR/suggest-variants.rs:15:12
|
||||||
|
|
|
||||||
|
|
@ -2,9 +2,12 @@ error: expected type, found `"foo"`
|
||||||
--> $DIR/type-ascription-instead-of-method.rs:2:13
|
--> $DIR/type-ascription-instead-of-method.rs:2:13
|
||||||
|
|
|
|
||||||
LL | Box:new("foo".to_string())
|
LL | Box:new("foo".to_string())
|
||||||
| - ^^^^^ expecting a type here because of type ascription
|
| - ^^^^^ expected type
|
||||||
| |
|
| |
|
||||||
| help: maybe you meant to write a path separator here: `::`
|
| help: maybe write a path separator here: `::`
|
||||||
|
|
|
||||||
|
= note: `#![feature(type_ascription)]` lets you annotate an expression with a type: `<expr>: <type>`
|
||||||
|
= note: for more information, see https://github.com/rust-lang/rust/issues/23416
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,9 +2,12 @@ error: expected type, found `""`
|
||||||
--> $DIR/type-ascription-instead-of-variant.rs:2:25
|
--> $DIR/type-ascription-instead-of-variant.rs:2:25
|
||||||
|
|
|
|
||||||
LL | let _ = Option:Some("");
|
LL | let _ = Option:Some("");
|
||||||
| - ^^ expecting a type here because of type ascription
|
| - ^^ expected type
|
||||||
| |
|
| |
|
||||||
| help: maybe you meant to write a path separator here: `::`
|
| help: maybe write a path separator here: `::`
|
||||||
|
|
|
||||||
|
= note: `#![feature(type_ascription)]` lets you annotate an expression with a type: `<expr>: <type>`
|
||||||
|
= note: for more information, see https://github.com/rust-lang/rust/issues/23416
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
|
|
||||||
15
src/test/ui/type/ascription/issue-34255-1.rs
Normal file
15
src/test/ui/type/ascription/issue-34255-1.rs
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
struct Reactor {
|
||||||
|
input_cells: Vec<usize>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Reactor {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
input_cells: Vec::new()
|
||||||
|
//~^ ERROR cannot find value `input_cells` in this scope
|
||||||
|
//~| ERROR parenthesized type parameters may only be used with a `Fn` trait
|
||||||
|
//~| ERROR wrong number of type arguments: expected 1, found 0
|
||||||
|
//~| WARNING this was previously accepted by the compiler but is being phased out
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// This case isn't currently being handled gracefully, including for completeness.
|
||||||
30
src/test/ui/type/ascription/issue-34255-1.stderr
Normal file
30
src/test/ui/type/ascription/issue-34255-1.stderr
Normal file
|
|
@ -0,0 +1,30 @@
|
||||||
|
error[E0425]: cannot find value `input_cells` in this scope
|
||||||
|
--> $DIR/issue-34255-1.rs:7:9
|
||||||
|
|
|
||||||
|
LL | input_cells: Vec::new()
|
||||||
|
| ^^^^^^^^^^^ a field by this name exists in `Self`
|
||||||
|
|
||||||
|
error: parenthesized type parameters may only be used with a `Fn` trait
|
||||||
|
--> $DIR/issue-34255-1.rs:7:30
|
||||||
|
|
|
||||||
|
LL | input_cells: Vec::new()
|
||||||
|
| ^^
|
||||||
|
|
|
||||||
|
= note: `#[deny(parenthesized_params_in_types_and_modules)]` on by default
|
||||||
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||||
|
= note: for more information, see issue #42238 <https://github.com/rust-lang/rust/issues/42238>
|
||||||
|
|
||||||
|
error[E0601]: `main` function not found in crate `issue_34255_1`
|
||||||
|
|
|
||||||
|
= note: consider adding a `main` function to `$DIR/issue-34255-1.rs`
|
||||||
|
|
||||||
|
error[E0107]: wrong number of type arguments: expected 1, found 0
|
||||||
|
--> $DIR/issue-34255-1.rs:7:22
|
||||||
|
|
|
||||||
|
LL | input_cells: Vec::new()
|
||||||
|
| ^^^^^^^^^^ expected 1 type argument
|
||||||
|
|
||||||
|
error: aborting due to 4 previous errors
|
||||||
|
|
||||||
|
Some errors have detailed explanations: E0107, E0425, E0601.
|
||||||
|
For more information about an error, try `rustc --explain E0107`.
|
||||||
5
src/test/ui/type/ascription/issue-47666.rs
Normal file
5
src/test/ui/type/ascription/issue-47666.rs
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
fn main() {
|
||||||
|
let _ = Option:Some(vec![0, 1]); //~ ERROR expected type, found
|
||||||
|
}
|
||||||
|
|
||||||
|
// This case isn't currently being handled gracefully due to the macro invocation.
|
||||||
13
src/test/ui/type/ascription/issue-47666.stderr
Normal file
13
src/test/ui/type/ascription/issue-47666.stderr
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
error: expected type, found reserved keyword `box`
|
||||||
|
--> $DIR/issue-47666.rs:2:25
|
||||||
|
|
|
||||||
|
LL | let _ = Option:Some(vec![0, 1]);
|
||||||
|
| ^^^^^^^^^^
|
||||||
|
| |
|
||||||
|
| expected type
|
||||||
|
| in this macro invocation
|
||||||
|
|
|
||||||
|
= note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
||||||
6
src/test/ui/type/ascription/issue-54516.rs
Normal file
6
src/test/ui/type/ascription/issue-54516.rs
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
use std::collections::BTreeMap;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
println!("{}", std::mem:size_of::<BTreeMap<u32, u32>>());
|
||||||
|
//~^ ERROR expected token: `,`
|
||||||
|
}
|
||||||
13
src/test/ui/type/ascription/issue-54516.stderr
Normal file
13
src/test/ui/type/ascription/issue-54516.stderr
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
error: expected token: `,`
|
||||||
|
--> $DIR/issue-54516.rs:4:58
|
||||||
|
|
|
||||||
|
LL | println!("{}", std::mem:size_of::<BTreeMap<u32, u32>>());
|
||||||
|
| - ^ expected `,`
|
||||||
|
| |
|
||||||
|
| help: maybe write a path separator here: `::`
|
||||||
|
|
|
||||||
|
= note: `#![feature(type_ascription)]` lets you annotate an expression with a type: `<expr>: <type>`
|
||||||
|
= note: for more information, see https://github.com/rust-lang/rust/issues/23416
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
||||||
4
src/test/ui/type/ascription/issue-60933.rs
Normal file
4
src/test/ui/type/ascription/issue-60933.rs
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
fn main() {
|
||||||
|
let u: usize = std::mem:size_of::<u32>();
|
||||||
|
//~^ ERROR expected one of
|
||||||
|
}
|
||||||
13
src/test/ui/type/ascription/issue-60933.stderr
Normal file
13
src/test/ui/type/ascription/issue-60933.stderr
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
error: expected one of `!`, `::`, or `;`, found `(`
|
||||||
|
--> $DIR/issue-60933.rs:2:43
|
||||||
|
|
|
||||||
|
LL | let u: usize = std::mem:size_of::<u32>();
|
||||||
|
| - ^ expected one of `!`, `::`, or `;` here
|
||||||
|
| |
|
||||||
|
| help: maybe write a path separator here: `::`
|
||||||
|
|
|
||||||
|
= note: `#![feature(type_ascription)]` lets you annotate an expression with a type: `<expr>: <type>`
|
||||||
|
= note: for more information, see https://github.com/rust-lang/rust/issues/23416
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
|
@ -2,7 +2,7 @@ error: expected type, found `10`
|
||||||
--> $DIR/type-ascription-instead-of-initializer.rs:2:31
|
--> $DIR/type-ascription-instead-of-initializer.rs:2:31
|
||||||
|
|
|
|
||||||
LL | let x: Vec::with_capacity(10, 20);
|
LL | let x: Vec::with_capacity(10, 20);
|
||||||
| -- ^^
|
| -- ^^ expected type
|
||||||
| ||
|
| ||
|
||||||
| |help: use `=` if you meant to assign
|
| |help: use `=` if you meant to assign
|
||||||
| while parsing the type for `x`
|
| while parsing the type for `x`
|
||||||
|
|
|
||||||
|
|
@ -4,21 +4,21 @@ error: expected type, found `0`
|
||||||
LL | println!("test"):
|
LL | println!("test"):
|
||||||
| - help: try using a semicolon: `;`
|
| - help: try using a semicolon: `;`
|
||||||
LL | 0;
|
LL | 0;
|
||||||
| ^ expecting a type here because of type ascription
|
| ^ expected type
|
||||||
|
|
|
||||||
|
= note: `#![feature(type_ascription)]` lets you annotate an expression with a type: `<expr>: <type>`
|
||||||
|
= note: for more information, see https://github.com/rust-lang/rust/issues/23416
|
||||||
|
|
||||||
error: expected type, found `0`
|
error: expected type, found `0`
|
||||||
--> $DIR/type-ascription-instead-of-statement-end.rs:9:23
|
--> $DIR/type-ascription-instead-of-statement-end.rs:9:23
|
||||||
|
|
|
|
||||||
LL | println!("test"): 0;
|
LL | println!("test"): 0;
|
||||||
| ^ expecting a type here because of type ascription
|
| - ^ expected type
|
||||||
|
| |
|
||||||
|
| tried to parse a type due to this type ascription
|
||||||
|
|
|
|
||||||
= note: `#![feature(type_ascription)]` lets you annotate an expression with a type: `<expr>: <type>`
|
= note: `#![feature(type_ascription)]` lets you annotate an expression with a type: `<expr>: <type>`
|
||||||
note: this expression expects an ascribed type after the colon
|
= note: for more information, see https://github.com/rust-lang/rust/issues/23416
|
||||||
--> $DIR/type-ascription-instead-of-statement-end.rs:9:5
|
|
||||||
|
|
|
||||||
LL | println!("test"): 0;
|
|
||||||
| ^^^^^^^^^^^^^^^^
|
|
||||||
= help: this might be indicative of a syntax error elsewhere
|
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -23,13 +23,19 @@ error[E0121]: the type placeholder `_` is not allowed within types on item signa
|
||||||
--> $DIR/typeck_type_placeholder_item.rs:11:15
|
--> $DIR/typeck_type_placeholder_item.rs:11:15
|
||||||
|
|
|
|
||||||
LL | static TEST3: _ = "test";
|
LL | static TEST3: _ = "test";
|
||||||
| ^ not allowed in type signatures
|
| ^
|
||||||
|
| |
|
||||||
|
| not allowed in type signatures
|
||||||
|
| help: replace `_` with the correct type: `&'static str`
|
||||||
|
|
||||||
error[E0121]: the type placeholder `_` is not allowed within types on item signatures
|
error[E0121]: the type placeholder `_` is not allowed within types on item signatures
|
||||||
--> $DIR/typeck_type_placeholder_item.rs:14:15
|
--> $DIR/typeck_type_placeholder_item.rs:14:15
|
||||||
|
|
|
|
||||||
LL | static TEST4: _ = 145;
|
LL | static TEST4: _ = 145;
|
||||||
| ^ not allowed in type signatures
|
| ^
|
||||||
|
| |
|
||||||
|
| not allowed in type signatures
|
||||||
|
| help: replace `_` with the correct type: `i32`
|
||||||
|
|
||||||
error[E0121]: the type placeholder `_` is not allowed within types on item signatures
|
error[E0121]: the type placeholder `_` is not allowed within types on item signatures
|
||||||
--> $DIR/typeck_type_placeholder_item.rs:17:16
|
--> $DIR/typeck_type_placeholder_item.rs:17:16
|
||||||
|
|
@ -122,13 +128,19 @@ error[E0121]: the type placeholder `_` is not allowed within types on item signa
|
||||||
--> $DIR/typeck_type_placeholder_item.rs:64:22
|
--> $DIR/typeck_type_placeholder_item.rs:64:22
|
||||||
|
|
|
|
||||||
LL | static FN_TEST3: _ = "test";
|
LL | static FN_TEST3: _ = "test";
|
||||||
| ^ not allowed in type signatures
|
| ^
|
||||||
|
| |
|
||||||
|
| not allowed in type signatures
|
||||||
|
| help: replace `_` with the correct type: `&'static str`
|
||||||
|
|
||||||
error[E0121]: the type placeholder `_` is not allowed within types on item signatures
|
error[E0121]: the type placeholder `_` is not allowed within types on item signatures
|
||||||
--> $DIR/typeck_type_placeholder_item.rs:67:22
|
--> $DIR/typeck_type_placeholder_item.rs:67:22
|
||||||
|
|
|
|
||||||
LL | static FN_TEST4: _ = 145;
|
LL | static FN_TEST4: _ = 145;
|
||||||
| ^ not allowed in type signatures
|
| ^
|
||||||
|
| |
|
||||||
|
| not allowed in type signatures
|
||||||
|
| help: replace `_` with the correct type: `i32`
|
||||||
|
|
||||||
error[E0121]: the type placeholder `_` is not allowed within types on item signatures
|
error[E0121]: the type placeholder `_` is not allowed within types on item signatures
|
||||||
--> $DIR/typeck_type_placeholder_item.rs:70:23
|
--> $DIR/typeck_type_placeholder_item.rs:70:23
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,24 @@
|
||||||
fn test1() -> _ { Some(42) }
|
fn test1() -> _ { Some(42) }
|
||||||
//~^ ERROR the type placeholder `_` is not allowed within types on item signatures
|
//~^ ERROR the type placeholder `_` is not allowed within types on item signatures
|
||||||
|
|
||||||
|
const TEST2: _ = 42u32;
|
||||||
|
//~^ ERROR the type placeholder `_` is not allowed within types on item signatures
|
||||||
|
|
||||||
|
const TEST3: _ = Some(42);
|
||||||
|
//~^ ERROR the type placeholder `_` is not allowed within types on item signatures
|
||||||
|
|
||||||
|
trait Test4 {
|
||||||
|
const TEST4: _ = 42;
|
||||||
|
//~^ ERROR the type placeholder `_` is not allowed within types on item signatures
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Test5;
|
||||||
|
|
||||||
|
impl Test5 {
|
||||||
|
const TEST5: _ = 13;
|
||||||
|
//~^ ERROR the type placeholder `_` is not allowed within types on item signatures
|
||||||
|
}
|
||||||
|
|
||||||
pub fn main() {
|
pub fn main() {
|
||||||
let _: Option<usize> = test1();
|
let _: Option<usize> = test1();
|
||||||
let _: f64 = test1();
|
let _: f64 = test1();
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,42 @@ LL | fn test1() -> _ { Some(42) }
|
||||||
| not allowed in type signatures
|
| not allowed in type signatures
|
||||||
| help: replace `_` with the correct return type: `std::option::Option<i32>`
|
| help: replace `_` with the correct return type: `std::option::Option<i32>`
|
||||||
|
|
||||||
error: aborting due to previous error
|
error[E0121]: the type placeholder `_` is not allowed within types on item signatures
|
||||||
|
--> $DIR/typeck_type_placeholder_item_help.rs:7:14
|
||||||
|
|
|
||||||
|
LL | const TEST2: _ = 42u32;
|
||||||
|
| ^
|
||||||
|
| |
|
||||||
|
| not allowed in type signatures
|
||||||
|
| help: replace `_` with the correct type: `u32`
|
||||||
|
|
||||||
|
error[E0121]: the type placeholder `_` is not allowed within types on item signatures
|
||||||
|
--> $DIR/typeck_type_placeholder_item_help.rs:10:14
|
||||||
|
|
|
||||||
|
LL | const TEST3: _ = Some(42);
|
||||||
|
| ^
|
||||||
|
| |
|
||||||
|
| not allowed in type signatures
|
||||||
|
| help: replace `_` with the correct type: `std::option::Option<i32>`
|
||||||
|
|
||||||
|
error[E0121]: the type placeholder `_` is not allowed within types on item signatures
|
||||||
|
--> $DIR/typeck_type_placeholder_item_help.rs:14:18
|
||||||
|
|
|
||||||
|
LL | const TEST4: _ = 42;
|
||||||
|
| ^
|
||||||
|
| |
|
||||||
|
| not allowed in type signatures
|
||||||
|
| help: replace `_` with the correct type: `i32`
|
||||||
|
|
||||||
|
error[E0121]: the type placeholder `_` is not allowed within types on item signatures
|
||||||
|
--> $DIR/typeck_type_placeholder_item_help.rs:21:18
|
||||||
|
|
|
||||||
|
LL | const TEST5: _ = 13;
|
||||||
|
| ^
|
||||||
|
| |
|
||||||
|
| not allowed in type signatures
|
||||||
|
| help: replace `_` with the correct type: `i32`
|
||||||
|
|
||||||
|
error: aborting due to 5 previous errors
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0121`.
|
For more information about this error, try `rustc --explain E0121`.
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue