Skip to content

Rollup of 6 pull requests #40211

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 16 commits into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/libcollections/fmt.rs
Original file line number Diff line number Diff line change
@@ -524,6 +524,7 @@ use string;
pub fn format(args: Arguments) -> string::String {
let capacity = args.estimated_capacity();
let mut output = string::String::with_capacity(capacity);
let _ = output.write_fmt(args);
output.write_fmt(args)
.expect("a formatting trait implementation returned an error");
output
}
6 changes: 6 additions & 0 deletions src/libcollections/macros.rs
Original file line number Diff line number Diff line change
@@ -72,6 +72,12 @@ macro_rules! vec {
///
/// [fmt]: ../std/fmt/index.html
///
/// # Panics
///
/// `format!` panics if a formatting trait implementation returns an error.
/// This indicates an incorrect implementation
/// since `fmt::Write for String` never returns an error itself.
///
/// # Examples
///
/// ```
9 changes: 8 additions & 1 deletion src/libcollections/string.rs
Original file line number Diff line number Diff line change
@@ -1900,13 +1900,20 @@ pub trait ToString {
fn to_string(&self) -> String;
}

/// # Panics
///
/// In this implementation, the `to_string` method panics
/// if the `Display` implementation returns an error.
/// This indicates an incorrect `Display` implementation
/// since `fmt::Write for String` never returns an error itself.
#[stable(feature = "rust1", since = "1.0.0")]
impl<T: fmt::Display + ?Sized> ToString for T {
#[inline]
default fn to_string(&self) -> String {
use core::fmt::Write;
let mut buf = String::new();
let _ = buf.write_fmt(format_args!("{}", self));
buf.write_fmt(format_args!("{}", self))
.expect("a Display implementation return an error unexpectedly");
buf.shrink_to_fit();
buf
}
4 changes: 4 additions & 0 deletions src/libproc_macro/lib.rs
Original file line number Diff line number Diff line change
@@ -125,6 +125,10 @@ pub mod __internal {
fn register_attr_proc_macro(&mut self,
name: &str,
expand: fn(TokenStream, TokenStream) -> TokenStream);

fn register_bang_proc_macro(&mut self,
name: &str,
expand: fn(TokenStream) -> TokenStream);
}

// Emulate scoped_thread_local!() here essentially
20 changes: 4 additions & 16 deletions src/librustc/mir/mod.rs
Original file line number Diff line number Diff line change
@@ -983,7 +983,7 @@ pub enum Rvalue<'tcx> {
Use(Operand<'tcx>),

/// [x; 32]
Repeat(Operand<'tcx>, TypedConstVal<'tcx>),
Repeat(Operand<'tcx>, ConstUsize),

/// &x or &mut x
Ref(&'tcx Region, BorrowKind, Lvalue<'tcx>),
@@ -1038,7 +1038,8 @@ pub enum CastKind {

#[derive(Clone, Debug, PartialEq, Eq, RustcEncodable, RustcDecodable)]
pub enum AggregateKind<'tcx> {
Array,
/// The type is of the element
Array(Ty<'tcx>),
Tuple,
/// The second field is variant number (discriminant), it's equal to 0
/// for struct and union expressions. The fourth field is active field
@@ -1135,7 +1136,7 @@ impl<'tcx> Debug for Rvalue<'tcx> {
}

match *kind {
AggregateKind::Array => write!(fmt, "{:?}", lvs),
AggregateKind::Array(_) => write!(fmt, "{:?}", lvs),

AggregateKind::Tuple => {
match lvs.len() {
@@ -1202,19 +1203,6 @@ pub struct Constant<'tcx> {
pub literal: Literal<'tcx>,
}

#[derive(Clone, RustcEncodable, RustcDecodable)]
pub struct TypedConstVal<'tcx> {
pub ty: Ty<'tcx>,
pub span: Span,
pub value: ConstUsize,
}

impl<'tcx> Debug for TypedConstVal<'tcx> {
fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
write!(fmt, "const {}", ConstInt::Usize(self.value))
}
}

newtype_index!(Promoted, "promoted");

#[derive(Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
44 changes: 19 additions & 25 deletions src/librustc/mir/tcx.rs
Original file line number Diff line number Diff line change
@@ -134,76 +134,70 @@ impl<'tcx> Lvalue<'tcx> {
}

impl<'tcx> Rvalue<'tcx> {
pub fn ty<'a, 'gcx>(&self, mir: &Mir<'tcx>, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Option<Ty<'tcx>>
pub fn ty<'a, 'gcx>(&self, mir: &Mir<'tcx>, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Ty<'tcx>
{
match *self {
Rvalue::Use(ref operand) => Some(operand.ty(mir, tcx)),
Rvalue::Use(ref operand) => operand.ty(mir, tcx),
Rvalue::Repeat(ref operand, ref count) => {
let op_ty = operand.ty(mir, tcx);
let count = count.value.as_u64(tcx.sess.target.uint_type);
let count = count.as_u64(tcx.sess.target.uint_type);
assert_eq!(count as usize as u64, count);
Some(tcx.mk_array(op_ty, count as usize))
tcx.mk_array(op_ty, count as usize)
}
Rvalue::Ref(reg, bk, ref lv) => {
let lv_ty = lv.ty(mir, tcx).to_ty(tcx);
Some(tcx.mk_ref(reg,
tcx.mk_ref(reg,
ty::TypeAndMut {
ty: lv_ty,
mutbl: bk.to_mutbl_lossy()
}
))
)
}
Rvalue::Len(..) => Some(tcx.types.usize),
Rvalue::Cast(.., ty) => Some(ty),
Rvalue::Len(..) => tcx.types.usize,
Rvalue::Cast(.., ty) => ty,
Rvalue::BinaryOp(op, ref lhs, ref rhs) => {
let lhs_ty = lhs.ty(mir, tcx);
let rhs_ty = rhs.ty(mir, tcx);
Some(op.ty(tcx, lhs_ty, rhs_ty))
op.ty(tcx, lhs_ty, rhs_ty)
}
Rvalue::CheckedBinaryOp(op, ref lhs, ref rhs) => {
let lhs_ty = lhs.ty(mir, tcx);
let rhs_ty = rhs.ty(mir, tcx);
let ty = op.ty(tcx, lhs_ty, rhs_ty);
let ty = tcx.intern_tup(&[ty, tcx.types.bool], false);
Some(ty)
tcx.intern_tup(&[ty, tcx.types.bool], false)
}
Rvalue::UnaryOp(_, ref operand) => {
Some(operand.ty(mir, tcx))
operand.ty(mir, tcx)
}
Rvalue::Discriminant(ref lval) => {
let ty = lval.ty(mir, tcx).to_ty(tcx);
if let ty::TyAdt(adt_def, _) = ty.sty {
Some(adt_def.repr.discr_type().to_ty(tcx))
adt_def.repr.discr_type().to_ty(tcx)
} else {
// Undefined behaviour, bug for now; may want to return something for
// the `discriminant` intrinsic later.
bug!("Rvalue::Discriminant on Lvalue of type {:?}", ty);
}
}
Rvalue::Box(t) => {
Some(tcx.mk_box(t))
tcx.mk_box(t)
}
Rvalue::Aggregate(ref ak, ref ops) => {
match *ak {
AggregateKind::Array => {
if let Some(operand) = ops.get(0) {
let ty = operand.ty(mir, tcx);
Some(tcx.mk_array(ty, ops.len()))
} else {
None
}
AggregateKind::Array(ty) => {
tcx.mk_array(ty, ops.len())
}
AggregateKind::Tuple => {
Some(tcx.mk_tup(
tcx.mk_tup(
ops.iter().map(|op| op.ty(mir, tcx)),
false
))
)
}
AggregateKind::Adt(def, _, substs, _) => {
Some(tcx.item_type(def.did).subst(tcx, substs))
tcx.item_type(def.did).subst(tcx, substs)
}
AggregateKind::Closure(did, substs) => {
Some(tcx.mk_closure_from_closure_substs(did, substs))
tcx.mk_closure_from_closure_substs(did, substs)
}
}
}
27 changes: 4 additions & 23 deletions src/librustc/mir/visit.rs
Original file line number Diff line number Diff line change
@@ -235,12 +235,6 @@ macro_rules! make_mir_visitor {
self.super_const_usize(const_usize);
}

fn visit_typed_const_val(&mut self,
val: & $($mutability)* TypedConstVal<'tcx>,
location: Location) {
self.super_typed_const_val(val, location);
}

fn visit_local_decl(&mut self,
local_decl: & $($mutability)* LocalDecl<'tcx>) {
self.super_local_decl(local_decl);
@@ -467,9 +461,9 @@ macro_rules! make_mir_visitor {
}

Rvalue::Repeat(ref $($mutability)* value,
ref $($mutability)* typed_const_val) => {
ref $($mutability)* length) => {
self.visit_operand(value, location);
self.visit_typed_const_val(typed_const_val, location);
self.visit_const_usize(length, location);
}

Rvalue::Ref(r, bk, ref $($mutability)* path) => {
@@ -515,7 +509,8 @@ macro_rules! make_mir_visitor {
Rvalue::Aggregate(ref $($mutability)* kind,
ref $($mutability)* operands) => {
match *kind {
AggregateKind::Array => {
AggregateKind::Array(ref $($mutability)* ty) => {
self.visit_ty(ty);
}
AggregateKind::Tuple => {
}
@@ -647,20 +642,6 @@ macro_rules! make_mir_visitor {
self.visit_literal(literal, location);
}

fn super_typed_const_val(&mut self,
constant: & $($mutability)* TypedConstVal<'tcx>,
location: Location) {
let TypedConstVal {
ref $($mutability)* span,
ref $($mutability)* ty,
ref $($mutability)* value,
} = *constant;

self.visit_span(span);
self.visit_ty(ty);
self.visit_const_usize(value, location);
}

fn super_literal(&mut self,
literal: & $($mutability)* Literal<'tcx>,
location: Location) {
2 changes: 1 addition & 1 deletion src/librustc/traits/error_reporting.rs
Original file line number Diff line number Diff line change
@@ -986,7 +986,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
fn suggest_new_overflow_limit(&self, err: &mut DiagnosticBuilder) {
let current_limit = self.tcx.sess.recursion_limit.get();
let suggested_limit = current_limit * 2;
err.note(&format!(
err.help(&format!(
"consider adding a `#![recursion_limit=\"{}\"]` attribute to your crate",
suggested_limit));
}
1 change: 1 addition & 0 deletions src/librustc_borrowck/borrowck/mir/elaborate_drops.rs
Original file line number Diff line number Diff line change
@@ -161,6 +161,7 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
fn create_drop_flag(&mut self, index: MovePathIndex) {
let tcx = self.tcx;
let patch = &mut self.patch;
debug!("create_drop_flag({:?})", self.mir.span);
self.drop_flags.entry(index).or_insert_with(|| {
patch.new_temp(tcx.types.bool)
});
11 changes: 10 additions & 1 deletion src/librustc_metadata/creader.rs
Original file line number Diff line number Diff line change
@@ -586,7 +586,7 @@ impl<'a> CrateLoader<'a> {
use proc_macro::__internal::Registry;
use rustc_back::dynamic_lib::DynamicLibrary;
use syntax_ext::deriving::custom::ProcMacroDerive;
use syntax_ext::proc_macro_impl::AttrProcMacro;
use syntax_ext::proc_macro_impl::{AttrProcMacro, BangProcMacro};

let path = match dylib {
Some(dylib) => dylib,
@@ -630,6 +630,15 @@ impl<'a> CrateLoader<'a> {
);
self.0.push((Symbol::intern(name), Rc::new(expand)));
}

fn register_bang_proc_macro(&mut self,
name: &str,
expand: fn(TokenStream) -> TokenStream) {
let expand = SyntaxExtension::ProcMacro(
Box::new(BangProcMacro { inner: expand })
);
self.0.push((Symbol::intern(name), Rc::new(expand)));
}
}

let mut my_registrar = MyRegistrar(Vec::new());
5 changes: 4 additions & 1 deletion src/librustc_mir/build/block.rs
Original file line number Diff line number Diff line change
@@ -67,7 +67,10 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
this.expr_into_pattern(block, pattern, init)
}));
} else {
this.storage_live_for_bindings(block, &pattern);
this.visit_bindings(&pattern, &mut |this, _, _, node, span, _| {
this.storage_live_binding(block, node, span);
this.schedule_drop_for_binding(node, span);
})
}

// Enter the visibility scope, after evaluating the initializer.
8 changes: 5 additions & 3 deletions src/librustc_mir/build/expr/as_lvalue.rs
Original file line number Diff line number Diff line change
@@ -56,8 +56,10 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
let (usize_ty, bool_ty) = (this.hir.usize_ty(), this.hir.bool_ty());

let slice = unpack!(block = this.as_lvalue(block, lhs));

let idx = unpack!(block = this.as_operand(block, index));
// extent=None so lvalue indexes live forever. They are scalars so they
// do not need storage annotations, and they are often copied between
// places.
let idx = unpack!(block = this.as_operand(block, None, index));

// bounds check:
let (len, lt) = (this.temp(usize_ty.clone()), this.temp(bool_ty));
@@ -121,7 +123,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
Some(Category::Lvalue) => false,
_ => true,
});
this.as_temp(block, expr)
this.as_temp(block, expr.temp_lifetime, expr)
}
}
}
32 changes: 28 additions & 4 deletions src/librustc_mir/build/expr/as_operand.rs
Original file line number Diff line number Diff line change
@@ -13,29 +13,52 @@
use build::{BlockAnd, BlockAndExtension, Builder};
use build::expr::category::Category;
use hair::*;
use rustc::middle::region::CodeExtent;
use rustc::mir::*;

impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
/// Returns an operand suitable for use until the end of the current
/// scope expression.
///
/// The operand returned from this function will *not be valid* after
/// an ExprKind::Scope is passed, so please do *not* return it from
/// functions to avoid bad miscompiles.
pub fn as_local_operand<M>(&mut self, block: BasicBlock, expr: M)
-> BlockAnd<Operand<'tcx>>
where M: Mirror<'tcx, Output = Expr<'tcx>>
{
let topmost_scope = self.topmost_scope(); // FIXME(#6393)
self.as_operand(block, Some(topmost_scope), expr)
}

/// Compile `expr` into a value that can be used as an operand.
/// If `expr` is an lvalue like `x`, this will introduce a
/// temporary `tmp = x`, so that we capture the value of `x` at
/// this time.
pub fn as_operand<M>(&mut self, block: BasicBlock, expr: M) -> BlockAnd<Operand<'tcx>>
///
/// The operand is known to be live until the end of `scope`.
pub fn as_operand<M>(&mut self,
block: BasicBlock,
scope: Option<CodeExtent>,
expr: M) -> BlockAnd<Operand<'tcx>>
where M: Mirror<'tcx, Output = Expr<'tcx>>
{
let expr = self.hir.mirror(expr);
self.expr_as_operand(block, expr)
self.expr_as_operand(block, scope, expr)
}

fn expr_as_operand(&mut self,
mut block: BasicBlock,
scope: Option<CodeExtent>,
expr: Expr<'tcx>)
-> BlockAnd<Operand<'tcx>> {
debug!("expr_as_operand(block={:?}, expr={:?})", block, expr);
let this = self;

if let ExprKind::Scope { extent, value } = expr.kind {
return this.in_scope(extent, block, |this| this.as_operand(block, value));
return this.in_scope(extent, block, |this| {
this.as_operand(block, scope, value)
});
}

let category = Category::of(&expr.kind).unwrap();
@@ -47,7 +70,8 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
}
Category::Lvalue |
Category::Rvalue(..) => {
let operand = unpack!(block = this.as_temp(block, expr));
let operand =
unpack!(block = this.as_temp(block, scope, expr));
block.and(Operand::Consume(operand))
}
}
Loading