diff --git a/src/doc/robots.txt b/src/doc/robots.txt new file mode 100644 index 0000000000000..a54ec508c1bef --- /dev/null +++ b/src/doc/robots.txt @@ -0,0 +1,19 @@ +# NB: This file is not automatically deployed. After changes, it needs to be uploaded manually to doc.rust-lang.org +User-agent: * +Disallow: /0.3/ +Disallow: /0.4/ +Disallow: /0.5/ +Disallow: /0.6/ +Disallow: /0.7/ +Disallow: /0.8/ +Disallow: /0.9/ +Disallow: /0.10/ +Disallow: /0.11.0/ +Disallow: /0.12.0/ +Disallow: /1.0.0-alpha/ +Disallow: /1.0.0-alpha.2/ +Disallow: /1.0.0-beta/ +Disallow: /1.0.0-beta.2/ +Disallow: /1.0.0-beta.3/ +Disallow: /1.0.0-beta.4/ +Disallow: /1.0.0-beta.5/ diff --git a/src/libcore/hint.rs b/src/libcore/hint.rs index 89de5c1bc8af8..b2f82ef0d175c 100644 --- a/src/libcore/hint.rs +++ b/src/libcore/hint.rs @@ -62,13 +62,32 @@ pub unsafe fn unreachable_unchecked() -> ! { #[inline] #[unstable(feature = "renamed_spin_loop", issue = "55002")] pub fn spin_loop() { - #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] - unsafe { - asm!("pause" ::: "memory" : "volatile"); + #[cfg( + all( + any(target_arch = "x86", target_arch = "x86_64"), + target_feature = "sse2" + ) + )] { + #[cfg(target_arch = "x86")] { + unsafe { crate::arch::x86::_mm_pause() }; + } + + #[cfg(target_arch = "x86_64")] { + unsafe { crate::arch::x86_64::_mm_pause() }; + } } - #[cfg(target_arch = "aarch64")] - unsafe { - asm!("yield" ::: "memory" : "volatile"); + #[cfg( + any( + target_arch = "aarch64", + all(target_arch = "arm", target_feature = "v6") + ) + )] { + #[cfg(target_arch = "aarch64")] { + unsafe { crate::arch::aarch64::__yield() }; + } + #[cfg(target_arch = "arm")] { + unsafe { crate::arch::arm::__yield() }; + } } } diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index 73c3b3026d98b..84d43b1a4b672 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -4335,13 +4335,14 @@ impl<'a> LoweringContext<'a> { // } // expand - let head = self.lower_expr(head); + let mut head = self.lower_expr(head); let head_sp = head.span; let desugared_span = self.mark_span_with_reason( CompilerDesugaringKind::ForLoop, head_sp, None, ); + head.span = desugared_span; let iter = self.str_to_ident("iter"); diff --git a/src/librustc/middle/dead.rs b/src/librustc/middle/dead.rs index ccec4bd143269..a686916453ecf 100644 --- a/src/librustc/middle/dead.rs +++ b/src/librustc/middle/dead.rs @@ -92,8 +92,8 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> { } fn lookup_and_handle_method(&mut self, id: hir::HirId) { - if let Some(def) = self.tables.type_dependent_defs().get(id) { - self.check_def_id(def.def_id()); + if let Some(def_id) = self.tables.type_dependent_def_id(id) { + self.check_def_id(def_id); } else { bug!("no type-dependent def for method"); } diff --git a/src/librustc/middle/expr_use_visitor.rs b/src/librustc/middle/expr_use_visitor.rs index 8ada67efaafdd..db640b581d353 100644 --- a/src/librustc/middle/expr_use_visitor.rs +++ b/src/librustc/middle/expr_use_visitor.rs @@ -559,8 +559,7 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> { } ty::Error => { } _ => { - if let Some(def) = self.mc.tables.type_dependent_defs().get(call.hir_id) { - let def_id = def.def_id(); + if let Some(def_id) = self.mc.tables.type_dependent_def_id(call.hir_id) { let call_scope = region::Scope { id: call.hir_id.local_id, data: region::ScopeData::Node diff --git a/src/librustc/middle/reachable.rs b/src/librustc/middle/reachable.rs index a7294dbf07c00..6a7073e04aa03 100644 --- a/src/librustc/middle/reachable.rs +++ b/src/librustc/middle/reachable.rs @@ -97,7 +97,7 @@ impl<'a, 'tcx> Visitor<'tcx> for ReachableContext<'a, 'tcx> { Some(self.tables.qpath_def(qpath, expr.hir_id)) } hir::ExprKind::MethodCall(..) => { - self.tables.type_dependent_defs().get(expr.hir_id).cloned() + self.tables.type_dependent_def(expr.hir_id) } _ => None }; diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index 6de0a39c91b51..ea003ba1ac701 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -482,6 +482,15 @@ impl<'tcx> TypeckTables<'tcx> { } } + pub fn type_dependent_def(&self, id: HirId) -> Option { + validate_hir_id_for_typeck_tables(self.local_id_root, id, false); + self.type_dependent_defs.get(&id.local_id).cloned() + } + + pub fn type_dependent_def_id(&self, id: HirId) -> Option { + self.type_dependent_def(id).map(|def| def.def_id()) + } + pub fn type_dependent_defs_mut(&mut self) -> LocalTableInContextMut<'_, Def> { LocalTableInContextMut { local_id_root: self.local_id_root, diff --git a/src/librustc/ty/query/mod.rs b/src/librustc/ty/query/mod.rs index 2f085a973d202..a2d7815920e0b 100644 --- a/src/librustc/ty/query/mod.rs +++ b/src/librustc/ty/query/mod.rs @@ -272,7 +272,7 @@ rustc_query_append! { [define_queries!][ <'tcx> TypeChecking { [] fn typeck_item_bodies: - typeck_item_bodies_dep_node(CrateNum) -> Result<(), ErrorReported>, + typeck_item_bodies_dep_node(CrateNum) -> (), [] fn typeck_tables_of: TypeckTables(DefId) -> &'tcx ty::TypeckTables<'tcx>, }, @@ -325,8 +325,7 @@ rustc_query_append! { [define_queries!][ <'tcx> }, TypeChecking { - [] fn check_match: CheckMatch(DefId) - -> Result<(), ErrorReported>, + [] fn check_match: CheckMatch(DefId) -> (), /// Performs part of the privacy check and computes "access levels". [] fn privacy_access_levels: PrivacyAccessLevels(CrateNum) -> Lrc, diff --git a/src/librustc_borrowck/borrowck/mod.rs b/src/librustc_borrowck/borrowck/mod.rs index 01bfe5d5af706..ce9e493962ecb 100644 --- a/src/librustc_borrowck/borrowck/mod.rs +++ b/src/librustc_borrowck/borrowck/mod.rs @@ -35,6 +35,7 @@ use std::rc::Rc; use rustc_data_structures::sync::Lrc; use std::hash::{Hash, Hasher}; use syntax::ast; +use syntax::source_map::CompilerDesugaringKind; use syntax_pos::{MultiSpan, Span}; use errors::{Applicability, DiagnosticBuilder, DiagnosticId}; use log::debug; @@ -746,6 +747,19 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> { }, moved_lp.ty)); } + if let (Some(CompilerDesugaringKind::ForLoop), Ok(snippet)) = ( + move_span.compiler_desugaring_kind(), + self.tcx.sess.source_map().span_to_snippet(move_span), + ) { + if !snippet.starts_with("&") { + err.span_suggestion( + move_span, + "consider borrowing this to avoid moving it into the for loop", + format!("&{}", snippet), + Applicability::MaybeIncorrect, + ); + } + } // Note: we used to suggest adding a `ref binding` or calling // `clone` but those suggestions have been removed because diff --git a/src/librustc_driver/pretty.rs b/src/librustc_driver/pretty.rs index dde88a212408d..ace5198deaf2e 100644 --- a/src/librustc_driver/pretty.rs +++ b/src/librustc_driver/pretty.rs @@ -633,10 +633,20 @@ fn print_flowgraph<'a, 'tcx, W: Write>(variants: Vec, let body = tcx.hir().body(body_id); let cfg = cfg::CFG::new(tcx, &body); let labelled_edges = mode != PpFlowGraphMode::UnlabelledEdges; + let hir_id = code.id(); + // We have to disassemble the hir_id because name must be ASCII + // alphanumeric. This does not appear in the rendered graph, so it does not + // have to be user friendly. + let name = format!( + "hir_id_{}_{}_{}", + hir_id.owner.address_space().index(), + hir_id.owner.as_array_index(), + hir_id.local_id.index(), + ); let lcfg = LabelledCFG { tcx, cfg: &cfg, - name: format!("node_{}", code.id()), + name, labelled_edges, }; diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs index 0c710fd283be8..c199829b298c0 100644 --- a/src/librustc_interface/passes.rs +++ b/src/librustc_interface/passes.rs @@ -323,22 +323,20 @@ pub fn register_plugins<'a>( .. } = registry; - sess.track_errors(|| { - let mut ls = sess.lint_store.borrow_mut(); - for pass in early_lint_passes { - ls.register_early_pass(Some(sess), true, false, pass); - } - for pass in late_lint_passes { - ls.register_late_pass(Some(sess), true, pass); - } + let mut ls = sess.lint_store.borrow_mut(); + for pass in early_lint_passes { + ls.register_early_pass(Some(sess), true, false, pass); + } + for pass in late_lint_passes { + ls.register_late_pass(Some(sess), true, pass); + } - for (name, (to, deprecated_name)) in lint_groups { - ls.register_group(Some(sess), true, name, deprecated_name, to); - } + for (name, (to, deprecated_name)) in lint_groups { + ls.register_group(Some(sess), true, name, deprecated_name, to); + } - *sess.plugin_llvm_passes.borrow_mut() = llvm_passes; - *sess.plugin_attributes.borrow_mut() = attributes.clone(); - })?; + *sess.plugin_llvm_passes.borrow_mut() = llvm_passes; + *sess.plugin_attributes.borrow_mut() = attributes.clone(); Ok((krate, PluginInfo { syntax_exts, diff --git a/src/librustc_lint/unused.rs b/src/librustc_lint/unused.rs index 648cae30da6c8..09ecca27850b8 100644 --- a/src/librustc_lint/unused.rs +++ b/src/librustc_lint/unused.rs @@ -112,7 +112,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedResults { } }, hir::ExprKind::MethodCall(..) => { - cx.tables.type_dependent_defs().get(expr.hir_id).cloned() + cx.tables.type_dependent_def(expr.hir_id) }, _ => None }; diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs index c4e371d5afedb..551f18b95fe52 100644 --- a/src/librustc_mir/borrow_check/mod.rs +++ b/src/librustc_mir/borrow_check/mod.rs @@ -156,7 +156,7 @@ fn do_mir_borrowck<'a, 'gcx, 'tcx>( let mut flow_inits = FlowAtLocation::new(do_dataflow( tcx, mir, - id, + def_id, &attributes, &dead_unwinds, MaybeInitializedPlaces::new(tcx, mir, &mdpe), @@ -191,7 +191,7 @@ fn do_mir_borrowck<'a, 'gcx, 'tcx>( let flow_borrows = FlowAtLocation::new(do_dataflow( tcx, mir, - id, + def_id, &attributes, &dead_unwinds, Borrows::new(tcx, mir, regioncx.clone(), &borrow_set), @@ -200,7 +200,7 @@ fn do_mir_borrowck<'a, 'gcx, 'tcx>( let flow_uninits = FlowAtLocation::new(do_dataflow( tcx, mir, - id, + def_id, &attributes, &dead_unwinds, MaybeUninitializedPlaces::new(tcx, mir, &mdpe), @@ -209,7 +209,7 @@ fn do_mir_borrowck<'a, 'gcx, 'tcx>( let flow_ever_inits = FlowAtLocation::new(do_dataflow( tcx, mir, - id, + def_id, &attributes, &dead_unwinds, EverInitializedPlaces::new(tcx, mir, &mdpe), diff --git a/src/librustc_mir/build/matches/mod.rs b/src/librustc_mir/build/matches/mod.rs index d3731e7c1274e..be3d730c61a1d 100644 --- a/src/librustc_mir/build/matches/mod.rs +++ b/src/librustc_mir/build/matches/mod.rs @@ -439,11 +439,17 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { self.simplify_candidate(&mut candidate); if !candidate.match_pairs.is_empty() { - span_bug!( + // ICE if no other errors have been emitted. This used to be a hard error that wouldn't + // be reached because `hair::pattern::check_match::check_match` wouldn't have let the + // compiler continue. In our tests this is only ever hit by + // `ui/consts/const-match-check.rs` with `--cfg eval1`, and that file already generates + // a different error before hand. + self.hir.tcx().sess.delay_span_bug( candidate.match_pairs[0].pattern.span, - "match pairs {:?} remaining after simplifying \ - irrefutable pattern", - candidate.match_pairs + &format!( + "match pairs {:?} remaining after simplifying irrefutable pattern", + candidate.match_pairs, + ), ); } diff --git a/src/librustc_mir/const_eval.rs b/src/librustc_mir/const_eval.rs index 79a3e0c5ee248..2e15f0de69f70 100644 --- a/src/librustc_mir/const_eval.rs +++ b/src/librustc_mir/const_eval.rs @@ -15,7 +15,6 @@ use rustc::ty::layout::{self, LayoutOf, VariantIdx}; use rustc::ty::subst::Subst; use rustc::traits::Reveal; use rustc_data_structures::fx::FxHashMap; -use rustc::util::common::ErrorReported; use syntax::ast::Mutability; use syntax::source_map::{Span, DUMMY_SP}; @@ -619,9 +618,8 @@ pub fn const_eval_raw_provider<'a, 'tcx>( let tables = tcx.typeck_tables_of(def_id); // Do match-check before building MIR - if let Err(ErrorReported) = tcx.check_match(def_id) { - return Err(ErrorHandled::Reported) - } + // FIXME(#59378) check_match may have errored but we're not checking for that anymore + tcx.check_match(def_id); if let hir::BodyOwnerKind::Const = tcx.hir().body_owner_kind_by_hir_id(id) { tcx.mir_const_qualif(def_id); diff --git a/src/librustc_mir/dataflow/graphviz.rs b/src/librustc_mir/dataflow/graphviz.rs index da9cc118f5521..d68377681f1ca 100644 --- a/src/librustc_mir/dataflow/graphviz.rs +++ b/src/librustc_mir/dataflow/graphviz.rs @@ -1,6 +1,6 @@ //! Hook into libgraphviz for rendering dataflow graphs for MIR. -use rustc::hir::HirId; +use rustc::hir::def_id::DefId; use rustc::mir::{BasicBlock, Mir}; use std::fs; @@ -8,13 +8,15 @@ use std::io; use std::marker::PhantomData; use std::path::Path; +use crate::util::graphviz_safe_def_name; + use super::{BitDenotation, DataflowState}; use super::DataflowBuilder; use super::DebugFormatted; pub trait MirWithFlowState<'tcx> { type BD: BitDenotation<'tcx>; - fn hir_id(&self) -> HirId; + fn def_id(&self) -> DefId; fn mir(&self) -> &Mir<'tcx>; fn flow_state(&self) -> &DataflowState<'tcx, Self::BD>; } @@ -23,7 +25,7 @@ impl<'a, 'tcx, BD> MirWithFlowState<'tcx> for DataflowBuilder<'a, 'tcx, BD> where BD: BitDenotation<'tcx> { type BD = BD; - fn hir_id(&self) -> HirId { self.hir_id } + fn def_id(&self) -> DefId { self.def_id } fn mir(&self) -> &Mir<'tcx> { self.flow_state.mir() } fn flow_state(&self) -> &DataflowState<'tcx, Self::BD> { &self.flow_state.flow_state } } @@ -47,8 +49,8 @@ pub(crate) fn print_borrowck_graph_to<'a, 'tcx, BD, P>( let g = Graph { mbcx, phantom: PhantomData, render_idx }; let mut v = Vec::new(); dot::render(&g, &mut v)?; - debug!("print_borrowck_graph_to path: {} hir_id: {}", - path.display(), mbcx.hir_id); + debug!("print_borrowck_graph_to path: {} def_id: {:?}", + path.display(), mbcx.def_id); fs::write(path, v) } @@ -69,9 +71,8 @@ impl<'a, 'tcx, MWF, P> dot::Labeller<'a> for Graph<'a, 'tcx, MWF, P> type Node = Node; type Edge = Edge; fn graph_id(&self) -> dot::Id<'_> { - dot::Id::new(format!("graph_for_node_{}", - self.mbcx.hir_id())) - .unwrap() + let name = graphviz_safe_def_name(self.mbcx.def_id()); + dot::Id::new(format!("graph_for_def_id_{}", name)).unwrap() } fn node_id(&self, n: &Node) -> dot::Id<'_> { diff --git a/src/librustc_mir/dataflow/mod.rs b/src/librustc_mir/dataflow/mod.rs index af2cd8f979a11..af0e3f5a27091 100644 --- a/src/librustc_mir/dataflow/mod.rs +++ b/src/librustc_mir/dataflow/mod.rs @@ -4,7 +4,7 @@ use rustc_data_structures::bit_set::{BitSet, BitSetOperator, HybridBitSet}; use rustc_data_structures::indexed_vec::Idx; use rustc_data_structures::work_queue::WorkQueue; -use rustc::hir::HirId; +use rustc::hir::def_id::DefId; use rustc::ty::{self, TyCtxt}; use rustc::mir::{self, Mir, BasicBlock, BasicBlockData, Location, Statement, Terminator}; use rustc::mir::traversal; @@ -39,7 +39,7 @@ pub(crate) struct DataflowBuilder<'a, 'tcx: 'a, BD> where BD: BitDenotation<'tcx> { - hir_id: HirId, + def_id: DefId, flow_state: DataflowAnalysis<'a, 'tcx, BD>, print_preflow_to: Option, print_postflow_to: Option, @@ -117,7 +117,7 @@ pub struct MoveDataParamEnv<'gcx, 'tcx> { pub(crate) fn do_dataflow<'a, 'gcx, 'tcx, BD, P>(tcx: TyCtxt<'a, 'gcx, 'tcx>, mir: &'a Mir<'tcx>, - hir_id: HirId, + def_id: DefId, attributes: &[ast::Attribute], dead_unwinds: &BitSet, bd: BD, @@ -127,14 +127,14 @@ pub(crate) fn do_dataflow<'a, 'gcx, 'tcx, BD, P>(tcx: TyCtxt<'a, 'gcx, 'tcx>, P: Fn(&BD, BD::Idx) -> DebugFormatted { let flow_state = DataflowAnalysis::new(mir, dead_unwinds, bd); - flow_state.run(tcx, hir_id, attributes, p) + flow_state.run(tcx, def_id, attributes, p) } impl<'a, 'gcx: 'tcx, 'tcx: 'a, BD> DataflowAnalysis<'a, 'tcx, BD> where BD: BitDenotation<'tcx> { pub(crate) fn run

