Auto merge of #41373 - frewsxcv:rollup, r=frewsxcv

Rollup of 6 pull requests

- Successful merges: #40290, #41353, #41356, #41360, #41361, #41364
- Failed merges:
This commit is contained in:
bors
2017-04-18 18:20:04 +00:00
36 changed files with 152 additions and 297 deletions

View File

@@ -404,14 +404,6 @@ class RustBuild(object):
raise Exception(err) raise Exception(err)
sys.exit(err) sys.exit(err)
# Darwin's `uname -s` lies and always returns i386. We have to use
# sysctl instead.
if ostype == 'Darwin' and cputype == 'i686':
args = ['sysctl', 'hw.optional.x86_64']
sysctl = subprocess.check_output(args).decode(default_encoding)
if ': 1' in sysctl:
cputype = 'x86_64'
# The goal here is to come up with the same triple as LLVM would, # The goal here is to come up with the same triple as LLVM would,
# at least for the subset of platforms we're willing to target. # at least for the subset of platforms we're willing to target.
if ostype == 'Linux': if ostype == 'Linux':

View File

@@ -79,6 +79,7 @@
- [fmt_internals](fmt-internals.md) - [fmt_internals](fmt-internals.md)
- [fn_traits](fn-traits.md) - [fn_traits](fn-traits.md)
- [fnbox](fnbox.md) - [fnbox](fnbox.md)
- [from_utf8_error_as_bytes](from_utf8_error_as_bytes.md)
- [fundamental](fundamental.md) - [fundamental](fundamental.md)
- [fused](fused.md) - [fused](fused.md)
- [future_atomic_orderings](future-atomic-orderings.md) - [future_atomic_orderings](future-atomic-orderings.md)

View File

