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:
bors 2019-07-23 19:50:46 +00:00
commit a7f28678bb
97 changed files with 777 additions and 377 deletions

View file

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

View file

@ -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)

View file

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

View file

@ -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::*;

View file

@ -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(

View file

@ -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) =>

View file

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

View file

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

View file

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

View file

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

View file

@ -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")
} }
} }
} }

View file

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

View file

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

View file

@ -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) => {

View file

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

View file

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

View file

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

View file

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

View file

@ -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(

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -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,
) { ) {

View file

@ -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,
) )

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -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!(),

View file

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

View file

@ -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!(),

View file

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

View file

@ -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");

View file

@ -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)

View file

@ -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) => {

View file

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

View file

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

View file

@ -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) {

View file

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

View file

@ -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)

View file

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

View file

@ -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),

View file

@ -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(

View file

@ -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;

View file

@ -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;

View file

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

View file

@ -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 didnt have to handle `x..`/`x..=`, it would be pretty easy to // If we didnt 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)
} }

View file

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

View file

@ -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;

View file

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

View file

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

View file

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

View file

@ -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;

View file

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

View file

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

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

View 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

View file

@ -0,0 +1,5 @@
// gate-test-rustc_private
extern crate libc; //~ ERROR use of unstable library feature 'rustc_private'
fn main() {}

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

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

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

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

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

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

View 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

View file

@ -0,0 +1,6 @@
use std::collections::BTreeMap;
fn main() {
println!("{}", std::mem:size_of::<BTreeMap<u32, u32>>());
//~^ ERROR expected token: `,`
}

View 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

View file

@ -0,0 +1,4 @@
fn main() {
let u: usize = std::mem:size_of::<u32>();
//~^ ERROR expected one of
}

View 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

View file

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

View file

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

View file

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

View file

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

View file

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