(self, tcx: TyCtxt<'a, 'gcx, 'tcx>, - hir_id: HirId, + def_id: DefId, attributes: &[ast::Attribute], p: P) -> DataflowResults<'tcx, BD> where P: Fn(&BD, BD::Idx) -> DebugFormatted @@ -159,7 +159,7 @@ impl<'a, 'gcx: 'tcx, 'tcx: 'a, BD> DataflowAnalysis<'a, 'tcx, BD> where BD: BitD name_found(tcx.sess, attributes, "borrowck_graphviz_postflow"); let mut mbcx = DataflowBuilder { - hir_id, + def_id, print_preflow_to, print_postflow_to, flow_state: self, }; diff --git a/src/librustc_mir/hair/cx/expr.rs b/src/librustc_mir/hair/cx/expr.rs index b83f048114b06..b3016cb01d409 100644 --- a/src/librustc_mir/hair/cx/expr.rs +++ b/src/librustc_mir/hair/cx/expr.rs @@ -838,13 +838,11 @@ fn method_callee<'a, 'gcx, 'tcx>( let (def_id, substs, user_ty) = match overloaded_callee { Some((def_id, substs)) => (def_id, substs, None), None => { - let type_dependent_defs = cx.tables().type_dependent_defs(); - let def = type_dependent_defs - .get(expr.hir_id) + let def = cx.tables().type_dependent_def(expr.hir_id) .unwrap_or_else(|| { span_bug!(expr.span, "no type-dependent def for method callee") }); - let user_ty = user_substs_applied_to_def(cx, expr.hir_id, def); + let user_ty = user_substs_applied_to_def(cx, expr.hir_id, &def); debug!("method_callee: user_ty={:?}", user_ty); (def.def_id(), cx.tables().node_substs(expr.hir_id), user_ty) } diff --git a/src/librustc_mir/hair/pattern/check_match.rs b/src/librustc_mir/hair/pattern/check_match.rs index 49967df08891b..50df676aea9fb 100644 --- a/src/librustc_mir/hair/pattern/check_match.rs +++ b/src/librustc_mir/hair/pattern/check_match.rs @@ -14,7 +14,6 @@ use rustc::ty::{self, Ty, TyCtxt, TyKind}; use rustc::ty::subst::{InternalSubsts, SubstsRef}; use rustc::lint; use rustc_errors::{Applicability, DiagnosticBuilder}; -use rustc::util::common::ErrorReported; use rustc::hir::def::*; use rustc::hir::def_id::DefId; @@ -27,25 +26,20 @@ use std::slice; use syntax::ptr::P; use syntax_pos::{Span, DUMMY_SP, MultiSpan}; -pub(crate) fn check_match<'a, 'tcx>( - tcx: TyCtxt<'a, 'tcx, 'tcx>, - def_id: DefId, -) -> Result<(), ErrorReported> { +pub(crate) fn check_match<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) { let body_id = if let Some(id) = tcx.hir().as_local_hir_id(def_id) { tcx.hir().body_owned_by(id) } else { - return Ok(()); + return; }; - tcx.sess.track_errors(|| { - MatchVisitor { - tcx, - tables: tcx.body_tables(body_id), - region_scope_tree: &tcx.region_scope_tree(def_id), - param_env: tcx.param_env(def_id), - identity_substs: InternalSubsts::identity_for_item(tcx, def_id), - }.visit_body(tcx.hir().body(body_id)); - }) + MatchVisitor { + tcx, + tables: tcx.body_tables(body_id), + region_scope_tree: &tcx.region_scope_tree(def_id), + param_env: tcx.param_env(def_id), + identity_substs: InternalSubsts::identity_for_item(tcx, def_id), + }.visit_body(tcx.hir().body(body_id)); } fn create_e0004<'a>(sess: &'a Session, sp: Span, error_message: String) -> DiagnosticBuilder<'a> { diff --git a/src/librustc_mir/transform/elaborate_drops.rs b/src/librustc_mir/transform/elaborate_drops.rs index d5098bc1db2b1..023a61588c42e 100644 --- a/src/librustc_mir/transform/elaborate_drops.rs +++ b/src/librustc_mir/transform/elaborate_drops.rs @@ -28,7 +28,7 @@ impl MirPass for ElaborateDrops { { debug!("elaborate_drops({:?} @ {:?})", src, mir.span); - let id = tcx.hir().as_local_hir_id(src.def_id()).unwrap(); + let def_id = src.def_id(); let param_env = tcx.param_env(src.def_id()).with_reveal_all(); let move_data = match MoveData::gather_moves(mir, tcx) { Ok(move_data) => move_data, @@ -50,13 +50,13 @@ impl MirPass for ElaborateDrops { move_data, param_env, }; - let dead_unwinds = find_dead_unwinds(tcx, mir, id, &env); + let dead_unwinds = find_dead_unwinds(tcx, mir, def_id, &env); let flow_inits = - do_dataflow(tcx, mir, id, &[], &dead_unwinds, + do_dataflow(tcx, mir, def_id, &[], &dead_unwinds, MaybeInitializedPlaces::new(tcx, mir, &env), |bd, p| DebugFormatted::new(&bd.move_data().move_paths[p])); let flow_uninits = - do_dataflow(tcx, mir, id, &[], &dead_unwinds, + do_dataflow(tcx, mir, def_id, &[], &dead_unwinds, MaybeUninitializedPlaces::new(tcx, mir, &env), |bd, p| DebugFormatted::new(&bd.move_data().move_paths[p])); @@ -80,7 +80,7 @@ impl MirPass for ElaborateDrops { fn find_dead_unwinds<'a, 'tcx>( tcx: TyCtxt<'a, 'tcx, 'tcx>, mir: &Mir<'tcx>, - id: hir::HirId, + def_id: hir::def_id::DefId, env: &MoveDataParamEnv<'tcx, 'tcx>) -> BitSet { @@ -89,7 +89,7 @@ fn find_dead_unwinds<'a, 'tcx>( // reach cleanup blocks, which can't have unwind edges themselves. let mut dead_unwinds = BitSet::new_empty(mir.basic_blocks().len()); let flow_inits = - do_dataflow(tcx, mir, id, &[], &dead_unwinds, + do_dataflow(tcx, mir, def_id, &[], &dead_unwinds, MaybeInitializedPlaces::new(tcx, mir, &env), |bd, p| DebugFormatted::new(&bd.move_data().move_paths[p])); for (bb, bb_data) in mir.basic_blocks().iter_enumerated() { diff --git a/src/librustc_mir/transform/generator.rs b/src/librustc_mir/transform/generator.rs index b22258a49b24b..c4e303eb9aa1f 100644 --- a/src/librustc_mir/transform/generator.rs +++ b/src/librustc_mir/transform/generator.rs @@ -390,13 +390,13 @@ fn locals_live_across_suspend_points( FxHashMap, ) { let dead_unwinds = BitSet::new_empty(mir.basic_blocks().len()); - let hir_id = tcx.hir().as_local_hir_id(source.def_id()).unwrap(); + let def_id = source.def_id(); // Calculate when MIR locals have live storage. This gives us an upper bound of their // lifetimes. let storage_live_analysis = MaybeStorageLive::new(mir); let storage_live = - do_dataflow(tcx, mir, hir_id, &[], &dead_unwinds, storage_live_analysis, + do_dataflow(tcx, mir, def_id, &[], &dead_unwinds, storage_live_analysis, |bd, p| DebugFormatted::new(&bd.mir().local_decls[p])); // Find the MIR locals which do not use StorageLive/StorageDead statements. @@ -410,7 +410,7 @@ fn locals_live_across_suspend_points( let borrowed_locals = if !movable { let analysis = HaveBeenBorrowedLocals::new(mir); let result = - do_dataflow(tcx, mir, hir_id, &[], &dead_unwinds, analysis, + do_dataflow(tcx, mir, def_id, &[], &dead_unwinds, analysis, |bd, p| DebugFormatted::new(&bd.mir().local_decls[p])); Some((analysis, result)) } else { diff --git a/src/librustc_mir/transform/rustc_peek.rs b/src/librustc_mir/transform/rustc_peek.rs index f9f8abbe6c065..246f876235d71 100644 --- a/src/librustc_mir/transform/rustc_peek.rs +++ b/src/librustc_mir/transform/rustc_peek.rs @@ -3,7 +3,7 @@ use syntax::ast; use syntax_pos::Span; use rustc::ty::{self, TyCtxt}; -use rustc::hir; +use rustc::hir::def_id::DefId; use rustc::mir::{self, Mir, Location}; use rustc_data_structures::bit_set::BitSet; use crate::transform::{MirPass, MirSource}; @@ -27,7 +27,6 @@ impl MirPass for SanityCheck { fn run_pass<'a, 'tcx>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, src: MirSource<'tcx>, mir: &mut Mir<'tcx>) { let def_id = src.def_id(); - let id = tcx.hir().as_local_hir_id(def_id).unwrap(); if !tcx.has_attr(def_id, "rustc_mir") { debug!("skipping rustc_peek::SanityCheck on {}", tcx.def_path_str(def_id)); return; @@ -41,26 +40,26 @@ impl MirPass for SanityCheck { let mdpe = MoveDataParamEnv { move_data: move_data, param_env: param_env }; let dead_unwinds = BitSet::new_empty(mir.basic_blocks().len()); let flow_inits = - do_dataflow(tcx, mir, id, &attributes, &dead_unwinds, + do_dataflow(tcx, mir, def_id, &attributes, &dead_unwinds, MaybeInitializedPlaces::new(tcx, mir, &mdpe), |bd, i| DebugFormatted::new(&bd.move_data().move_paths[i])); let flow_uninits = - do_dataflow(tcx, mir, id, &attributes, &dead_unwinds, + do_dataflow(tcx, mir, def_id, &attributes, &dead_unwinds, MaybeUninitializedPlaces::new(tcx, mir, &mdpe), |bd, i| DebugFormatted::new(&bd.move_data().move_paths[i])); let flow_def_inits = - do_dataflow(tcx, mir, id, &attributes, &dead_unwinds, + do_dataflow(tcx, mir, def_id, &attributes, &dead_unwinds, DefinitelyInitializedPlaces::new(tcx, mir, &mdpe), |bd, i| DebugFormatted::new(&bd.move_data().move_paths[i])); if has_rustc_mir_with(&attributes, "rustc_peek_maybe_init").is_some() { - sanity_check_via_rustc_peek(tcx, mir, id, &attributes, &flow_inits); + sanity_check_via_rustc_peek(tcx, mir, def_id, &attributes, &flow_inits); } if has_rustc_mir_with(&attributes, "rustc_peek_maybe_uninit").is_some() { - sanity_check_via_rustc_peek(tcx, mir, id, &attributes, &flow_uninits); + sanity_check_via_rustc_peek(tcx, mir, def_id, &attributes, &flow_uninits); } if has_rustc_mir_with(&attributes, "rustc_peek_definite_init").is_some() { - sanity_check_via_rustc_peek(tcx, mir, id, &attributes, &flow_def_inits); + sanity_check_via_rustc_peek(tcx, mir, def_id, &attributes, &flow_def_inits); } if has_rustc_mir_with(&attributes, "stop_after_dataflow").is_some() { tcx.sess.fatal("stop_after_dataflow ended compilation"); @@ -86,12 +85,12 @@ impl MirPass for SanityCheck { /// errors are not intended to be used for unit tests.) pub fn sanity_check_via_rustc_peek<'a, 'tcx, O>(tcx: TyCtxt<'a, 'tcx, 'tcx>, mir: &Mir<'tcx>, - id: hir::HirId, + def_id: DefId, _attributes: &[ast::Attribute], results: &DataflowResults<'tcx, O>) where O: BitDenotation<'tcx, Idx=MovePathIndex> + HasMoveData<'tcx> { - debug!("sanity_check_via_rustc_peek id: {:?}", id); + debug!("sanity_check_via_rustc_peek def_id: {:?}", def_id); // FIXME: this is not DRY. Figure out way to abstract this and // `dataflow::build_sets`. (But note it is doing non-standard // stuff, so such generalization may not be realistic.) diff --git a/src/librustc_mir/util/graphviz.rs b/src/librustc_mir/util/graphviz.rs index 69a2adcfce026..f87714b58c442 100644 --- a/src/librustc_mir/util/graphviz.rs +++ b/src/librustc_mir/util/graphviz.rs @@ -1,6 +1,7 @@ use rustc::hir::def_id::DefId; use rustc::mir::*; use rustc::ty::TyCtxt; +use rustc_data_structures::indexed_vec::Idx; use std::fmt::Debug; use std::io::{self, Write}; @@ -20,6 +21,17 @@ pub fn write_mir_graphviz<'tcx, W>(tcx: TyCtxt<'_, '_, 'tcx>, Ok(()) } +// Must match `[0-9A-Za-z_]*`. This does not appear in the rendered graph, so +// it does not have to be user friendly. +pub fn graphviz_safe_def_name(def_id: DefId) -> String { + format!( + "{}_{}_{}", + def_id.krate.index(), + def_id.index.address_space().index(), + def_id.index.as_array_index(), + ) +} + /// Write a graphviz DOT graph of the MIR. pub fn write_mir_fn_graphviz<'tcx, W>(tcx: TyCtxt<'_, '_, 'tcx>, def_id: DefId, @@ -27,7 +39,7 @@ pub fn write_mir_fn_graphviz<'tcx, W>(tcx: TyCtxt<'_, '_, 'tcx>, w: &mut W) -> io::Result<()> where W: Write { - writeln!(w, "digraph Mir_{} {{", tcx.hir().as_local_hir_id(def_id).unwrap())?; + writeln!(w, "digraph Mir_{} {{", graphviz_safe_def_name(def_id))?; // Global graph properties writeln!(w, r#" graph [fontname="monospace"];"#)?; diff --git a/src/librustc_mir/util/mod.rs b/src/librustc_mir/util/mod.rs index 29614a33f8e27..1a5a2a92247dd 100644 --- a/src/librustc_mir/util/mod.rs +++ b/src/librustc_mir/util/mod.rs @@ -15,7 +15,7 @@ pub mod collect_writes; pub use self::alignment::is_disaligned; pub use self::pretty::{dump_enabled, dump_mir, write_mir_pretty, PassWhere}; -pub use self::graphviz::{write_mir_graphviz}; +pub use self::graphviz::{graphviz_safe_def_name, write_mir_graphviz}; pub use self::graphviz::write_node_label as write_graphviz_node_label; /// If possible, suggest replacing `ref` with `ref mut`. diff --git a/src/librustc_passes/rvalue_promotion.rs b/src/librustc_passes/rvalue_promotion.rs index 6de98675a3dc8..fcd51062cd97a 100644 --- a/src/librustc_passes/rvalue_promotion.rs +++ b/src/librustc_passes/rvalue_promotion.rs @@ -406,8 +406,7 @@ fn check_expr_kind<'a, 'tcx>( for index in hirvec.iter() { method_call_result &= v.check_expr(index); } - if let Some(def) = v.tables.type_dependent_defs().get(e.hir_id) { - let def_id = def.def_id(); + if let Some(def_id) = v.tables.type_dependent_def_id(e.hir_id) { match v.tcx.associated_item(def_id).container { ty::ImplContainer(_) => method_call_result & v.handle_const_fn_call(def_id), ty::TraitContainer(_) => NotPromotable, diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs index 19b5fa1bfbe57..ee72a08b895c6 100644 --- a/src/librustc_privacy/lib.rs +++ b/src/librustc_privacy/lib.rs @@ -1039,8 +1039,8 @@ impl<'a, 'tcx> Visitor<'tcx> for TypePrivacyVisitor<'a, 'tcx> { hir::ExprKind::MethodCall(_, span, _) => { // Method calls have to be checked specially. self.span = span; - if let Some(def) = self.tables.type_dependent_defs().get(expr.hir_id) { - if self.visit(self.tcx.type_of(def.def_id())) { + if let Some(def_id) = self.tables.type_dependent_def_id(expr.hir_id) { + if self.visit(self.tcx.type_of(def_id)) { return; } } else { @@ -1069,7 +1069,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypePrivacyVisitor<'a, 'tcx> { _ => None, } hir::QPath::TypeRelative(..) => { - self.tables.type_dependent_defs().get(id).cloned() + self.tables.type_dependent_def(id) } }; if let Some(def) = def { diff --git a/src/librustc_save_analysis/lib.rs b/src/librustc_save_analysis/lib.rs index 7ad5b7ce8c73e..0b6e9d1bd9917 100644 --- a/src/librustc_save_analysis/lib.rs +++ b/src/librustc_save_analysis/lib.rs @@ -573,8 +573,8 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { } ast::ExprKind::MethodCall(ref seg, ..) => { let expr_hir_id = self.tcx.hir().definitions().node_to_hir_id(expr.id); - let method_id = match self.tables.type_dependent_defs().get(expr_hir_id) { - Some(id) => id.def_id(), + let method_id = match self.tables.type_dependent_def_id(expr_hir_id) { + Some(id) => id, None => { debug!("Could not resolve method id for {:?}", expr); return None; diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs index c30b9d65fec83..5fd6d9330098b 100644 --- a/src/librustc_typeck/check/_match.rs +++ b/src/librustc_typeck/check/_match.rs @@ -973,7 +973,7 @@ https://doc.rust-lang.org/reference/types.html#trait-objects"); self.field_ty(span, f, substs) }) .unwrap_or_else(|| { - inexistent_fields.push((span, field.ident)); + inexistent_fields.push(field.ident); no_field_errors = false; tcx.types.err }) @@ -989,15 +989,15 @@ https://doc.rust-lang.org/reference/types.html#trait-objects"); .collect::>(); if inexistent_fields.len() > 0 && !variant.recovered { let (field_names, t, plural) = if inexistent_fields.len() == 1 { - (format!("a field named `{}`", inexistent_fields[0].1), "this", "") + (format!("a field named `{}`", inexistent_fields[0]), "this", "") } else { (format!("fields named {}", inexistent_fields.iter() - .map(|(_, name)| format!("`{}`", name)) + .map(|ident| format!("`{}`", ident)) .collect::>() .join(", ")), "these", "s") }; - let spans = inexistent_fields.iter().map(|(span, _)| *span).collect::>(); + let spans = inexistent_fields.iter().map(|ident| ident.span).collect::>(); let mut err = struct_span_err!(tcx.sess, spans, E0026, @@ -1005,8 +1005,8 @@ https://doc.rust-lang.org/reference/types.html#trait-objects"); kind_name, tcx.def_path_str(variant.did), field_names); - if let Some((span, ident)) = inexistent_fields.last() { - err.span_label(*span, + if let Some(ident) = inexistent_fields.last() { + err.span_label(ident.span, format!("{} `{}` does not have {} field{}", kind_name, tcx.def_path_str(variant.did), @@ -1018,8 +1018,8 @@ https://doc.rust-lang.org/reference/types.html#trait-objects"); find_best_match_for_name(input, &ident.as_str(), None); if let Some(suggested_name) = suggested_name { err.span_suggestion( - *span, - "did you mean", + ident.span, + "a field with a similar name exists", suggested_name.to_string(), Applicability::MaybeIncorrect, ); diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index ab0e4b086bc77..be2454cdd5a85 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -702,15 +702,11 @@ fn check_mod_item_types<'tcx>(tcx: TyCtxt<'_, 'tcx, 'tcx>, module_def_id: DefId) tcx.hir().visit_item_likes_in_module(module_def_id, &mut CheckItemTypesVisitor { tcx }); } -fn typeck_item_bodies<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, crate_num: CrateNum) - -> Result<(), ErrorReported> -{ +fn typeck_item_bodies<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, crate_num: CrateNum) { debug_assert!(crate_num == LOCAL_CRATE); - Ok(tcx.sess.track_errors(|| { - tcx.par_body_owners(|body_owner_def_id| { - tcx.ensure().typeck_tables_of(body_owner_def_id); - }); - })?) + tcx.par_body_owners(|body_owner_def_id| { + tcx.ensure().typeck_tables_of(body_owner_def_id); + }); } fn check_item_well_formed<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) { @@ -4807,10 +4803,10 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { (self.to_ty(qself), qself, segment) } }; - if let Some(cached_def) = self.tables.borrow().type_dependent_defs().get(hir_id) { + if let Some(cached_def) = self.tables.borrow().type_dependent_def(hir_id) { // Return directly on cache hit. This is useful to avoid doubly reporting // errors with default match binding modes. See #44614. - return (*cached_def, Some(ty), slice::from_ref(&**item_segment)) + return (cached_def, Some(ty), slice::from_ref(&**item_segment)) } let item_name = item_segment.ident; let def = match self.resolve_ufcs(span, item_name, ty, hir_id) { diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs index cbed7d26a9950..b2c2b233c81ab 100644 --- a/src/librustc_typeck/lib.rs +++ b/src/librustc_typeck/lib.rs @@ -363,7 +363,7 @@ pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) }) })?; - time(tcx.sess, "item-bodies checking", || tcx.typeck_item_bodies(LOCAL_CRATE))?; + time(tcx.sess, "item-bodies checking", || tcx.typeck_item_bodies(LOCAL_CRATE)); check_unused::check_crate(tcx); check_for_entry_fn(tcx); diff --git a/src/libstd/Cargo.toml b/src/libstd/Cargo.toml index 1a6b58f35b398..b2eaf956d0e2d 100644 --- a/src/libstd/Cargo.toml +++ b/src/libstd/Cargo.toml @@ -72,3 +72,7 @@ wasm-bindgen-threads = [] # https://github.com/rust-lang-nursery/stdsimd/blob/master/crates/std_detect/Cargo.toml std_detect_file_io = [] std_detect_dlsym_getauxval = [] + +[package.metadata.fortanix-sgx] +# Maximum possible number of threads when testing +threads = 125 diff --git a/src/libstd/env.rs b/src/libstd/env.rs index 97c67f562a7df..f723a2b0bb281 100644 --- a/src/libstd/env.rs +++ b/src/libstd/env.rs @@ -975,7 +975,7 @@ mod tests { use crate::path::Path; #[test] - #[cfg_attr(target_os = "emscripten", ignore)] + #[cfg_attr(any(target_os = "emscripten", target_env = "sgx"), ignore)] fn test_self_exe_path() { let path = current_exe(); assert!(path.is_ok()); @@ -989,6 +989,7 @@ mod tests { fn test() { assert!((!Path::new("test-path").is_absolute())); + #[cfg(not(target_env = "sgx"))] current_dir().unwrap(); } diff --git a/src/libstd/fs.rs b/src/libstd/fs.rs index 8c3d0da0a7e40..dfff44b88ea78 100644 --- a/src/libstd/fs.rs +++ b/src/libstd/fs.rs @@ -2095,7 +2095,7 @@ impl AsInnerMut for DirBuilder { } } -#[cfg(all(test, not(any(target_os = "cloudabi", target_os = "emscripten"))))] +#[cfg(all(test, not(any(target_os = "cloudabi", target_os = "emscripten", target_env = "sgx"))))] mod tests { use crate::io::prelude::*; diff --git a/src/libstd/net/addr.rs b/src/libstd/net/addr.rs index f5a87cc3ea67a..eaa6a070154f7 100644 --- a/src/libstd/net/addr.rs +++ b/src/libstd/net/addr.rs @@ -941,7 +941,10 @@ mod tests { assert_eq!(Ok(vec![a]), tsa(("2a02:6b8:0:1::1", 53))); let a = sa4(Ipv4Addr::new(127, 0, 0, 1), 23924); + #[cfg(not(target_env = "sgx"))] assert!(tsa(("localhost", 23924)).unwrap().contains(&a)); + #[cfg(target_env = "sgx")] + let _ = a; } #[test] @@ -953,7 +956,10 @@ mod tests { assert_eq!(Ok(vec![a]), tsa("[2a02:6b8:0:1::1]:53")); let a = sa4(Ipv4Addr::new(127, 0, 0, 1), 23924); + #[cfg(not(target_env = "sgx"))] assert!(tsa("localhost:23924").unwrap().contains(&a)); + #[cfg(target_env = "sgx")] + let _ = a; } #[test] diff --git a/src/libstd/net/tcp.rs b/src/libstd/net/tcp.rs index ce0c5c0bb0dc7..304cdb0155814 100644 --- a/src/libstd/net/tcp.rs +++ b/src/libstd/net/tcp.rs @@ -929,12 +929,12 @@ impl fmt::Debug for TcpListener { #[cfg(all(test, not(any(target_os = "cloudabi", target_os = "emscripten"))))] mod tests { + use crate::fmt; use crate::io::{ErrorKind, IoVec, IoVecMut}; use crate::io::prelude::*; use crate::net::*; use crate::net::test::{next_test_ip4, next_test_ip6}; use crate::sync::mpsc::channel; - use crate::sys_common::AsInner; use crate::time::{Instant, Duration}; use crate::thread; @@ -1129,7 +1129,7 @@ mod tests { connect(i + 1, addr); t!(stream.write(&[i as u8])); }); - t.join().ok().unwrap(); + t.join().ok().expect("thread panicked"); } } @@ -1162,7 +1162,7 @@ mod tests { connect(i + 1, addr); t!(stream.write(&[99])); }); - t.join().ok().unwrap(); + t.join().ok().expect("thread panicked"); } } @@ -1377,6 +1377,8 @@ mod tests { } #[test] + // FIXME: https://github.com/fortanix/rust-sgx/issues/110 + #[cfg_attr(target_env = "sgx", ignore)] fn shutdown_smoke() { each_ip(&mut |addr| { let a = t!(TcpListener::bind(&addr)); @@ -1397,6 +1399,8 @@ mod tests { } #[test] + // FIXME: https://github.com/fortanix/rust-sgx/issues/110 + #[cfg_attr(target_env = "sgx", ignore)] fn close_readwrite_smoke() { each_ip(&mut |addr| { let a = t!(TcpListener::bind(&addr)); @@ -1550,30 +1554,51 @@ mod tests { #[test] fn debug() { - let name = if cfg!(windows) {"socket"} else {"fd"}; + #[cfg(not(target_env = "sgx"))] + fn render_socket_addr<'a>(addr: &'a SocketAddr) -> impl fmt::Debug + 'a { + addr + } + #[cfg(target_env = "sgx")] + fn render_socket_addr<'a>(addr: &'a SocketAddr) -> impl fmt::Debug + 'a { + addr.to_string() + } + + #[cfg(unix)] + use crate::os::unix::io::AsRawFd; + #[cfg(target_env = "sgx")] + use crate::os::fortanix_sgx::io::AsRawFd; + #[cfg(not(windows))] + fn render_inner(addr: &dyn AsRawFd) -> impl fmt::Debug { + addr.as_raw_fd() + } + #[cfg(windows)] + fn render_inner(addr: &dyn os::windows::io::AsRawSocket) -> impl fmt::Debug { + addr.as_raw_socket() + } + + let inner_name = if cfg!(windows) {"socket"} else {"fd"}; let socket_addr = next_test_ip4(); let listener = t!(TcpListener::bind(&socket_addr)); - let listener_inner = listener.0.socket().as_inner(); let compare = format!("TcpListener {{ addr: {:?}, {}: {:?} }}", - socket_addr, name, listener_inner); + render_socket_addr(&socket_addr), + inner_name, + render_inner(&listener)); assert_eq!(format!("{:?}", listener), compare); - let stream = t!(TcpStream::connect(&("localhost", - socket_addr.port()))); - let stream_inner = stream.0.socket().as_inner(); - let compare = format!("TcpStream {{ addr: {:?}, \ - peer: {:?}, {}: {:?} }}", - stream.local_addr().unwrap(), - stream.peer_addr().unwrap(), - name, - stream_inner); + let stream = t!(TcpStream::connect(&("localhost", socket_addr.port()))); + let compare = format!("TcpStream {{ addr: {:?}, peer: {:?}, {}: {:?} }}", + render_socket_addr(&stream.local_addr().unwrap()), + render_socket_addr(&stream.peer_addr().unwrap()), + inner_name, + render_inner(&stream)); assert_eq!(format!("{:?}", stream), compare); } // FIXME: re-enabled bitrig/openbsd tests once their socket timeout code // no longer has rounding errors. #[cfg_attr(any(target_os = "bitrig", target_os = "netbsd", target_os = "openbsd"), ignore)] + #[cfg_attr(target_env = "sgx", ignore)] // FIXME: https://github.com/fortanix/rust-sgx/issues/31 #[test] fn timeouts() { let addr = next_test_ip4(); @@ -1601,6 +1626,7 @@ mod tests { } #[test] + #[cfg_attr(target_env = "sgx", ignore)] // FIXME: https://github.com/fortanix/rust-sgx/issues/31 fn test_read_timeout() { let addr = next_test_ip4(); let listener = t!(TcpListener::bind(&addr)); @@ -1618,6 +1644,7 @@ mod tests { } #[test] + #[cfg_attr(target_env = "sgx", ignore)] // FIXME: https://github.com/fortanix/rust-sgx/issues/31 fn test_read_with_timeout() { let addr = next_test_ip4(); let listener = t!(TcpListener::bind(&addr)); @@ -1661,6 +1688,7 @@ mod tests { } #[test] + #[cfg_attr(target_env = "sgx", ignore)] fn nodelay() { let addr = next_test_ip4(); let _listener = t!(TcpListener::bind(&addr)); @@ -1675,6 +1703,7 @@ mod tests { } #[test] + #[cfg_attr(target_env = "sgx", ignore)] fn ttl() { let ttl = 100; @@ -1691,6 +1720,7 @@ mod tests { } #[test] + #[cfg_attr(target_env = "sgx", ignore)] fn set_nonblocking() { let addr = next_test_ip4(); let listener = t!(TcpListener::bind(&addr)); @@ -1712,6 +1742,7 @@ mod tests { } #[test] + #[cfg_attr(target_env = "sgx", ignore)] // FIXME: https://github.com/fortanix/rust-sgx/issues/31 fn peek() { each_ip(&mut |addr| { let (txdone, rxdone) = channel(); @@ -1743,6 +1774,7 @@ mod tests { } #[test] + #[cfg_attr(target_env = "sgx", ignore)] // FIXME: https://github.com/fortanix/rust-sgx/issues/31 fn connect_timeout_valid() { let listener = TcpListener::bind("127.0.0.1:0").unwrap(); let addr = listener.local_addr().unwrap(); diff --git a/src/libstd/net/test.rs b/src/libstd/net/test.rs index 89fefd9d1d5e0..e2991cbdd8822 100644 --- a/src/libstd/net/test.rs +++ b/src/libstd/net/test.rs @@ -36,12 +36,16 @@ pub fn tsa(a: A) -> Result, String> { // all want to use ports. This function figures out which workspace // it is running in and assigns a port range based on it. fn base_port() -> u16 { - let cwd = env::current_dir().unwrap(); + let cwd = if cfg!(target_env = "sgx") { + String::from("sgx") + } else { + env::current_dir().unwrap().into_os_string().into_string().unwrap() + }; let dirs = ["32-opt", "32-nopt", "musl-64-opt", "cross-opt", "64-opt", "64-nopt", "64-opt-vg", "64-debug-opt", - "all-opt", "snap3", "dist"]; + "all-opt", "snap3", "dist", "sgx"]; dirs.iter().enumerate().find(|&(_, dir)| { - cwd.to_str().unwrap().contains(dir) + cwd.contains(dir) }).map(|p| p.0).unwrap_or(0) as u16 * 1000 + 19600 } diff --git a/src/libstd/net/udp.rs b/src/libstd/net/udp.rs index b42a812304269..836d1f8be632b 100644 --- a/src/libstd/net/udp.rs +++ b/src/libstd/net/udp.rs @@ -837,7 +837,7 @@ impl fmt::Debug for UdpSocket { } } -#[cfg(all(test, not(any(target_os = "cloudabi", target_os = "emscripten"))))] +#[cfg(all(test, not(any(target_os = "cloudabi", target_os = "emscripten", target_env = "sgx"))))] mod tests { use crate::io::ErrorKind; use crate::net::*; diff --git a/src/libstd/path.rs b/src/libstd/path.rs index ea3fcd8ce2859..4048bc4da2557 100644 --- a/src/libstd/path.rs +++ b/src/libstd/path.rs @@ -3801,7 +3801,7 @@ mod tests { }); ); - if cfg!(unix) { + if cfg!(unix) || cfg!(all(target_env = "sgx", target_vendor = "fortanix")) { tp!("", "foo", "foo"); tp!("foo", "bar", "foo/bar"); tp!("foo/", "bar", "foo/bar"); @@ -3960,7 +3960,7 @@ mod tests { tfn!("foo", "bar", "bar"); tfn!("foo", "", ""); tfn!("", "foo", "foo"); - if cfg!(unix) { + if cfg!(unix) || cfg!(all(target_env = "sgx", target_vendor = "fortanix")) { tfn!(".", "foo", "./foo"); tfn!("foo/", "bar", "bar"); tfn!("foo/.", "bar", "bar"); diff --git a/src/libstd/process.rs b/src/libstd/process.rs index ad86acbb47de4..054b398b01f26 100644 --- a/src/libstd/process.rs +++ b/src/libstd/process.rs @@ -1621,7 +1621,7 @@ impl Termination for ExitCode { } } -#[cfg(all(test, not(any(target_os = "cloudabi", target_os = "emscripten"))))] +#[cfg(all(test, not(any(target_os = "cloudabi", target_os = "emscripten", target_env = "sgx"))))] mod tests { use crate::io::prelude::*; diff --git a/src/libstd/sync/condvar.rs b/src/libstd/sync/condvar.rs index c383f21dcd752..2e8182671dd6f 100644 --- a/src/libstd/sync/condvar.rs +++ b/src/libstd/sync/condvar.rs @@ -705,6 +705,7 @@ mod tests { #[test] #[cfg_attr(target_os = "emscripten", ignore)] + #[cfg_attr(target_env = "sgx", ignore)] // FIXME: https://github.com/fortanix/rust-sgx/issues/31 fn wait_timeout_wait() { let m = Arc::new(Mutex::new(())); let c = Arc::new(Condvar::new()); @@ -724,6 +725,7 @@ mod tests { #[test] #[cfg_attr(target_os = "emscripten", ignore)] + #[cfg_attr(target_env = "sgx", ignore)] // FIXME: https://github.com/fortanix/rust-sgx/issues/31 fn wait_timeout_until_wait() { let m = Arc::new(Mutex::new(())); let c = Arc::new(Condvar::new()); @@ -748,6 +750,7 @@ mod tests { #[test] #[cfg_attr(target_os = "emscripten", ignore)] + #[cfg_attr(target_env = "sgx", ignore)] // FIXME: https://github.com/fortanix/rust-sgx/issues/31 fn wait_timeout_until_wake() { let pair = Arc::new((Mutex::new(false), Condvar::new())); let pair_copy = pair.clone(); @@ -771,6 +774,7 @@ mod tests { #[test] #[cfg_attr(target_os = "emscripten", ignore)] + #[cfg_attr(target_env = "sgx", ignore)] // FIXME: https://github.com/fortanix/rust-sgx/issues/31 fn wait_timeout_wake() { let m = Arc::new(Mutex::new(())); let c = Arc::new(Condvar::new()); diff --git a/src/libstd/sync/mpsc/mod.rs b/src/libstd/sync/mpsc/mod.rs index 90c5c50c23b9c..4ed2bfb175a46 100644 --- a/src/libstd/sync/mpsc/mod.rs +++ b/src/libstd/sync/mpsc/mod.rs @@ -1951,7 +1951,7 @@ mod tests { for _ in 0..10000 { assert_eq!(rx.recv().unwrap(), 1); } - t.join().ok().unwrap(); + t.join().ok().expect("thread panicked"); } #[test] @@ -1977,7 +1977,7 @@ mod tests { }); } drop(tx); - t.join().ok().unwrap(); + t.join().ok().expect("thread panicked"); } #[test] @@ -1996,8 +1996,8 @@ mod tests { tx2.send(1).unwrap(); } }); - t1.join().ok().unwrap(); - t2.join().ok().unwrap(); + t1.join().ok().expect("thread panicked"); + t2.join().ok().expect("thread panicked"); } #[test] @@ -2011,7 +2011,7 @@ mod tests { for _ in 0..40 { tx.send(1).unwrap(); } - t.join().ok().unwrap(); + t.join().ok().expect("thread panicked"); } #[test] @@ -2026,8 +2026,8 @@ mod tests { tx1.send(1).unwrap(); assert_eq!(rx2.recv().unwrap(), 2); }); - t1.join().ok().unwrap(); - t2.join().ok().unwrap(); + t1.join().ok().expect("thread panicked"); + t2.join().ok().expect("thread panicked"); } #[test] @@ -2225,6 +2225,7 @@ mod tests { } #[test] + #[cfg_attr(target_env = "sgx", ignore)] // FIXME: https://github.com/fortanix/rust-sgx/issues/31 fn oneshot_single_thread_recv_timeout() { let (tx, rx) = channel(); tx.send(()).unwrap(); @@ -2235,6 +2236,7 @@ mod tests { } #[test] + #[cfg_attr(target_env = "sgx", ignore)] // FIXME: https://github.com/fortanix/rust-sgx/issues/31 fn stress_recv_timeout_two_threads() { let (tx, rx) = channel(); let stress = stress_factor() + 100; @@ -2265,6 +2267,7 @@ mod tests { } #[test] + #[cfg_attr(target_env = "sgx", ignore)] // FIXME: https://github.com/fortanix/rust-sgx/issues/31 fn recv_timeout_upgrade() { let (tx, rx) = channel::<()>(); let timeout = Duration::from_millis(1); @@ -2276,6 +2279,7 @@ mod tests { } #[test] + #[cfg_attr(target_env = "sgx", ignore)] // FIXME: https://github.com/fortanix/rust-sgx/issues/31 fn stress_recv_timeout_shared() { let (tx, rx) = channel(); let stress = stress_factor() + 100; @@ -2306,6 +2310,7 @@ mod tests { } #[test] + #[cfg_attr(target_env = "sgx", ignore)] // FIXME: https://github.com/fortanix/rust-sgx/issues/31 fn very_long_recv_timeout_wont_panic() { let (tx, rx) = channel::<()>(); let join_handle = thread::spawn(move || { @@ -2325,6 +2330,7 @@ mod tests { } #[test] + #[cfg_attr(target_env = "sgx", ignore)] // FIXME: https://github.com/fortanix/rust-sgx/issues/31 fn shared_recv_timeout() { let (tx, rx) = channel(); let total = 5; @@ -2550,6 +2556,7 @@ mod sync_tests { } #[test] + #[cfg_attr(target_env = "sgx", ignore)] // FIXME: https://github.com/fortanix/rust-sgx/issues/31 fn recv_timeout() { let (tx, rx) = sync_channel::(1); assert_eq!(rx.recv_timeout(Duration::from_millis(1)), Err(RecvTimeoutError::Timeout)); @@ -2639,6 +2646,7 @@ mod sync_tests { } #[test] + #[cfg_attr(target_env = "sgx", ignore)] // FIXME: https://github.com/fortanix/rust-sgx/issues/31 fn stress_recv_timeout_two_threads() { let (tx, rx) = sync_channel::(0); @@ -2662,6 +2670,7 @@ mod sync_tests { } #[test] + #[cfg_attr(target_env = "sgx", ignore)] // FIXME: https://github.com/fortanix/rust-sgx/issues/31 fn stress_recv_timeout_shared() { const AMT: u32 = 1000; const NTHREADS: u32 = 8; diff --git a/src/libstd/sys/sgx/abi/mod.rs b/src/libstd/sys/sgx/abi/mod.rs index 7426f7be9e961..85ec8be4aae69 100644 --- a/src/libstd/sys/sgx/abi/mod.rs +++ b/src/libstd/sys/sgx/abi/mod.rs @@ -1,3 +1,5 @@ +#![cfg_attr(test, allow(unused))] // RT initialization logic is not compiled for test + use core::sync::atomic::{AtomicUsize, Ordering}; use crate::io::Write; @@ -12,8 +14,10 @@ pub mod tls; #[macro_use] pub mod usercalls; +#[cfg(not(test))] global_asm!(include_str!("entry.S")); +#[cfg(not(test))] #[no_mangle] unsafe extern "C" fn tcs_init(secondary: bool) { // Be very careful when changing this code: it runs before the binary has been @@ -48,6 +52,7 @@ unsafe extern "C" fn tcs_init(secondary: bool) { // FIXME: this item should only exist if this is linked into an executable // (main function exists). If this is a library, the crate author should be // able to specify this +#[cfg(not(test))] #[no_mangle] extern "C" fn entry(p1: u64, p2: u64, p3: u64, secondary: bool, p4: u64, p5: u64) -> (u64, u64) { // FIXME: how to support TLS in library mode? diff --git a/src/libstd/sys/sgx/abi/panic.rs b/src/libstd/sys/sgx/abi/panic.rs index 83411cb5b4c26..de86394b4b88c 100644 --- a/src/libstd/sys/sgx/abi/panic.rs +++ b/src/libstd/sys/sgx/abi/panic.rs @@ -49,7 +49,7 @@ impl Write for SgxPanicOutput { } } -#[no_mangle] +#[cfg_attr(not(test), no_mangle)] pub extern "C" fn panic_msg(msg: &str) -> ! { let _ = SgxPanicOutput::new().map(|mut out| out.write(msg.as_bytes())); usercalls::exit(true) diff --git a/src/libstd/sys/sgx/abi/tls.rs b/src/libstd/sys/sgx/abi/tls.rs index b2a812c7231da..6b9ab7e383c01 100644 --- a/src/libstd/sys/sgx/abi/tls.rs +++ b/src/libstd/sys/sgx/abi/tls.rs @@ -10,45 +10,16 @@ const USIZE_BITS: usize = 64; const TLS_KEYS: usize = 128; // Same as POSIX minimum const TLS_KEYS_BITSET_SIZE: usize = (TLS_KEYS + (USIZE_BITS - 1)) / USIZE_BITS; +#[cfg_attr(test, linkage = "available_externally")] +#[export_name = "_ZN16__rust_internals3std3sys3sgx3abi3tls14TLS_KEY_IN_USEE"] static TLS_KEY_IN_USE: SyncBitset = SYNC_BITSET_INIT; macro_rules! dup { ((* $($exp:tt)*) $($val:tt)*) => (dup!( ($($exp)*) $($val)* $($val)* )); (() $($val:tt)*) => ([$($val),*]) } -static TLS_DESTRUCTOR: [AtomicUsize; TLS_KEYS] = [ - AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), - AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), - AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), - AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), - AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), - AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), - AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), - AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), - AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), - AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), - AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), - AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), - AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), - AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), - AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), - AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), - AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), - AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), - AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), - AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), - AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), - AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), - AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), - AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), - AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), - AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), - AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), - AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), - AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), - AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), - AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), - AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), -]; +#[cfg_attr(test, linkage = "available_externally")] +#[export_name = "_ZN16__rust_internals3std3sys3sgx3abi3tls14TLS_DESTRUCTORE"] +static TLS_DESTRUCTOR: [AtomicUsize; TLS_KEYS] = dup!((* * * * * * *) (AtomicUsize::new(0))); extern "C" { fn get_tls_ptr() -> *const u8; diff --git a/src/libstd/sys/sgx/abi/usercalls/alloc.rs b/src/libstd/sys/sgx/abi/usercalls/alloc.rs index b787bd1a5abac..449a5fe5ae308 100644 --- a/src/libstd/sys/sgx/abi/usercalls/alloc.rs +++ b/src/libstd/sys/sgx/abi/usercalls/alloc.rs @@ -188,8 +188,13 @@ impl User where T: UserSafe { // from outside as obtained by `super::alloc`. fn new_uninit_bytes(size: usize) -> Self { unsafe { - let ptr = super::alloc(size, T::align_of()).expect("User memory allocation failed"); - User(NonNull::new_userref(T::from_raw_sized(ptr as _, size))) + // Mustn't call alloc with size 0. + let ptr = if size > 0 { + super::alloc(size, T::align_of()).expect("User memory allocation failed") as _ + } else { + T::align_of() as _ // dangling pointer ok for size 0 + }; + User(NonNull::new_userref(T::from_raw_sized(ptr, size))) } } diff --git a/src/libstd/sys/sgx/alloc.rs b/src/libstd/sys/sgx/alloc.rs index 94dc8ec25b587..98eb8397436bf 100644 --- a/src/libstd/sys/sgx/alloc.rs +++ b/src/libstd/sys/sgx/alloc.rs @@ -4,6 +4,8 @@ use super::waitqueue::SpinMutex; // Using a SpinMutex because we never want to exit the enclave waiting for the // allocator. +#[cfg_attr(test, linkage = "available_externally")] +#[export_name = "_ZN16__rust_internals3std3sys3sgx5alloc8DLMALLOCE"] static DLMALLOC: SpinMutex = SpinMutex::new(dlmalloc::DLMALLOC_INIT); #[stable(feature = "alloc_system_type", since = "1.28.0")] diff --git a/src/libstd/sys/sgx/args.rs b/src/libstd/sys/sgx/args.rs index b73bf9213b772..a84ab4138761e 100644 --- a/src/libstd/sys/sgx/args.rs +++ b/src/libstd/sys/sgx/args.rs @@ -5,9 +5,12 @@ use crate::sys::os_str::Buf; use crate::sys_common::FromInner; use crate::slice; +#[cfg_attr(test, linkage = "available_externally")] +#[export_name = "_ZN16__rust_internals3std3sys3sgx4args4ARGSE"] static ARGS: AtomicUsize = AtomicUsize::new(0); type ArgsStore = Vec; +#[cfg_attr(test, allow(dead_code))] pub unsafe fn init(argc: isize, argv: *const *const u8) { if argc != 0 { let args = alloc::User::<[ByteBuffer]>::from_raw_parts(argv as _, argc as _); diff --git a/src/libstd/sys/sgx/condvar.rs b/src/libstd/sys/sgx/condvar.rs index e9a7684f74d00..f9a76f0baf51a 100644 --- a/src/libstd/sys/sgx/condvar.rs +++ b/src/libstd/sys/sgx/condvar.rs @@ -32,7 +32,8 @@ impl Condvar { mutex.lock() } - pub unsafe fn wait_timeout(&self, _mutex: &Mutex, _dur: Duration) -> bool { + pub unsafe fn wait_timeout(&self, mutex: &Mutex, _dur: Duration) -> bool { + mutex.unlock(); // don't hold the lock while panicking panic!("timeout not supported in SGX"); } diff --git a/src/libstd/sys/sgx/net.rs b/src/libstd/sys/sgx/net.rs index 81f33c16294c3..0e7602a906efa 100644 --- a/src/libstd/sys/sgx/net.rs +++ b/src/libstd/sys/sgx/net.rs @@ -41,12 +41,29 @@ impl FromInner for Socket { } } -#[derive(Debug, Clone)] +#[derive(Clone)] pub struct TcpStream { inner: Socket, peer_addr: Option, } +impl fmt::Debug for TcpStream { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + let mut res = f.debug_struct("TcpStream"); + + if let Some(ref addr) = self.inner.local_addr { + res.field("addr", addr); + } + + if let Some(ref peer) = self.peer_addr { + res.field("peer", peer); + } + + res.field("fd", &self.inner.inner.as_inner()) + .finish() + } +} + fn io_err_to_addr(result: io::Result<&SocketAddr>) -> io::Result { match result { Ok(saddr) => Ok(saddr.to_string()), @@ -75,16 +92,32 @@ impl TcpStream { Ok(TcpStream { inner: Socket::new(fd, local_addr), peer_addr: Some(peer_addr) }) } - pub fn connect_timeout(addr: &SocketAddr, _: Duration) -> io::Result { + pub fn connect_timeout(addr: &SocketAddr, dur: Duration) -> io::Result { + if dur == Duration::default() { + return Err(io::Error::new(io::ErrorKind::InvalidInput, + "cannot set a 0 duration timeout")); + } Self::connect(Ok(addr)) // FIXME: ignoring timeout } - pub fn set_read_timeout(&self, _: Option) -> io::Result<()> { - sgx_ineffective(()) + pub fn set_read_timeout(&self, dur: Option) -> io::Result<()> { + match dur { + Some(dur) if dur == Duration::default() => { + return Err(io::Error::new(io::ErrorKind::InvalidInput, + "cannot set a 0 duration timeout")); + } + _ => sgx_ineffective(()) + } } - pub fn set_write_timeout(&self, _: Option) -> io::Result<()> { - sgx_ineffective(()) + pub fn set_write_timeout(&self, dur: Option) -> io::Result<()> { + match dur { + Some(dur) if dur == Duration::default() => { + return Err(io::Error::new(io::ErrorKind::InvalidInput, + "cannot set a 0 duration timeout")); + } + _ => sgx_ineffective(()) + } } pub fn read_timeout(&self) -> io::Result> { @@ -174,11 +207,24 @@ impl FromInner<(Socket, Option)> for TcpStream { } } -#[derive(Debug, Clone)] +#[derive(Clone)] pub struct TcpListener { inner: Socket, } +impl fmt::Debug for TcpListener { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + let mut res = f.debug_struct("TcpListener"); + + if let Some(ref addr) = self.inner.local_addr { + res.field("addr", addr); + } + + res.field("fd", &self.inner.inner.as_inner()) + .finish() + } +} + impl TcpListener { pub fn bind(addr: io::Result<&SocketAddr>) -> io::Result { let addr = io_err_to_addr(addr)?; diff --git a/src/libstd/sys/sgx/os.rs b/src/libstd/sys/sgx/os.rs index 2725e66ce5de4..0bb7b897058db 100644 --- a/src/libstd/sys/sgx/os.rs +++ b/src/libstd/sys/sgx/os.rs @@ -73,7 +73,11 @@ pub fn current_exe() -> io::Result { unsupported() } +#[cfg_attr(test, linkage = "available_externally")] +#[export_name = "_ZN16__rust_internals3std3sys3sgx2os3ENVE"] static ENV: AtomicUsize = AtomicUsize::new(0); +#[cfg_attr(test, linkage = "available_externally")] +#[export_name = "_ZN16__rust_internals3std3sys3sgx2os8ENV_INITE"] static ENV_INIT: Once = Once::new(); type EnvStore = Mutex>; diff --git a/src/libstd/sys/sgx/rwlock.rs b/src/libstd/sys/sgx/rwlock.rs index 372760bbf26b4..7b113267865b6 100644 --- a/src/libstd/sys/sgx/rwlock.rs +++ b/src/libstd/sys/sgx/rwlock.rs @@ -1,6 +1,9 @@ +#[cfg(not(test))] use crate::alloc::{self, Layout}; use crate::num::NonZeroUsize; +#[cfg(not(test))] use crate::slice; +#[cfg(not(test))] use crate::str; use super::waitqueue::{ @@ -147,6 +150,7 @@ impl RWLock { // only used by __rust_rwlock_unlock below #[inline] + #[cfg_attr(test, allow(dead_code))] unsafe fn unlock(&self) { let rguard = self.readers.lock(); let wguard = self.writer.lock(); @@ -161,9 +165,11 @@ impl RWLock { pub unsafe fn destroy(&self) {} } +#[cfg(not(test))] const EINVAL: i32 = 22; // used by libunwind port +#[cfg(not(test))] #[no_mangle] pub unsafe extern "C" fn __rust_rwlock_rdlock(p: *mut RWLock) -> i32 { if p.is_null() { @@ -173,6 +179,7 @@ pub unsafe extern "C" fn __rust_rwlock_rdlock(p: *mut RWLock) -> i32 { return 0; } +#[cfg(not(test))] #[no_mangle] pub unsafe extern "C" fn __rust_rwlock_wrlock(p: *mut RWLock) -> i32 { if p.is_null() { @@ -181,6 +188,7 @@ pub unsafe extern "C" fn __rust_rwlock_wrlock(p: *mut RWLock) -> i32 { (*p).write(); return 0; } +#[cfg(not(test))] #[no_mangle] pub unsafe extern "C" fn __rust_rwlock_unlock(p: *mut RWLock) -> i32 { if p.is_null() { @@ -192,6 +200,7 @@ pub unsafe extern "C" fn __rust_rwlock_unlock(p: *mut RWLock) -> i32 { // the following functions are also used by the libunwind port. They're // included here to make sure parallel codegen and LTO don't mess things up. +#[cfg(not(test))] #[no_mangle] pub unsafe extern "C" fn __rust_print_err(m: *mut u8, s: i32) { if s < 0 { @@ -203,17 +212,20 @@ pub unsafe extern "C" fn __rust_print_err(m: *mut u8, s: i32) { } } +#[cfg(not(test))] #[no_mangle] // NB. used by both libunwind and libpanic_abort pub unsafe extern "C" fn __rust_abort() { crate::sys::abort_internal(); } +#[cfg(not(test))] #[no_mangle] pub unsafe extern "C" fn __rust_c_alloc(size: usize, align: usize) -> *mut u8 { alloc::alloc(Layout::from_size_align_unchecked(size, align)) } +#[cfg(not(test))] #[no_mangle] pub unsafe extern "C" fn __rust_c_dealloc(ptr: *mut u8, size: usize, align: usize) { alloc::dealloc(ptr, Layout::from_size_align_unchecked(size, align)) @@ -221,15 +233,13 @@ pub unsafe extern "C" fn __rust_c_dealloc(ptr: *mut u8, size: usize, align: usiz #[cfg(test)] mod tests { - use super::*; use core::array::FixedSizeArray; - use crate::mem::MaybeUninit; - use crate::{mem, ptr}; + use crate::mem::{self, MaybeUninit}; - // The below test verifies that the bytes of initialized RWLock are the ones - // we use in libunwind. - // If they change we need to update src/UnwindRustSgx.h in libunwind. + // Verify that the bytes of initialized RWLock are the same as in + // libunwind. If they change, `src/UnwindRustSgx.h` in libunwind needs to + // be changed too. #[test] fn test_c_rwlock_initializer() { const RWLOCK_INIT: &[u8] = &[ @@ -251,11 +261,28 @@ mod tests { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, ]; - let mut init = MaybeUninit::::zeroed(); - init.set(RWLock::new()); - assert_eq!( - mem::transmute::<_, [u8; 128]>(init.into_inner()).as_slice(), - RWLOCK_INIT - ); + #[inline(never)] + fn zero_stack() { + test::black_box(MaybeUninit::<[RWLock; 16]>::zeroed()); + } + + #[inline(never)] + unsafe fn rwlock_new(init: &mut MaybeUninit) { + init.set(RWLock::new()); + } + + unsafe { + // try hard to make sure that the padding/unused bytes in RWLock + // get initialized as 0. If the assertion below fails, that might + // just be an issue with the test code and not with the value of + // RWLOCK_INIT. + zero_stack(); + let mut init = MaybeUninit::::zeroed(); + rwlock_new(&mut init); + assert_eq!( + mem::transmute::<_, [u8; 128]>(init.into_initialized()).as_slice(), + RWLOCK_INIT + ) + }; } } diff --git a/src/libstd/sys/sgx/stack_overflow.rs b/src/libstd/sys/sgx/stack_overflow.rs index c0e7c824615c8..e63fa2bed65d5 100644 --- a/src/libstd/sys/sgx/stack_overflow.rs +++ b/src/libstd/sys/sgx/stack_overflow.rs @@ -6,6 +6,7 @@ impl Handler { } } +#[cfg_attr(test, allow(dead_code))] pub unsafe fn init() { } diff --git a/src/libstd/sys/sgx/thread.rs b/src/libstd/sys/sgx/thread.rs index 13569062ac184..a3637723ba1bd 100644 --- a/src/libstd/sys/sgx/thread.rs +++ b/src/libstd/sys/sgx/thread.rs @@ -1,3 +1,4 @@ +#![cfg_attr(test, allow(dead_code))] // why is this necessary? use crate::boxed::FnBox; use crate::ffi::CStr; use crate::io; @@ -33,7 +34,11 @@ mod task_queue { } } + #[cfg_attr(test, linkage = "available_externally")] + #[export_name = "_ZN16__rust_internals3std3sys3sgx6thread15TASK_QUEUE_INITE"] static TASK_QUEUE_INIT: Once = Once::new(); + #[cfg_attr(test, linkage = "available_externally")] + #[export_name = "_ZN16__rust_internals3std3sys3sgx6thread10TASK_QUEUEE"] static mut TASK_QUEUE: Option>> = None; pub(super) fn lock() -> MutexGuard<'static, Vec> { diff --git a/src/libstd/sys/sgx/waitqueue.rs b/src/libstd/sys/sgx/waitqueue.rs index 1dbf2afbf4987..3f5e03ddad69e 100644 --- a/src/libstd/sys/sgx/waitqueue.rs +++ b/src/libstd/sys/sgx/waitqueue.rs @@ -498,6 +498,7 @@ mod spin_mutex { use super::*; use crate::sync::Arc; use crate::thread; + use crate::time::{SystemTime, Duration}; #[test] fn sleep() { @@ -507,7 +508,13 @@ mod spin_mutex { let t1 = thread::spawn(move || { *mutex2.lock() = 1; }); - thread::sleep_ms(50); + + // "sleep" for 50ms + // FIXME: https://github.com/fortanix/rust-sgx/issues/31 + let start = SystemTime::now(); + let max = Duration::from_millis(50); + while start.elapsed().unwrap() < max {} + assert_eq!(*guard, 0); drop(guard); t1.join().unwrap(); @@ -530,7 +537,8 @@ mod tests { let locked = wq.lock(); let t1 = thread::spawn(move || { - assert!(WaitQueue::notify_one(wq2.lock()).is_none()) + // if we obtain the lock, the main thread should be waiting + assert!(WaitQueue::notify_one(wq2.lock()).is_ok()); }); WaitQueue::wait(locked); diff --git a/src/libstd/thread/local.rs b/src/libstd/thread/local.rs index 7ad6b124e3a38..b73c5856b8805 100644 --- a/src/libstd/thread/local.rs +++ b/src/libstd/thread/local.rs @@ -530,7 +530,7 @@ mod tests { thread::spawn(|| { assert!(FOO.try_with(|_| ()).is_ok()); - }).join().ok().unwrap(); + }).join().ok().expect("thread panicked"); } #[test] @@ -584,7 +584,7 @@ mod tests { thread::spawn(move|| { drop(S1); - }).join().ok().unwrap(); + }).join().ok().expect("thread panicked"); } #[test] @@ -600,7 +600,7 @@ mod tests { thread::spawn(move|| unsafe { K1.with(|s| *s.get() = Some(S1)); - }).join().ok().unwrap(); + }).join().ok().expect("thread panicked"); } // Note that this test will deadlock if TLS destructors aren't run (this diff --git a/src/libstd/thread/mod.rs b/src/libstd/thread/mod.rs index d856f9b465e04..6d305aed748d0 100644 --- a/src/libstd/thread/mod.rs +++ b/src/libstd/thread/mod.rs @@ -1499,7 +1499,7 @@ mod tests { fn test_unnamed_thread() { thread::spawn(move|| { assert!(thread::current().name().is_none()); - }).join().ok().unwrap(); + }).join().ok().expect("thread panicked"); } #[test] @@ -1693,6 +1693,7 @@ mod tests { } #[test] + #[cfg_attr(target_env = "sgx", ignore)] // FIXME: https://github.com/fortanix/rust-sgx/issues/31 fn test_park_timeout_unpark_not_called() { for _ in 0..10 { thread::park_timeout(Duration::from_millis(10)); @@ -1700,6 +1701,7 @@ mod tests { } #[test] + #[cfg_attr(target_env = "sgx", ignore)] // FIXME: https://github.com/fortanix/rust-sgx/issues/31 fn test_park_timeout_unpark_called_other_thread() { for _ in 0..10 { let th = thread::current(); @@ -1714,6 +1716,7 @@ mod tests { } #[test] + #[cfg_attr(target_env = "sgx", ignore)] // FIXME: https://github.com/fortanix/rust-sgx/issues/31 fn sleep_ms_smoke() { thread::sleep(Duration::from_millis(2)); } diff --git a/src/test/mir-opt/graphviz.rs b/src/test/mir-opt/graphviz.rs new file mode 100644 index 0000000000000..660576996e5d4 --- /dev/null +++ b/src/test/mir-opt/graphviz.rs @@ -0,0 +1,23 @@ +// Test graphviz output +// compile-flags: -Z dump-mir-graphviz + +// ignore-tidy-linelength + +fn main() {} + +// END RUST SOURCE +// START rustc.main.mir_map.0.dot +// digraph Mir_0_0_3 { // The name here MUST be an ASCII identifier. +// graph [fontname="monospace"]; +// node [fontname="monospace"]; +// edge [fontname="monospace"]; +// label=>; +// bb0 [shape="none", label=<
0
_0 = ()
goto
+// >]; +// bb1 [shape="none", label=<
1
resume
+// >]; +// bb2 [shape="none", label=<
2
return
+// >]; +// bb0 -> bb2 [label=""]; +// } +// END rustc.main.mir_map.0.dot diff --git a/src/test/ui/issues/issue-17800.stderr b/src/test/ui/issues/issue-17800.stderr index b4234245bfb38..6efc7f0c06e11 100644 --- a/src/test/ui/issues/issue-17800.stderr +++ b/src/test/ui/issues/issue-17800.stderr @@ -2,10 +2,10 @@ error[E0026]: variant `MyOption::MySome` does not have a field named `x` --> $DIR/issue-17800.rs:8:28 | LL | MyOption::MySome { x: 42 } => (), - | ^^^^^ + | ^ | | | variant `MyOption::MySome` does not have this field - | help: did you mean: `0` + | help: a field with a similar name exists: `0` error: aborting due to previous error diff --git a/src/test/ui/issues/issue-26217.rs b/src/test/ui/issues/issue-26217.rs index a700807d7f216..05e0462190906 100644 --- a/src/test/ui/issues/issue-26217.rs +++ b/src/test/ui/issues/issue-26217.rs @@ -1,6 +1,10 @@ fn foo() where for<'a> T: 'a {} -fn main<'a>() { +fn bar<'a>() { foo::<&'a i32>(); //~^ ERROR the type `&'a i32` does not fulfill the required lifetime } + +fn main() { + bar(); +} diff --git a/src/test/ui/issues/issue-51102.stderr b/src/test/ui/issues/issue-51102.stderr index 1b2948db2d6c3..4d4b977374ef9 100644 --- a/src/test/ui/issues/issue-51102.stderr +++ b/src/test/ui/issues/issue-51102.stderr @@ -2,7 +2,7 @@ error[E0026]: struct `SimpleStruct` does not have a field named `state` --> $DIR/issue-51102.rs:13:17 | LL | state: 0, - | ^^^^^^^^ struct `SimpleStruct` does not have this field + | ^^^^^ struct `SimpleStruct` does not have this field error[E0025]: field `no_state_here` bound multiple times in the pattern --> $DIR/issue-51102.rs:24:17 @@ -16,7 +16,7 @@ error[E0026]: variant `SimpleEnum::NoState` does not have a field named `state` --> $DIR/issue-51102.rs:33:17 | LL | state: 0 - | ^^^^^^^^ variant `SimpleEnum::NoState` does not have this field + | ^^^^^ variant `SimpleEnum::NoState` does not have this field error: aborting due to 3 previous errors diff --git a/src/test/ui/issues/issue-52717.stderr b/src/test/ui/issues/issue-52717.stderr index 408819813b075..468cdf2dcf921 100644 --- a/src/test/ui/issues/issue-52717.stderr +++ b/src/test/ui/issues/issue-52717.stderr @@ -5,7 +5,7 @@ LL | A::A { fob } => { println!("{}", fob); } | ^^^ | | | variant `A::A` does not have this field - | help: did you mean: `foo` + | help: a field with a similar name exists: `foo` error: aborting due to previous error diff --git a/src/test/ui/numeric/numeric-fields.stderr b/src/test/ui/numeric/numeric-fields.stderr index 1a2ad4a0c0945..ce51bbaa114fd 100644 --- a/src/test/ui/numeric/numeric-fields.stderr +++ b/src/test/ui/numeric/numeric-fields.stderr @@ -10,7 +10,7 @@ error[E0026]: struct `S` does not have a field named `0x1` --> $DIR/numeric-fields.rs:7:17 | LL | S{0: a, 0x1: b, ..} => {} - | ^^^^^^ struct `S` does not have this field + | ^^^ struct `S` does not have this field error: aborting due to 2 previous errors diff --git a/src/test/ui/structs/struct-field-cfg.stderr b/src/test/ui/structs/struct-field-cfg.stderr index c8c624d548b67..565866a682ada 100644 --- a/src/test/ui/structs/struct-field-cfg.stderr +++ b/src/test/ui/structs/struct-field-cfg.stderr @@ -22,7 +22,7 @@ error[E0026]: struct `Foo` does not have a field named `absent` --> $DIR/struct-field-cfg.rs:16:42 | LL | let Foo { present: (), #[cfg(all())] absent: () } = foo; - | ^^^^^^^^^^ struct `Foo` does not have this field + | ^^^^^^ struct `Foo` does not have this field error: aborting due to 4 previous errors diff --git a/src/test/ui/suggestions/borrow-for-loop-head.rs b/src/test/ui/suggestions/borrow-for-loop-head.rs new file mode 100644 index 0000000000000..c2bda55e58903 --- /dev/null +++ b/src/test/ui/suggestions/borrow-for-loop-head.rs @@ -0,0 +1,10 @@ +fn main() { + let a = vec![1, 2, 3]; + for i in &a { + for j in a { + //~^ ERROR cannot move out of `a` because it is borrowed + //~| ERROR use of moved value: `a` + println!("{} * {} = {}", i, j, i * j); + } + } +} diff --git a/src/test/ui/suggestions/borrow-for-loop-head.stderr b/src/test/ui/suggestions/borrow-for-loop-head.stderr new file mode 100644 index 0000000000000..17ac3fe86d083 --- /dev/null +++ b/src/test/ui/suggestions/borrow-for-loop-head.stderr @@ -0,0 +1,24 @@ +error[E0505]: cannot move out of `a` because it is borrowed + --> $DIR/borrow-for-loop-head.rs:4:18 + | +LL | for i in &a { + | - borrow of `a` occurs here +LL | for j in a { + | ^ move out of `a` occurs here + +error[E0382]: use of moved value: `a` + --> $DIR/borrow-for-loop-head.rs:4:18 + | +LL | for j in a { + | ^ value moved here in previous iteration of loop + | + = note: move occurs because `a` has type `std::vec::Vec`, which does not implement the `Copy` trait +help: consider borrowing this to avoid moving it into the for loop + | +LL | for j in &a { + | ^^ + +error: aborting due to 2 previous errors + +Some errors occurred: E0382, E0505. +For more information about an error, try `rustc --explain E0382`. diff --git a/src/tools/tidy/src/pal.rs b/src/tools/tidy/src/pal.rs index ed2218f09d26b..0be3ec839e9a2 100644 --- a/src/tools/tidy/src/pal.rs +++ b/src/tools/tidy/src/pal.rs @@ -54,6 +54,7 @@ const EXCEPTION_PATHS: &[&str] = &[ "src/libstd/f64.rs", // Integration test for platform-specific run-time feature detection: "src/libstd/tests/run-time-detect.rs" , + "src/libstd/net/test.rs", "src/libstd/sys_common/mod.rs", "src/libstd/sys_common/net.rs", "src/libterm", // Not sure how to make this crate portable, but test crate needs it.