@@ -0,0 +1,7 @@
# `from_utf8_error_as_bytes`
The tracking issue for this feature is: [#40895]
[#40895]: https://github.com/rust-lang/rust/issues/40895
------------------------

View File

@@ -1403,6 +1403,26 @@ impl String {
} }
impl FromUtf8Error { impl FromUtf8Error {
/// Returns a slice of [`u8`]s bytes that were attempted to convert to a `String`.
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// #![feature(from_utf8_error_as_bytes)]
/// // some invalid bytes, in a vector
/// let bytes = vec![0, 159];
///
/// let value = String::from_utf8(bytes);
///
/// assert_eq!(&[0, 159], value.unwrap_err().as_bytes());
/// ```
#[unstable(feature = "from_utf8_error_as_bytes", reason = "recently added", issue = "40895")]
pub fn as_bytes(&self) -> &[u8] {
&self.bytes[..]
}
/// Returns the bytes that were attempted to convert to a `String`. /// Returns the bytes that were attempted to convert to a `String`.
/// ///
/// This method is carefully constructed to avoid allocation. It will /// This method is carefully constructed to avoid allocation. It will

View File

@@ -56,30 +56,15 @@ pub enum DepNode<D: Clone + Debug> {
WorkProduct(Arc<WorkProductId>), WorkProduct(Arc<WorkProductId>),
// Represents different phases in the compiler. // Represents different phases in the compiler.
CollectLanguageItems,
ResolveLifetimes,
RegionResolveCrate, RegionResolveCrate,
PluginRegistrar,
StabilityIndex,
CollectItem(D),
CollectItemSig(D),
Coherence, Coherence,
Resolve, Resolve,
EntryPoint,
CheckEntryFn,
CoherenceCheckTrait(D), CoherenceCheckTrait(D),
CoherenceCheckImpl(D), CoherenceCheckImpl(D),
CoherenceOverlapCheck(D), CoherenceOverlapCheck(D),
CoherenceOverlapCheckSpecial(D), CoherenceOverlapCheckSpecial(D),
CoherenceOrphanCheck(D),
Variance, Variance,
WfCheck(D),
TypeckItemType(D),
UnusedTraitCheck,
CheckConst(D),
PrivacyAccessLevels(CrateNum), PrivacyAccessLevels(CrateNum),
IntrinsicCheck(D),
MatchCheck(D),
// Represents the MIR for a fn; also used as the task node for // Represents the MIR for a fn; also used as the task node for
// things read/modify that MIR. // things read/modify that MIR.
@@ -91,14 +76,10 @@ pub enum DepNode<D: Clone + Debug> {
BorrowCheck(D), BorrowCheck(D),
RvalueCheck(D), RvalueCheck(D),
Reachability, Reachability,
DeadCheck,
StabilityCheck(D),
LateLintCheck, LateLintCheck,
TransCrate,
TransCrateItem(D), TransCrateItem(D),
TransInlinedItem(D), TransInlinedItem(D),
TransWriteMetadata, TransWriteMetadata,
LinkBinary,
// Nodes representing bits of computed IR in the tcx. Each shared // Nodes representing bits of computed IR in the tcx. Each shared
// table in the tcx (or elsewhere) maps to one of these // table in the tcx (or elsewhere) maps to one of these
@@ -184,12 +165,10 @@ impl<D: Clone + Debug> DepNode<D> {
} }
check! { check! {
CollectItem,
BorrowCheck, BorrowCheck,
Hir, Hir,
HirBody, HirBody,
TransCrateItem, TransCrateItem,
TypeckItemType,
AssociatedItems, AssociatedItems,
ItemSignature, ItemSignature,
AssociatedItemDefIds, AssociatedItemDefIds,
@@ -211,24 +190,14 @@ impl<D: Clone + Debug> DepNode<D> {
BorrowCheckKrate => Some(BorrowCheckKrate), BorrowCheckKrate => Some(BorrowCheckKrate),
MirKrate => Some(MirKrate), MirKrate => Some(MirKrate),
TypeckBodiesKrate => Some(TypeckBodiesKrate), TypeckBodiesKrate => Some(TypeckBodiesKrate),
CollectLanguageItems => Some(CollectLanguageItems),
ResolveLifetimes => Some(ResolveLifetimes),
RegionResolveCrate => Some(RegionResolveCrate), RegionResolveCrate => Some(RegionResolveCrate),
PluginRegistrar => Some(PluginRegistrar),
StabilityIndex => Some(StabilityIndex),
Coherence => Some(Coherence), Coherence => Some(Coherence),
Resolve => Some(Resolve), Resolve => Some(Resolve),
EntryPoint => Some(EntryPoint),
CheckEntryFn => Some(CheckEntryFn),
Variance => Some(Variance), Variance => Some(Variance),
UnusedTraitCheck => Some(UnusedTraitCheck),
PrivacyAccessLevels(k) => Some(PrivacyAccessLevels(k)), PrivacyAccessLevels(k) => Some(PrivacyAccessLevels(k)),
Reachability => Some(Reachability), Reachability => Some(Reachability),
DeadCheck => Some(DeadCheck),
LateLintCheck => Some(LateLintCheck), LateLintCheck => Some(LateLintCheck),
TransCrate => Some(TransCrate),
TransWriteMetadata => Some(TransWriteMetadata), TransWriteMetadata => Some(TransWriteMetadata),
LinkBinary => Some(LinkBinary),
// work product names do not need to be mapped, because // work product names do not need to be mapped, because
// they are always absolute. // they are always absolute.
@@ -237,18 +206,10 @@ impl<D: Clone + Debug> DepNode<D> {
Hir(ref d) => op(d).map(Hir), Hir(ref d) => op(d).map(Hir),
HirBody(ref d) => op(d).map(HirBody), HirBody(ref d) => op(d).map(HirBody),
MetaData(ref d) => op(d).map(MetaData), MetaData(ref d) => op(d).map(MetaData),
CollectItem(ref d) => op(d).map(CollectItem),
CollectItemSig(ref d) => op(d).map(CollectItemSig),
CoherenceCheckTrait(ref d) => op(d).map(CoherenceCheckTrait), CoherenceCheckTrait(ref d) => op(d).map(CoherenceCheckTrait),
CoherenceCheckImpl(ref d) => op(d).map(CoherenceCheckImpl), CoherenceCheckImpl(ref d) => op(d).map(CoherenceCheckImpl),
CoherenceOverlapCheck(ref d) => op(d).map(CoherenceOverlapCheck), CoherenceOverlapCheck(ref d) => op(d).map(CoherenceOverlapCheck),
CoherenceOverlapCheckSpecial(ref d) => op(d).map(CoherenceOverlapCheckSpecial), CoherenceOverlapCheckSpecial(ref d) => op(d).map(CoherenceOverlapCheckSpecial),
CoherenceOrphanCheck(ref d) => op(d).map(CoherenceOrphanCheck),
WfCheck(ref d) => op(d).map(WfCheck),
TypeckItemType(ref d) => op(d).map(TypeckItemType),
CheckConst(ref d) => op(d).map(CheckConst),
IntrinsicCheck(ref d) => op(d).map(IntrinsicCheck),
MatchCheck(ref d) => op(d).map(MatchCheck),
Mir(ref d) => op(d).map(Mir), Mir(ref d) => op(d).map(Mir),
MirShim(ref def_ids) => { MirShim(ref def_ids) => {
let def_ids: Option<Vec<E>> = def_ids.iter().map(op).collect(); let def_ids: Option<Vec<E>> = def_ids.iter().map(op).collect();
@@ -256,7 +217,6 @@ impl<D: Clone + Debug> DepNode<D> {
} }
BorrowCheck(ref d) => op(d).map(BorrowCheck), BorrowCheck(ref d) => op(d).map(BorrowCheck),
RvalueCheck(ref d) => op(d).map(RvalueCheck), RvalueCheck(ref d) => op(d).map(RvalueCheck),
StabilityCheck(ref d) => op(d).map(StabilityCheck),
TransCrateItem(ref d) => op(d).map(TransCrateItem), TransCrateItem(ref d) => op(d).map(TransCrateItem),
TransInlinedItem(ref d) => op(d).map(TransInlinedItem), TransInlinedItem(ref d) => op(d).map(TransInlinedItem),
AssociatedItems(ref d) => op(d).map(AssociatedItems), AssociatedItems(ref d) => op(d).map(AssociatedItems),

View File

@@ -12,7 +12,6 @@
// closely. The idea is that all reachable symbols are live, codes called // closely. The idea is that all reachable symbols are live, codes called
// from live codes are live, and everything else is dead. // from live codes are live, and everything else is dead.
use dep_graph::DepNode;
use hir::map as hir_map; use hir::map as hir_map;
use hir::{self, PatKind}; use hir::{self, PatKind};
use hir::intravisit::{self, Visitor, NestedVisitorMap}; use hir::intravisit::{self, Visitor, NestedVisitorMap};
@@ -594,7 +593,6 @@ impl<'a, 'tcx> Visitor<'tcx> for DeadVisitor<'a, 'tcx> {
} }
pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) { pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
let _task = tcx.dep_graph.in_task(DepNode::DeadCheck);
let access_levels = &ty::queries::privacy_access_levels::get(tcx, DUMMY_SP, LOCAL_CRATE); let access_levels = &ty::queries::privacy_access_levels::get(tcx, DUMMY_SP, LOCAL_CRATE);
let krate = tcx.hir.krate(); let krate = tcx.hir.krate();
let live_symbols = find_live(tcx, access_levels, krate); let live_symbols = find_live(tcx, access_levels, krate);

View File

@@ -9,7 +9,6 @@
// except according to those terms. // except according to those terms.
use dep_graph::DepNode;
use hir::map as hir_map; use hir::map as hir_map;
use hir::def_id::{CRATE_DEF_INDEX}; use hir::def_id::{CRATE_DEF_INDEX};
use session::{config, Session}; use session::{config, Session};
@@ -57,8 +56,6 @@ impl<'a, 'tcx> ItemLikeVisitor<'tcx> for EntryContext<'a, 'tcx> {
} }
pub fn find_entry_point(session: &Session, hir_map: &hir_map::Map) { pub fn find_entry_point(session: &Session, hir_map: &hir_map::Map) {
let _task = hir_map.dep_graph.in_task(DepNode::EntryPoint);
let any_exe = session.crate_types.borrow().iter().any(|ty| { let any_exe = session.crate_types.borrow().iter().any(|ty| {
*ty == config::CrateTypeExecutable *ty == config::CrateTypeExecutable
}); });

View File

@@ -8,7 +8,6 @@
// 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.
use dep_graph::DepNode;
use hir::def::Def; use hir::def::Def;
use hir::def_id::DefId; use hir::def_id::DefId;
use infer::InferCtxt; use infer::InferCtxt;
@@ -25,7 +24,7 @@ pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
let mut visitor = ItemVisitor { let mut visitor = ItemVisitor {
tcx: tcx tcx: tcx
}; };
tcx.visit_all_item_likes_in_krate(DepNode::IntrinsicCheck, &mut visitor.as_deep_visitor()); tcx.hir.krate().visit_all_item_likes(&mut visitor.as_deep_visitor());
} }
struct ItemVisitor<'a, 'tcx: 'a> { struct ItemVisitor<'a, 'tcx: 'a> {

View File

@@ -21,7 +21,6 @@
pub use self::LangItem::*; pub use self::LangItem::*;
use dep_graph::DepNode;
use hir::map as hir_map; use hir::map as hir_map;
use session::Session; use session::Session;
use hir::def_id::DefId; use hir::def_id::DefId;
@@ -236,7 +235,6 @@ pub fn extract(attrs: &[ast::Attribute]) -> Option<Symbol> {
pub fn collect_language_items(session: &Session, pub fn collect_language_items(session: &Session,
map: &hir_map::Map) map: &hir_map::Map)
-> LanguageItems { -> LanguageItems {
let _task = map.dep_graph.in_task(DepNode::CollectLanguageItems);
let krate: &hir::Crate = map.krate(); let krate: &hir::Crate = map.krate();
let mut collector = LanguageItemCollector::new(session, map); let mut collector = LanguageItemCollector::new(session, map);
collector.collect(krate); collector.collect(krate);

View File

@@ -15,7 +15,6 @@
//! used between functions, and they operate in a purely top-down //! used between functions, and they operate in a purely top-down
//! way. Therefore we break lifetime name resolution into a separate pass. //! way. Therefore we break lifetime name resolution into a separate pass.
use dep_graph::DepNode;
use hir::map::Map; use hir::map::Map;
use session::Session; use session::Session;
use hir::def::Def; use hir::def::Def;
@@ -259,7 +258,6 @@ const ROOT_SCOPE: ScopeRef<'static> = &Scope::Root;
pub fn krate(sess: &Session, pub fn krate(sess: &Session,
hir_map: &Map) hir_map: &Map)
-> Result<NamedRegionMap, usize> { -> Result<NamedRegionMap, usize> {
let _task = hir_map.dep_graph.in_task(DepNode::ResolveLifetimes);
let krate = hir_map.krate(); let krate = hir_map.krate();
let mut map = NamedRegionMap { let mut map = NamedRegionMap {
defs: NodeMap(), defs: NodeMap(),

View File

@@ -13,7 +13,6 @@
pub use self::StabilityLevel::*; pub use self::StabilityLevel::*;
use dep_graph::DepNode;
use hir::map as hir_map; use hir::map as hir_map;
use lint; use lint;
use hir::def::Def; use hir::def::Def;
@@ -383,7 +382,6 @@ impl<'a, 'tcx> Index<'tcx> {
// Put the active features into a map for quick lookup // Put the active features into a map for quick lookup
self.active_features = active_lib_features.iter().map(|&(ref s, _)| s.clone()).collect(); self.active_features = active_lib_features.iter().map(|&(ref s, _)| s.clone()).collect();
let _task = tcx.dep_graph.in_task(DepNode::StabilityIndex);
let krate = tcx.hir.krate(); let krate = tcx.hir.krate();
let mut annotator = Annotator { let mut annotator = Annotator {
tcx: tcx, tcx: tcx,
@@ -397,7 +395,6 @@ impl<'a, 'tcx> Index<'tcx> {
} }
pub fn new(hir_map: &hir_map::Map) -> Index<'tcx> { pub fn new(hir_map: &hir_map::Map) -> Index<'tcx> {
let _task = hir_map.dep_graph.in_task(DepNode::StabilityIndex);
let krate = hir_map.krate(); let krate = hir_map.krate();
let mut is_staged_api = false; let mut is_staged_api = false;
@@ -424,7 +421,7 @@ impl<'a, 'tcx> Index<'tcx> {
/// features and possibly prints errors. /// features and possibly prints errors.
pub fn check_unstable_api_usage<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) { pub fn check_unstable_api_usage<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
let mut checker = Checker { tcx: tcx }; let mut checker = Checker { tcx: tcx };
tcx.visit_all_item_likes_in_krate(DepNode::StabilityCheck, &mut checker.as_deep_visitor()); tcx.hir.krate().visit_all_item_likes(&mut checker.as_deep_visitor());
} }
struct Checker<'a, 'tcx: 'a> { struct Checker<'a, 'tcx: 'a> {
@@ -662,7 +659,6 @@ pub fn check_unused_or_stable_features<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
let access_levels = &ty::queries::privacy_access_levels::get(tcx, DUMMY_SP, LOCAL_CRATE); let access_levels = &ty::queries::privacy_access_levels::get(tcx, DUMMY_SP, LOCAL_CRATE);
if tcx.stability.borrow().staged_api[&LOCAL_CRATE] && tcx.sess.features.borrow().staged_api { if tcx.stability.borrow().staged_api[&LOCAL_CRATE] && tcx.sess.features.borrow().staged_api {
let _task = tcx.dep_graph.in_task(DepNode::StabilityIndex);
let krate = tcx.hir.krate(); let krate = tcx.hir.krate();
let mut missing = MissingStabilityAnnotations { let mut missing = MissingStabilityAnnotations {
tcx: tcx, tcx: tcx,

View File

@@ -14,8 +14,6 @@ use _match::WitnessPreference::*;
use pattern::{Pattern, PatternContext, PatternError, PatternKind}; use pattern::{Pattern, PatternContext, PatternError, PatternKind};
use rustc::dep_graph::DepNode;
use rustc::middle::expr_use_visitor::{ConsumeMode, Delegate, ExprUseVisitor}; use rustc::middle::expr_use_visitor::{ConsumeMode, Delegate, ExprUseVisitor};
use rustc::middle::expr_use_visitor::{LoanCause, MutateMode}; use rustc::middle::expr_use_visitor::{LoanCause, MutateMode};
use rustc::middle::expr_use_visitor as euv; use rustc::middle::expr_use_visitor as euv;
@@ -56,8 +54,7 @@ impl<'a, 'tcx> Visitor<'tcx> for OuterVisitor<'a, 'tcx> {
} }
pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) { pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
tcx.visit_all_item_likes_in_krate(DepNode::MatchCheck, tcx.hir.krate().visit_all_item_likes(&mut OuterVisitor { tcx: tcx }.as_deep_visitor());
&mut OuterVisitor { tcx: tcx }.as_deep_visitor());
tcx.sess.abort_if_errors(); tcx.sess.abort_if_errors();
} }

View File

@@ -8,7 +8,6 @@
// 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.
use rustc::dep_graph::DepNode;
use rustc::hir::itemlikevisit::ItemLikeVisitor; use rustc::hir::itemlikevisit::ItemLikeVisitor;
use rustc::hir::map::Map; use rustc::hir::map::Map;
use rustc::hir; use rustc::hir;
@@ -16,7 +15,6 @@ use syntax::ast;
use syntax::attr; use syntax::attr;
pub fn find(hir_map: &Map) -> Option<ast::NodeId> { pub fn find(hir_map: &Map) -> Option<ast::NodeId> {
let _task = hir_map.dep_graph.in_task(DepNode::PluginRegistrar);
let krate = hir_map.krate(); let krate = hir_map.krate();
let mut finder = Finder { registrar: None }; let mut finder = Finder { registrar: None };

View File

@@ -38,9 +38,10 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
debug!("expr_as_temp(block={:?}, expr={:?})", block, expr); debug!("expr_as_temp(block={:?}, expr={:?})", block, expr);
let this = self; let this = self;
if let ExprKind::Scope { .. } = expr.kind { if let ExprKind::Scope { extent, value } = expr.kind {
span_bug!(expr.span, "unexpected scope expression in as_temp: {:?}", return this.in_scope(extent, block, |this| {
expr); this.as_temp(block, temp_lifetime, value)
});
} }
let expr_ty = expr.ty.clone(); let expr_ty = expr.ty.clone();

View File

@@ -16,6 +16,8 @@ use hair::*;
use rustc::ty; use rustc::ty;
use rustc::mir::*; use rustc::mir::*;
use syntax::abi::Abi;
impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
/// Compile `expr`, storing the result into `destination`, which /// Compile `expr`, storing the result into `destination`, which
/// is assumed to be uninitialized. /// is assumed to be uninitialized.
@@ -206,7 +208,30 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
} }
_ => false _ => false
}; };
let intrinsic = match ty.sty {
ty::TyFnDef(def_id, _, ref f) if
f.abi() == Abi::RustIntrinsic ||
f.abi() == Abi::PlatformIntrinsic =>
{
Some(this.hir.tcx().item_name(def_id).as_str())
}
_ => None
};
let intrinsic = intrinsic.as_ref().map(|s| &s[..]);
let fun = unpack!(block = this.as_local_operand(block, fun)); let fun = unpack!(block = this.as_local_operand(block, fun));
if intrinsic == Some("move_val_init") {
// `move_val_init` has "magic" semantics - the second argument is
// always evaluated "directly" into the first one.
let mut args = args.into_iter();
let ptr = args.next().expect("0 arguments to `move_val_init`");
let val = args.next().expect("1 argument to `move_val_init`");
assert!(args.next().is_none(), ">2 arguments to `move_val_init`");
let topmost_scope = this.topmost_scope();
let ptr = unpack!(block = this.as_temp(block, Some(topmost_scope), ptr));
this.into(&ptr.deref(), block, val)
} else {
let args: Vec<_> = let args: Vec<_> =
args.into_iter() args.into_iter()
.map(|arg| unpack!(block = this.as_local_operand(block, arg))) .map(|arg| unpack!(block = this.as_local_operand(block, arg)))
@@ -226,6 +251,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
}); });
success.unit() success.unit()
} }
}
// These cases don't actually need a destination // These cases don't actually need a destination
ExprKind::Assign { .. } | ExprKind::Assign { .. } |

View File

@@ -68,7 +68,7 @@ pub fn build_mir_for_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
NestedVisitorMap::None NestedVisitorMap::None
} }
} }
tcx.visit_all_item_likes_in_krate(DepNode::Mir, &mut GatherCtors { tcx.hir.krate().visit_all_item_likes(&mut GatherCtors {
tcx: tcx tcx: tcx
}.as_deep_visitor()); }.as_deep_visitor());
} }

