mirror of
https://github.com/rust-lang/rust.git
synced 2024-12-17 19:14:16 +00:00
Auto merge of #40806 - frewsxcv:rollup, r=frewsxcv
Rollup of 8 pull requests - Successful merges: #40567, #40602, #40636, #40739, #40756, #40790, #40794, #40803 - Failed merges:
This commit is contained in:
commit
49c67bd632
@ -311,9 +311,13 @@ To save @bors some work, and to get small changes through more quickly, when
|
|||||||
the other rollup-eligible patches too, and they'll get tested and merged at
|
the other rollup-eligible patches too, and they'll get tested and merged at
|
||||||
the same time.
|
the same time.
|
||||||
|
|
||||||
To find documentation-related issues, sort by the [A-docs label][adocs].
|
To find documentation-related issues, sort by the [T-doc label][tdoc].
|
||||||
|
|
||||||
[adocs]: https://github.com/rust-lang/rust/issues?q=is%3Aopen+is%3Aissue+label%3AA-docs
|
[tdoc]: https://github.com/rust-lang/rust/issues?q=is%3Aopen%20is%3Aissue%20label%3AT-doc
|
||||||
|
|
||||||
|
You can find documentation style guidelines in [RFC 1574][rfc1574].
|
||||||
|
|
||||||
|
[rfc1574]: https://github.com/rust-lang/rfcs/blob/master/text/1574-more-api-documentation-conventions.md#appendix-a-full-conventions-text
|
||||||
|
|
||||||
In many cases, you don't need a full `./x.py doc`. You can use `rustdoc` directly
|
In many cases, you don't need a full `./x.py doc`. You can use `rustdoc` directly
|
||||||
to check small fixes. For example, `rustdoc src/doc/reference.md` will render
|
to check small fixes. For example, `rustdoc src/doc/reference.md` will render
|
||||||
|
@ -141,8 +141,7 @@ pub struct BTreeMap<K, V> {
|
|||||||
unsafe impl<#[may_dangle] K, #[may_dangle] V> Drop for BTreeMap<K, V> {
|
unsafe impl<#[may_dangle] K, #[may_dangle] V> Drop for BTreeMap<K, V> {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
unsafe {
|
unsafe {
|
||||||
for _ in ptr::read(self).into_iter() {
|
drop(ptr::read(self).into_iter());
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1162,7 +1162,7 @@ impl<T> [T] {
|
|||||||
///
|
///
|
||||||
/// # Current implementation
|
/// # Current implementation
|
||||||
///
|
///
|
||||||
/// The current algorithm is based on Orson Peters' [pdqsort][pattern-defeating quicksort],
|
/// The current algorithm is based on Orson Peters' [pattern-defeating quicksort][pdqsort],
|
||||||
/// which is a quicksort variant designed to be very fast on certain kinds of patterns,
|
/// which is a quicksort variant designed to be very fast on certain kinds of patterns,
|
||||||
/// sometimes achieving linear time. It is randomized but deterministic, and falls back to
|
/// sometimes achieving linear time. It is randomized but deterministic, and falls back to
|
||||||
/// heapsort on degenerate inputs.
|
/// heapsort on degenerate inputs.
|
||||||
@ -1199,7 +1199,7 @@ impl<T> [T] {
|
|||||||
///
|
///
|
||||||
/// # Current implementation
|
/// # Current implementation
|
||||||
///
|
///
|
||||||
/// The current algorithm is based on Orson Peters' [pdqsort][pattern-defeating quicksort],
|
/// The current algorithm is based on Orson Peters' [pattern-defeating quicksort][pdqsort],
|
||||||
/// which is a quicksort variant designed to be very fast on certain kinds of patterns,
|
/// which is a quicksort variant designed to be very fast on certain kinds of patterns,
|
||||||
/// sometimes achieving linear time. It is randomized but deterministic, and falls back to
|
/// sometimes achieving linear time. It is randomized but deterministic, and falls back to
|
||||||
/// heapsort on degenerate inputs.
|
/// heapsort on degenerate inputs.
|
||||||
@ -1239,7 +1239,7 @@ impl<T> [T] {
|
|||||||
///
|
///
|
||||||
/// # Current implementation
|
/// # Current implementation
|
||||||
///
|
///
|
||||||
/// The current algorithm is based on Orson Peters' [pdqsort][pattern-defeating quicksort],
|
/// The current algorithm is based on Orson Peters' [pattern-defeating quicksort][pdqsort],
|
||||||
/// which is a quicksort variant designed to be very fast on certain kinds of patterns,
|
/// which is a quicksort variant designed to be very fast on certain kinds of patterns,
|
||||||
/// sometimes achieving linear time. It is randomized but deterministic, and falls back to
|
/// sometimes achieving linear time. It is randomized but deterministic, and falls back to
|
||||||
/// heapsort on degenerate inputs.
|
/// heapsort on degenerate inputs.
|
||||||
|
@ -983,16 +983,16 @@ impl<'tcx> Debug for Operand<'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> Operand<'tcx> {
|
impl<'tcx> Operand<'tcx> {
|
||||||
pub fn item<'a>(tcx: ty::TyCtxt<'a, 'tcx, 'tcx>,
|
pub fn function_handle<'a>(
|
||||||
def_id: DefId,
|
tcx: ty::TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
substs: &'tcx Substs<'tcx>,
|
def_id: DefId,
|
||||||
span: Span)
|
substs: &'tcx Substs<'tcx>,
|
||||||
-> Self
|
span: Span,
|
||||||
{
|
) -> Self {
|
||||||
Operand::Constant(Constant {
|
Operand::Constant(Constant {
|
||||||
span: span,
|
span: span,
|
||||||
ty: tcx.item_type(def_id).subst(tcx, substs),
|
ty: tcx.item_type(def_id).subst(tcx, substs),
|
||||||
literal: Literal::Item { def_id, substs }
|
literal: Literal::Value { value: ConstVal::Function(def_id, substs) },
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -89,6 +89,7 @@ should go to.
|
|||||||
use build::{BlockAnd, BlockAndExtension, Builder, CFG};
|
use build::{BlockAnd, BlockAndExtension, Builder, CFG};
|
||||||
use rustc::middle::region::{CodeExtent, CodeExtentData};
|
use rustc::middle::region::{CodeExtent, CodeExtentData};
|
||||||
use rustc::middle::lang_items;
|
use rustc::middle::lang_items;
|
||||||
|
use rustc::middle::const_val::ConstVal;
|
||||||
use rustc::ty::subst::{Kind, Subst};
|
use rustc::ty::subst::{Kind, Subst};
|
||||||
use rustc::ty::{Ty, TyCtxt};
|
use rustc::ty::{Ty, TyCtxt};
|
||||||
use rustc::mir::*;
|
use rustc::mir::*;
|
||||||
@ -784,9 +785,8 @@ fn build_free<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
|||||||
func: Operand::Constant(Constant {
|
func: Operand::Constant(Constant {
|
||||||
span: data.span,
|
span: data.span,
|
||||||
ty: tcx.item_type(free_func).subst(tcx, substs),
|
ty: tcx.item_type(free_func).subst(tcx, substs),
|
||||||
literal: Literal::Item {
|
literal: Literal::Value {
|
||||||
def_id: free_func,
|
value: ConstVal::Function(free_func, substs),
|
||||||
substs: substs
|
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
args: vec![Operand::Consume(data.value.clone())],
|
args: vec![Operand::Consume(data.value.clone())],
|
||||||
|
@ -714,9 +714,8 @@ fn method_callee<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
|
|||||||
ty: callee.ty,
|
ty: callee.ty,
|
||||||
span: expr.span,
|
span: expr.span,
|
||||||
kind: ExprKind::Literal {
|
kind: ExprKind::Literal {
|
||||||
literal: Literal::Item {
|
literal: Literal::Value {
|
||||||
def_id: callee.def_id,
|
value: ConstVal::Function(callee.def_id, callee.substs),
|
||||||
substs: callee.substs,
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -743,14 +742,24 @@ fn convert_path_expr<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
|
|||||||
-> ExprKind<'tcx> {
|
-> ExprKind<'tcx> {
|
||||||
let substs = cx.tables().node_id_item_substs(expr.id)
|
let substs = cx.tables().node_id_item_substs(expr.id)
|
||||||
.unwrap_or_else(|| cx.tcx.intern_substs(&[]));
|
.unwrap_or_else(|| cx.tcx.intern_substs(&[]));
|
||||||
let def_id = match def {
|
match def {
|
||||||
// A regular function, constructor function or a constant.
|
// A regular function, constructor function or a constant.
|
||||||
Def::Fn(def_id) |
|
Def::Fn(def_id) |
|
||||||
Def::Method(def_id) |
|
Def::Method(def_id) |
|
||||||
Def::StructCtor(def_id, CtorKind::Fn) |
|
Def::StructCtor(def_id, CtorKind::Fn) |
|
||||||
Def::VariantCtor(def_id, CtorKind::Fn) |
|
Def::VariantCtor(def_id, CtorKind::Fn) => ExprKind::Literal {
|
||||||
|
literal: Literal::Value {
|
||||||
|
value: ConstVal::Function(def_id, substs),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
Def::Const(def_id) |
|
Def::Const(def_id) |
|
||||||
Def::AssociatedConst(def_id) => def_id,
|
Def::AssociatedConst(def_id) => ExprKind::Literal {
|
||||||
|
literal: Literal::Item {
|
||||||
|
def_id: def_id,
|
||||||
|
substs: substs,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
Def::StructCtor(def_id, CtorKind::Const) |
|
Def::StructCtor(def_id, CtorKind::Const) |
|
||||||
Def::VariantCtor(def_id, CtorKind::Const) => {
|
Def::VariantCtor(def_id, CtorKind::Const) => {
|
||||||
@ -758,7 +767,7 @@ fn convert_path_expr<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
|
|||||||
// A unit struct/variant which is used as a value.
|
// A unit struct/variant which is used as a value.
|
||||||
// We return a completely different ExprKind here to account for this special case.
|
// We return a completely different ExprKind here to account for this special case.
|
||||||
ty::TyAdt(adt_def, substs) => {
|
ty::TyAdt(adt_def, substs) => {
|
||||||
return ExprKind::Adt {
|
ExprKind::Adt {
|
||||||
adt_def: adt_def,
|
adt_def: adt_def,
|
||||||
variant_index: adt_def.variant_index_with_id(def_id),
|
variant_index: adt_def.variant_index_with_id(def_id),
|
||||||
substs: substs,
|
substs: substs,
|
||||||
@ -770,17 +779,11 @@ fn convert_path_expr<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Def::Static(node_id, _) => return ExprKind::StaticRef { id: node_id },
|
Def::Static(node_id, _) => ExprKind::StaticRef { id: node_id },
|
||||||
|
|
||||||
Def::Local(..) | Def::Upvar(..) => return convert_var(cx, expr, def),
|
Def::Local(..) | Def::Upvar(..) => convert_var(cx, expr, def),
|
||||||
|
|
||||||
_ => span_bug!(expr.span, "def `{:?}` not yet implemented", def),
|
_ => span_bug!(expr.span, "def `{:?}` not yet implemented", def),
|
||||||
};
|
|
||||||
ExprKind::Literal {
|
|
||||||
literal: Literal::Item {
|
|
||||||
def_id: def_id,
|
|
||||||
substs: substs,
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -132,9 +132,8 @@ impl<'a, 'gcx, 'tcx> Cx<'a, 'gcx, 'tcx> {
|
|||||||
let method_ty = self.tcx.item_type(item.def_id);
|
let method_ty = self.tcx.item_type(item.def_id);
|
||||||
let method_ty = method_ty.subst(self.tcx, substs);
|
let method_ty = method_ty.subst(self.tcx, substs);
|
||||||
return (method_ty,
|
return (method_ty,
|
||||||
Literal::Item {
|
Literal::Value {
|
||||||
def_id: item.def_id,
|
value: ConstVal::Function(item.def_id, substs),
|
||||||
substs: substs,
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,7 @@ use rustc::hir;
|
|||||||
use rustc::hir::def_id::DefId;
|
use rustc::hir::def_id::DefId;
|
||||||
use rustc::infer;
|
use rustc::infer;
|
||||||
use rustc::middle::region::ROOT_CODE_EXTENT;
|
use rustc::middle::region::ROOT_CODE_EXTENT;
|
||||||
|
use rustc::middle::const_val::ConstVal;
|
||||||
use rustc::mir::*;
|
use rustc::mir::*;
|
||||||
use rustc::mir::transform::MirSource;
|
use rustc::mir::transform::MirSource;
|
||||||
use rustc::ty::{self, Ty};
|
use rustc::ty::{self, Ty};
|
||||||
@ -335,7 +336,9 @@ fn build_call_shim<'a, 'tcx>(tcx: ty::TyCtxt<'a, 'tcx, 'tcx>,
|
|||||||
Operand::Constant(Constant {
|
Operand::Constant(Constant {
|
||||||
span: span,
|
span: span,
|
||||||
ty: tcx.item_type(def_id).subst(tcx, param_env.free_substs),
|
ty: tcx.item_type(def_id).subst(tcx, param_env.free_substs),
|
||||||
literal: Literal::Item { def_id, substs: param_env.free_substs },
|
literal: Literal::Value {
|
||||||
|
value: ConstVal::Function(def_id, param_env.free_substs),
|
||||||
|
},
|
||||||
}),
|
}),
|
||||||
vec![rcvr]
|
vec![rcvr]
|
||||||
)
|
)
|
||||||
|
@ -568,11 +568,6 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
Operand::Constant(ref constant) => {
|
Operand::Constant(ref constant) => {
|
||||||
// Only functions and methods can have these types.
|
|
||||||
if let ty::TyFnDef(..) = constant.ty.sty {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Literal::Item { def_id, substs } = constant.literal {
|
if let Literal::Item { def_id, substs } = constant.literal {
|
||||||
// Don't peek inside generic (associated) constants.
|
// Don't peek inside generic (associated) constants.
|
||||||
if substs.types().next().is_some() {
|
if substs.types().next().is_some() {
|
||||||
|
@ -15,6 +15,7 @@ use rustc::infer::{self, InferCtxt, InferOk};
|
|||||||
use rustc::traits::{self, Reveal};
|
use rustc::traits::{self, Reveal};
|
||||||
use rustc::ty::fold::TypeFoldable;
|
use rustc::ty::fold::TypeFoldable;
|
||||||
use rustc::ty::{self, Ty, TyCtxt, TypeVariants};
|
use rustc::ty::{self, Ty, TyCtxt, TypeVariants};
|
||||||
|
use rustc::middle::const_val::ConstVal;
|
||||||
use rustc::mir::*;
|
use rustc::mir::*;
|
||||||
use rustc::mir::tcx::LvalueTy;
|
use rustc::mir::tcx::LvalueTy;
|
||||||
use rustc::mir::transform::{MirPass, MirSource, Pass};
|
use rustc::mir::transform::{MirPass, MirSource, Pass};
|
||||||
@ -526,7 +527,9 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
|
|||||||
fn is_box_free(&self, operand: &Operand<'tcx>) -> bool {
|
fn is_box_free(&self, operand: &Operand<'tcx>) -> bool {
|
||||||
match operand {
|
match operand {
|
||||||
&Operand::Constant(Constant {
|
&Operand::Constant(Constant {
|
||||||
literal: Literal::Item { def_id, .. }, ..
|
literal: Literal::Value {
|
||||||
|
value: ConstVal::Function(def_id, _), ..
|
||||||
|
}, ..
|
||||||
}) => {
|
}) => {
|
||||||
Some(def_id) == self.tcx().lang_items.box_free_fn()
|
Some(def_id) == self.tcx().lang_items.box_free_fn()
|
||||||
}
|
}
|
||||||
|
@ -525,8 +525,8 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D>
|
|||||||
}],
|
}],
|
||||||
terminator: Some(Terminator {
|
terminator: Some(Terminator {
|
||||||
kind: TerminatorKind::Call {
|
kind: TerminatorKind::Call {
|
||||||
func: Operand::item(tcx, drop_fn.def_id, substs,
|
func: Operand::function_handle(tcx, drop_fn.def_id, substs,
|
||||||
self.source_info.span),
|
self.source_info.span),
|
||||||
args: vec![Operand::Consume(Lvalue::Local(ref_lvalue))],
|
args: vec![Operand::Consume(Lvalue::Local(ref_lvalue))],
|
||||||
destination: Some((unit_temp, succ)),
|
destination: Some((unit_temp, succ)),
|
||||||
cleanup: unwind,
|
cleanup: unwind,
|
||||||
@ -629,7 +629,7 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D>
|
|||||||
let substs = tcx.mk_substs(iter::once(Kind::from(ty)));
|
let substs = tcx.mk_substs(iter::once(Kind::from(ty)));
|
||||||
|
|
||||||
let call = TerminatorKind::Call {
|
let call = TerminatorKind::Call {
|
||||||
func: Operand::item(tcx, free_func, substs, self.source_info.span),
|
func: Operand::function_handle(tcx, free_func, substs, self.source_info.span),
|
||||||
args: vec![Operand::Consume(self.lvalue.clone())],
|
args: vec![Operand::Consume(self.lvalue.clone())],
|
||||||
destination: Some((unit_temp, target)),
|
destination: Some((unit_temp, target)),
|
||||||
cleanup: None
|
cleanup: None
|
||||||
|
@ -13,7 +13,8 @@
|
|||||||
|
|
||||||
use rustc_data_structures::bitvec::BitVector;
|
use rustc_data_structures::bitvec::BitVector;
|
||||||
use rustc_data_structures::indexed_vec::{Idx, IndexVec};
|
use rustc_data_structures::indexed_vec::{Idx, IndexVec};
|
||||||
use rustc::mir::{self, Location, TerminatorKind};
|
use rustc::middle::const_val::ConstVal;
|
||||||
|
use rustc::mir::{self, Location, TerminatorKind, Literal};
|
||||||
use rustc::mir::visit::{Visitor, LvalueContext};
|
use rustc::mir::visit::{Visitor, LvalueContext};
|
||||||
use rustc::mir::traversal;
|
use rustc::mir::traversal;
|
||||||
use common;
|
use common;
|
||||||
@ -109,7 +110,9 @@ impl<'mir, 'a, 'tcx> Visitor<'tcx> for LocalAnalyzer<'mir, 'a, 'tcx> {
|
|||||||
match *kind {
|
match *kind {
|
||||||
mir::TerminatorKind::Call {
|
mir::TerminatorKind::Call {
|
||||||
func: mir::Operand::Constant(mir::Constant {
|
func: mir::Operand::Constant(mir::Constant {
|
||||||
literal: mir::Literal::Item { def_id, .. }, ..
|
literal: Literal::Value {
|
||||||
|
value: ConstVal::Function(def_id, _), ..
|
||||||
|
}, ..
|
||||||
}),
|
}),
|
||||||
ref args, ..
|
ref args, ..
|
||||||
} if Some(def_id) == self.cx.ccx.tcx().lang_items.box_free_fn() => {
|
} if Some(def_id) == self.cx.ccx.tcx().lang_items.box_free_fn() => {
|
||||||
|
@ -101,9 +101,12 @@ impl<'tcx> Const<'tcx> {
|
|||||||
ConstVal::Str(ref v) => C_str_slice(ccx, v.clone()),
|
ConstVal::Str(ref v) => C_str_slice(ccx, v.clone()),
|
||||||
ConstVal::ByteStr(ref v) => consts::addr_of(ccx, C_bytes(ccx, v), 1, "byte_str"),
|
ConstVal::ByteStr(ref v) => consts::addr_of(ccx, C_bytes(ccx, v), 1, "byte_str"),
|
||||||
ConstVal::Struct(_) | ConstVal::Tuple(_) |
|
ConstVal::Struct(_) | ConstVal::Tuple(_) |
|
||||||
ConstVal::Array(..) | ConstVal::Repeat(..) |
|
ConstVal::Array(..) | ConstVal::Repeat(..) => {
|
||||||
|
bug!("MIR must not use `{:?}` (aggregates are expanded to MIR rvalues)", cv)
|
||||||
|
}
|
||||||
ConstVal::Function(..) => {
|
ConstVal::Function(..) => {
|
||||||
bug!("MIR must not use `{:?}` (which refers to a local ID)", cv)
|
let llty = type_of::type_of(ccx, ty);
|
||||||
|
return Const::new(C_null(llty), ty);
|
||||||
}
|
}
|
||||||
ConstVal::Char(c) => C_integral(Type::char(ccx), c as u64, false),
|
ConstVal::Char(c) => C_integral(Type::char(ccx), c as u64, false),
|
||||||
};
|
};
|
||||||
@ -476,13 +479,6 @@ impl<'a, 'tcx> MirConstContext<'a, 'tcx> {
|
|||||||
let ty = self.monomorphize(&constant.ty);
|
let ty = self.monomorphize(&constant.ty);
|
||||||
match constant.literal.clone() {
|
match constant.literal.clone() {
|
||||||
mir::Literal::Item { def_id, substs } => {
|
mir::Literal::Item { def_id, substs } => {
|
||||||
// Shortcut for zero-sized types, including function item
|
|
||||||
// types, which would not work with MirConstContext.
|
|
||||||
if common::type_is_zero_size(self.ccx, ty) {
|
|
||||||
let llty = type_of::type_of(self.ccx, ty);
|
|
||||||
return Ok(Const::new(C_null(llty), ty));
|
|
||||||
}
|
|
||||||
|
|
||||||
let substs = self.monomorphize(&substs);
|
let substs = self.monomorphize(&substs);
|
||||||
MirConstContext::trans_def(self.ccx, def_id, substs, IndexVec::new())
|
MirConstContext::trans_def(self.ccx, def_id, substs, IndexVec::new())
|
||||||
}
|
}
|
||||||
@ -924,13 +920,6 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> {
|
|||||||
let ty = self.monomorphize(&constant.ty);
|
let ty = self.monomorphize(&constant.ty);
|
||||||
let result = match constant.literal.clone() {
|
let result = match constant.literal.clone() {
|
||||||
mir::Literal::Item { def_id, substs } => {
|
mir::Literal::Item { def_id, substs } => {
|
||||||
// Shortcut for zero-sized types, including function item
|
|
||||||
// types, which would not work with MirConstContext.
|
|
||||||
if common::type_is_zero_size(bcx.ccx, ty) {
|
|
||||||
let llty = type_of::type_of(bcx.ccx, ty);
|
|
||||||
return Const::new(C_null(llty), ty);
|
|
||||||
}
|
|
||||||
|
|
||||||
let substs = self.monomorphize(&substs);
|
let substs = self.monomorphize(&substs);
|
||||||
MirConstContext::trans_def(bcx.ccx, def_id, substs, IndexVec::new())
|
MirConstContext::trans_def(bcx.ccx, def_id, substs, IndexVec::new())
|
||||||
}
|
}
|
||||||
|
@ -4099,6 +4099,17 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
if self.diverges.get().always() {
|
if self.diverges.get().always() {
|
||||||
|
if let ExpectHasType(ety) = expected {
|
||||||
|
// Avoid forcing a type (only `!` for now) in unreachable code.
|
||||||
|
// FIXME(aburka) do we need this special case? and should it be is_uninhabited?
|
||||||
|
if !ety.is_never() {
|
||||||
|
if let Some(ref e) = blk.expr {
|
||||||
|
// Coerce the tail expression to the right type.
|
||||||
|
self.demand_coerce(e, ty, ety);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ty = self.next_diverging_ty_var(TypeVariableOrigin::DivergingBlockExpr(blk.span));
|
ty = self.next_diverging_ty_var(TypeVariableOrigin::DivergingBlockExpr(blk.span));
|
||||||
} else if let ExpectHasType(ety) = expected {
|
} else if let ExpectHasType(ety) = expected {
|
||||||
if let Some(ref e) = blk.expr {
|
if let Some(ref e) = blk.expr {
|
||||||
|
@ -1700,6 +1700,23 @@ fn document_stability(w: &mut fmt::Formatter, cx: &Context, item: &clean::Item)
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn name_key(name: &str) -> (&str, u64, usize) {
|
||||||
|
// find number at end
|
||||||
|
let split = name.bytes().rposition(|b| b < b'0' || b'9' < b).map_or(0, |s| s + 1);
|
||||||
|
|
||||||
|
// count leading zeroes
|
||||||
|
let after_zeroes =
|
||||||
|
name[split..].bytes().position(|b| b != b'0').map_or(name.len(), |extra| split + extra);
|
||||||
|
|
||||||
|
// sort leading zeroes last
|
||||||
|
let num_zeroes = after_zeroes - split;
|
||||||
|
|
||||||
|
match name[split..].parse() {
|
||||||
|
Ok(n) => (&name[..split], n, num_zeroes),
|
||||||
|
Err(_) => (name, 0, num_zeroes),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn item_module(w: &mut fmt::Formatter, cx: &Context,
|
fn item_module(w: &mut fmt::Formatter, cx: &Context,
|
||||||
item: &clean::Item, items: &[clean::Item]) -> fmt::Result {
|
item: &clean::Item, items: &[clean::Item]) -> fmt::Result {
|
||||||
document(w, cx, item)?;
|
document(w, cx, item)?;
|
||||||
@ -1744,7 +1761,9 @@ fn item_module(w: &mut fmt::Formatter, cx: &Context,
|
|||||||
(Some(stability::Stable), Some(stability::Unstable)) => return Ordering::Less,
|
(Some(stability::Stable), Some(stability::Unstable)) => return Ordering::Less,
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
i1.name.cmp(&i2.name)
|
let lhs = i1.name.as_ref().map_or("", |s| &**s);
|
||||||
|
let rhs = i2.name.as_ref().map_or("", |s| &**s);
|
||||||
|
name_key(lhs).cmp(&name_key(rhs))
|
||||||
}
|
}
|
||||||
|
|
||||||
indices.sort_by(|&i1, &i2| cmp(&items[i1], &items[i2], i1, i2));
|
indices.sort_by(|&i1, &i2| cmp(&items[i1], &items[i2], i1, i2));
|
||||||
@ -3198,3 +3217,32 @@ fn test_unique_id() {
|
|||||||
reset_ids(true);
|
reset_ids(true);
|
||||||
test();
|
test();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
#[test]
|
||||||
|
fn test_name_key() {
|
||||||
|
assert_eq!(name_key("0"), ("", 0, 1));
|
||||||
|
assert_eq!(name_key("123"), ("", 123, 0));
|
||||||
|
assert_eq!(name_key("Fruit"), ("Fruit", 0, 0));
|
||||||
|
assert_eq!(name_key("Fruit0"), ("Fruit", 0, 1));
|
||||||
|
assert_eq!(name_key("Fruit0000"), ("Fruit", 0, 4));
|
||||||
|
assert_eq!(name_key("Fruit01"), ("Fruit", 1, 1));
|
||||||
|
assert_eq!(name_key("Fruit10"), ("Fruit", 10, 0));
|
||||||
|
assert_eq!(name_key("Fruit123"), ("Fruit", 123, 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
#[test]
|
||||||
|
fn test_name_sorting() {
|
||||||
|
let names = ["Apple",
|
||||||
|
"Banana",
|
||||||
|
"Fruit", "Fruit0", "Fruit00",
|
||||||
|
"Fruit1", "Fruit01",
|
||||||
|
"Fruit2", "Fruit02",
|
||||||
|
"Fruit20",
|
||||||
|
"Fruit100",
|
||||||
|
"Pear"];
|
||||||
|
let mut sorted = names.to_owned();
|
||||||
|
sorted.sort_by_key(|&s| name_key(s));
|
||||||
|
assert_eq!(names, sorted);
|
||||||
|
}
|
||||||
|
@ -896,15 +896,23 @@ impl<K, V> RawTable<K, V> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns an iterator that copies out each entry. Used while the table
|
/// Drops buckets in reverse order. It leaves the table in an inconsistent
|
||||||
/// is being dropped.
|
/// state and should only be used for dropping the table's remaining
|
||||||
unsafe fn rev_move_buckets(&mut self) -> RevMoveBuckets<K, V> {
|
/// entries. It's used in the implementation of Drop.
|
||||||
let raw_bucket = self.first_bucket_raw();
|
unsafe fn rev_drop_buckets(&mut self) {
|
||||||
RevMoveBuckets {
|
let first_raw = self.first_bucket_raw();
|
||||||
raw: raw_bucket.offset(self.capacity as isize),
|
let mut raw = first_raw.offset(self.capacity as isize);
|
||||||
hashes_end: raw_bucket.hash,
|
let mut elems_left = self.size;
|
||||||
elems_left: self.size,
|
|
||||||
marker: marker::PhantomData,
|
while elems_left != 0 {
|
||||||
|
debug_assert!(raw.hash != first_raw.hash);
|
||||||
|
|
||||||
|
raw = raw.offset(-1);
|
||||||
|
|
||||||
|
if *raw.hash != EMPTY_BUCKET {
|
||||||
|
elems_left -= 1;
|
||||||
|
ptr::drop_in_place(raw.pair as *mut (K, V));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -964,43 +972,6 @@ impl<'a, K, V> Iterator for RawBuckets<'a, K, V> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// An iterator that moves out buckets in reverse order. It leaves the table
|
|
||||||
/// in an inconsistent state and should only be used for dropping
|
|
||||||
/// the table's remaining entries. It's used in the implementation of Drop.
|
|
||||||
struct RevMoveBuckets<'a, K, V> {
|
|
||||||
raw: RawBucket<K, V>,
|
|
||||||
hashes_end: *mut HashUint,
|
|
||||||
elems_left: usize,
|
|
||||||
|
|
||||||
// As above, `&'a (K,V)` would seem better, but we often use
|
|
||||||
// 'static for the lifetime, and this is not a publicly exposed
|
|
||||||
// type.
|
|
||||||
marker: marker::PhantomData<&'a ()>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a, K, V> Iterator for RevMoveBuckets<'a, K, V> {
|
|
||||||
type Item = (K, V);
|
|
||||||
|
|
||||||
fn next(&mut self) -> Option<(K, V)> {
|
|
||||||
if self.elems_left == 0 {
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
|
|
||||||
loop {
|
|
||||||
debug_assert!(self.raw.hash != self.hashes_end);
|
|
||||||
|
|
||||||
unsafe {
|
|
||||||
self.raw = self.raw.offset(-1);
|
|
||||||
|
|
||||||
if *self.raw.hash != EMPTY_BUCKET {
|
|
||||||
self.elems_left -= 1;
|
|
||||||
return Some(ptr::read(self.raw.pair));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Iterator over shared references to entries in a table.
|
/// Iterator over shared references to entries in a table.
|
||||||
pub struct Iter<'a, K: 'a, V: 'a> {
|
pub struct Iter<'a, K: 'a, V: 'a> {
|
||||||
iter: RawBuckets<'a, K, V>,
|
iter: RawBuckets<'a, K, V>,
|
||||||
@ -1227,7 +1198,7 @@ unsafe impl<#[may_dangle] K, #[may_dangle] V> Drop for RawTable<K, V> {
|
|||||||
unsafe {
|
unsafe {
|
||||||
if needs_drop::<(K, V)>() {
|
if needs_drop::<(K, V)>() {
|
||||||
// avoid linear runtime for types that don't need drop
|
// avoid linear runtime for types that don't need drop
|
||||||
for _ in self.rev_move_buckets() {}
|
self.rev_drop_buckets();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -437,7 +437,10 @@ impl Command {
|
|||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
/// Basic usage:
|
/// Basic usage:
|
||||||
|
///
|
||||||
/// ```no_run
|
/// ```no_run
|
||||||
|
/// #![feature(command_envs)]
|
||||||
|
///
|
||||||
/// use std::process::{Command, Stdio};
|
/// use std::process::{Command, Stdio};
|
||||||
/// use std::env;
|
/// use std::env;
|
||||||
/// use std::collections::HashMap;
|
/// use std::collections::HashMap;
|
||||||
|
@ -8,12 +8,12 @@
|
|||||||
// option. This file may not be copied, modified, or distributed
|
// option. This file may not be copied, modified, or distributed
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
fn g() {
|
|
||||||
&panic!()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn f() -> isize {
|
fn f() -> isize {
|
||||||
(return 1, return 2)
|
(return 1, return 2)
|
||||||
|
//~^ ERROR mismatched types
|
||||||
|
//~| expected type `isize`
|
||||||
|
//~| found type `(_, _)`
|
||||||
|
//~| expected isize, found tuple
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
17
src/test/compile-fail/issue-5500.rs
Normal file
17
src/test/compile-fail/issue-5500.rs
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
|
||||||
|
// file at the top-level directory of this distribution and at
|
||||||
|
// http://rust-lang.org/COPYRIGHT.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
// option. This file may not be copied, modified, or distributed
|
||||||
|
// except according to those terms.
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
&panic!()
|
||||||
|
//~^ ERROR mismatched types
|
||||||
|
//~| expected type `()`
|
||||||
|
//~| found type `&_`
|
||||||
|
//~| expected (), found reference
|
||||||
|
}
|
@ -8,8 +8,7 @@
|
|||||||
// option. This file may not be copied, modified, or distributed
|
// option. This file may not be copied, modified, or distributed
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
#![allow(unused_features)]
|
#![allow(unknown_features)]
|
||||||
#![allow(unreachable_code)]
|
|
||||||
#![feature(box_syntax)]
|
#![feature(box_syntax)]
|
||||||
|
|
||||||
#[derive(PartialEq, Debug)]
|
#[derive(PartialEq, Debug)]
|
||||||
@ -29,14 +28,14 @@ struct Foo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn foo() -> Result<Foo, isize> {
|
fn foo() -> Result<Foo, isize> {
|
||||||
return Ok::<Foo, isize>(Foo {
|
return Ok(Foo {
|
||||||
x: Bar { x: 22 },
|
x: Bar { x: 22 },
|
||||||
a: return Err(32)
|
a: return Err(32)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn baz() -> Result<Foo, isize> {
|
fn baz() -> Result<Foo, isize> {
|
||||||
Ok::<Foo, isize>(Foo {
|
Ok(Foo {
|
||||||
x: Bar { x: 22 },
|
x: Bar { x: 22 },
|
||||||
a: return Err(32)
|
a: return Err(32)
|
||||||
})
|
})
|
||||||
|
21
src/test/run-pass/issue-39984.rs
Normal file
21
src/test/run-pass/issue-39984.rs
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
|
||||||
|
// file at the top-level directory of this distribution and at
|
||||||
|
// http://rust-lang.org/COPYRIGHT.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
// option. This file may not be copied, modified, or distributed
|
||||||
|
// except according to those terms.
|
||||||
|
|
||||||
|
// Regression test for issue #39984.
|
||||||
|
//
|
||||||
|
// The key here is that the error type of the `Ok` call ought to be
|
||||||
|
// constrained to `String`, even though it is dead-code.
|
||||||
|
|
||||||
|
fn main() {}
|
||||||
|
|
||||||
|
fn t() -> Result<(), String> {
|
||||||
|
return Err("".into());
|
||||||
|
Ok(())
|
||||||
|
}
|
@ -11,8 +11,6 @@
|
|||||||
// A regression test extracted from image-0.3.11. The point of
|
// A regression test extracted from image-0.3.11. The point of
|
||||||
// failure was in `index_colors` below.
|
// failure was in `index_colors` below.
|
||||||
|
|
||||||
#![allow(unused)]
|
|
||||||
|
|
||||||
use std::ops::{Deref, DerefMut};
|
use std::ops::{Deref, DerefMut};
|
||||||
|
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone)]
|
||||||
@ -94,7 +92,7 @@ pub fn index_colors<Pix>(image: &ImageBuffer<Pix, Vec<u8>>)
|
|||||||
-> ImageBuffer<Luma<u8>, Vec<u8>>
|
-> ImageBuffer<Luma<u8>, Vec<u8>>
|
||||||
where Pix: Pixel<Subpixel=u8> + 'static,
|
where Pix: Pixel<Subpixel=u8> + 'static,
|
||||||
{
|
{
|
||||||
let mut indices: ImageBuffer<Luma<u8>, Vec<u8>> = loop { };
|
let mut indices: ImageBuffer<_,Vec<_>> = loop { };
|
||||||
for (pixel, idx) in image.pixels().zip(indices.pixels_mut()) {
|
for (pixel, idx) in image.pixels().zip(indices.pixels_mut()) {
|
||||||
// failured occurred here ^^ because we were requiring that we
|
// failured occurred here ^^ because we were requiring that we
|
||||||
// could project Pixel or Subpixel from `T_indices` (type of
|
// could project Pixel or Subpixel from `T_indices` (type of
|
||||||
|
Loading…
Reference in New Issue
Block a user