diff --git a/src/Cargo.lock b/src/Cargo.lock index 8b7f3591a2505..94a07f6c91cfa 100644 --- a/src/Cargo.lock +++ b/src/Cargo.lock @@ -185,11 +185,11 @@ dependencies = [ "clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)", "core-foundation 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "crates-io 0.21.0", - "crossbeam-utils 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-utils 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "crypto-hash 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "curl 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)", "curl-sys 0.4.15 (registry+https://github.com/rust-lang/crates.io-index)", - "env_logger 0.5.12 (registry+https://github.com/rust-lang/crates.io-index)", + "env_logger 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "failure 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "filetime 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "flate2 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -539,6 +539,14 @@ name = "crossbeam-utils" version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "crossbeam-utils" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "crypto-hash" version = "0.3.1" @@ -662,6 +670,18 @@ dependencies = [ "termcolor 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "env_logger" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "humantime 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "termcolor 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "environment" version = "0.1.1" @@ -731,6 +751,7 @@ version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", + "libz-sys 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", "miniz-sys 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2170,7 +2191,6 @@ dependencies = [ "graphviz 0.0.0", "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot_core 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-rayon 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-rayon-core 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3211,6 +3231,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum crossbeam-epoch 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9c90f1474584f38e270b5b613e898c8c328aa4f3dea85e0a27ac2e642f009416" "checksum crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2760899e32a1d58d5abb31129f8fae5de75220bc2176e77ff7c627ae45c918d9" "checksum crossbeam-utils 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "677d453a17e8bd2b913fa38e8b9cf04bcdbb5be790aa294f2389661d72036015" +"checksum crossbeam-utils 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c55913cc2799171a550e307918c0a360e8c16004820291bf3b638969b4a01816" "checksum crypto-hash 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "09de9ee0fc255ace04c7fa0763c9395a945c37c8292bb554f8d48361d1dcf1b4" "checksum curl 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)" = "c7c9d851c825e0c033979d4516c9173bc19a78a96eb4d6ae51d4045440eafa16" "checksum curl-sys 0.4.15 (registry+https://github.com/rust-lang/crates.io-index)" = "721c204978be2143fab0a84b708c49d79d1f6100b8785610f456043a90708870" @@ -3223,6 +3244,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum elasticlunr-rs 2.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4837d77a1e157489a3933b743fd774ae75074e0e390b2b7f071530048a0d87ee" "checksum ena 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)" = "88dc8393b3c7352f94092497f6b52019643e493b6b890eb417cdb7c46117e621" "checksum env_logger 0.5.12 (registry+https://github.com/rust-lang/crates.io-index)" = "f4d7e69c283751083d53d01eac767407343b8b69c4bd70058e08adc2637cb257" +"checksum env_logger 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "afb070faf94c85d17d50ca44f6ad076bce18ae92f0037d350947240a36e9d42e" "checksum environment 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1f4b14e20978669064c33b4c1e0fb4083412e40fe56cbea2eae80fd7591503ee" "checksum error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ff511d5dc435d703f4971bc399647c9bc38e20cb41452e3b9feb4765419ed3f3" "checksum error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "07e791d3be96241c77c43846b665ef1384606da2cd2a48730abe606a12906e02" diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs index c8689f7814086..b6bb11d07ef04 100644 --- a/src/bootstrap/compile.rs +++ b/src/bootstrap/compile.rs @@ -22,7 +22,7 @@ use std::fs::{self, File}; use std::io::BufReader; use std::io::prelude::*; use std::path::{Path, PathBuf}; -use std::process::{Command, Stdio}; +use std::process::{Command, Stdio, exit}; use std::str; use build_helper::{output, mtime, up_to_date}; @@ -1098,7 +1098,7 @@ pub fn run_cargo(builder: &Builder, }); if !ok { - panic!("cargo must succeed"); + exit(1); } // Ok now we need to actually find all the files listed in `toplevel`. We've diff --git a/src/etc/gdb_rust_pretty_printing.py b/src/etc/gdb_rust_pretty_printing.py index e6d5ef1a23ff7..a5c8e73f919ed 100755 --- a/src/etc/gdb_rust_pretty_printing.py +++ b/src/etc/gdb_rust_pretty_printing.py @@ -18,6 +18,8 @@ if sys.version_info[0] >= 3: xrange = range +rust_enabled = 'set language rust' in gdb.execute('complete set language ru', to_string = True) + #=============================================================================== # GDB Pretty Printing Module for Rust #=============================================================================== @@ -99,27 +101,9 @@ def rust_pretty_printer_lookup_function(gdb_val): val = GdbValue(gdb_val) type_kind = val.type.get_type_kind() - if type_kind == rustpp.TYPE_KIND_EMPTY: - return RustEmptyPrinter(val) - - if type_kind == rustpp.TYPE_KIND_REGULAR_STRUCT: - return RustStructPrinter(val, - omit_first_field = False, - omit_type_name = False, - is_tuple_like = False) - - if type_kind == rustpp.TYPE_KIND_STRUCT_VARIANT: - return RustStructPrinter(val, - omit_first_field = True, - omit_type_name = False, - is_tuple_like = False) - if type_kind == rustpp.TYPE_KIND_SLICE: return RustSlicePrinter(val) - if type_kind == rustpp.TYPE_KIND_STR_SLICE: - return RustStringSlicePrinter(val) - if type_kind == rustpp.TYPE_KIND_STD_VEC: return RustStdVecPrinter(val) @@ -138,6 +122,29 @@ def rust_pretty_printer_lookup_function(gdb_val): if type_kind == rustpp.TYPE_KIND_OS_STRING: return RustOsStringPrinter(val) + # Checks after this point should only be for "compiler" types -- + # things that gdb's Rust language support knows about. + if rust_enabled: + return None + + if type_kind == rustpp.TYPE_KIND_EMPTY: + return RustEmptyPrinter(val) + + if type_kind == rustpp.TYPE_KIND_REGULAR_STRUCT: + return RustStructPrinter(val, + omit_first_field = False, + omit_type_name = False, + is_tuple_like = False) + + if type_kind == rustpp.TYPE_KIND_STRUCT_VARIANT: + return RustStructPrinter(val, + omit_first_field = True, + omit_type_name = False, + is_tuple_like = False) + + if type_kind == rustpp.TYPE_KIND_STR_SLICE: + return RustStringSlicePrinter(val) + if type_kind == rustpp.TYPE_KIND_TUPLE: return RustStructPrinter(val, omit_first_field = False, diff --git a/src/libcore/cell.rs b/src/libcore/cell.rs index 9cf42eff219ba..d8d51f53377f7 100644 --- a/src/libcore/cell.rs +++ b/src/libcore/cell.rs @@ -1509,7 +1509,9 @@ impl UnsafeCell { #[inline] #[stable(feature = "rust1", since = "1.0.0")] pub const fn get(&self) -> *mut T { - &self.value as *const T as *mut T + // We can just cast the pointer from `UnsafeCell` to `T` because of + // #[repr(transparent)] + self as *const UnsafeCell as *const T as *mut T } } diff --git a/src/libcore/tests/num/mod.rs b/src/libcore/tests/num/mod.rs index ab96d3126bb22..0928f7560e175 100644 --- a/src/libcore/tests/num/mod.rs +++ b/src/libcore/tests/num/mod.rs @@ -82,36 +82,28 @@ fn from_str_issue7588() { #[test] fn test_int_from_str_overflow() { - let mut i8_val: i8 = 127; - assert_eq!("127".parse::().ok(), Some(i8_val)); + assert_eq!("127".parse::().ok(), Some(127i8)); assert_eq!("128".parse::().ok(), None); - i8_val = i8_val.wrapping_add(1); - assert_eq!("-128".parse::().ok(), Some(i8_val)); + assert_eq!("-128".parse::().ok(), Some(-128i8)); assert_eq!("-129".parse::().ok(), None); - let mut i16_val: i16 = 32_767; - assert_eq!("32767".parse::().ok(), Some(i16_val)); + assert_eq!("32767".parse::().ok(), Some(32_767i16)); assert_eq!("32768".parse::().ok(), None); - i16_val = i16_val.wrapping_add(1); - assert_eq!("-32768".parse::().ok(), Some(i16_val)); + assert_eq!("-32768".parse::().ok(), Some(-32_768i16)); assert_eq!("-32769".parse::().ok(), None); - let mut i32_val: i32 = 2_147_483_647; - assert_eq!("2147483647".parse::().ok(), Some(i32_val)); + assert_eq!("2147483647".parse::().ok(), Some(2_147_483_647i32)); assert_eq!("2147483648".parse::().ok(), None); - i32_val = i32_val.wrapping_add(1); - assert_eq!("-2147483648".parse::().ok(), Some(i32_val)); + assert_eq!("-2147483648".parse::().ok(), Some(-2_147_483_648i32)); assert_eq!("-2147483649".parse::().ok(), None); - let mut i64_val: i64 = 9_223_372_036_854_775_807; - assert_eq!("9223372036854775807".parse::().ok(), Some(i64_val)); + assert_eq!("9223372036854775807".parse::().ok(), Some(9_223_372_036_854_775_807i64)); assert_eq!("9223372036854775808".parse::().ok(), None); - i64_val = i64_val.wrapping_add(1); - assert_eq!("-9223372036854775808".parse::().ok(), Some(i64_val)); + assert_eq!("-9223372036854775808".parse::().ok(), Some(-9_223_372_036_854_775_808i64)); assert_eq!("-9223372036854775809".parse::().ok(), None); } diff --git a/src/librustc/cfg/graphviz.rs b/src/librustc/cfg/graphviz.rs index cc4f3f95d079a..650aa39114fad 100644 --- a/src/librustc/cfg/graphviz.rs +++ b/src/librustc/cfg/graphviz.rs @@ -106,8 +106,7 @@ impl<'a> dot::GraphWalk<'a> for &'a cfg::CFG { type Node = Node<'a>; type Edge = Edge<'a>; fn nodes(&'a self) -> dot::Nodes<'a, Node<'a>> { - let mut v = Vec::new(); - self.graph.each_node(|i, nd| { v.push((i, nd)); true }); + let v: Vec<_> = self.graph.enumerated_nodes().collect(); v.into() } fn edges(&'a self) -> dot::Edges<'a, Edge<'a>> { diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index e532b50a28b6b..ce1e678043188 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -1062,8 +1062,7 @@ impl<'a> LoweringContext<'a> { attrs .iter() .map(|a| self.lower_attr(a)) - .collect::>() - .into() + .collect() } fn lower_attr(&mut self, attr: &Attribute) -> Attribute { diff --git a/src/librustc/ich/impls_ty.rs b/src/librustc/ich/impls_ty.rs index f3a62975dd9f4..928a6accf2d12 100644 --- a/src/librustc/ich/impls_ty.rs +++ b/src/librustc/ich/impls_ty.rs @@ -216,7 +216,9 @@ impl<'gcx> HashStable> for ty::adjustment::AutoBorrow } } -impl_stable_hash_for!(struct ty::UpvarId { var_id, closure_expr_id }); +impl_stable_hash_for!(struct ty::UpvarPath { hir_id }); + +impl_stable_hash_for!(struct ty::UpvarId { var_path, closure_expr_id }); impl_stable_hash_for!(enum ty::BorrowKind { ImmBorrow, diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs index f833ebc7ca763..59a490f4a013d 100644 --- a/src/librustc/infer/error_reporting/mod.rs +++ b/src/librustc/infer/error_reporting/mod.rs @@ -1315,7 +1315,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { format!(" for lifetime parameter `{}` in coherence check", name) } infer::UpvarRegion(ref upvar_id, _) => { - let var_node_id = self.tcx.hir.hir_to_node_id(upvar_id.var_id); + let var_node_id = self.tcx.hir.hir_to_node_id(upvar_id.var_path.hir_id); let var_name = self.tcx.hir.name(var_node_id); format!(" for capture of `{}` by closure", var_name) } diff --git a/src/librustc/infer/error_reporting/note.rs b/src/librustc/infer/error_reporting/note.rs index 54d01a035a8be..a539c321af3f0 100644 --- a/src/librustc/infer/error_reporting/note.rs +++ b/src/librustc/infer/error_reporting/note.rs @@ -41,7 +41,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { "...so that reference does not outlive borrowed content"); } infer::ReborrowUpvar(span, ref upvar_id) => { - let var_node_id = self.tcx.hir.hir_to_node_id(upvar_id.var_id); + let var_node_id = self.tcx.hir.hir_to_node_id(upvar_id.var_path.hir_id); let var_name = self.tcx.hir.name(var_node_id); err.span_note(span, &format!("...so that closure can access `{}`", var_name)); @@ -174,7 +174,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { err } infer::ReborrowUpvar(span, ref upvar_id) => { - let var_node_id = self.tcx.hir.hir_to_node_id(upvar_id.var_id); + let var_node_id = self.tcx.hir.hir_to_node_id(upvar_id.var_path.hir_id); let var_name = self.tcx.hir.name(var_node_id); let mut err = struct_span_err!(self.tcx.sess, span, diff --git a/src/librustc/middle/expr_use_visitor.rs b/src/librustc/middle/expr_use_visitor.rs index 7e9b26bbf729c..5b92bfe6ad3c4 100644 --- a/src/librustc/middle/expr_use_visitor.rs +++ b/src/librustc/middle/expr_use_visitor.rs @@ -938,7 +938,7 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> { let var_hir_id = self.tcx().hir.node_to_hir_id(freevar.var_id()); let closure_def_id = self.tcx().hir.local_def_id(closure_expr.id); let upvar_id = ty::UpvarId { - var_id: var_hir_id, + var_path: ty::UpvarPath { hir_id: var_hir_id }, closure_expr_id: closure_def_id.to_local(), }; let upvar_capture = self.mc.tables.upvar_capture(upvar_id); diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs index 59ef8fa14484b..cadf0c42d228f 100644 --- a/src/librustc/middle/mem_categorization.rs +++ b/src/librustc/middle/mem_categorization.rs @@ -818,7 +818,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> { let closure_expr_def_id = self.tcx.hir.local_def_id(fn_node_id); let var_hir_id = self.tcx.hir.node_to_hir_id(var_id); let upvar_id = ty::UpvarId { - var_id: var_hir_id, + var_path: ty::UpvarPath { hir_id: var_hir_id }, closure_expr_id: closure_expr_def_id.to_local(), }; diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index cdfe8f53b854b..923d362c2345f 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -789,7 +789,7 @@ impl<'a, 'gcx> HashStable> for TypeckTables<'gcx> { pat_adjustments.hash_stable(hcx, hasher); hash_stable_hashmap(hcx, hasher, upvar_capture_map, |up_var_id, hcx| { let ty::UpvarId { - var_id, + var_path, closure_expr_id } = *up_var_id; @@ -798,14 +798,14 @@ impl<'a, 'gcx> HashStable> for TypeckTables<'gcx> { let var_owner_def_id = DefId { krate: local_id_root.krate, - index: var_id.owner, + index: var_path.hir_id.owner, }; let closure_def_id = DefId { krate: local_id_root.krate, index: closure_expr_id.to_def_id().index, }; (hcx.def_path_hash(var_owner_def_id), - var_id.local_id, + var_path.hir_id.local_id, hcx.def_path_hash(closure_def_id)) }); diff --git a/src/librustc/ty/layout.rs b/src/librustc/ty/layout.rs index 79324bd97a3db..d7fb8da7acd05 100644 --- a/src/librustc/ty/layout.rs +++ b/src/librustc/ty/layout.rs @@ -697,7 +697,9 @@ impl<'a, 'tcx> LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>> { Align::from_bytes(repr_align, repr_align).unwrap()); } + let optimize = !def.repr.inhibit_union_abi_opt(); let mut size = Size::ZERO; + let mut abi = Abi::Aggregate { sized: true }; let index = VariantIdx::new(0); for field in &variants[index] { assert!(!field.is_unsized()); @@ -708,13 +710,44 @@ impl<'a, 'tcx> LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>> { } else { align = align.max(field.align); } + + // If all non-ZST fields have the same ABI, forward this ABI + if optimize && !field.is_zst() { + // Normalize scalar_unit to the maximal valid range + let field_abi = match &field.abi { + Abi::Scalar(x) => Abi::Scalar(scalar_unit(x.value)), + Abi::ScalarPair(x, y) => { + Abi::ScalarPair( + scalar_unit(x.value), + scalar_unit(y.value), + ) + } + Abi::Vector { element: x, count } => { + Abi::Vector { + element: scalar_unit(x.value), + count: *count, + } + } + Abi::Uninhabited | + Abi::Aggregate { .. } => Abi::Aggregate { sized: true }, + }; + + if size == Size::ZERO { + // first non ZST: initialize 'abi' + abi = field_abi; + } else if abi != field_abi { + // different fields have different ABI: reset to Aggregate + abi = Abi::Aggregate { sized: true }; + } + } + size = cmp::max(size, field.size); } return Ok(tcx.intern_layout(LayoutDetails { variants: Variants::Single { index }, fields: FieldPlacement::Union(variants[index].len()), - abi: Abi::Aggregate { sized: true }, + abi, align, size: size.abi_align(align) })); diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index 96f4b1ef8e32a..dfdffa2d54783 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -49,7 +49,6 @@ use std::hash::{Hash, Hasher}; use std::ops::Deref; use rustc_data_structures::sync::{self, Lrc, ParallelIterator, par_iter}; use std::slice; -use std::vec::IntoIter; use std::{mem, ptr}; use syntax::ast::{self, DUMMY_NODE_ID, Name, Ident, NodeId}; use syntax::attr; @@ -731,12 +730,17 @@ impl List { } } +#[derive(Clone, Copy, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)] +pub struct UpvarPath { + pub hir_id: hir::HirId, +} + /// Upvars do not get their own node-id. Instead, we use the pair of /// the original var id (that is, the root variable that is referenced /// by the upvar) and the id of the closure expression. #[derive(Clone, Copy, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)] pub struct UpvarId { - pub var_id: hir::HirId, + pub var_path: UpvarPath, pub closure_expr_id: LocalDefId, } @@ -1343,49 +1347,88 @@ impl<'tcx> ToPredicate<'tcx> for PolyProjectionPredicate<'tcx> { } } +// A custom iterator used by Predicate::walk_tys. +enum WalkTysIter<'tcx, I, J, K> + where I: Iterator>, + J: Iterator>, + K: Iterator> +{ + None, + One(Ty<'tcx>), + Two(Ty<'tcx>, Ty<'tcx>), + Types(I), + InputTypes(J), + ProjectionTypes(K) +} + +impl<'tcx, I, J, K> Iterator for WalkTysIter<'tcx, I, J, K> + where I: Iterator>, + J: Iterator>, + K: Iterator> +{ + type Item = Ty<'tcx>; + + fn next(&mut self) -> Option> { + match *self { + WalkTysIter::None => None, + WalkTysIter::One(item) => { + *self = WalkTysIter::None; + Some(item) + }, + WalkTysIter::Two(item1, item2) => { + *self = WalkTysIter::One(item2); + Some(item1) + }, + WalkTysIter::Types(ref mut iter) => { + iter.next() + }, + WalkTysIter::InputTypes(ref mut iter) => { + iter.next() + }, + WalkTysIter::ProjectionTypes(ref mut iter) => { + iter.next() + } + } + } +} + impl<'tcx> Predicate<'tcx> { /// Iterates over the types in this predicate. Note that in all /// cases this is skipping over a binder, so late-bound regions /// with depth 0 are bound by the predicate. - pub fn walk_tys(&self) -> IntoIter> { - let vec: Vec<_> = match *self { + pub fn walk_tys(&'a self) -> impl Iterator> + 'a { + match *self { ty::Predicate::Trait(ref data) => { - data.skip_binder().input_types().collect() + WalkTysIter::InputTypes(data.skip_binder().input_types()) } ty::Predicate::Subtype(binder) => { let SubtypePredicate { a, b, a_is_expected: _ } = binder.skip_binder(); - vec![a, b] + WalkTysIter::Two(a, b) } ty::Predicate::TypeOutlives(binder) => { - vec![binder.skip_binder().0] + WalkTysIter::One(binder.skip_binder().0) } ty::Predicate::RegionOutlives(..) => { - vec![] + WalkTysIter::None } ty::Predicate::Projection(ref data) => { let inner = data.skip_binder(); - inner.projection_ty.substs.types().chain(Some(inner.ty)).collect() + WalkTysIter::ProjectionTypes( + inner.projection_ty.substs.types().chain(Some(inner.ty))) } ty::Predicate::WellFormed(data) => { - vec![data] + WalkTysIter::One(data) } ty::Predicate::ObjectSafe(_trait_def_id) => { - vec![] + WalkTysIter::None } ty::Predicate::ClosureKind(_closure_def_id, closure_substs, _kind) => { - closure_substs.substs.types().collect() + WalkTysIter::Types(closure_substs.substs.types()) } ty::Predicate::ConstEvaluatable(_, substs) => { - substs.types().collect() + WalkTysIter::Types(substs.types()) } - }; - - // FIXME: The only reason to collect into a vector here is that I was - // too lazy to make the full (somewhat complicated) iterator - // type that would be needed here. But I wanted this fn to - // return an iterator conceptually, rather than a `Vec`, so as - // to be closer to `Ty::walk`. - vec.into_iter() + } } pub fn to_opt_poly_trait_ref(&self) -> Option> { @@ -1998,6 +2041,12 @@ impl ReprOptions { pub fn inhibit_struct_field_reordering_opt(&self) -> bool { !(self.flags & ReprFlags::IS_UNOPTIMISABLE).is_empty() || (self.pack == 1) } + + /// Returns true if this `#[repr()]` should inhibit union abi optimisations + pub fn inhibit_union_abi_opt(&self) -> bool { + self.c() + } + } impl<'a, 'gcx, 'tcx> AdtDef { diff --git a/src/librustc/ty/query/on_disk_cache.rs b/src/librustc/ty/query/on_disk_cache.rs index 54550b8a2055f..7d3ae64f4fcd6 100644 --- a/src/librustc/ty/query/on_disk_cache.rs +++ b/src/librustc/ty/query/on_disk_cache.rs @@ -281,7 +281,7 @@ impl<'sess> OnDiskCache<'sess> { // otherwise, abort break; } - interpret_alloc_index.reserve(new_n); + interpret_alloc_index.reserve(new_n - n); for idx in n..new_n { let id = encoder.interpret_allocs_inverse[idx]; let pos = encoder.position() as u32; diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index e44c0c05bb1a6..d53370d242bd9 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -678,8 +678,8 @@ impl<'tcx> fmt::Debug for ty::ClosureUpvar<'tcx> { impl fmt::Debug for ty::UpvarId { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "UpvarId({:?};`{}`;{:?})", - self.var_id, - ty::tls::with(|tcx| tcx.hir.name(tcx.hir.hir_to_node_id(self.var_id))), + self.var_path.hir_id, + ty::tls::with(|tcx| tcx.hir.name(tcx.hir.hir_to_node_id(self.var_path.hir_id))), self.closure_expr_id) } } diff --git a/src/librustc_borrowck/borrowck/gather_loans/mod.rs b/src/librustc_borrowck/borrowck/gather_loans/mod.rs index 78a31ed668fca..21fb0cdf90ad1 100644 --- a/src/librustc_borrowck/borrowck/gather_loans/mod.rs +++ b/src/librustc_borrowck/borrowck/gather_loans/mod.rs @@ -453,8 +453,8 @@ impl<'a, 'tcx> GatherLoanCtxt<'a, 'tcx> { } None } - LpUpvar(ty::UpvarId{ var_id, closure_expr_id: _ }) => { - self.bccx.used_mut_nodes.borrow_mut().insert(var_id); + LpUpvar(ty::UpvarId{ var_path: ty::UpvarPath { hir_id }, closure_expr_id: _ }) => { + self.bccx.used_mut_nodes.borrow_mut().insert(hir_id); None } LpExtend(ref base, mc::McInherited, LpDeref(pointer_kind)) | diff --git a/src/librustc_borrowck/borrowck/gather_loans/move_error.rs b/src/librustc_borrowck/borrowck/gather_loans/move_error.rs index e1a4473539c8c..cfd530b7e3d09 100644 --- a/src/librustc_borrowck/borrowck/gather_loans/move_error.rs +++ b/src/librustc_borrowck/borrowck/gather_loans/move_error.rs @@ -97,7 +97,7 @@ fn report_move_errors<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>, errors: &[MoveErr } } if let NoteClosureEnv(upvar_id) = error.move_from.note { - let var_node_id = bccx.tcx.hir.hir_to_node_id(upvar_id.var_id); + let var_node_id = bccx.tcx.hir.hir_to_node_id(upvar_id.var_path.hir_id); err.span_label(bccx.tcx.hir.span(var_node_id), "captured outer variable"); } diff --git a/src/librustc_borrowck/borrowck/mod.rs b/src/librustc_borrowck/borrowck/mod.rs index d52d78181b77a..d189460d08848 100644 --- a/src/librustc_borrowck/borrowck/mod.rs +++ b/src/librustc_borrowck/borrowck/mod.rs @@ -846,7 +846,7 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> { MutabilityViolation => { let mut db = self.cannot_assign(error_span, &descr, Origin::Ast); if let mc::NoteClosureEnv(upvar_id) = err.cmt.note { - let node_id = self.tcx.hir.hir_to_node_id(upvar_id.var_id); + let node_id = self.tcx.hir.hir_to_node_id(upvar_id.var_path.hir_id); let sp = self.tcx.hir.span(node_id); let fn_closure_msg = "`Fn` closures cannot capture their enclosing \ environment for modifications"; @@ -1415,7 +1415,7 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> { loan_path: &LoanPath<'tcx>, out: &mut String) { match loan_path.kind { - LpUpvar(ty::UpvarId { var_id: id, closure_expr_id: _ }) => { + LpUpvar(ty::UpvarId { var_path: ty::UpvarPath { hir_id: id}, closure_expr_id: _ }) => { out.push_str(&self.tcx.hir.name(self.tcx.hir.hir_to_node_id(id)).as_str()); } LpVar(id) => { @@ -1533,7 +1533,7 @@ impl<'tcx> fmt::Debug for LoanPath<'tcx> { write!(f, "$({})", ty::tls::with(|tcx| tcx.hir.node_to_string(id))) } - LpUpvar(ty::UpvarId{ var_id, closure_expr_id }) => { + LpUpvar(ty::UpvarId{ var_path: ty::UpvarPath {hir_id: var_id}, closure_expr_id }) => { let s = ty::tls::with(|tcx| { let var_node_id = tcx.hir.hir_to_node_id(var_id); tcx.hir.node_to_string(var_node_id) @@ -1568,9 +1568,9 @@ impl<'tcx> fmt::Display for LoanPath<'tcx> { write!(f, "$({})", ty::tls::with(|tcx| tcx.hir.node_to_user_string(id))) } - LpUpvar(ty::UpvarId{ var_id, closure_expr_id: _ }) => { + LpUpvar(ty::UpvarId{ var_path: ty::UpvarPath { hir_id }, closure_expr_id: _ }) => { let s = ty::tls::with(|tcx| { - let var_node_id = tcx.hir.hir_to_node_id(var_id); + let var_node_id = tcx.hir.hir_to_node_id(hir_id); tcx.hir.node_to_string(var_node_id) }); write!(f, "$({} captured by closure)", s) diff --git a/src/librustc_data_structures/Cargo.toml b/src/librustc_data_structures/Cargo.toml index 10820007629ff..79f073d643ddc 100644 --- a/src/librustc_data_structures/Cargo.toml +++ b/src/librustc_data_structures/Cargo.toml @@ -16,7 +16,6 @@ serialize = { path = "../libserialize" } graphviz = { path = "../libgraphviz" } cfg-if = "0.1.2" stable_deref_trait = "1.0.0" -parking_lot_core = "0.2.8" rustc-rayon = "0.1.1" rustc-rayon-core = "0.1.1" rustc-hash = "1.0.1" diff --git a/src/librustc_mir/build/mod.rs b/src/librustc_mir/build/mod.rs index a01f8940a948a..0aa1924c0e59c 100644 --- a/src/librustc_mir/build/mod.rs +++ b/src/librustc_mir/build/mod.rs @@ -664,7 +664,7 @@ fn construct_fn<'a, 'gcx, 'tcx, A>(hir: Cx<'a, 'gcx, 'tcx>, let var_hir_id = tcx.hir.node_to_hir_id(var_id); let closure_expr_id = tcx.hir.local_def_id(fn_id); let capture = hir.tables().upvar_capture(ty::UpvarId { - var_id: var_hir_id, + var_path: ty::UpvarPath {hir_id: var_hir_id}, closure_expr_id: LocalDefId::from_def_id(closure_expr_id), }); let by_ref = match capture { diff --git a/src/librustc_mir/hair/cx/expr.rs b/src/librustc_mir/hair/cx/expr.rs index 656a467fb4912..2e9edf20c5708 100644 --- a/src/librustc_mir/hair/cx/expr.rs +++ b/src/librustc_mir/hair/cx/expr.rs @@ -1061,7 +1061,7 @@ fn convert_var<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, // ...but the upvar might be an `&T` or `&mut T` capture, at which // point we need an implicit deref let upvar_id = ty::UpvarId { - var_id: var_hir_id, + var_path: ty::UpvarPath {hir_id: var_hir_id}, closure_expr_id: LocalDefId::from_def_id(closure_def_id), }; match cx.tables().upvar_capture(upvar_id) { @@ -1178,7 +1178,7 @@ fn capture_freevar<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, -> ExprRef<'tcx> { let var_hir_id = cx.tcx.hir.node_to_hir_id(freevar.var_id()); let upvar_id = ty::UpvarId { - var_id: var_hir_id, + var_path: ty::UpvarPath { hir_id: var_hir_id }, closure_expr_id: cx.tcx.hir.local_def_id(closure_expr.id).to_local(), }; let upvar_capture = cx.tables().upvar_capture(upvar_id); diff --git a/src/librustc_mir/interpret/cast.rs b/src/librustc_mir/interpret/cast.rs index 118539fc58ebf..7d636b77ced4c 100644 --- a/src/librustc_mir/interpret/cast.rs +++ b/src/librustc_mir/interpret/cast.rs @@ -44,16 +44,22 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> } Misc => { + let src_layout = src.layout; let src = self.read_immediate(src)?; - if self.type_is_fat_ptr(src.layout.ty) { - match (*src, self.type_is_fat_ptr(dest.layout.ty)) { + // There are no casts to references + assert!(!dest.layout.ty.is_region_ptr()); + // Hence we make all casts erase the tag + let src = src.erase_tag().with_default_tag(); + + if self.type_is_fat_ptr(src_layout.ty) { + match (src, self.type_is_fat_ptr(dest.layout.ty)) { // pointers to extern types (Immediate::Scalar(_),_) | // slices and trait objects to other slices/trait objects (Immediate::ScalarPair(..), true) => { // No change to immediate - self.write_immediate(*src, dest)?; + self.write_immediate(src, dest)?; } // slices and trait objects to thin pointers (dropping the metadata) (Immediate::ScalarPair(data, _), false) => { @@ -61,11 +67,11 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> } } } else { - match src.layout.variants { + match src_layout.variants { layout::Variants::Single { index } => { - if let Some(def) = src.layout.ty.ty_adt_def() { + if let Some(def) = src_layout.ty.ty_adt_def() { // Cast from a univariant enum - assert!(src.layout.is_zst()); + assert!(src_layout.is_zst()); let discr_val = def .discriminant_for_variant(*self.tcx, index) .val; @@ -78,7 +84,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> layout::Variants::NicheFilling { .. } => {}, } - let dest_val = self.cast_scalar(src.to_scalar()?, src.layout, dest.layout)?; + let dest_val = self.cast_scalar(src.to_scalar()?, src_layout, dest.layout)?; self.write_scalar(dest_val, dest)?; } } diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs index e6267012dc275..ca09857bbd5ff 100644 --- a/src/librustc_mir/interpret/eval_context.rs +++ b/src/librustc_mir/interpret/eval_context.rs @@ -341,8 +341,21 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tc // the last field). Can't have foreign types here, how would we // adjust alignment and size for them? let field = layout.field(self, layout.fields.count() - 1)?; - let (unsized_size, unsized_align) = self.size_and_align_of(metadata, field)? - .expect("Fields cannot be extern types"); + let (unsized_size, unsized_align) = match self.size_and_align_of(metadata, field)? { + Some(size_and_align) => size_and_align, + None => { + // A field with extern type. If this field is at offset 0, we behave + // like the underlying extern type. + // FIXME: Once we have made decisions for how to handle size and alignment + // of `extern type`, this should be adapted. It is just a temporary hack + // to get some code to work that probably ought to work. + if sized_size == Size::ZERO { + return Ok(None) + } else { + bug!("Fields cannot be extern types, unless they are at offset 0") + } + } + }; // FIXME (#26403, #27023): We should be adding padding // to `sized_size` (to accommodate the `unsized_align` diff --git a/src/librustc_mir/interpret/mod.rs b/src/librustc_mir/interpret/mod.rs index 82fe08fa038a4..96ea0d5094966 100644 --- a/src/librustc_mir/interpret/mod.rs +++ b/src/librustc_mir/interpret/mod.rs @@ -39,6 +39,6 @@ pub use self::machine::{Machine, AllocMap, MayLeak}; pub use self::operand::{ScalarMaybeUndef, Immediate, ImmTy, Operand, OpTy}; -pub use self::visitor::ValueVisitor; +pub use self::visitor::{ValueVisitor, MutValueVisitor}; pub use self::validity::RefTracking; diff --git a/src/librustc_mir/interpret/place.rs b/src/librustc_mir/interpret/place.rs index 201d320dcd858..fa76eeb2fedd5 100644 --- a/src/librustc_mir/interpret/place.rs +++ b/src/librustc_mir/interpret/place.rs @@ -351,8 +351,17 @@ where // Offset may need adjustment for unsized fields let (meta, offset) = if field_layout.is_unsized() { // re-use parent metadata to determine dynamic field layout - let (_, align) = self.size_and_align_of(base.meta, field_layout)? - .expect("Fields cannot be extern types"); + let align = match self.size_and_align_of(base.meta, field_layout)? { + Some((_, align)) => align, + None if offset == Size::ZERO => + // An extern type at offset 0, we fall back to its static alignment. + // FIXME: Once we have made decisions for how to handle size and alignment + // of `extern type`, this should be adapted. It is just a temporary hack + // to get some code to work that probably ought to work. + field_layout.align, + None => + bug!("Cannot compute offset for extern type field at non-0 offset"), + }; (base.meta, offset.abi_align(align)) } else { // base.meta could be present; we might be accessing a sized field of an unsized diff --git a/src/librustc_mir/interpret/validity.rs b/src/librustc_mir/interpret/validity.rs index 988ff7e75163d..e8fb06feb901c 100644 --- a/src/librustc_mir/interpret/validity.rs +++ b/src/librustc_mir/interpret/validity.rs @@ -21,7 +21,7 @@ use rustc::mir::interpret::{ }; use super::{ - OpTy, MPlaceTy, ImmTy, Machine, EvalContext, ValueVisitor + OpTy, MPlaceTy, Machine, EvalContext, ValueVisitor }; macro_rules! validation_failure { @@ -281,8 +281,9 @@ impl<'rt, 'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> } } - fn visit_primitive(&mut self, value: ImmTy<'tcx, M::PointerTag>) -> EvalResult<'tcx> + fn visit_primitive(&mut self, value: OpTy<'tcx, M::PointerTag>) -> EvalResult<'tcx> { + let value = self.ecx.read_immediate(value)?; // Go over all the primitive types let ty = value.layout.ty; match ty.sty { diff --git a/src/librustc_mir/interpret/visitor.rs b/src/librustc_mir/interpret/visitor.rs index 4a47045643253..f0a71242599bf 100644 --- a/src/librustc_mir/interpret/visitor.rs +++ b/src/librustc_mir/interpret/visitor.rs @@ -8,7 +8,7 @@ use rustc::mir::interpret::{ }; use super::{ - Machine, EvalContext, MPlaceTy, OpTy, ImmTy, + Machine, EvalContext, MPlaceTy, OpTy, }; // A thing that we can project into, and that has a layout. @@ -201,9 +201,11 @@ macro_rules! make_value_visitor { { Ok(()) } /// Called whenever we reach a value of primitive type. There can be no recursion - /// below such a value. This is the leave function. + /// below such a value. This is the leaf function. + /// We do *not* provide an `ImmTy` here because some implementations might want + /// to write to the place this primitive lives in. #[inline(always)] - fn visit_primitive(&mut self, _val: ImmTy<'tcx, M::PointerTag>) -> EvalResult<'tcx> + fn visit_primitive(&mut self, _v: Self::V) -> EvalResult<'tcx> { Ok(()) } // Default recursors. Not meant to be overloaded. @@ -279,9 +281,7 @@ macro_rules! make_value_visitor { _ => v.layout().ty.builtin_deref(true).is_some(), }; if primitive { - let op = v.to_op(self.ecx())?; - let val = self.ecx().read_immediate(op)?; - return self.visit_primitive(val); + return self.visit_primitive(v); } // Proceed into the fields. diff --git a/src/librustc_typeck/check/upvar.rs b/src/librustc_typeck/check/upvar.rs index df994ad9e55c4..312ce402775d2 100644 --- a/src/librustc_typeck/check/upvar.rs +++ b/src/librustc_typeck/check/upvar.rs @@ -45,14 +45,14 @@ use super::FnCtxt; use middle::expr_use_visitor as euv; use middle::mem_categorization as mc; use middle::mem_categorization::Categorization; +use rustc::hir; use rustc::hir::def_id::DefId; -use rustc::ty::{self, Ty, TyCtxt, UpvarSubsts}; +use rustc::hir::def_id::LocalDefId; +use rustc::hir::intravisit::{self, NestedVisitorMap, Visitor}; use rustc::infer::UpvarRegion; +use rustc::ty::{self, Ty, TyCtxt, UpvarSubsts}; use syntax::ast; use syntax_pos::Span; -use rustc::hir; -use rustc::hir::def_id::LocalDefId; -use rustc::hir::intravisit::{self, NestedVisitorMap, Visitor}; impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { pub fn closure_analyze(&self, body: &'gcx hir::Body) { @@ -121,7 +121,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { } }; - let infer_kind = if let UpvarSubsts::Closure(closure_substs) = substs{ + let infer_kind = if let UpvarSubsts::Closure(closure_substs) = substs { if self.closure_kind(closure_def_id, closure_substs).is_none() { Some(closure_substs) } else { @@ -134,7 +134,9 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { self.tcx.with_freevars(closure_node_id, |freevars| { for freevar in freevars { let upvar_id = ty::UpvarId { - var_id: self.tcx.hir.node_to_hir_id(freevar.var_id()), + var_path: ty::UpvarPath { + hir_id : self.tcx.hir.node_to_hir_id(freevar.var_id()), + }, closure_expr_id: LocalDefId::from_def_id(closure_def_id), }; debug!("seed upvar_id {:?}", upvar_id); @@ -213,12 +215,11 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { let final_upvar_tys = self.final_upvar_tys(closure_node_id); debug!( "analyze_closure: id={:?} substs={:?} final_upvar_tys={:?}", - closure_node_id, - substs, - final_upvar_tys + closure_node_id, substs, final_upvar_tys ); - for (upvar_ty, final_upvar_ty) in substs.upvar_tys(closure_def_id, self.tcx) - .zip(final_upvar_tys) + for (upvar_ty, final_upvar_ty) in substs + .upvar_tys(closure_def_id, self.tcx) + .zip(final_upvar_tys) { self.demand_suptype(span, upvar_ty, final_upvar_ty); } @@ -249,16 +250,16 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { let var_hir_id = tcx.hir.node_to_hir_id(var_node_id); let freevar_ty = self.node_ty(var_hir_id); let upvar_id = ty::UpvarId { - var_id: var_hir_id, + var_path: ty::UpvarPath { + hir_id: var_hir_id, + }, closure_expr_id: LocalDefId::from_def_id(closure_def_index), }; let capture = self.tables.borrow().upvar_capture(upvar_id); debug!( "var_id={:?} freevar_ty={:?} capture={:?}", - var_node_id, - freevar_ty, - capture + var_node_id, freevar_ty, capture ); match capture { @@ -271,8 +272,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { }, ), } - }) - .collect() + }).collect() }) } } @@ -301,12 +301,14 @@ struct InferBorrowKind<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> { } impl<'a, 'gcx, 'tcx> InferBorrowKind<'a, 'gcx, 'tcx> { - fn adjust_upvar_borrow_kind_for_consume(&mut self, cmt: &mc::cmt_<'tcx>, - mode: euv::ConsumeMode) { + fn adjust_upvar_borrow_kind_for_consume( + &mut self, + cmt: &mc::cmt_<'tcx>, + mode: euv::ConsumeMode, + ) { debug!( "adjust_upvar_borrow_kind_for_consume(cmt={:?}, mode={:?})", - cmt, - mode + cmt, mode ); // we only care about moves @@ -349,7 +351,7 @@ impl<'a, 'gcx, 'tcx> InferBorrowKind<'a, 'gcx, 'tcx> { upvar_id.closure_expr_id, ty::ClosureKind::FnOnce, guarantor.span, - var_name(tcx, upvar_id.var_id), + var_name(tcx, upvar_id.var_path.hir_id), ); self.adjust_upvar_captures @@ -366,7 +368,7 @@ impl<'a, 'gcx, 'tcx> InferBorrowKind<'a, 'gcx, 'tcx> { upvar_id.closure_expr_id, ty::ClosureKind::FnOnce, guarantor.span, - var_name(tcx, upvar_id.var_id), + var_name(tcx, upvar_id.var_path.hir_id), ); } mc::NoteIndex | mc::NoteNone => {} @@ -381,9 +383,9 @@ impl<'a, 'gcx, 'tcx> InferBorrowKind<'a, 'gcx, 'tcx> { debug!("adjust_upvar_borrow_kind_for_mut(cmt={:?})", cmt); match cmt.cat.clone() { - Categorization::Deref(base, mc::Unique) | - Categorization::Interior(base, _) | - Categorization::Downcast(base, _) => { + Categorization::Deref(base, mc::Unique) + | Categorization::Interior(base, _) + | Categorization::Downcast(base, _) => { // Interior or owned data is mutable if base is // mutable, so iterate to the base. self.adjust_upvar_borrow_kind_for_mut(&base); @@ -399,12 +401,12 @@ impl<'a, 'gcx, 'tcx> InferBorrowKind<'a, 'gcx, 'tcx> { } } - Categorization::Deref(_, mc::UnsafePtr(..)) | - Categorization::StaticItem | - Categorization::ThreadLocal(..) | - Categorization::Rvalue(..) | - Categorization::Local(_) | - Categorization::Upvar(..) => { + Categorization::Deref(_, mc::UnsafePtr(..)) + | Categorization::StaticItem + | Categorization::ThreadLocal(..) + | Categorization::Rvalue(..) + | Categorization::Local(_) + | Categorization::Upvar(..) => { return; } } @@ -414,9 +416,9 @@ impl<'a, 'gcx, 'tcx> InferBorrowKind<'a, 'gcx, 'tcx> { debug!("adjust_upvar_borrow_kind_for_unique(cmt={:?})", cmt); match cmt.cat.clone() { - Categorization::Deref(base, mc::Unique) | - Categorization::Interior(base, _) | - Categorization::Downcast(base, _) => { + Categorization::Deref(base, mc::Unique) + | Categorization::Interior(base, _) + | Categorization::Downcast(base, _) => { // Interior or owned data is unique if base is // unique. self.adjust_upvar_borrow_kind_for_unique(&base); @@ -430,18 +432,20 @@ impl<'a, 'gcx, 'tcx> InferBorrowKind<'a, 'gcx, 'tcx> { } } - Categorization::Deref(_, mc::UnsafePtr(..)) | - Categorization::StaticItem | - Categorization::ThreadLocal(..) | - Categorization::Rvalue(..) | - Categorization::Local(_) | - Categorization::Upvar(..) => {} + Categorization::Deref(_, mc::UnsafePtr(..)) + | Categorization::StaticItem + | Categorization::ThreadLocal(..) + | Categorization::Rvalue(..) + | Categorization::Local(_) + | Categorization::Upvar(..) => {} } } - fn try_adjust_upvar_deref(&mut self, cmt: &mc::cmt_<'tcx>, borrow_kind: ty::BorrowKind) - -> bool - { + fn try_adjust_upvar_deref( + &mut self, + cmt: &mc::cmt_<'tcx>, + borrow_kind: ty::BorrowKind, + ) -> bool { assert!(match borrow_kind { ty::MutBorrow => true, ty::UniqueImmBorrow => true, @@ -465,7 +469,7 @@ impl<'a, 'gcx, 'tcx> InferBorrowKind<'a, 'gcx, 'tcx> { upvar_id.closure_expr_id, ty::ClosureKind::FnMut, cmt.span, - var_name(tcx, upvar_id.var_id), + var_name(tcx, upvar_id.var_path.hir_id), ); true @@ -478,7 +482,7 @@ impl<'a, 'gcx, 'tcx> InferBorrowKind<'a, 'gcx, 'tcx> { upvar_id.closure_expr_id, ty::ClosureKind::FnMut, cmt.span, - var_name(tcx, upvar_id.var_id), + var_name(tcx, upvar_id.var_path.hir_id), ); true @@ -493,15 +497,14 @@ impl<'a, 'gcx, 'tcx> InferBorrowKind<'a, 'gcx, 'tcx> { /// Here the argument `mutbl` is the borrow_kind that is required by /// some particular use. fn adjust_upvar_borrow_kind(&mut self, upvar_id: ty::UpvarId, kind: ty::BorrowKind) { - let upvar_capture = self.adjust_upvar_captures + let upvar_capture = self + .adjust_upvar_captures .get(&upvar_id) .cloned() .unwrap_or_else(|| self.fcx.tables.borrow().upvar_capture(upvar_id)); debug!( "adjust_upvar_borrow_kind(upvar_id={:?}, upvar_capture={:?}, kind={:?})", - upvar_id, - upvar_capture, - kind + upvar_id, upvar_capture, kind ); match upvar_capture { @@ -511,18 +514,18 @@ impl<'a, 'gcx, 'tcx> InferBorrowKind<'a, 'gcx, 'tcx> { ty::UpvarCapture::ByRef(mut upvar_borrow) => { match (upvar_borrow.kind, kind) { // Take RHS: - (ty::ImmBorrow, ty::UniqueImmBorrow) | - (ty::ImmBorrow, ty::MutBorrow) | - (ty::UniqueImmBorrow, ty::MutBorrow) => { + (ty::ImmBorrow, ty::UniqueImmBorrow) + | (ty::ImmBorrow, ty::MutBorrow) + | (ty::UniqueImmBorrow, ty::MutBorrow) => { upvar_borrow.kind = kind; self.adjust_upvar_captures .insert(upvar_id, ty::UpvarCapture::ByRef(upvar_borrow)); } // Take LHS: - (ty::ImmBorrow, ty::ImmBorrow) | - (ty::UniqueImmBorrow, ty::ImmBorrow) | - (ty::UniqueImmBorrow, ty::UniqueImmBorrow) | - (ty::MutBorrow, _) => {} + (ty::ImmBorrow, ty::ImmBorrow) + | (ty::UniqueImmBorrow, ty::ImmBorrow) + | (ty::UniqueImmBorrow, ty::UniqueImmBorrow) + | (ty::MutBorrow, _) => {} } } } @@ -537,10 +540,7 @@ impl<'a, 'gcx, 'tcx> InferBorrowKind<'a, 'gcx, 'tcx> { ) { debug!( "adjust_closure_kind(closure_id={:?}, new_kind={:?}, upvar_span={:?}, var_name={})", - closure_id, - new_kind, - upvar_span, - var_name + closure_id, new_kind, upvar_span, var_name ); // Is this the closure whose kind is currently being inferred? @@ -554,22 +554,20 @@ impl<'a, 'gcx, 'tcx> InferBorrowKind<'a, 'gcx, 'tcx> { debug!( "adjust_closure_kind: closure_id={:?}, existing_kind={:?}, new_kind={:?}", - closure_id, - existing_kind, - new_kind + closure_id, existing_kind, new_kind ); match (existing_kind, new_kind) { - (ty::ClosureKind::Fn, ty::ClosureKind::Fn) | - (ty::ClosureKind::FnMut, ty::ClosureKind::Fn) | - (ty::ClosureKind::FnMut, ty::ClosureKind::FnMut) | - (ty::ClosureKind::FnOnce, _) => { + (ty::ClosureKind::Fn, ty::ClosureKind::Fn) + | (ty::ClosureKind::FnMut, ty::ClosureKind::Fn) + | (ty::ClosureKind::FnMut, ty::ClosureKind::FnMut) + | (ty::ClosureKind::FnOnce, _) => { // no change needed } - (ty::ClosureKind::Fn, ty::ClosureKind::FnMut) | - (ty::ClosureKind::Fn, ty::ClosureKind::FnOnce) | - (ty::ClosureKind::FnMut, ty::ClosureKind::FnOnce) => { + (ty::ClosureKind::Fn, ty::ClosureKind::FnMut) + | (ty::ClosureKind::Fn, ty::ClosureKind::FnOnce) + | (ty::ClosureKind::FnMut, ty::ClosureKind::FnOnce) => { // new kind is stronger than the old kind self.current_closure_kind = new_kind; self.current_origin = Some((upvar_span, var_name)); @@ -590,12 +588,20 @@ impl<'a, 'gcx, 'tcx> euv::Delegate<'tcx> for InferBorrowKind<'a, 'gcx, 'tcx> { self.adjust_upvar_borrow_kind_for_consume(cmt, mode); } - fn matched_pat(&mut self, _matched_pat: &hir::Pat, _cmt: &mc::cmt_<'tcx>, - _mode: euv::MatchMode) { + fn matched_pat( + &mut self, + _matched_pat: &hir::Pat, + _cmt: &mc::cmt_<'tcx>, + _mode: euv::MatchMode, + ) { } - fn consume_pat(&mut self, _consume_pat: &hir::Pat, cmt: &mc::cmt_<'tcx>, - mode: euv::ConsumeMode) { + fn consume_pat( + &mut self, + _consume_pat: &hir::Pat, + cmt: &mc::cmt_<'tcx>, + mode: euv::ConsumeMode, + ) { debug!("consume_pat(cmt={:?},mode={:?})", cmt, mode); self.adjust_upvar_borrow_kind_for_consume(cmt, mode); } @@ -611,9 +617,7 @@ impl<'a, 'gcx, 'tcx> euv::Delegate<'tcx> for InferBorrowKind<'a, 'gcx, 'tcx> { ) { debug!( "borrow(borrow_id={}, cmt={:?}, bk={:?})", - borrow_id, - cmt, - bk + borrow_id, cmt, bk ); match bk { diff --git a/src/librustc_typeck/check/writeback.rs b/src/librustc_typeck/check/writeback.rs index d968bf222aa09..4460d5f64ce26 100644 --- a/src/librustc_typeck/check/writeback.rs +++ b/src/librustc_typeck/check/writeback.rs @@ -306,7 +306,7 @@ impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> { ty::UpvarCapture::ByValue => ty::UpvarCapture::ByValue, ty::UpvarCapture::ByRef(ref upvar_borrow) => { let r = upvar_borrow.region; - let r = self.resolve(&r, &upvar_id.var_id); + let r = self.resolve(&r, &upvar_id.var_path.hir_id); ty::UpvarCapture::ByRef(ty::UpvarBorrow { kind: upvar_borrow.kind, region: r, diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index 471ba6345e248..f3ded2a5376a6 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -527,7 +527,7 @@ fn resolution_failure( doc_comment_padding + // Each subsequent leading whitespace and `///` code_dox.lines().skip(1).take(line_offset - 1).fold(0, |sum, line| { - sum + doc_comment_padding + line.len() - line.trim().len() + sum + doc_comment_padding + line.len() - line.trim_start().len() }) }; diff --git a/src/libserialize/hex.rs b/src/libserialize/hex.rs index 7f3736e82caa6..5604729d2f8dc 100644 --- a/src/libserialize/hex.rs +++ b/src/libserialize/hex.rs @@ -146,7 +146,7 @@ impl FromHex for str { } match modulus { - 0 => Ok(b.into_iter().collect()), + 0 => Ok(b), _ => Err(InvalidHexLength), } } diff --git a/src/libstd/sync/mutex.rs b/src/libstd/sync/mutex.rs index 54bfd8122b4ed..ec9207ea45b4f 100644 --- a/src/libstd/sync/mutex.rs +++ b/src/libstd/sync/mutex.rs @@ -69,7 +69,7 @@ use sys_common::poison::{self, TryLockError, TryLockResult, LockResult}; /// /// let (tx, rx) = channel(); /// for _ in 0..N { -/// let (data, tx) = (data.clone(), tx.clone()); +/// let (data, tx) = (Arc::clone(&data), tx.clone()); /// thread::spawn(move || { /// // The shared state can only be accessed once the lock is held. /// // Our non-atomic increment is safe because we're the only thread diff --git a/src/libstd/time.rs b/src/libstd/time.rs index 90ab349159915..651c874583e69 100644 --- a/src/libstd/time.rs +++ b/src/libstd/time.rs @@ -481,7 +481,8 @@ mod tests { let (a, b) = ($a, $b); if a != b { let (a, b) = if a > b {(a, b)} else {(b, a)}; - assert!(a - Duration::new(0, 100) <= b); + assert!(a - Duration::new(0, 100) <= b, + "{:?} is not almost equal to {:?}", a, b); } }) } diff --git a/src/libsyntax_ext/deriving/generic/mod.rs b/src/libsyntax_ext/deriving/generic/mod.rs index 2f6b306e8f8ba..a5b12ce4c4d83 100644 --- a/src/libsyntax_ext/deriving/generic/mod.rs +++ b/src/libsyntax_ext/deriving/generic/mod.rs @@ -1200,16 +1200,14 @@ impl<'a> MethodDef<'a> { let sp = trait_.span; let variants = &enum_def.variants; - let self_arg_names = self_args.iter() - .enumerate() - .map(|(arg_count, _self_arg)| { - if arg_count == 0 { - "__self".to_string() - } else { + let self_arg_names = iter::once("__self".to_string()).chain( + self_args.iter() + .enumerate() + .skip(1) + .map(|(arg_count, _self_arg)| format!("__arg_{}", arg_count) - } - }) - .collect::>(); + ) + ).collect::>(); let self_arg_idents = self_arg_names.iter() .map(|name| cx.ident_of(&name[..])) @@ -1218,7 +1216,7 @@ impl<'a> MethodDef<'a> { // The `vi_idents` will be bound, solely in the catch-all, to // a series of let statements mapping each self_arg to an int // value corresponding to its discriminant. - let vi_idents: Vec = self_arg_names.iter() + let vi_idents = self_arg_names.iter() .map(|name| { let vi_suffix = format!("{}_vi", &name[..]); cx.ident_of(&vi_suffix[..]).gensym() diff --git a/src/test/codegen/union-abi.rs b/src/test/codegen/union-abi.rs new file mode 100644 index 0000000000000..786968128ec1b --- /dev/null +++ b/src/test/codegen/union-abi.rs @@ -0,0 +1,80 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// compile-flags: -C no-prepopulate-passes + +// This test that using union forward the abi of the inner type, as +// discussed in #54668 + +#![crate_type="lib"] +#![feature(repr_simd)] + +#[derive(Copy, Clone)] +pub enum Unhab {} + +#[repr(simd)] +#[derive(Copy, Clone)] +pub struct i64x4(i64, i64, i64, i64); + +#[derive(Copy, Clone)] +pub union UnionI64x4{ a:(), b: i64x4 } + +// CHECK: define void @test_UnionI64x4(<4 x i64>* {{.*}} %arg0) +#[no_mangle] +pub fn test_UnionI64x4(_: UnionI64x4) { loop {} } + +pub union UnionI64x4_{ a: i64x4, b: (), c:i64x4, d: Unhab, e: ((),()), f: UnionI64x4 } + +// CHECK: define void @test_UnionI64x4_(<4 x i64>* {{.*}} %arg0) +#[no_mangle] +pub fn test_UnionI64x4_(_: UnionI64x4_) { loop {} } + +pub union UnionI64x4I64{ a: i64x4, b: i64 } + +// CHECK: define void @test_UnionI64x4I64(%UnionI64x4I64* {{.*}} %arg0) +#[no_mangle] +pub fn test_UnionI64x4I64(_: UnionI64x4I64) { loop {} } + +pub union UnionI64x4Tuple{ a: i64x4, b: (i64, i64, i64, i64) } + +// CHECK: define void @test_UnionI64x4Tuple(%UnionI64x4Tuple* {{.*}} %arg0) +#[no_mangle] +pub fn test_UnionI64x4Tuple(_: UnionI64x4Tuple) { loop {} } + + +pub union UnionF32{a:f32} + +// CHECK: define float @test_UnionF32(float %arg0) +#[no_mangle] +pub fn test_UnionF32(_: UnionF32) -> UnionF32 { loop {} } + +pub union UnionF32F32{a:f32, b:f32} + +// CHECK: define float @test_UnionF32F32(float %arg0) +#[no_mangle] +pub fn test_UnionF32F32(_: UnionF32F32) -> UnionF32F32 { loop {} } + +pub union UnionF32U32{a:f32, b:u32} + +// CHECK: define i32 @test_UnionF32U32(i32) +#[no_mangle] +pub fn test_UnionF32U32(_: UnionF32U32) -> UnionF32U32 { loop {} } + +pub union UnionU128{a:u128} +// CHECK: define i128 @test_UnionU128(i128 %arg0) +#[no_mangle] +pub fn test_UnionU128(_: UnionU128) -> UnionU128 { loop {} } + +#[repr(C)] +pub union CUnionU128{a:u128} +// CHECK: define void @test_CUnionU128(%CUnionU128* {{.*}} %arg0) +#[no_mangle] +pub fn test_CUnionU128(_: CUnionU128) { loop {} } + diff --git a/src/test/debuginfo/gdb-pretty-struct-and-enums-pre-gdb-7-7.rs b/src/test/debuginfo/gdb-pretty-struct-and-enums.rs similarity index 71% rename from src/test/debuginfo/gdb-pretty-struct-and-enums-pre-gdb-7-7.rs rename to src/test/debuginfo/gdb-pretty-struct-and-enums.rs index 158a1f17fc03d..40dd42898f81d 100644 --- a/src/test/debuginfo/gdb-pretty-struct-and-enums-pre-gdb-7-7.rs +++ b/src/test/debuginfo/gdb-pretty-struct-and-enums.rs @@ -8,34 +8,33 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// ignore-bitrig -// ignore-solaris -// ignore-windows failing on win32 bot -// ignore-freebsd: gdb package too new // ignore-tidy-linelength // ignore-lldb -// ignore-android: FIXME(#10381) +// min-gdb-version: 7.11 + // compile-flags:-g // gdb-command: run // gdb-command: print regular_struct -// gdb-check:$1 = RegularStruct = {the_first_field = 101, the_second_field = 102.5, the_third_field = false} +// gdbg-check:$1 = RegularStruct = {the_first_field = 101, the_second_field = 102.5, the_third_field = false} +// gdbr-check:$1 = gdb_pretty_struct_and_enums::RegularStruct {the_first_field: 101, the_second_field: 102.5, the_third_field: false} // gdb-command: print empty_struct -// gdb-check:$2 = EmptyStruct +// gdbg-check:$2 = EmptyStruct +// gdbr-check:$2 = gdb_pretty_struct_and_enums::EmptyStruct // gdb-command: print c_style_enum1 // gdbg-check:$3 = CStyleEnumVar1 -// gdbr-check:$3 = gdb_pretty_struct_and_enums_pre_gdb_7_7::CStyleEnum::CStyleEnumVar1 +// gdbr-check:$3 = gdb_pretty_struct_and_enums::CStyleEnum::CStyleEnumVar1 // gdb-command: print c_style_enum2 // gdbg-check:$4 = CStyleEnumVar2 -// gdbr-check:$4 = gdb_pretty_struct_and_enums_pre_gdb_7_7::CStyleEnum::CStyleEnumVar2 +// gdbr-check:$4 = gdb_pretty_struct_and_enums::CStyleEnum::CStyleEnumVar2 // gdb-command: print c_style_enum3 // gdbg-check:$5 = CStyleEnumVar3 -// gdbr-check:$5 = gdb_pretty_struct_and_enums_pre_gdb_7_7::CStyleEnum::CStyleEnumVar3 +// gdbr-check:$5 = gdb_pretty_struct_and_enums::CStyleEnum::CStyleEnumVar3 #![allow(dead_code, unused_variables)] diff --git a/src/test/run-pass-fulldeps/auxiliary/linkage-visibility.rs b/src/test/run-pass-fulldeps/auxiliary/linkage-visibility.rs index 4ea3d0d0d0a07..2aaa28341ad91 100644 --- a/src/test/run-pass-fulldeps/auxiliary/linkage-visibility.rs +++ b/src/test/run-pass-fulldeps/auxiliary/linkage-visibility.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// ignore-musl - dlsym doesn't see symbols without "-C link-arg=-Wl,--export-dynamic" + #![feature(rustc_private)] // We're testing linkage visibility; the compiler warns us, but we want to diff --git a/src/test/run-pass/mpsc_stress.rs b/src/test/run-pass/mpsc_stress.rs new file mode 100644 index 0000000000000..aa369bb17fead --- /dev/null +++ b/src/test/run-pass/mpsc_stress.rs @@ -0,0 +1,172 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// compile-flags:--test +// ignore-emscripten + +use std::sync::mpsc::channel; +use std::sync::mpsc::TryRecvError; +use std::sync::mpsc::RecvError; +use std::sync::mpsc::RecvTimeoutError; +use std::sync::Arc; +use std::sync::atomic::AtomicUsize; +use std::sync::atomic::Ordering; + +use std::thread; +use std::time::Duration; + + +/// Simple thread synchronization utility +struct Barrier { + // Not using mutex/condvar for precision + shared: Arc, + count: usize, +} + +impl Barrier { + fn new(count: usize) -> Vec { + let shared = Arc::new(AtomicUsize::new(0)); + (0..count).map(|_| Barrier { shared: shared.clone(), count: count }).collect() + } + + fn new2() -> (Barrier, Barrier) { + let mut v = Barrier::new(2); + (v.pop().unwrap(), v.pop().unwrap()) + } + + /// Returns when `count` threads enter `wait` + fn wait(self) { + self.shared.fetch_add(1, Ordering::SeqCst); + while self.shared.load(Ordering::SeqCst) != self.count { + } + } +} + + +fn shared_close_sender_does_not_lose_messages_iter() { + let (tb, rb) = Barrier::new2(); + + let (tx, rx) = channel(); + let _ = tx.clone(); // convert to shared + + thread::spawn(move || { + tb.wait(); + thread::sleep(Duration::from_micros(1)); + tx.send(17).expect("send"); + drop(tx); + }); + + let i = rx.into_iter(); + rb.wait(); + // Make sure it doesn't return disconnected before returning an element + assert_eq!(vec![17], i.collect::>()); +} + +#[test] +fn shared_close_sender_does_not_lose_messages() { + for _ in 0..10000 { + shared_close_sender_does_not_lose_messages_iter(); + } +} + + +// https://github.com/rust-lang/rust/issues/39364 +fn concurrent_recv_timeout_and_upgrade_iter() { + // 1 us + let sleep = Duration::new(0, 1_000); + + let (a, b) = Barrier::new2(); + let (tx, rx) = channel(); + let th = thread::spawn(move || { + a.wait(); + loop { + match rx.recv_timeout(sleep) { + Ok(_) => { + break; + }, + Err(_) => {}, + } + } + }); + b.wait(); + thread::sleep(sleep); + tx.clone().send(()).expect("send"); + th.join().unwrap(); +} + +#[test] +fn concurrent_recv_timeout_and_upgrade() { + // FIXME: fix and enable + if true { return } + + // at the moment of writing this test fails like this: + // thread '' panicked at 'assertion failed: `(left == right)` + // left: `4561387584`, + // right: `0`', libstd/sync/mpsc/shared.rs:253:13 + + for _ in 0..10000 { + concurrent_recv_timeout_and_upgrade_iter(); + } +} + + +fn concurrent_writes_iter() { + const THREADS: usize = 4; + const PER_THR: usize = 100; + + let mut bs = Barrier::new(THREADS + 1); + let (tx, rx) = channel(); + + let mut threads = Vec::new(); + for j in 0..THREADS { + let tx = tx.clone(); + let b = bs.pop().unwrap(); + threads.push(thread::spawn(move || { + b.wait(); + for i in 0..PER_THR { + tx.send(j * 1000 + i).expect("send"); + } + })); + } + + let b = bs.pop().unwrap(); + b.wait(); + + let mut v: Vec<_> = rx.iter().take(THREADS * PER_THR).collect(); + v.sort(); + + for j in 0..THREADS { + for i in 0..PER_THR { + assert_eq!(j * 1000 + i, v[j * PER_THR + i]); + } + } + + for t in threads { + t.join().unwrap(); + } + + let one_us = Duration::new(0, 1000); + + assert_eq!(TryRecvError::Empty, rx.try_recv().unwrap_err()); + assert_eq!(RecvTimeoutError::Timeout, rx.recv_timeout(one_us).unwrap_err()); + + drop(tx); + + assert_eq!(RecvError, rx.recv().unwrap_err()); + assert_eq!(RecvTimeoutError::Disconnected, rx.recv_timeout(one_us).unwrap_err()); + assert_eq!(TryRecvError::Disconnected, rx.try_recv().unwrap_err()); +} + +#[test] +fn concurrent_writes() { + for _ in 0..100 { + concurrent_writes_iter(); + } +} diff --git a/src/test/rustdoc-ui/intra-link-span-ice-55723.rs b/src/test/rustdoc-ui/intra-link-span-ice-55723.rs new file mode 100644 index 0000000000000..12e59a4813f85 --- /dev/null +++ b/src/test/rustdoc-ui/intra-link-span-ice-55723.rs @@ -0,0 +1,24 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// ignore-tidy-end-whitespace + +#![deny(intra_doc_link_resolution_failure)] + +// An error in calculating spans while reporting intra-doc link resolution errors caused rustdoc to +// attempt to slice in the middle of a multibyte character. See +// https://github.com/rust-lang/rust/issues/55723 + +/// ## For example: +/// +/// (arr[i]) +pub fn test_ice() { + unimplemented!(); +} diff --git a/src/test/rustdoc-ui/intra-link-span-ice-55723.stderr b/src/test/rustdoc-ui/intra-link-span-ice-55723.stderr new file mode 100644 index 0000000000000..7ae6af4a75e8c --- /dev/null +++ b/src/test/rustdoc-ui/intra-link-span-ice-55723.stderr @@ -0,0 +1,13 @@ +error: `[i]` cannot be resolved, ignoring it... + --> $DIR/intra-link-span-ice-55723.rs:21:10 + | +LL | /// (arr[i]) + | ^ cannot be resolved, ignoring + | +note: lint level defined here + --> $DIR/intra-link-span-ice-55723.rs:13:9 + | +LL | #![deny(intra_doc_link_resolution_failure)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = help: to escape `[` and `]` characters, just add '/' before them like `/[` or `/]` + diff --git a/src/test/ui/consts/const-eval/issue-55541.rs b/src/test/ui/consts/const-eval/issue-55541.rs new file mode 100644 index 0000000000000..611fb89341de4 --- /dev/null +++ b/src/test/ui/consts/const-eval/issue-55541.rs @@ -0,0 +1,27 @@ +// compile-pass + +// Test that we can handle newtypes wrapping extern types + +#![feature(extern_types, const_transmute)] + +use std::marker::PhantomData; + +extern "C" { + pub type ExternType; +} +unsafe impl Sync for ExternType {} +static MAGIC_FFI_STATIC: u8 = 42; + +#[repr(transparent)] +pub struct Wrapper(ExternType); +pub static MAGIC_FFI_REF: &'static Wrapper = unsafe { + std::mem::transmute(&MAGIC_FFI_STATIC) +}; + +#[repr(transparent)] +pub struct Wrapper2(PhantomData>, ExternType); +pub static MAGIC_FFI_REF2: &'static Wrapper2 = unsafe { + std::mem::transmute(&MAGIC_FFI_STATIC) +}; + +fn main() {} diff --git a/src/tools/cargo b/src/tools/cargo index 241fac0e39330..b3d0b2e545b61 160000 --- a/src/tools/cargo +++ b/src/tools/cargo @@ -1 +1 @@ -Subproject commit 241fac0e3933063fa48a1a01f5d577e40af12e4d +Subproject commit b3d0b2e545b61d4cd08096911724b7d49d213f73 diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs index 72c47273e63b5..2dfb9fc68ac16 100644 --- a/src/tools/tidy/src/deps.rs +++ b/src/tools/tidy/src/deps.rs @@ -92,6 +92,7 @@ const WHITELIST: &[Crate] = &[ Crate("kernel32-sys"), Crate("lazy_static"), Crate("libc"), + Crate("libz-sys"), Crate("lock_api"), Crate("log"), Crate("log_settings"), @@ -133,6 +134,7 @@ const WHITELIST: &[Crate] = &[ Crate("utf8-ranges"), Crate("version_check"), Crate("void"), + Crate("vcpkg"), Crate("winapi"), Crate("winapi-build"), Crate("winapi-i686-pc-windows-gnu"),