diff --git a/src/librustc/ich/mod.rs b/src/librustc/ich/mod.rs index ece438266c0c2..cd2e32de9d5c4 100644 --- a/src/librustc/ich/mod.rs +++ b/src/librustc/ich/mod.rs @@ -12,21 +12,13 @@ mod impls_hir; mod impls_ty; mod impls_syntax; -pub const ATTR_DIRTY: Symbol = sym::rustc_dirty; -pub const ATTR_CLEAN: Symbol = sym::rustc_clean; -pub const ATTR_IF_THIS_CHANGED: Symbol = sym::rustc_if_this_changed; -pub const ATTR_THEN_THIS_WOULD_NEED: Symbol = sym::rustc_then_this_would_need; -pub const ATTR_PARTITION_REUSED: Symbol = sym::rustc_partition_reused; -pub const ATTR_PARTITION_CODEGENED: Symbol = sym::rustc_partition_codegened; -pub const ATTR_EXPECTED_CGU_REUSE: Symbol = sym::rustc_expected_cgu_reuse; - pub const IGNORED_ATTRIBUTES: &[Symbol] = &[ sym::cfg, - ATTR_IF_THIS_CHANGED, - ATTR_THEN_THIS_WOULD_NEED, - ATTR_DIRTY, - ATTR_CLEAN, - ATTR_PARTITION_REUSED, - ATTR_PARTITION_CODEGENED, - ATTR_EXPECTED_CGU_REUSE, + sym::rustc_if_this_changed, + sym::rustc_then_this_would_need, + sym::rustc_dirty, + sym::rustc_clean, + sym::rustc_partition_reused, + sym::rustc_partition_codegened, + sym::rustc_expected_cgu_reuse, ]; diff --git a/src/librustc_codegen_llvm/attributes.rs b/src/librustc_codegen_llvm/attributes.rs index 5479a1f31445e..3f2a51b45bd06 100644 --- a/src/librustc_codegen_llvm/attributes.rs +++ b/src/librustc_codegen_llvm/attributes.rs @@ -344,6 +344,17 @@ pub fn from_fn_attrs( const_cstr!("wasm-import-module"), &module, ); + + let name = codegen_fn_attrs.link_name.unwrap_or_else(|| { + cx.tcx.item_name(instance.def_id()) + }); + let name = CString::new(&name.as_str()[..]).unwrap(); + llvm::AddFunctionAttrStringValue( + llfn, + llvm::AttributePlace::Function, + const_cstr!("wasm-import-name"), + &name, + ); } } } diff --git a/src/librustc_codegen_llvm/llvm_util.rs b/src/librustc_codegen_llvm/llvm_util.rs index 40739387b00c4..3145b0df63b8a 100644 --- a/src/librustc_codegen_llvm/llvm_util.rs +++ b/src/librustc_codegen_llvm/llvm_util.rs @@ -3,6 +3,7 @@ use crate::llvm; use syntax_pos::symbol::Symbol; use rustc::session::Session; use rustc::session::config::PrintRequest; +use rustc_data_structures::fx::FxHashSet; use rustc_target::spec::{MergeFunctions, PanicStrategy}; use libc::c_int; use std::ffi::CString; @@ -51,20 +52,37 @@ unsafe fn configure_llvm(sess: &Session) { llvm::LLVMRustInstallFatalErrorHandler(); + fn llvm_arg_to_arg_name(full_arg: &str) -> &str { + full_arg.trim().split(|c: char| { + c == '=' || c.is_whitespace() + }).next().unwrap_or("") + } + + let user_specified_args: FxHashSet<_> = sess + .opts + .cg + .llvm_args + .iter() + .map(|s| llvm_arg_to_arg_name(s)) + .filter(|s| s.len() > 0) + .collect(); + { - let mut add = |arg: &str| { - let s = CString::new(arg).unwrap(); - llvm_args.push(s.as_ptr()); - llvm_c_strs.push(s); + // This adds the given argument to LLVM. Unless `force` is true + // user specified arguments are *not* overridden. + let mut add = |arg: &str, force: bool| { + if force || !user_specified_args.contains(llvm_arg_to_arg_name(arg)) { + let s = CString::new(arg).unwrap(); + llvm_args.push(s.as_ptr()); + llvm_c_strs.push(s); + } }; - add("rustc"); // fake program name - if sess.time_llvm_passes() { add("-time-passes"); } - if sess.print_llvm_passes() { add("-debug-pass=Structure"); } - if sess.opts.debugging_opts.disable_instrumentation_preinliner { - add("-disable-preinline"); - } + add("rustc", true); // fake program name + if sess.time_llvm_passes() { add("-time-passes", false); } + if sess.print_llvm_passes() { add("-debug-pass=Structure", false); } + if sess.opts.debugging_opts.generate_arange_section { - add("-generate-arange-section"); + add("-generate-arange-section", false); } if get_major_version() >= 8 { match sess.opts.debugging_opts.merge_functions @@ -72,22 +90,22 @@ unsafe fn configure_llvm(sess: &Session) { MergeFunctions::Disabled | MergeFunctions::Trampolines => {} MergeFunctions::Aliases => { - add("-mergefunc-use-aliases"); + add("-mergefunc-use-aliases", false); } } } if sess.target.target.target_os == "emscripten" && sess.panic_strategy() == PanicStrategy::Unwind { - add("-enable-emscripten-cxx-exceptions"); + add("-enable-emscripten-cxx-exceptions", false); } // HACK(eddyb) LLVM inserts `llvm.assume` calls to preserve align attributes // during inlining. Unfortunately these may block other optimizations. - add("-preserve-alignment-assumptions-during-inlining=false"); + add("-preserve-alignment-assumptions-during-inlining=false", false); for arg in &sess.opts.cg.llvm_args { - add(&(*arg)); + add(&(*arg), true); } } diff --git a/src/librustc_codegen_ssa/mir/rvalue.rs b/src/librustc_codegen_ssa/mir/rvalue.rs index 488ae8dbf9036..55d63f18cd906 100644 --- a/src/librustc_codegen_ssa/mir/rvalue.rs +++ b/src/librustc_codegen_ssa/mir/rvalue.rs @@ -341,6 +341,13 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { llval } } + (CastTy::Int(_), CastTy::Float) => { + if signed { + bx.sitofp(llval, ll_t_out) + } else { + bx.uitofp(llval, ll_t_out) + } + } (CastTy::Ptr(_), CastTy::Ptr(_)) | (CastTy::FnPtr, CastTy::Ptr(_)) | (CastTy::RPtr(_), CastTy::Ptr(_)) => @@ -352,8 +359,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let usize_llval = bx.intcast(llval, bx.cx().type_isize(), signed); bx.inttoptr(usize_llval, ll_t_out) } - (CastTy::Int(_), CastTy::Float) => - cast_int_to_float(&mut bx, signed, llval, ll_t_in, ll_t_out), (CastTy::Float, CastTy::Int(IntTy::I)) => cast_float_to_int(&mut bx, true, llval, ll_t_in, ll_t_out), (CastTy::Float, CastTy::Int(_)) => @@ -720,40 +725,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { } } -fn cast_int_to_float<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( - bx: &mut Bx, - signed: bool, - x: Bx::Value, - int_ty: Bx::Type, - float_ty: Bx::Type -) -> Bx::Value { - // Most integer types, even i128, fit into [-f32::MAX, f32::MAX] after rounding. - // It's only u128 -> f32 that can cause overflows (i.e., should yield infinity). - // LLVM's uitofp produces undef in those cases, so we manually check for that case. - let is_u128_to_f32 = !signed && - bx.cx().int_width(int_ty) == 128 && - bx.cx().float_width(float_ty) == 32; - if is_u128_to_f32 { - // All inputs greater or equal to (f32::MAX + 0.5 ULP) are rounded to infinity, - // and for everything else LLVM's uitofp works just fine. - use rustc_apfloat::ieee::Single; - const MAX_F32_PLUS_HALF_ULP: u128 = ((1 << (Single::PRECISION + 1)) - 1) - << (Single::MAX_EXP - Single::PRECISION as i16); - let max = bx.cx().const_uint_big(int_ty, MAX_F32_PLUS_HALF_ULP); - let overflow = bx.icmp(IntPredicate::IntUGE, x, max); - let infinity_bits = bx.cx().const_u32(ieee::Single::INFINITY.to_bits() as u32); - let infinity = bx.bitcast(infinity_bits, float_ty); - let fp = bx.uitofp(x, float_ty); - bx.select(overflow, infinity, fp) - } else { - if signed { - bx.sitofp(x, float_ty) - } else { - bx.uitofp(x, float_ty) - } - } -} - fn cast_float_to_int<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( bx: &mut Bx, signed: bool, diff --git a/src/librustc_codegen_utils/symbol_names.rs b/src/librustc_codegen_utils/symbol_names.rs index c52c6cfa83c91..922964ee45f6b 100644 --- a/src/librustc_codegen_utils/symbol_names.rs +++ b/src/librustc_codegen_utils/symbol_names.rs @@ -142,12 +142,32 @@ fn symbol_name(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>) -> Symbol { }; let attrs = tcx.codegen_fn_attrs(def_id); + + // Foreign items by default use no mangling for their symbol name. There's a + // few exceptions to this rule though: + // + // * This can be overridden with the `#[link_name]` attribute + // + // * On the wasm32 targets there is a bug (or feature) in LLD [1] where the + // same-named symbol when imported from different wasm modules will get + // hooked up incorectly. As a result foreign symbols, on the wasm target, + // with a wasm import module, get mangled. Additionally our codegen will + // deduplicate symbols based purely on the symbol name, but for wasm this + // isn't quite right because the same-named symbol on wasm can come from + // different modules. For these reasons if `#[link(wasm_import_module)]` + // is present we mangle everything on wasm because the demangled form will + // show up in the `wasm-import-name` custom attribute in LLVM IR. + // + // [1]: https://bugs.llvm.org/show_bug.cgi?id=44316 if is_foreign { - if let Some(name) = attrs.link_name { - return name; + if tcx.sess.target.target.arch != "wasm32" || + !tcx.wasm_import_module_map(def_id.krate).contains_key(&def_id) + { + if let Some(name) = attrs.link_name { + return name; + } + return tcx.item_name(def_id); } - // Don't mangle foreign items. - return tcx.item_name(def_id); } if let Some(name) = attrs.export_name { diff --git a/src/librustc_incremental/assert_dep_graph.rs b/src/librustc_incremental/assert_dep_graph.rs index 07d426af6ee95..e3e3b0b17483e 100644 --- a/src/librustc_incremental/assert_dep_graph.rs +++ b/src/librustc_incremental/assert_dep_graph.rs @@ -44,11 +44,10 @@ use rustc_data_structures::graph::implementation::{ }; use rustc::hir; use rustc::hir::intravisit::{self, NestedVisitorMap, Visitor}; -use rustc::ich::{ATTR_IF_THIS_CHANGED, ATTR_THEN_THIS_WOULD_NEED}; use std::env; use std::fs::{self, File}; use std::io::Write; -use syntax::ast; +use syntax::{ast, symbol::sym}; use syntax_pos::Span; pub fn assert_dep_graph(tcx: TyCtxt<'_>) { @@ -78,7 +77,7 @@ pub fn assert_dep_graph(tcx: TyCtxt<'_>) { assert!(tcx.sess.opts.debugging_opts.query_dep_graph, "cannot use the `#[{}]` or `#[{}]` annotations \ without supplying `-Z query-dep-graph`", - ATTR_IF_THIS_CHANGED, ATTR_THEN_THIS_WOULD_NEED); + sym::rustc_if_this_changed, sym::rustc_then_this_would_need); } // Check paths. @@ -114,7 +113,7 @@ impl IfThisChanged<'tcx> { let def_id = self.tcx.hir().local_def_id(hir_id); let def_path_hash = self.tcx.def_path_hash(def_id); for attr in attrs { - if attr.check_name(ATTR_IF_THIS_CHANGED) { + if attr.check_name(sym::rustc_if_this_changed) { let dep_node_interned = self.argument(attr); let dep_node = match dep_node_interned { None => def_path_hash.to_dep_node(DepKind::Hir), @@ -130,7 +129,7 @@ impl IfThisChanged<'tcx> { } }; self.if_this_changed.push((attr.span, def_id, dep_node)); - } else if attr.check_name(ATTR_THEN_THIS_WOULD_NEED) { + } else if attr.check_name(sym::rustc_then_this_would_need) { let dep_node_interned = self.argument(attr); let dep_node = match dep_node_interned { Some(n) => { diff --git a/src/librustc_incremental/assert_module_sources.rs b/src/librustc_incremental/assert_module_sources.rs index c2e3fa8f28d2f..1a675ea002cda 100644 --- a/src/librustc_incremental/assert_module_sources.rs +++ b/src/librustc_incremental/assert_module_sources.rs @@ -28,8 +28,6 @@ use rustc::ty::TyCtxt; use std::collections::BTreeSet; use syntax::ast; use syntax::symbol::{Symbol, sym}; -use rustc::ich::{ATTR_PARTITION_REUSED, ATTR_PARTITION_CODEGENED, - ATTR_EXPECTED_CGU_REUSE}; pub fn assert_module_sources(tcx: TyCtxt<'_>) { tcx.dep_graph.with_ignore(|| { @@ -62,11 +60,11 @@ struct AssertModuleSource<'tcx> { impl AssertModuleSource<'tcx> { fn check_attr(&self, attr: &ast::Attribute) { - let (expected_reuse, comp_kind) = if attr.check_name(ATTR_PARTITION_REUSED) { + let (expected_reuse, comp_kind) = if attr.check_name(sym::rustc_partition_reused) { (CguReuse::PreLto, ComparisonKind::AtLeast) - } else if attr.check_name(ATTR_PARTITION_CODEGENED) { + } else if attr.check_name(sym::rustc_partition_codegened) { (CguReuse::No, ComparisonKind::Exact) - } else if attr.check_name(ATTR_EXPECTED_CGU_REUSE) { + } else if attr.check_name(sym::rustc_expected_cgu_reuse) { match &*self.field(attr, sym::kind).as_str() { "no" => (CguReuse::No, ComparisonKind::Exact), "pre-lto" => (CguReuse::PreLto, ComparisonKind::Exact), diff --git a/src/librustc_incremental/persist/dirty_clean.rs b/src/librustc_incremental/persist/dirty_clean.rs index ea156a94ea17b..c919db070a6bb 100644 --- a/src/librustc_incremental/persist/dirty_clean.rs +++ b/src/librustc_incremental/persist/dirty_clean.rs @@ -22,7 +22,6 @@ use rustc::hir::Node as HirNode; use rustc::hir::def_id::DefId; use rustc::hir::itemlikevisit::ItemLikeVisitor; use rustc::hir::intravisit; -use rustc::ich::{ATTR_DIRTY, ATTR_CLEAN}; use rustc::ty::TyCtxt; use rustc_data_structures::fingerprint::Fingerprint; use rustc_data_structures::fx::FxHashSet; @@ -224,7 +223,7 @@ pub fn check_dirty_clean_annotations(tcx: TyCtxt<'_>) { let mut all_attrs = FindAllAttrs { tcx, - attr_names: vec![ATTR_DIRTY, ATTR_CLEAN], + attr_names: vec![sym::rustc_dirty, sym::rustc_clean], found_attrs: vec![], }; intravisit::walk_crate(&mut all_attrs, krate); @@ -246,9 +245,9 @@ impl DirtyCleanVisitor<'tcx> { fn assertion_maybe(&mut self, item_id: hir::HirId, attr: &Attribute) -> Option { - let is_clean = if attr.check_name(ATTR_DIRTY) { + let is_clean = if attr.check_name(sym::rustc_dirty) { false - } else if attr.check_name(ATTR_CLEAN) { + } else if attr.check_name(sym::rustc_clean) { true } else { // skip: not rustc_clean/dirty diff --git a/src/librustc_mir/transform/inline.rs b/src/librustc_mir/transform/inline.rs index 9763913082ddc..dca142279463c 100644 --- a/src/librustc_mir/transform/inline.rs +++ b/src/librustc_mir/transform/inline.rs @@ -663,9 +663,9 @@ impl<'a, 'tcx> Integrator<'a, 'tcx> { fn make_integrate_local(&self, local: &Local) -> Local { if *local == RETURN_PLACE { - match self.destination.as_local() { - Some(l) => return l, - ref place => bug!("Return place is {:?}, not local", place), + match self.destination.base { + PlaceBase::Local(l) => return l, + PlaceBase::Static(ref s) => bug!("Return place is {:?}, not local", s), } } @@ -695,14 +695,24 @@ impl<'a, 'tcx> MutVisitor<'tcx> for Integrator<'a, 'tcx> { fn visit_place( &mut self, place: &mut Place<'tcx>, - context: PlaceContext, - location: Location, + _context: PlaceContext, + _location: Location, ) { - if let Some(RETURN_PLACE) = place.as_local() { - // Return pointer; update the place itself - *place = self.destination.clone(); - } else { - self.super_place(place, context, location); + match &mut place.base { + PlaceBase::Static(_) => {}, + PlaceBase::Local(l) => { + // If this is the `RETURN_PLACE`, we need to rebase any projections onto it. + let dest_proj_len = self.destination.projection.len(); + if *l == RETURN_PLACE && dest_proj_len > 0 { + let mut projs = Vec::with_capacity(dest_proj_len + place.projection.len()); + projs.extend(self.destination.projection); + projs.extend(place.projection); + + place.projection = self.tcx.intern_place_elems(&*projs); + } + + *l = self.make_integrate_local(l); + } } } diff --git a/src/librustc_session/config.rs b/src/librustc_session/config.rs index 7f3bab8f23299..8dc0ba67533eb 100644 --- a/src/librustc_session/config.rs +++ b/src/librustc_session/config.rs @@ -1488,8 +1488,6 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options, "extra arguments to prepend to the linker invocation (space separated)"), profile: bool = (false, parse_bool, [TRACKED], "insert profiling code"), - disable_instrumentation_preinliner: bool = (false, parse_bool, [TRACKED], - "Disable the instrumentation pre-inliner, useful for profiling / PGO."), relro_level: Option = (None, parse_relro_level, [TRACKED], "choose which RELRO level to use"), nll_facts: bool = (false, parse_bool, [UNTRACKED], diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 09771bb762536..7f1c6c99cf8d1 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -3880,36 +3880,45 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { call_sp: Span, args: &'tcx [hir::Expr], ) { - if !call_sp.desugaring_kind().is_some() { - // We *do not* do this for desugared call spans to keep good diagnostics when involving - // the `?` operator. - for error in errors { - if let ty::Predicate::Trait(predicate) = error.obligation.predicate { - // Collect the argument position for all arguments that could have caused this - // `FulfillmentError`. - let mut referenced_in = final_arg_types.iter() - .map(|(i, checked_ty, _)| (i, checked_ty)) - .chain(final_arg_types.iter().map(|(i, _, coerced_ty)| (i, coerced_ty))) - .flat_map(|(i, ty)| { - let ty = self.resolve_vars_if_possible(ty); - // We walk the argument type because the argument's type could have - // been `Option`, but the `FulfillmentError` references `T`. - ty.walk() - .filter(|&ty| ty == predicate.skip_binder().self_ty()) - .map(move |_| *i) - }) - .collect::>(); + // We *do not* do this for desugared call spans to keep good diagnostics when involving + // the `?` operator. + if call_sp.desugaring_kind().is_some() { + return + } + + for error in errors { + // Only if the cause is somewhere inside the expression we want try to point at arg. + // Otherwise, it means that the cause is somewhere else and we should not change + // anything because we can break the correct span. + if !call_sp.contains(error.obligation.cause.span) { + continue + } + + if let ty::Predicate::Trait(predicate) = error.obligation.predicate { + // Collect the argument position for all arguments that could have caused this + // `FulfillmentError`. + let mut referenced_in = final_arg_types.iter() + .map(|(i, checked_ty, _)| (i, checked_ty)) + .chain(final_arg_types.iter().map(|(i, _, coerced_ty)| (i, coerced_ty))) + .flat_map(|(i, ty)| { + let ty = self.resolve_vars_if_possible(ty); + // We walk the argument type because the argument's type could have + // been `Option`, but the `FulfillmentError` references `T`. + ty.walk() + .filter(|&ty| ty == predicate.skip_binder().self_ty()) + .map(move |_| *i) + }) + .collect::>(); - // Both checked and coerced types could have matched, thus we need to remove - // duplicates. - referenced_in.dedup(); + // Both checked and coerced types could have matched, thus we need to remove + // duplicates. + referenced_in.dedup(); - if let (Some(ref_in), None) = (referenced_in.pop(), referenced_in.pop()) { - // We make sure that only *one* argument matches the obligation failure - // and we assign the obligation's span to its expression's. - error.obligation.cause.span = args[ref_in].span; - error.points_at_arg_span = true; - } + if let (Some(ref_in), None) = (referenced_in.pop(), referenced_in.pop()) { + // We make sure that only *one* argument matches the obligation failure + // and we assign the obligation's span to its expression's. + error.obligation.cause.span = args[ref_in].span; + error.points_at_arg_span = true; } } } diff --git a/src/libstd/net/addr.rs b/src/libstd/net/addr.rs index d5f4ece726bea..a9d88370c612f 100644 --- a/src/libstd/net/addr.rs +++ b/src/libstd/net/addr.rs @@ -4,7 +4,7 @@ use crate::hash; use crate::io; use crate::iter; use crate::mem; -use crate::net::{hton, ntoh, IpAddr, Ipv4Addr, Ipv6Addr}; +use crate::net::{htons, ntohs, IpAddr, Ipv4Addr, Ipv6Addr}; use crate::option; use crate::slice; use crate::sys::net::netc as c; @@ -276,7 +276,7 @@ impl SocketAddrV4 { SocketAddrV4 { inner: c::sockaddr_in { sin_family: c::AF_INET as c::sa_family_t, - sin_port: hton(port), + sin_port: htons(port), sin_addr: *ip.as_inner(), ..unsafe { mem::zeroed() } }, @@ -326,7 +326,7 @@ impl SocketAddrV4 { /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn port(&self) -> u16 { - ntoh(self.inner.sin_port) + ntohs(self.inner.sin_port) } /// Changes the port number associated with this socket address. @@ -342,7 +342,7 @@ impl SocketAddrV4 { /// ``` #[stable(feature = "sockaddr_setters", since = "1.9.0")] pub fn set_port(&mut self, new_port: u16) { - self.inner.sin_port = hton(new_port); + self.inner.sin_port = htons(new_port); } } @@ -368,7 +368,7 @@ impl SocketAddrV6 { SocketAddrV6 { inner: c::sockaddr_in6 { sin6_family: c::AF_INET6 as c::sa_family_t, - sin6_port: hton(port), + sin6_port: htons(port), sin6_addr: *ip.as_inner(), sin6_flowinfo: flowinfo, sin6_scope_id: scope_id, @@ -420,7 +420,7 @@ impl SocketAddrV6 { /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn port(&self) -> u16 { - ntoh(self.inner.sin6_port) + ntohs(self.inner.sin6_port) } /// Changes the port number associated with this socket address. @@ -436,7 +436,7 @@ impl SocketAddrV6 { /// ``` #[stable(feature = "sockaddr_setters", since = "1.9.0")] pub fn set_port(&mut self, new_port: u16) { - self.inner.sin6_port = hton(new_port); + self.inner.sin6_port = htons(new_port); } /// Returns the flow information associated with this address. diff --git a/src/libstd/net/mod.rs b/src/libstd/net/mod.rs index b68146939fdcc..8652ed8b046bb 100644 --- a/src/libstd/net/mod.rs +++ b/src/libstd/net/mod.rs @@ -85,21 +85,10 @@ pub enum Shutdown { Both, } -#[doc(hidden)] -trait NetInt { - fn from_be(i: Self) -> Self; - fn to_be(&self) -> Self; -} -macro_rules! doit { - ($($t:ident)*) => ($(impl NetInt for $t { - fn from_be(i: Self) -> Self { <$t>::from_be(i) } - fn to_be(&self) -> Self { <$t>::to_be(*self) } - })*) -} -doit! { i8 i16 i32 i64 isize u8 u16 u32 u64 usize } - -fn hton(i: I) -> I { i.to_be() } -fn ntoh(i: I) -> I { I::from_be(i) } +#[inline] +const fn htons(i: u16) -> u16 { i.to_be() } +#[inline] +const fn ntohs(i: u16) -> u16 { u16::from_be(i) } fn each_addr(addr: A, mut f: F) -> io::Result where F: FnMut(io::Result<&SocketAddr>) -> io::Result diff --git a/src/libstd/sys/unix/net.rs b/src/libstd/sys/unix/net.rs index 946b2b9d8decf..5d101ed1f2e2b 100644 --- a/src/libstd/sys/unix/net.rs +++ b/src/libstd/sys/unix/net.rs @@ -28,14 +28,6 @@ use libc::SOCK_CLOEXEC; #[cfg(not(target_os = "linux"))] const SOCK_CLOEXEC: c_int = 0; -// Another conditional constant for name resolution: Macos et iOS use -// SO_NOSIGPIPE as a setsockopt flag to disable SIGPIPE emission on socket. -// Other platforms do otherwise. -#[cfg(target_vendor = "apple")] -use libc::SO_NOSIGPIPE; -#[cfg(not(target_vendor = "apple"))] -const SO_NOSIGPIPE: c_int = 0; - pub struct Socket(FileDesc); pub fn init() {} @@ -89,9 +81,12 @@ impl Socket { let fd = FileDesc::new(fd); fd.set_cloexec()?; let socket = Socket(fd); - if cfg!(target_vendor = "apple") { - setsockopt(&socket, libc::SOL_SOCKET, SO_NOSIGPIPE, 1)?; - } + + // macOS and iOS use `SO_NOSIGPIPE` as a `setsockopt` + // flag to disable `SIGPIPE` emission on socket. + #[cfg(target_vendor = "apple")] + setsockopt(&socket, libc::SOL_SOCKET, libc::SO_NOSIGPIPE, 1)?; + Ok(socket) } } diff --git a/src/libstd/sys/vxworks/net.rs b/src/libstd/sys/vxworks/net.rs index 85f5fcff2c259..54466ff2c2e07 100644 --- a/src/libstd/sys/vxworks/net.rs +++ b/src/libstd/sys/vxworks/net.rs @@ -19,7 +19,6 @@ pub extern crate libc as netc; pub type wrlen_t = size_t; const SOCK_CLOEXEC: c_int = 0; -const SO_NOSIGPIPE: c_int = 0; pub struct Socket(FileDesc); diff --git a/src/libsyntax/ptr.rs b/src/libsyntax/ptr.rs index d987dc855b615..e75cc8b1756d1 100644 --- a/src/libsyntax/ptr.rs +++ b/src/libsyntax/ptr.rs @@ -1,17 +1,12 @@ //! The AST pointer. //! -//! Provides `P`, a frozen owned smart pointer, as a replacement for `@T` in -//! the AST. +//! Provides `P`, a frozen owned smart pointer. //! //! # Motivations and benefits //! //! * **Identity**: sharing AST nodes is problematic for the various analysis //! passes (e.g., one may be able to bypass the borrow checker with a shared -//! `ExprKind::AddrOf` node taking a mutable borrow). The only reason `@T` in the -//! AST hasn't caused issues is because of inefficient folding passes which -//! would always deduplicate any such shared nodes. Even if the AST were to -//! switch to an arena, this would still hold, i.e., it couldn't use `&'a T`, -//! but rather a wrapper like `P<'a, T>`. +//! `ExprKind::AddrOf` node taking a mutable borrow). //! //! * **Immutability**: `P` disallows mutating its inner `T`, unlike `Box` //! (unless it contains an `Unsafe` interior, but that may be denied later). diff --git a/src/test/mir-opt/inline-any-operand.rs b/src/test/mir-opt/inline/inline-any-operand.rs similarity index 100% rename from src/test/mir-opt/inline-any-operand.rs rename to src/test/mir-opt/inline/inline-any-operand.rs diff --git a/src/test/mir-opt/inline-closure-borrows-arg.rs b/src/test/mir-opt/inline/inline-closure-borrows-arg.rs similarity index 100% rename from src/test/mir-opt/inline-closure-borrows-arg.rs rename to src/test/mir-opt/inline/inline-closure-borrows-arg.rs diff --git a/src/test/mir-opt/inline-closure-captures.rs b/src/test/mir-opt/inline/inline-closure-captures.rs similarity index 100% rename from src/test/mir-opt/inline-closure-captures.rs rename to src/test/mir-opt/inline/inline-closure-captures.rs diff --git a/src/test/mir-opt/inline-closure.rs b/src/test/mir-opt/inline/inline-closure.rs similarity index 100% rename from src/test/mir-opt/inline-closure.rs rename to src/test/mir-opt/inline/inline-closure.rs diff --git a/src/test/mir-opt/inline/inline-into-box-place.rs b/src/test/mir-opt/inline/inline-into-box-place.rs new file mode 100644 index 0000000000000..e96b61a59932e --- /dev/null +++ b/src/test/mir-opt/inline/inline-into-box-place.rs @@ -0,0 +1,70 @@ +// ignore-tidy-linelength +#![feature(box_syntax)] + +fn main() { + let _x: Box> = box Vec::new(); +} + +// END RUST SOURCE +// START rustc.main.Inline.before.mir +// let mut _0: (); +// let _1: std::boxed::Box> as UserTypeProjection { base: UserType(0), projs: [] }; +// let mut _2: std::boxed::Box>; +// let mut _3: (); +// scope 1 { +// debug _x => _1; +// } +// bb0: { +// StorageLive(_1); +// StorageLive(_2); +// _2 = Box(std::vec::Vec); +// (*_2) = const std::vec::Vec::::new() -> [return: bb2, unwind: bb4]; +// } +// bb1 (cleanup): { +// resume; +// } +// bb2: { +// _1 = move _2; +// StorageDead(_2); +// _0 = (); +// drop(_1) -> [return: bb3, unwind: bb1]; +// } +// bb3: { +// StorageDead(_1); +// return; +// } +// bb4 (cleanup): { +// _3 = const alloc::alloc::box_free::>(move (_2.0: std::ptr::Unique>)) -> bb1; +// } +// END rustc.main.Inline.before.mir +// START rustc.main.Inline.after.mir +// let mut _0: (); +// let _1: std::boxed::Box> as UserTypeProjection { base: UserType(0), projs: [] }; +// let mut _2: std::boxed::Box>; +// let mut _3: (); +// let mut _4: &mut std::vec::Vec; +// scope 1 { +// debug _x => _1; +// } +// scope 2 { +// } +// bb0: { +// StorageLive(_1); +// StorageLive(_2); +// _2 = Box(std::vec::Vec); +// _4 = &mut (*_2); +// ((*_4).0: alloc::raw_vec::RawVec) = const alloc::raw_vec::RawVec::::NEW; +// ((*_4).1: usize) = const 0usize; +// _1 = move _2; +// StorageDead(_2); +// _0 = (); +// drop(_1) -> [return: bb2, unwind: bb1]; +// } +// bb1 (cleanup): { +// resume; +// } +// bb2: { +// StorageDead(_1); +// return; +// } +// END rustc.main.Inline.after.mir diff --git a/src/test/mir-opt/inline-retag.rs b/src/test/mir-opt/inline/inline-retag.rs similarity index 100% rename from src/test/mir-opt/inline-retag.rs rename to src/test/mir-opt/inline/inline-retag.rs diff --git a/src/test/mir-opt/inline-trait-method.rs b/src/test/mir-opt/inline/inline-trait-method.rs similarity index 100% rename from src/test/mir-opt/inline-trait-method.rs rename to src/test/mir-opt/inline/inline-trait-method.rs diff --git a/src/test/mir-opt/inline-trait-method_2.rs b/src/test/mir-opt/inline/inline-trait-method_2.rs similarity index 100% rename from src/test/mir-opt/inline-trait-method_2.rs rename to src/test/mir-opt/inline/inline-trait-method_2.rs diff --git a/src/test/run-make/wasm-symbols-different-module/Makefile b/src/test/run-make/wasm-symbols-different-module/Makefile new file mode 100644 index 0000000000000..bb6a5d3c9d24a --- /dev/null +++ b/src/test/run-make/wasm-symbols-different-module/Makefile @@ -0,0 +1,28 @@ +-include ../../run-make-fulldeps/tools.mk + +# only-wasm32-bare + +all: + $(RUSTC) foo.rs --target wasm32-unknown-unknown + $(NODE) verify-imports.js $(TMPDIR)/foo.wasm a/foo b/foo + $(RUSTC) foo.rs --target wasm32-unknown-unknown -C lto + $(NODE) verify-imports.js $(TMPDIR)/foo.wasm a/foo b/foo + $(RUSTC) foo.rs --target wasm32-unknown-unknown -O + $(NODE) verify-imports.js $(TMPDIR)/foo.wasm a/foo b/foo + $(RUSTC) foo.rs --target wasm32-unknown-unknown -O -C lto + $(NODE) verify-imports.js $(TMPDIR)/foo.wasm a/foo b/foo + + $(RUSTC) bar.rs --target wasm32-unknown-unknown + $(NODE) verify-imports.js $(TMPDIR)/bar.wasm m1/f m1/g m2/f + $(RUSTC) bar.rs --target wasm32-unknown-unknown -C lto + $(NODE) verify-imports.js $(TMPDIR)/bar.wasm m1/f m1/g m2/f + $(RUSTC) bar.rs --target wasm32-unknown-unknown -O + $(NODE) verify-imports.js $(TMPDIR)/bar.wasm m1/f m1/g m2/f + $(RUSTC) bar.rs --target wasm32-unknown-unknown -O -C lto + $(NODE) verify-imports.js $(TMPDIR)/bar.wasm m1/f m1/g m2/f + + $(RUSTC) baz.rs --target wasm32-unknown-unknown + $(NODE) verify-imports.js $(TMPDIR)/baz.wasm sqlite/allocate sqlite/deallocate + + $(RUSTC) log.rs --target wasm32-unknown-unknown + $(NODE) verify-imports.js $(TMPDIR)/log.wasm test/log diff --git a/src/test/run-make/wasm-symbols-different-module/bar.rs b/src/test/run-make/wasm-symbols-different-module/bar.rs new file mode 100644 index 0000000000000..7567060d7813a --- /dev/null +++ b/src/test/run-make/wasm-symbols-different-module/bar.rs @@ -0,0 +1,33 @@ +//! Issue #50021 + +#![crate_type = "cdylib"] + +mod m1 { + #[link(wasm_import_module = "m1")] + extern "C" { + pub fn f(); + } + #[link(wasm_import_module = "m1")] + extern "C" { + pub fn g(); + } +} + +mod m2 { + #[link(wasm_import_module = "m2")] + extern "C" { + pub fn f(_: i32); + } +} + +#[no_mangle] +pub unsafe fn run() { + m1::f(); + m1::g(); + + // In generated code, expected: + // (import "m2" "f" (func $f (param i32))) + // but got: + // (import "m1" "f" (func $f (param i32))) + m2::f(0); +} diff --git a/src/test/run-make/wasm-symbols-different-module/baz.rs b/src/test/run-make/wasm-symbols-different-module/baz.rs new file mode 100644 index 0000000000000..fbb78619bb8f5 --- /dev/null +++ b/src/test/run-make/wasm-symbols-different-module/baz.rs @@ -0,0 +1,22 @@ +//! Issue #63562 + +#![crate_type = "cdylib"] + +mod foo { + #[link(wasm_import_module = "sqlite")] + extern "C" { + pub fn allocate(size: usize) -> i32; + pub fn deallocate(ptr: i32, size: usize); + } +} + +#[no_mangle] +pub extern "C" fn allocate() { + unsafe { + foo::allocate(1); + foo::deallocate(1, 2); + } +} + +#[no_mangle] +pub extern "C" fn deallocate() {} diff --git a/src/test/run-make/wasm-symbols-different-module/foo.rs b/src/test/run-make/wasm-symbols-different-module/foo.rs new file mode 100644 index 0000000000000..a4ba7e714cc77 --- /dev/null +++ b/src/test/run-make/wasm-symbols-different-module/foo.rs @@ -0,0 +1,23 @@ +#![crate_type = "cdylib"] + +mod a { + #[link(wasm_import_module = "a")] + extern "C" { + pub fn foo(); + } +} + +mod b { + #[link(wasm_import_module = "b")] + extern "C" { + pub fn foo(); + } +} + +#[no_mangle] +pub fn start() { + unsafe { + a::foo(); + b::foo(); + } +} diff --git a/src/test/run-make/wasm-symbols-different-module/log.rs b/src/test/run-make/wasm-symbols-different-module/log.rs new file mode 100644 index 0000000000000..ea3e0b4b2be91 --- /dev/null +++ b/src/test/run-make/wasm-symbols-different-module/log.rs @@ -0,0 +1,16 @@ +//! Issue #56309 + +#![crate_type = "cdylib"] + +#[link(wasm_import_module = "test")] +extern "C" { + fn log(message_data: u32, message_size: u32); +} + +#[no_mangle] +pub fn main() { + let message = "Hello, world!"; + unsafe { + log(message.as_ptr() as u32, message.len() as u32); + } +} diff --git a/src/test/run-make/wasm-symbols-different-module/verify-imports.js b/src/test/run-make/wasm-symbols-different-module/verify-imports.js new file mode 100644 index 0000000000000..7e9f90cf8bdc6 --- /dev/null +++ b/src/test/run-make/wasm-symbols-different-module/verify-imports.js @@ -0,0 +1,32 @@ +const fs = require('fs'); +const process = require('process'); +const assert = require('assert'); +const buffer = fs.readFileSync(process.argv[2]); + +let m = new WebAssembly.Module(buffer); +let list = WebAssembly.Module.imports(m); +console.log('imports', list); +if (list.length !== process.argv.length - 3) + throw new Error("wrong number of imports") + +const imports = new Map(); +for (let i = 3; i < process.argv.length; i++) { + const [module, name] = process.argv[i].split('/'); + if (!imports.has(module)) + imports.set(module, new Map()); + imports.get(module).set(name, true); +} + +for (let i of list) { + if (imports.get(i.module) === undefined || imports.get(i.module).get(i.name) === undefined) + throw new Error(`didn't find import of ${i.module}::${i.name}`); + imports.get(i.module).delete(i.name); + + if (imports.get(i.module).size === 0) + imports.delete(i.module); +} + +console.log(imports); +if (imports.size !== 0) { + throw new Error('extra imports'); +} diff --git a/src/test/ui/const-generics/array-impls/core-traits-no-impls-length-33.rs b/src/test/ui/const-generics/array-impls/core-traits-no-impls-length-33.rs index 8397d204f35cf..7fa059583f539 100644 --- a/src/test/ui/const-generics/array-impls/core-traits-no-impls-length-33.rs +++ b/src/test/ui/const-generics/array-impls/core-traits-no-impls-length-33.rs @@ -6,6 +6,7 @@ pub fn no_debug() { pub fn no_hash() { use std::collections::HashSet; let mut set = HashSet::new(); + //~^ ERROR arrays only have std trait implementations for lengths 0..=32 set.insert([0_usize; 33]); //~^ ERROR arrays only have std trait implementations for lengths 0..=32 } diff --git a/src/test/ui/const-generics/array-impls/core-traits-no-impls-length-33.stderr b/src/test/ui/const-generics/array-impls/core-traits-no-impls-length-33.stderr index 594a0d4b5d844..d885c98dcb287 100644 --- a/src/test/ui/const-generics/array-impls/core-traits-no-impls-length-33.stderr +++ b/src/test/ui/const-generics/array-impls/core-traits-no-impls-length-33.stderr @@ -8,15 +8,24 @@ LL | println!("{:?}", [0_usize; 33]); = note: required by `std::fmt::Debug::fmt` error[E0277]: arrays only have std trait implementations for lengths 0..=32 - --> $DIR/core-traits-no-impls-length-33.rs:9:16 + --> $DIR/core-traits-no-impls-length-33.rs:10:16 | LL | set.insert([0_usize; 33]); | ^^^^^^^^^^^^^ the trait `std::array::LengthAtMost32` is not implemented for `[usize; 33]` | = note: required because of the requirements on the impl of `std::cmp::Eq` for `[usize; 33]` +error[E0277]: arrays only have std trait implementations for lengths 0..=32 + --> $DIR/core-traits-no-impls-length-33.rs:8:19 + | +LL | let mut set = HashSet::new(); + | ^^^^^^^^^^^^ the trait `std::array::LengthAtMost32` is not implemented for `[usize; 33]` + | + = note: required because of the requirements on the impl of `std::cmp::Eq` for `[usize; 33]` + = note: required by `std::collections::HashSet::::new` + error[E0369]: binary operation `==` cannot be applied to type `[usize; 33]` - --> $DIR/core-traits-no-impls-length-33.rs:14:19 + --> $DIR/core-traits-no-impls-length-33.rs:15:19 | LL | [0_usize; 33] == [1_usize; 33] | ------------- ^^ ------------- [usize; 33] @@ -26,7 +35,7 @@ LL | [0_usize; 33] == [1_usize; 33] = note: an implementation of `std::cmp::PartialEq` might be missing for `[usize; 33]` error[E0369]: binary operation `<` cannot be applied to type `[usize; 33]` - --> $DIR/core-traits-no-impls-length-33.rs:19:19 + --> $DIR/core-traits-no-impls-length-33.rs:20:19 | LL | [0_usize; 33] < [1_usize; 33] | ------------- ^ ------------- [usize; 33] @@ -36,7 +45,7 @@ LL | [0_usize; 33] < [1_usize; 33] = note: an implementation of `std::cmp::PartialOrd` might be missing for `[usize; 33]` error[E0277]: the trait bound `&[usize; 33]: std::iter::IntoIterator` is not satisfied - --> $DIR/core-traits-no-impls-length-33.rs:24:14 + --> $DIR/core-traits-no-impls-length-33.rs:25:14 | LL | for _ in &[0_usize; 33] { | ^^^^^^^^^^^^^^ the trait `std::iter::IntoIterator` is not implemented for `&[usize; 33]` @@ -48,7 +57,7 @@ LL | for _ in &[0_usize; 33] { <&'a mut [T] as std::iter::IntoIterator> = note: required by `std::iter::IntoIterator::into_iter` -error: aborting due to 5 previous errors +error: aborting due to 6 previous errors Some errors have detailed explanations: E0277, E0369. For more information about an error, try `rustc --explain E0277`. diff --git a/src/test/ui/issues/issue-66923-show-error-for-correct-call.rs b/src/test/ui/issues/issue-66923-show-error-for-correct-call.rs new file mode 100644 index 0000000000000..8332807397247 --- /dev/null +++ b/src/test/ui/issues/issue-66923-show-error-for-correct-call.rs @@ -0,0 +1,15 @@ +// This test checks that errors are showed for lines with `collect` rather than `push` method. + +fn main() { + let v = vec![1_f64, 2.2_f64]; + let mut fft: Vec> = vec![]; + + let x1: &[f64] = &v; + let x2: Vec = x1.into_iter().collect(); + //~^ ERROR a value of type + fft.push(x2); + + let x3 = x1.into_iter().collect::>(); + //~^ ERROR a value of type + fft.push(x3); +} diff --git a/src/test/ui/issues/issue-66923-show-error-for-correct-call.stderr b/src/test/ui/issues/issue-66923-show-error-for-correct-call.stderr new file mode 100644 index 0000000000000..8e7ee97e0b907 --- /dev/null +++ b/src/test/ui/issues/issue-66923-show-error-for-correct-call.stderr @@ -0,0 +1,19 @@ +error[E0277]: a value of type `std::vec::Vec` cannot be built from an iterator over elements of type `&f64` + --> $DIR/issue-66923-show-error-for-correct-call.rs:8:39 + | +LL | let x2: Vec = x1.into_iter().collect(); + | ^^^^^^^ value of type `std::vec::Vec` cannot be built from `std::iter::Iterator` + | + = help: the trait `std::iter::FromIterator<&f64>` is not implemented for `std::vec::Vec` + +error[E0277]: a value of type `std::vec::Vec` cannot be built from an iterator over elements of type `&f64` + --> $DIR/issue-66923-show-error-for-correct-call.rs:12:29 + | +LL | let x3 = x1.into_iter().collect::>(); + | ^^^^^^^ value of type `std::vec::Vec` cannot be built from `std::iter::Iterator` + | + = help: the trait `std::iter::FromIterator<&f64>` is not implemented for `std::vec::Vec` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0277`.