View File

@@ -205,12 +205,7 @@ fn build_drop_shim<'a, 'tcx>(tcx: ty::TyCtxt<'a, 'tcx, 'tcx>,
patch: MirPatch::new(&mir), patch: MirPatch::new(&mir),
tcx, param_env tcx, param_env
}; };
let dropee = Lvalue::Projection( let dropee = Lvalue::Local(Local::new(1+0)).deref();
box Projection {
base: Lvalue::Local(Local::new(1+0)),
elem: ProjectionElem::Deref
}
);
let resume_block = elaborator.patch.resume_block(); let resume_block = elaborator.patch.resume_block();
elaborate_drops::elaborate_drop( elaborate_drops::elaborate_drop(
&mut elaborator, &mut elaborator,
@@ -310,9 +305,7 @@ fn build_call_shim<'a, 'tcx>(tcx: ty::TyCtxt<'a, 'tcx, 'tcx>,
let rcvr = match rcvr_adjustment { let rcvr = match rcvr_adjustment {
Adjustment::Identity => Operand::Consume(rcvr_l), Adjustment::Identity => Operand::Consume(rcvr_l),
Adjustment::Deref => Operand::Consume(Lvalue::Projection( Adjustment::Deref => Operand::Consume(rcvr_l.deref()),
box Projection { base: rcvr_l, elem: ProjectionElem::Deref }
)),
Adjustment::RefMut => { Adjustment::RefMut => {
// let rcvr = &mut rcvr; // let rcvr = &mut rcvr;
let re_erased = tcx.mk_region(ty::ReErased); let re_erased = tcx.mk_region(ty::ReErased);
@@ -352,10 +345,7 @@ fn build_call_shim<'a, 'tcx>(tcx: ty::TyCtxt<'a, 'tcx, 'tcx>,
if let Some(untuple_args) = untuple_args { if let Some(untuple_args) = untuple_args {
args.extend(untuple_args.iter().enumerate().map(|(i, ity)| { args.extend(untuple_args.iter().enumerate().map(|(i, ity)| {
let arg_lv = Lvalue::Local(Local::new(1+1)); let arg_lv = Lvalue::Local(Local::new(1+1));
Operand::Consume(Lvalue::Projection(box Projection { Operand::Consume(arg_lv.field(Field::new(i), *ity))
base: arg_lv,
elem: ProjectionElem::Field(Field::new(i), *ity)
}))
})); }));
} else { } else {
args.extend((1..sig.inputs().len()).map(|i| { args.extend((1..sig.inputs().len()).map(|i| {

View File

@@ -24,7 +24,6 @@
// - It's not possible to take the address of a static item with unsafe interior. This is enforced // - It's not possible to take the address of a static item with unsafe interior. This is enforced
// by borrowck::gather_loans // by borrowck::gather_loans
use rustc::dep_graph::DepNode;
use rustc::ty::cast::CastKind; use rustc::ty::cast::CastKind;
use rustc_const_eval::ConstContext; use rustc_const_eval::ConstContext;
use rustc::middle::const_val::ConstEvalErr; use rustc::middle::const_val::ConstEvalErr;
@@ -459,8 +458,7 @@ fn check_adjustments<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>, e: &hir::Exp
} }
pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) { pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
tcx.visit_all_item_likes_in_krate(DepNode::CheckConst, tcx.hir.krate().visit_all_item_likes(&mut CheckCrateVisitor {
&mut CheckCrateVisitor {
tcx: tcx, tcx: tcx,
tables: &ty::TypeckTables::empty(), tables: &ty::TypeckTables::empty(),
in_fn: false, in_fn: false,

View File

@@ -14,7 +14,6 @@ use syntax::ast;
use syntax::attr; use syntax::attr;
use errors; use errors;
use syntax_pos::Span; use syntax_pos::Span;
use rustc::dep_graph::DepNode;
use rustc::hir::map::Map; use rustc::hir::map::Map;
use rustc::hir::itemlikevisit::ItemLikeVisitor; use rustc::hir::itemlikevisit::ItemLikeVisitor;
use rustc::hir; use rustc::hir;
@@ -44,7 +43,6 @@ impl<'v> ItemLikeVisitor<'v> for RegistrarFinder {
pub fn find_plugin_registrar(diagnostic: &errors::Handler, pub fn find_plugin_registrar(diagnostic: &errors::Handler,
hir_map: &Map) hir_map: &Map)
-> Option<ast::NodeId> { -> Option<ast::NodeId> {
let _task = hir_map.dep_graph.in_task(DepNode::PluginRegistrar);
let krate = hir_map.krate(); let krate = hir_map.krate();
let mut finder = RegistrarFinder { registrars: Vec::new() }; let mut finder = RegistrarFinder { registrars: Vec::new() };

View File

@@ -192,8 +192,6 @@ pub fn link_binary(sess: &Session,
trans: &CrateTranslation, trans: &CrateTranslation,
outputs: &OutputFilenames, outputs: &OutputFilenames,
crate_name: &str) -> Vec<PathBuf> { crate_name: &str) -> Vec<PathBuf> {
let _task = sess.dep_graph.in_task(DepNode::LinkBinary);
let mut out_filenames = Vec::new(); let mut out_filenames = Vec::new();
for &crate_type in sess.crate_types.borrow().iter() { for &crate_type in sess.crate_types.borrow().iter() {
// Ignore executable crates if we have -Z no-trans, as they will error. // Ignore executable crates if we have -Z no-trans, as they will error.

View File

@@ -38,7 +38,7 @@ use rustc::hir::def_id::LOCAL_CRATE;
use middle::lang_items::StartFnLangItem; use middle::lang_items::StartFnLangItem;
use middle::cstore::EncodedMetadata; use middle::cstore::EncodedMetadata;
use rustc::ty::{self, Ty, TyCtxt}; use rustc::ty::{self, Ty, TyCtxt};
use rustc::dep_graph::{AssertDepGraphSafe, DepNode}; use rustc::dep_graph::AssertDepGraphSafe;
use rustc::middle::cstore::LinkMeta; use rustc::middle::cstore::LinkMeta;
use rustc::hir::map as hir_map; use rustc::hir::map as hir_map;
use rustc::util::common::time; use rustc::util::common::time;
@@ -1057,8 +1057,6 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
analysis: ty::CrateAnalysis, analysis: ty::CrateAnalysis,
incremental_hashes_map: &IncrementalHashesMap) incremental_hashes_map: &IncrementalHashesMap)
-> CrateTranslation { -> CrateTranslation {
let _task = tcx.dep_graph.in_task(DepNode::TransCrate);
// Be careful with this krate: obviously it gives access to the // Be careful with this krate: obviously it gives access to the
// entire contents of the krate. So if you push any subtasks of // entire contents of the krate. So if you push any subtasks of
// `TransCrate`, you need to be careful to register "reads" of the // `TransCrate`, you need to be careful to register "reads" of the

View File

@@ -418,16 +418,6 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> {
}; };
let intrinsic = intrinsic.as_ref().map(|s| &s[..]); let intrinsic = intrinsic.as_ref().map(|s| &s[..]);
if intrinsic == Some("move_val_init") {
let &(_, target) = destination.as_ref().unwrap();
// The first argument is a thin destination pointer.
let llptr = self.trans_operand(&bcx, &args[0]).immediate();
let val = self.trans_operand(&bcx, &args[1]);
self.store_operand(&bcx, llptr, None, val);
funclet_br(self, bcx, target);
return;
}
if intrinsic == Some("transmute") { if intrinsic == Some("transmute") {
let &(ref dest, target) = destination.as_ref().unwrap(); let &(ref dest, target) = destination.as_ref().unwrap();
self.trans_transmute(&bcx, &args[0], dest); self.trans_transmute(&bcx, &args[0], dest);

View File

@@ -82,7 +82,6 @@ pub use self::compare_method::{compare_impl_method, compare_const_impl};
use self::TupleArgumentsFlag::*; use self::TupleArgumentsFlag::*;
use astconv::AstConv; use astconv::AstConv;
use dep_graph::DepNode;
use fmt_macros::{Parser, Piece, Position}; use fmt_macros::{Parser, Piece, Position};
use hir::def::{Def, CtorKind}; use hir::def::{Def, CtorKind};
use hir::def_id::{CrateNum, DefId, LOCAL_CRATE}; use hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
@@ -577,14 +576,13 @@ impl<'a, 'tcx> ItemLikeVisitor<'tcx> for CheckItemTypesVisitor<'a, 'tcx> {
pub fn check_wf_new<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> CompileResult { pub fn check_wf_new<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> CompileResult {
tcx.sess.track_errors(|| { tcx.sess.track_errors(|| {
let mut visit = wfcheck::CheckTypeWellFormedVisitor::new(tcx); let mut visit = wfcheck::CheckTypeWellFormedVisitor::new(tcx);
tcx.visit_all_item_likes_in_krate(DepNode::WfCheck, &mut visit.as_deep_visitor()); tcx.hir.krate().visit_all_item_likes(&mut visit.as_deep_visitor());
}) })
} }
pub fn check_item_types<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> CompileResult { pub fn check_item_types<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> CompileResult {
tcx.sess.track_errors(|| { tcx.sess.track_errors(|| {
tcx.visit_all_item_likes_in_krate(DepNode::TypeckItemType, tcx.hir.krate().visit_all_item_likes(&mut CheckItemTypesVisitor { tcx });
&mut CheckItemTypesVisitor { tcx });
}) })
} }

View File

@@ -9,7 +9,6 @@
// except according to those terms. // except according to those terms.
use lint; use lint;
use rustc::dep_graph::DepNode;
use rustc::ty::TyCtxt; use rustc::ty::TyCtxt;
use syntax::ast; use syntax::ast;
@@ -62,8 +61,6 @@ impl<'a, 'tcx, 'v> ItemLikeVisitor<'v> for CheckVisitor<'a, 'tcx> {
} }
pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) { pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
let _task = tcx.dep_graph.in_task(DepNode::UnusedTraitCheck);
let mut used_trait_imports = DefIdSet(); let mut used_trait_imports = DefIdSet();
for &body_id in tcx.hir.krate().bodies.keys() { for &body_id in tcx.hir.krate().bodies.keys() {
let item_id = tcx.hir.body_owner(body_id); let item_id = tcx.hir.body_owner(body_id);

View File

@@ -18,7 +18,6 @@
use hir::def_id::{CrateNum, DefId, LOCAL_CRATE}; use hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
use rustc::ty::{self, TyCtxt, TypeFoldable}; use rustc::ty::{self, TyCtxt, TypeFoldable};
use rustc::ty::maps::Providers; use rustc::ty::maps::Providers;
use rustc::dep_graph::DepNode;
use syntax::ast; use syntax::ast;
use syntax_pos::DUMMY_SP; use syntax_pos::DUMMY_SP;
@@ -132,7 +131,6 @@ fn coherent_trait<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
} }
pub fn check_coherence<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) { pub fn check_coherence<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
let _task = tcx.dep_graph.in_task(DepNode::Coherence);
for &trait_def_id in tcx.hir.krate().trait_impls.keys() { for &trait_def_id in tcx.hir.krate().trait_impls.keys() {
ty::queries::coherent_trait::get(tcx, DUMMY_SP, (LOCAL_CRATE, trait_def_id)); ty::queries::coherent_trait::get(tcx, DUMMY_SP, (LOCAL_CRATE, trait_def_id));
} }

View File

@@ -13,13 +13,12 @@
use rustc::traits; use rustc::traits;
use rustc::ty::{self, TyCtxt}; use rustc::ty::{self, TyCtxt};
use rustc::dep_graph::DepNode;
use rustc::hir::itemlikevisit::ItemLikeVisitor; use rustc::hir::itemlikevisit::ItemLikeVisitor;
use rustc::hir; use rustc::hir;
pub fn check<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) { pub fn check<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
let mut orphan = OrphanChecker { tcx: tcx }; let mut orphan = OrphanChecker { tcx: tcx };
tcx.visit_all_item_likes_in_krate(DepNode::CoherenceOrphanCheck, &mut orphan); tcx.hir.krate().visit_all_item_likes(&mut orphan);
} }
struct OrphanChecker<'cx, 'tcx: 'cx> { struct OrphanChecker<'cx, 'tcx: 'cx> {

View File

@@ -24,7 +24,7 @@ pub fn check_default_impls<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
// this secondary walk specifically checks for some other cases, // this secondary walk specifically checks for some other cases,
// like defaulted traits, for which additional overlap rules exist // like defaulted traits, for which additional overlap rules exist
tcx.visit_all_item_likes_in_krate(DepNode::CoherenceOverlapCheckSpecial, &mut overlap); tcx.hir.krate().visit_all_item_likes(&mut overlap);
} }
pub fn check_impl<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, node_id: ast::NodeId) { pub fn check_impl<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, node_id: ast::NodeId) {

View File

@@ -64,7 +64,6 @@ use rustc::ty::{ToPredicate, ReprOptions};
use rustc::ty::{self, AdtKind, ToPolyTraitRef, Ty, TyCtxt}; use rustc::ty::{self, AdtKind, ToPolyTraitRef, Ty, TyCtxt};
use rustc::ty::maps::Providers; use rustc::ty::maps::Providers;
use rustc::ty::util::IntTypeExt; use rustc::ty::util::IntTypeExt;
use rustc::dep_graph::DepNode;
use util::nodemap::{NodeMap, FxHashMap}; use util::nodemap::{NodeMap, FxHashMap};
use rustc_const_math::ConstInt; use rustc_const_math::ConstInt;
@@ -87,7 +86,7 @@ use rustc::hir::def_id::DefId;
pub fn collect_item_types<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) { pub fn collect_item_types<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
let mut visitor = CollectItemTypesVisitor { tcx: tcx }; let mut visitor = CollectItemTypesVisitor { tcx: tcx };
tcx.visit_all_item_likes_in_krate(DepNode::CollectItem, &mut visitor.as_deep_visitor()); tcx.hir.krate().visit_all_item_likes(&mut visitor.as_deep_visitor());
} }
pub fn provide(providers: &mut Providers) { pub fn provide(providers: &mut Providers) {
@@ -126,57 +125,13 @@ struct CollectItemTypesVisitor<'a, 'tcx: 'a> {
tcx: TyCtxt<'a, 'tcx, 'tcx> tcx: TyCtxt<'a, 'tcx, 'tcx>
} }
impl<'a, 'tcx> CollectItemTypesVisitor<'a, 'tcx> {
/// Collect item types is structured into two tasks. The outer
/// task, `CollectItem`, walks the entire content of an item-like
/// thing, including its body. It also spawns an inner task,
/// `CollectItemSig`, which walks only the signature. This inner
/// task is the one that writes the item-type into the various
/// maps. This setup ensures that the item body is never
/// accessible to the task that computes its signature, so that
/// changes to the body don't affect the signature.
///
/// Consider an example function `foo` that also has a closure in its body:
///
/// ```
/// fn foo(<sig>) {
/// ...
/// let bar = || ...; // we'll label this closure as "bar" below
/// }
/// ```
///
/// This results in a dep-graph like so. I've labeled the edges to
/// document where they arise.
///
/// ```
/// [HirBody(foo)] -2--> [CollectItem(foo)] -4-> [ItemSignature(bar)]
/// ^ ^
/// 1 3
/// [Hir(foo)] -----------+-6-> [CollectItemSig(foo)] -5-> [ItemSignature(foo)]
/// ```
///
/// 1. This is added by the `visit_all_item_likes_in_krate`.
/// 2. This is added when we fetch the item body.
/// 3. This is added because `CollectItem` launches `CollectItemSig`.
/// - it is arguably false; if we refactor the `with_task` system;
/// we could get probably rid of it, but it is also harmless enough.
/// 4. This is added by the code in `visit_expr` when we write to `item_types`.
/// 5. This is added by the code in `convert_item` when we write to `item_types`;
/// note that this write occurs inside the `CollectItemSig` task.
/// 6. Added by reads from within `op`.
fn with_collect_item_sig(&self, id: ast::NodeId, op: fn(TyCtxt<'a, 'tcx, 'tcx>, ast::NodeId)) {
let def_id = self.tcx.hir.local_def_id(id);
self.tcx.dep_graph.with_task(DepNode::CollectItemSig(def_id), self.tcx, id, op);
}
}
impl<'a, 'tcx> Visitor<'tcx> for CollectItemTypesVisitor<'a, 'tcx> { impl<'a, 'tcx> Visitor<'tcx> for CollectItemTypesVisitor<'a, 'tcx> {
fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> { fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> {
NestedVisitorMap::OnlyBodies(&self.tcx.hir) NestedVisitorMap::OnlyBodies(&self.tcx.hir)
} }
fn visit_item(&mut self, item: &'tcx hir::Item) { fn visit_item(&mut self, item: &'tcx hir::Item) {
self.with_collect_item_sig(item.id, convert_item); convert_item(self.tcx, item.id);
intravisit::walk_item(self, item); intravisit::walk_item(self, item);
} }
@@ -209,12 +164,12 @@ impl<'a, 'tcx> Visitor<'tcx> for CollectItemTypesVisitor<'a, 'tcx> {
} }
fn visit_trait_item(&mut self, trait_item: &'tcx hir::TraitItem) { fn visit_trait_item(&mut self, trait_item: &'tcx hir::TraitItem) {
self.with_collect_item_sig(trait_item.id, convert_trait_item); convert_trait_item(self.tcx, trait_item.id);
intravisit::walk_trait_item(self, trait_item); intravisit::walk_trait_item(self, trait_item);
} }
fn visit_impl_item(&mut self, impl_item: &'tcx hir::ImplItem) { fn visit_impl_item(&mut self, impl_item: &'tcx hir::ImplItem) {
self.with_collect_item_sig(impl_item.id, convert_impl_item); convert_impl_item(self.tcx, impl_item.id);
intravisit::walk_impl_item(self, impl_item); intravisit::walk_impl_item(self, impl_item);
} }
} }

View File

@@ -19,7 +19,6 @@
//! fixed, but for the moment it's easier to do these checks early. //! fixed, but for the moment it's easier to do these checks early.
use constrained_type_params as ctp; use constrained_type_params as ctp;
use rustc::dep_graph::DepNode;
use rustc::hir; use rustc::hir;
use rustc::hir::itemlikevisit::ItemLikeVisitor; use rustc::hir::itemlikevisit::ItemLikeVisitor;
use rustc::hir::def_id::DefId; use rustc::hir::def_id::DefId;
@@ -63,7 +62,7 @@ pub fn impl_wf_check<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
// We will tag this as part of the WF check -- logically, it is, // We will tag this as part of the WF check -- logically, it is,
// but it's one that we must perform earlier than the rest of // but it's one that we must perform earlier than the rest of
// WfCheck. // WfCheck.
tcx.visit_all_item_likes_in_krate(DepNode::WfCheck, &mut ImplWfCheck { tcx: tcx }); tcx.hir.krate().visit_all_item_likes(&mut ImplWfCheck { tcx: tcx });
} }
struct ImplWfCheck<'a, 'tcx: 'a> { struct ImplWfCheck<'a, 'tcx: 'a> {

View File

@@ -104,7 +104,6 @@ pub use rustc::middle;
pub use rustc::session; pub use rustc::session;
pub use rustc::util; pub use rustc::util;
use dep_graph::DepNode;
use hir::map as hir_map; use hir::map as hir_map;
use rustc::infer::InferOk; use rustc::infer::InferOk;
use rustc::ty::subst::Substs; use rustc::ty::subst::Substs;
@@ -273,7 +272,6 @@ fn check_start_fn_ty<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
} }
fn check_for_entry_fn<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) { fn check_for_entry_fn<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
let _task = tcx.dep_graph.in_task(DepNode::CheckEntryFn);
if let Some((id, sp)) = *tcx.sess.entry_fn.borrow() { if let Some((id, sp)) = *tcx.sess.entry_fn.borrow() {
match tcx.sess.entry_type.get() { match tcx.sess.entry_type.get() {
Some(config::EntryMain) => check_main_fn_ty(tcx, id, sp), Some(config::EntryMain) => check_main_fn_ty(tcx, id, sp),

View File

@@ -270,19 +270,22 @@ impl Command {
} }
if let Some(fd) = stdio.stderr.fd() { if let Some(fd) = stdio.stderr.fd() {
let _ = syscall::close(2); t!(cvt(syscall::dup2(fd, 2, &[])));
t!(cvt(syscall::dup(fd, &[]))); let mut flags = t!(cvt(syscall::fcntl(2, syscall::F_GETFL, 0)));
let _ = syscall::close(fd); flags &= ! syscall::O_CLOEXEC;
t!(cvt(syscall::fcntl(2, syscall::F_SETFL, flags)));
} }
if let Some(fd) = stdio.stdout.fd() { if let Some(fd) = stdio.stdout.fd() {
let _ = syscall::close(1); t!(cvt(syscall::dup2(fd, 1, &[])));
t!(cvt(syscall::dup(fd, &[]))); let mut flags = t!(cvt(syscall::fcntl(1, syscall::F_GETFL, 0)));
let _ = syscall::close(fd); flags &= ! syscall::O_CLOEXEC;
t!(cvt(syscall::fcntl(1, syscall::F_SETFL, flags)));
} }
if let Some(fd) = stdio.stdin.fd() { if let Some(fd) = stdio.stdin.fd() {
let _ = syscall::close(0); t!(cvt(syscall::dup2(fd, 0, &[])));
t!(cvt(syscall::dup(fd, &[]))); let mut flags = t!(cvt(syscall::fcntl(0, syscall::F_GETFL, 0)));
let _ = syscall::close(fd); flags &= ! syscall::O_CLOEXEC;
t!(cvt(syscall::fcntl(0, syscall::F_SETFL, flags)));
} }
if let Some(g) = self.gid { if let Some(g) = self.gid {

View File

@@ -71,6 +71,11 @@ pub fn dup(fd: usize, buf: &[u8]) -> Result<usize> {
unsafe { syscall3(SYS_DUP, fd, buf.as_ptr() as usize, buf.len()) } unsafe { syscall3(SYS_DUP, fd, buf.as_ptr() as usize, buf.len()) }
} }
/// Copy and transform a file descriptor
pub fn dup2(fd: usize, newfd: usize, buf: &[u8]) -> Result<usize> {
unsafe { syscall4(SYS_DUP2, fd, newfd, buf.as_ptr() as usize, buf.len()) }
}
/// Replace the current process with a new executable /// Replace the current process with a new executable
pub fn execve(path: &str, args: &[[usize; 2]]) -> Result<usize> { pub fn execve(path: &str, args: &[[usize; 2]]) -> Result<usize> {
unsafe { syscall4(SYS_EXECVE, path.as_ptr() as usize, path.len(), unsafe { syscall4(SYS_EXECVE, path.as_ptr() as usize, path.len(),

View File

@@ -28,6 +28,7 @@ pub const SYS_UNLINK: usize = SYS_CLASS_PATH | 10;
pub const SYS_CLOSE: usize = SYS_CLASS_FILE | 6; pub const SYS_CLOSE: usize = SYS_CLASS_FILE | 6;
pub const SYS_DUP: usize = SYS_CLASS_FILE | SYS_RET_FILE | 41; pub const SYS_DUP: usize = SYS_CLASS_FILE | SYS_RET_FILE | 41;
pub const SYS_DUP2: usize = SYS_CLASS_FILE | SYS_RET_FILE | 63;
pub const SYS_READ: usize = SYS_CLASS_FILE | SYS_ARG_MSLICE | 3; pub const SYS_READ: usize = SYS_CLASS_FILE | SYS_ARG_MSLICE | 3;
pub const SYS_WRITE: usize = SYS_CLASS_FILE | SYS_ARG_SLICE | 4; pub const SYS_WRITE: usize = SYS_CLASS_FILE | SYS_ARG_SLICE | 4;
pub const SYS_LSEEK: usize = SYS_CLASS_FILE | 19; pub const SYS_LSEEK: usize = SYS_CLASS_FILE | 19;

View File

@@ -93,87 +93,11 @@ fn _print(w: &mut Write, format: PrintFormat) -> io::Result<()> {
Ok(()) Ok(())
} }
fn filter_frames(frames: &[Frame], fn filter_frames(_frames: &[Frame],
format: PrintFormat, _format: PrintFormat,
context: &BacktraceContext) -> (usize, usize) _context: &BacktraceContext) -> (usize, usize)
{ {
if format == PrintFormat::Full { (0, 0)
return (0, 0);
}
// We want to filter out frames with some prefixes
// from both top and bottom of the call stack.
static BAD_PREFIXES_TOP: &'static [&'static str] = &[
"_ZN3std3sys3imp9backtrace",
"ZN3std3sys3imp9backtrace",
"std::sys::imp::backtrace",
"_ZN3std10sys_common9backtrace",
"ZN3std10sys_common9backtrace",
"std::sys_common::backtrace",
"_ZN3std9panicking",
"ZN3std9panicking",
"std::panicking",
"_ZN4core9panicking",
"ZN4core9panicking",
"core::panicking",
"_ZN4core6result13unwrap_failed",
"ZN4core6result13unwrap_failed",
"core::result::unwrap_failed",
"rust_begin_unwind",
"_ZN4drop",
"mingw_set_invalid_parameter_handler",
];
static BAD_PREFIXES_BOTTOM: &'static [&'static str] = &[
"_ZN3std9panicking",
"ZN3std9panicking",
"std::panicking",
"_ZN3std5panic",
"ZN3std5panic",
"std::panic",
"_ZN4core9panicking",
"ZN4core9panicking",
"core::panicking",
"_ZN3std2rt10lang_start",
"ZN3std2rt10lang_start",
"std::rt::lang_start",
"panic_unwind::__rust_maybe_catch_panic",
"__rust_maybe_catch_panic",
"_rust_maybe_catch_panic",
"__libc_start_main",
"__rust_try",
"_start",
"main",
"BaseThreadInitThunk",
"RtlInitializeExceptionChain",
"__scrt_common_main_seh",
"_ZN4drop",
"mingw_set_invalid_parameter_handler",
];
let is_good_frame = |frame: Frame, bad_prefixes: &[&str]| {
resolve_symname(frame, |symname| {
if let Some(mangled_symbol_name) = symname {
if !bad_prefixes.iter().any(|s| mangled_symbol_name.starts_with(s)) {
return Ok(())
}
}
Err(io::Error::from(io::ErrorKind::Other))
}, context).is_ok()
};
let skipped_before = frames.iter().position(|frame| {
is_good_frame(*frame, BAD_PREFIXES_TOP)
}).unwrap_or(frames.len());
let skipped_after = frames[skipped_before..].iter().rev().position(|frame| {
is_good_frame(*frame, BAD_PREFIXES_BOTTOM)
}).unwrap_or(frames.len() - skipped_before);
if skipped_before + skipped_after == frames.len() {
// Avoid showing completely empty backtraces
return (0, 0);
}
(skipped_before, skipped_after)
} }
/// Controls how the backtrace should be formated. /// Controls how the backtrace should be formated.

View File

@@ -0,0 +1,29 @@
// Copyright 2017 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.
// compile-flags: -C no-prepopulate-passes
#![feature(core_intrinsics)]
#![crate_type = "lib"]
// test that `move_val_init` actually avoids big allocas
use std::intrinsics::move_val_init;
pub struct Big {
pub data: [u8; 65536]
}
// CHECK-LABEL: @test_mvi
#[no_mangle]
pub unsafe fn test_mvi(target: *mut Big, make_big: fn() -> Big) {
// CHECK: call void %1(%Big*{{[^%]*}} %0)
move_val_init(target, make_big());
}

View File

@@ -35,44 +35,36 @@ mod signatures {
use WillChange; use WillChange;
#[rustc_then_this_would_need(ItemSignature)] //~ ERROR no path #[rustc_then_this_would_need(ItemSignature)] //~ ERROR no path
#[rustc_then_this_would_need(CollectItem)] //~ ERROR no path
trait Bar { trait Bar {
#[rustc_then_this_would_need(ItemSignature)] //~ ERROR OK #[rustc_then_this_would_need(ItemSignature)] //~ ERROR OK
#[rustc_then_this_would_need(CollectItem)] //~ ERROR OK
fn do_something(x: WillChange); fn do_something(x: WillChange);
} }
#[rustc_then_this_would_need(ItemSignature)] //~ ERROR OK #[rustc_then_this_would_need(ItemSignature)] //~ ERROR OK
#[rustc_then_this_would_need(CollectItem)] //~ ERROR OK
fn some_fn(x: WillChange) { } fn some_fn(x: WillChange) { }
#[rustc_then_this_would_need(ItemSignature)] //~ ERROR OK #[rustc_then_this_would_need(ItemSignature)] //~ ERROR OK
#[rustc_then_this_would_need(CollectItem)] //~ ERROR OK
fn new_foo(x: u32, y: u32) -> WillChange { fn new_foo(x: u32, y: u32) -> WillChange {
WillChange { x: x, y: y } WillChange { x: x, y: y }
} }
#[rustc_then_this_would_need(ItemSignature)] //~ ERROR OK #[rustc_then_this_would_need(ItemSignature)] //~ ERROR OK
#[rustc_then_this_would_need(CollectItem)] //~ ERROR OK
impl WillChange { impl WillChange {
fn new(x: u32, y: u32) -> WillChange { loop { } } fn new(x: u32, y: u32) -> WillChange { loop { } }
} }
#[rustc_then_this_would_need(ItemSignature)] //~ ERROR OK #[rustc_then_this_would_need(ItemSignature)] //~ ERROR OK
#[rustc_then_this_would_need(CollectItem)] //~ ERROR OK
impl WillChange { impl WillChange {
fn method(&self, x: u32) { } fn method(&self, x: u32) { }
} }
#[rustc_then_this_would_need(ItemSignature)] //~ ERROR OK #[rustc_then_this_would_need(ItemSignature)] //~ ERROR OK
#[rustc_then_this_would_need(CollectItem)] //~ ERROR OK
struct WillChanges { struct WillChanges {
x: WillChange, x: WillChange,
y: WillChange y: WillChange
} }
#[rustc_then_this_would_need(ItemSignature)] //~ ERROR OK #[rustc_then_this_would_need(ItemSignature)] //~ ERROR OK
#[rustc_then_this_would_need(CollectItem)] //~ ERROR OK
fn indirect(x: WillChanges) { } fn indirect(x: WillChanges) { }
} }
@@ -80,17 +72,14 @@ mod invalid_signatures {
use WontChange; use WontChange;
#[rustc_then_this_would_need(ItemSignature)] //~ ERROR no path #[rustc_then_this_would_need(ItemSignature)] //~ ERROR no path
#[rustc_then_this_would_need(CollectItem)] //~ ERROR no path
trait A { trait A {
fn do_something_else_twice(x: WontChange); fn do_something_else_twice(x: WontChange);
} }
#[rustc_then_this_would_need(ItemSignature)] //~ ERROR no path #[rustc_then_this_would_need(ItemSignature)] //~ ERROR no path
#[rustc_then_this_would_need(CollectItem)] //~ ERROR no path
fn b(x: WontChange) { } fn b(x: WontChange) { }
#[rustc_then_this_would_need(ItemSignature)] //~ ERROR no path from `WillChange` #[rustc_then_this_would_need(ItemSignature)] //~ ERROR no path from `WillChange`
#[rustc_then_this_would_need(CollectItem)] //~ ERROR no path from `WillChange`
fn c(x: u32) { } fn c(x: u32) { }
} }