diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index 1272643edd259..780513dd94394 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -377,6 +377,11 @@ impl<'a> Builder<'a> { self.ensure(Libdir { compiler, target }) } + pub fn sysroot_codegen_backends(&self, compiler: Compiler) -> PathBuf { + self.sysroot_libdir(compiler, compiler.host) + .with_file_name("codegen-backends") + } + /// Returns the compiler's libdir where it stores the dynamic libraries that /// it itself links against. /// diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs index fa289bbd76a8b..1d5e11c5d6d41 100644 --- a/src/bootstrap/compile.rs +++ b/src/bootstrap/compile.rs @@ -724,8 +724,7 @@ fn copy_codegen_backends_to_sysroot(builder: &Builder, // // Here we're looking for the output dylib of the `CodegenBackend` step and // we're copying that into the `codegen-backends` folder. - let libdir = builder.sysroot_libdir(target_compiler, target); - let dst = libdir.join("codegen-backends"); + let dst = builder.sysroot_codegen_backends(target_compiler); t!(fs::create_dir_all(&dst)); for backend in builder.config.rust_codegen_backends.iter() { diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index 4127239dc49b8..dbb7d19e43285 100644 --- a/src/bootstrap/dist.rs +++ b/src/bootstrap/dist.rs @@ -435,11 +435,9 @@ impl Step for Rustc { } // Copy over the codegen backends - let backends_src = builder.sysroot_libdir(compiler, host) - .join("codegen-backends"); - let backends_dst = image.join("lib/rustlib") - .join(&*host) - .join("lib/codegen-backends"); + let backends_src = builder.sysroot_codegen_backends(compiler); + let backends_rel = backends_src.strip_prefix(&src).unwrap(); + let backends_dst = image.join(&backends_rel); t!(fs::create_dir_all(&backends_dst)); cp_r(&backends_src, &backends_dst); diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs index 65aacb23bd768..6c8a1c3062b00 100644 --- a/src/libcore/fmt/mod.rs +++ b/src/libcore/fmt/mod.rs @@ -1586,6 +1586,7 @@ impl Display for ! { #[stable(feature = "rust1", since = "1.0.0")] impl Debug for bool { + #[inline] fn fmt(&self, f: &mut Formatter) -> Result { Display::fmt(self, f) } @@ -1748,6 +1749,7 @@ impl Debug for [T] { #[stable(feature = "rust1", since = "1.0.0")] impl Debug for () { + #[inline] fn fmt(&self, f: &mut Formatter) -> Result { f.pad("()") } diff --git a/src/libcore/fmt/num.rs b/src/libcore/fmt/num.rs index ee989854a3772..2992e7cf8db34 100644 --- a/src/libcore/fmt/num.rs +++ b/src/libcore/fmt/num.rs @@ -157,6 +157,7 @@ macro_rules! debug { ($T:ident) => { #[stable(feature = "rust1", since = "1.0.0")] impl fmt::Debug for $T { + #[inline] fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fmt::Display::fmt(self, f) } diff --git a/src/libcore/iter/mod.rs b/src/libcore/iter/mod.rs index 06c29b47bf921..7314fac282b66 100644 --- a/src/libcore/iter/mod.rs +++ b/src/libcore/iter/mod.rs @@ -307,6 +307,7 @@ use fmt; use iter_private::TrustedRandomAccess; use ops::Try; use usize; +use intrinsics; #[stable(feature = "rust1", since = "1.0.0")] pub use self::iterator::Iterator; @@ -694,6 +695,49 @@ impl Iterator for StepBy where I: Iterator { (f(inner_hint.0), inner_hint.1.map(f)) } } + + #[inline] + fn nth(&mut self, mut n: usize) -> Option { + if self.first_take { + self.first_take = false; + let first = self.iter.next(); + if n == 0 { + return first; + } + n -= 1; + } + // n and self.step are indices, we need to add 1 to get the amount of elements + // When calling `.nth`, we need to subtract 1 again to convert back to an index + // step + 1 can't overflow because `.step_by` sets `self.step` to `step - 1` + let mut step = self.step + 1; + // n + 1 could overflow + // thus, if n is usize::MAX, instead of adding one, we call .nth(step) + if n == usize::MAX { + self.iter.nth(step - 1); + } else { + n += 1; + } + + // overflow handling + loop { + let mul = n.checked_mul(step); + if unsafe { intrinsics::likely(mul.is_some()) } { + return self.iter.nth(mul.unwrap() - 1); + } + let div_n = usize::MAX / n; + let div_step = usize::MAX / step; + let nth_n = div_n * n; + let nth_step = div_step * step; + let nth = if nth_n > nth_step { + step -= div_n; + nth_n + } else { + n -= div_step; + nth_step + }; + self.iter.nth(nth - 1); + } + } } // StepBy can only make the iterator shorter, so the len will still fit. diff --git a/src/libcore/tests/iter.rs b/src/libcore/tests/iter.rs index 8997cf9c6bff9..e52e119ff59b9 100644 --- a/src/libcore/tests/iter.rs +++ b/src/libcore/tests/iter.rs @@ -161,6 +161,68 @@ fn test_iterator_step_by() { assert_eq!(it.next(), None); } +#[test] +fn test_iterator_step_by_nth() { + let mut it = (0..16).step_by(5); + assert_eq!(it.nth(0), Some(0)); + assert_eq!(it.nth(0), Some(5)); + assert_eq!(it.nth(0), Some(10)); + assert_eq!(it.nth(0), Some(15)); + assert_eq!(it.nth(0), None); + + let it = (0..18).step_by(5); + assert_eq!(it.clone().nth(0), Some(0)); + assert_eq!(it.clone().nth(1), Some(5)); + assert_eq!(it.clone().nth(2), Some(10)); + assert_eq!(it.clone().nth(3), Some(15)); + assert_eq!(it.clone().nth(4), None); + assert_eq!(it.clone().nth(42), None); +} + +#[test] +fn test_iterator_step_by_nth_overflow() { + #[cfg(target_pointer_width = "8")] + type Bigger = u16; + #[cfg(target_pointer_width = "16")] + type Bigger = u32; + #[cfg(target_pointer_width = "32")] + type Bigger = u64; + #[cfg(target_pointer_width = "64")] + type Bigger = u128; + + #[derive(Clone)] + struct Test(Bigger); + impl<'a> Iterator for &'a mut Test { + type Item = i32; + fn next(&mut self) -> Option { Some(21) } + fn nth(&mut self, n: usize) -> Option { + self.0 += n as Bigger + 1; + Some(42) + } + } + + let mut it = Test(0); + let root = usize::MAX >> (::std::mem::size_of::() * 8 / 2); + let n = root + 20; + (&mut it).step_by(n).nth(n); + assert_eq!(it.0, n as Bigger * n as Bigger); + + // large step + let mut it = Test(0); + (&mut it).step_by(usize::MAX).nth(5); + assert_eq!(it.0, (usize::MAX as Bigger) * 5); + + // n + 1 overflows + let mut it = Test(0); + (&mut it).step_by(2).nth(usize::MAX); + assert_eq!(it.0, (usize::MAX as Bigger) * 2); + + // n + 1 overflows + let mut it = Test(0); + (&mut it).step_by(1).nth(usize::MAX); + assert_eq!(it.0, (usize::MAX as Bigger) * 1); +} + #[test] #[should_panic] fn test_iterator_step_by_zero() { diff --git a/src/libpanic_abort/lib.rs b/src/libpanic_abort/lib.rs index c3bd6a2bc187d..5f768ef4399e8 100644 --- a/src/libpanic_abort/lib.rs +++ b/src/libpanic_abort/lib.rs @@ -27,10 +27,12 @@ #![feature(libc)] #![feature(panic_runtime)] #![feature(staged_api)] +#![feature(rustc_attrs)] // Rust's "try" function, but if we're aborting on panics we just call the // function as there's nothing else we need to do here. #[no_mangle] +#[rustc_std_internal_symbol] pub unsafe extern fn __rust_maybe_catch_panic(f: fn(*mut u8), data: *mut u8, _data_ptr: *mut usize, @@ -50,6 +52,7 @@ pub unsafe extern fn __rust_maybe_catch_panic(f: fn(*mut u8), // will kill us with an illegal instruction, which will do a good enough job for // now hopefully. #[no_mangle] +#[rustc_std_internal_symbol] pub unsafe extern fn __rust_start_panic(_data: usize, _vtable: usize) -> u32 { abort(); diff --git a/src/librustc/README.md b/src/librustc/README.md index ddf71a06d607c..722456a76ce59 100644 --- a/src/librustc/README.md +++ b/src/librustc/README.md @@ -176,6 +176,7 @@ pointers for understanding them better. - `'gcx` -- the lifetime of the global arena (see `librustc/ty`). - generics -- the set of generic type parameters defined on a type or item - ICE -- internal compiler error. When the compiler crashes. +- ICH -- incremental compilation hash. - infcx -- the inference context (see `librustc/infer`) - MIR -- the **Mid-level IR** that is created after type-checking for use by borrowck and trans. Defined in the `src/librustc/mir/` module, but much of the code that manipulates it is diff --git a/src/librustc/dep_graph/dep_node.rs b/src/librustc/dep_graph/dep_node.rs index 1de9091b5df7d..4034055d04155 100644 --- a/src/librustc/dep_graph/dep_node.rs +++ b/src/librustc/dep_graph/dep_node.rs @@ -639,6 +639,9 @@ define_dep_nodes!( <'tcx> [] TargetFeaturesEnabled(DefId), [] InstanceDefSizeEstimate { instance_def: InstanceDef<'tcx> }, + + [] GetSymbolExportLevel(DefId), + ); trait DepNodeParams<'a, 'gcx: 'tcx + 'a, 'tcx: 'a> : fmt::Debug { diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index 42200a3a44728..d65becb912a3c 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -831,6 +831,11 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { span, node: hir::ImplItemKind::Method(hir::MethodSig { ref decl, .. }, _), .. + }) | + hir::map::NodeTraitItem(&hir::TraitItem { + span, + node: hir::TraitItemKind::Method(hir::MethodSig { ref decl, .. }, _), + .. }) => { (self.tcx.sess.codemap().def_span(span), decl.inputs.iter() .map(|arg| match arg.clone().into_inner().node { diff --git a/src/librustc/ty/maps/mod.rs b/src/librustc/ty/maps/mod.rs index 6c79f6a62fa0b..85fca68187fe6 100644 --- a/src/librustc/ty/maps/mod.rs +++ b/src/librustc/ty/maps/mod.rs @@ -343,6 +343,7 @@ define_maps! { <'tcx> -> (Arc, Arc>>>), [] fn export_name: ExportName(DefId) -> Option, [] fn contains_extern_indicator: ContainsExternIndicator(DefId) -> bool, + [] fn symbol_export_level: GetSymbolExportLevel(DefId) -> SymbolExportLevel, [] fn is_translated_function: IsTranslatedFunction(DefId) -> bool, [] fn codegen_unit: CodegenUnit(InternedString) -> Arc>, [] fn compile_codegen_unit: CompileCodegenUnit(InternedString) -> Stats, diff --git a/src/librustc/ty/maps/plumbing.rs b/src/librustc/ty/maps/plumbing.rs index c9eebc3d2a0a7..0ab6ee1a54a9b 100644 --- a/src/librustc/ty/maps/plumbing.rs +++ b/src/librustc/ty/maps/plumbing.rs @@ -921,6 +921,8 @@ pub fn force_from_dep_node<'a, 'gcx, 'lcx>(tcx: TyCtxt<'a, 'gcx, 'lcx>, DepKind::TargetFeaturesWhitelist => { force!(target_features_whitelist, LOCAL_CRATE); } DepKind::TargetFeaturesEnabled => { force!(target_features_enabled, def_id!()); } + + DepKind::GetSymbolExportLevel => { force!(symbol_export_level, def_id!()); } } true diff --git a/src/librustc_back/target/mod.rs b/src/librustc_back/target/mod.rs index 3c8a676dcc200..2872c59157d6b 100644 --- a/src/librustc_back/target/mod.rs +++ b/src/librustc_back/target/mod.rs @@ -468,6 +468,10 @@ pub struct TargetOptions { /// The codegen backend to use for this target, typically "llvm" pub codegen_backend: String, + + /// The default visibility for symbols in this target should be "hidden" + /// rather than "default" + pub default_hidden_visibility: bool, } impl Default for TargetOptions { @@ -538,6 +542,7 @@ impl Default for TargetOptions { no_builtins: false, i128_lowering: false, codegen_backend: "llvm".to_string(), + default_hidden_visibility: false, } } } @@ -785,6 +790,7 @@ impl Target { key!(singlethread, bool); key!(no_builtins, bool); key!(codegen_backend); + key!(default_hidden_visibility, bool); if let Some(array) = obj.find("abi-blacklist").and_then(Json::as_array) { for name in array.iter().filter_map(|abi| abi.as_string()) { @@ -982,6 +988,7 @@ impl ToJson for Target { target_option_val!(singlethread); target_option_val!(no_builtins); target_option_val!(codegen_backend); + target_option_val!(default_hidden_visibility); if default.abi_blacklist != self.options.abi_blacklist { d.insert("abi-blacklist".to_string(), self.options.abi_blacklist.iter() diff --git a/src/librustc_back/target/msp430_none_elf.rs b/src/librustc_back/target/msp430_none_elf.rs index 509a7cf5e0323..966df897f01f1 100644 --- a/src/librustc_back/target/msp430_none_elf.rs +++ b/src/librustc_back/target/msp430_none_elf.rs @@ -53,6 +53,12 @@ pub fn target() -> TargetResult { // don't want to invoke that many gcc instances. default_codegen_units: Some(1), + // Since MSP430 doesn't meaningfully support faulting on illegal + // instructions, LLVM generates a call to abort() function instead + // of a trap instruction. Such calls are 4 bytes long, and that is + // too much overhead for such small target. + trap_unreachable: false, + .. Default::default( ) } }) diff --git a/src/librustc_back/target/wasm32_unknown_unknown.rs b/src/librustc_back/target/wasm32_unknown_unknown.rs index 7e1011ab8af96..242860e5c6e92 100644 --- a/src/librustc_back/target/wasm32_unknown_unknown.rs +++ b/src/librustc_back/target/wasm32_unknown_unknown.rs @@ -83,6 +83,9 @@ pub fn target() -> Result { // performing LTO with compiler-builtins. no_builtins: true, + // no dynamic linking, no need for default visibility! + default_hidden_visibility: true, + .. Default::default() }; Ok(Target { diff --git a/src/librustc_const_eval/check_match.rs b/src/librustc_const_eval/check_match.rs index fd171b8992470..ae53ed0e1140d 100644 --- a/src/librustc_const_eval/check_match.rs +++ b/src/librustc_const_eval/check_match.rs @@ -127,13 +127,16 @@ impl<'a, 'tcx> Visitor<'tcx> for MatchVisitor<'a, 'tcx> { } } + impl<'a, 'tcx> PatternContext<'a, 'tcx> { fn report_inlining_errors(&self, pat_span: Span) { for error in &self.errors { match *error { PatternError::StaticInPattern(span) => { - span_err!(self.tcx.sess, span, E0158, - "statics cannot be referenced in patterns"); + self.span_e0158(span, "statics cannot be referenced in patterns") + } + PatternError::AssociatedConstInPattern(span) => { + self.span_e0158(span, "associated consts cannot be referenced in patterns") } PatternError::ConstEval(ref err) => { err.report(self.tcx, pat_span, "pattern"); @@ -141,6 +144,10 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> { } } } + + fn span_e0158(&self, span: Span, text: &str) { + span_err!(self.tcx.sess, span, E0158, "{}", text) + } } impl<'a, 'tcx> MatchVisitor<'a, 'tcx> { diff --git a/src/librustc_const_eval/pattern.rs b/src/librustc_const_eval/pattern.rs index 3577feaf90c1a..e0b3929e32a8d 100644 --- a/src/librustc_const_eval/pattern.rs +++ b/src/librustc_const_eval/pattern.rs @@ -27,6 +27,7 @@ use syntax_pos::Span; #[derive(Clone, Debug)] pub enum PatternError<'tcx> { + AssociatedConstInPattern(Span), StaticInPattern(Span), ConstEval(ConstEvalErr<'tcx>), } @@ -635,6 +636,10 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> { -> Pattern<'tcx> { let ty = self.tables.node_id_to_type(id); let def = self.tables.qpath_def(qpath, id); + let is_associated_const = match def { + Def::AssociatedConst(_) => true, + _ => false, + }; let kind = match def { Def::Const(def_id) | Def::AssociatedConst(def_id) => { let substs = self.tables.node_substs(id); @@ -656,7 +661,11 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> { return pat; } None => { - self.errors.push(PatternError::StaticInPattern(span)); + self.errors.push(if is_associated_const { + PatternError::AssociatedConstInPattern(span) + } else { + PatternError::StaticInPattern(span) + }); PatternKind::Wild } } diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index 6118ee94c84cf..87c3b9a553e03 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -289,7 +289,7 @@ fn get_trans_sysroot(backend_name: &str) -> fn() -> Box { let sysroot = sysroot_candidates.iter() .map(|sysroot| { let libdir = filesearch::relative_target_lib_path(&sysroot, &target); - sysroot.join(&libdir).join("codegen-backends") + sysroot.join(libdir).with_file_name("codegen-backends") }) .filter(|f| { info!("codegen backend candidate: {}", f.display()); @@ -456,10 +456,13 @@ pub fn run_compiler<'a>(args: &[String], None); let (odir, ofile) = make_output(&matches); - let (input, input_file_path) = match make_input(&matches.free) { - Some((input, input_file_path)) => callbacks.some_input(input, input_file_path), + let (input, input_file_path, input_err) = match make_input(&matches.free) { + Some((input, input_file_path, input_err)) => { + let (input, input_file_path) = callbacks.some_input(input, input_file_path); + (input, input_file_path, input_err) + }, None => match callbacks.no_input(&matches, &sopts, &cfg, &odir, &ofile, &descriptions) { - Some((input, input_file_path)) => (input, input_file_path), + Some((input, input_file_path)) => (input, input_file_path, None), None => return (Ok(()), None), }, }; @@ -470,6 +473,13 @@ pub fn run_compiler<'a>(args: &[String], sopts, input_file_path.clone(), descriptions, codemap, emitter_dest, ); + if let Some(err) = input_err { + // Immediately stop compilation if there was an issue reading + // the input (for example if the input stream is not UTF-8). + sess.err(&format!("{}", err)); + return (Err(CompileIncomplete::Stopped), Some(sess)); + } + let trans = get_trans(&sess); rustc_lint::register_builtins(&mut sess.lint_store.borrow_mut(), Some(&sess)); @@ -512,17 +522,22 @@ fn make_output(matches: &getopts::Matches) -> (Option, Option) } // Extract input (string or file and optional path) from matches. -fn make_input(free_matches: &[String]) -> Option<(Input, Option)> { +fn make_input(free_matches: &[String]) -> Option<(Input, Option, Option)> { if free_matches.len() == 1 { let ifile = &free_matches[0]; if ifile == "-" { let mut src = String::new(); - io::stdin().read_to_string(&mut src).unwrap(); + let err = if io::stdin().read_to_string(&mut src).is_err() { + Some(io::Error::new(io::ErrorKind::InvalidData, + "couldn't read from stdin, as it did not contain valid UTF-8")) + } else { + None + }; Some((Input::Str { name: FileName::Anon, input: src }, - None)) + None, err)) } else { Some((Input::File(PathBuf::from(ifile)), - Some(PathBuf::from(ifile)))) + Some(PathBuf::from(ifile)), None)) } } else { None diff --git a/src/librustc_errors/emitter.rs b/src/librustc_errors/emitter.rs index ffb5efd93ed54..c4f256be96a19 100644 --- a/src/librustc_errors/emitter.rs +++ b/src/librustc_errors/emitter.rs @@ -284,6 +284,10 @@ impl EmitterWriter { line: &Line, width_offset: usize, code_offset: usize) -> Vec<(usize, Style)> { + if line.line_index == 0 { + return Vec::new(); + } + let source_string = match file.get_line(line.line_index - 1) { Some(s) => s, None => return Vec::new(), diff --git a/src/librustc_mir/monomorphize/partitioning.rs b/src/librustc_mir/monomorphize/partitioning.rs index 806d787c84522..e9471cdb4f949 100644 --- a/src/librustc_mir/monomorphize/partitioning.rs +++ b/src/librustc_mir/monomorphize/partitioning.rs @@ -107,6 +107,7 @@ use rustc::dep_graph::WorkProductId; use rustc::hir::def_id::DefId; use rustc::hir::map::DefPathData; use rustc::mir::mono::{Linkage, Visibility}; +use rustc::middle::exported_symbols::SymbolExportLevel; use rustc::ty::{self, TyCtxt, InstanceDef}; use rustc::ty::item_path::characteristic_def_id_of_type; use rustc::util::nodemap::{FxHashMap, FxHashSet}; @@ -322,7 +323,16 @@ fn place_root_translation_items<'a, 'tcx, I>(tcx: TyCtxt<'a, 'tcx, 'tcx>, .or_insert_with(make_codegen_unit); let mut can_be_internalized = true; - let (linkage, visibility) = match trans_item.explicit_linkage(tcx) { + let default_visibility = |id: DefId| { + if tcx.sess.target.target.options.default_hidden_visibility && + tcx.symbol_export_level(id) != SymbolExportLevel::C + { + Visibility::Hidden + } else { + Visibility::Default + } + }; + let (linkage, mut visibility) = match trans_item.explicit_linkage(tcx) { Some(explicit_linkage) => (explicit_linkage, Visibility::Default), None => { match trans_item { @@ -352,7 +362,8 @@ fn place_root_translation_items<'a, 'tcx, I>(tcx: TyCtxt<'a, 'tcx, 'tcx>, Visibility::Hidden } else if def_id.is_local() { if tcx.is_exported_symbol(def_id) { - Visibility::Default + can_be_internalized = false; + default_visibility(def_id) } else { Visibility::Hidden } @@ -375,7 +386,8 @@ fn place_root_translation_items<'a, 'tcx, I>(tcx: TyCtxt<'a, 'tcx, 'tcx>, MonoItem::GlobalAsm(node_id) => { let def_id = tcx.hir.local_def_id(node_id); let visibility = if tcx.is_exported_symbol(def_id) { - Visibility::Default + can_be_internalized = false; + default_visibility(def_id) } else { Visibility::Hidden }; diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index ecf3c9e42d58f..2da4bfedd3a17 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -3998,14 +3998,20 @@ impl<'a> Resolver<'a> { if let (Ok(snippet), false) = (cm.span_to_snippet(binding.span), binding.is_renamed_extern_crate()) { + let suggested_name = if name.as_str().chars().next().unwrap().is_uppercase() { + format!("Other{}", name) + } else { + format!("other_{}", name) + }; + err.span_suggestion(binding.span, rename_msg, if snippet.ends_with(';') { - format!("{} as Other{};", + format!("{} as {};", &snippet[..snippet.len()-1], - name) + suggested_name) } else { - format!("{} as Other{}", snippet, name) + format!("{} as {}", snippet, suggested_name) }); } else { err.span_label(binding.span, rename_msg); diff --git a/src/librustc_trans/allocator.rs b/src/librustc_trans/allocator.rs index fd5aa1364d381..e1c145b122d76 100644 --- a/src/librustc_trans/allocator.rs +++ b/src/librustc_trans/allocator.rs @@ -86,6 +86,10 @@ pub(crate) unsafe fn trans(tcx: TyCtxt, mods: &ModuleLlvm, kind: AllocatorKind) name.as_ptr(), ty); + if tcx.sess.target.target.options.default_hidden_visibility { + llvm::LLVMRustSetVisibility(llfn, llvm::Visibility::Hidden); + } + let callee = CString::new(kind.fn_name(method.name)).unwrap(); let callee = llvm::LLVMRustGetOrInsertFunction(llmod, callee.as_ptr(), diff --git a/src/librustc_trans/asm.rs b/src/librustc_trans/asm.rs index c7be0c4e67d71..751f8148a2a90 100644 --- a/src/librustc_trans/asm.rs +++ b/src/librustc_trans/asm.rs @@ -59,8 +59,9 @@ pub fn trans_inline_asm<'a, 'tcx>( // Default per-arch clobbers // Basically what clang does let arch_clobbers = match &bx.sess().target.target.arch[..] { - "x86" | "x86_64" => vec!["~{dirflag}", "~{fpsr}", "~{flags}"], - _ => Vec::new() + "x86" | "x86_64" => vec!["~{dirflag}", "~{fpsr}", "~{flags}"], + "mips" | "mips64" => vec!["~{$1}"], + _ => Vec::new() }; let all_constraints = diff --git a/src/librustc_trans/back/symbol_export.rs b/src/librustc_trans/back/symbol_export.rs index 15ff59c7df998..989ef8a953746 100644 --- a/src/librustc_trans/back/symbol_export.rs +++ b/src/librustc_trans/back/symbol_export.rs @@ -133,6 +133,8 @@ pub fn provide(providers: &mut Providers) { Arc::new(local_crate) }; + + providers.symbol_export_level = export_level; } pub fn provide_extern(providers: &mut Providers) { @@ -203,6 +205,7 @@ pub fn provide_extern(providers: &mut Providers) { Arc::new(crate_exports) }; + providers.symbol_export_level = export_level; } fn export_level(tcx: TyCtxt, sym_def_id: DefId) -> SymbolExportLevel { diff --git a/src/librustc_trans/type_of.rs b/src/librustc_trans/type_of.rs index b1533cfad19f5..af957500f7002 100644 --- a/src/librustc_trans/type_of.rs +++ b/src/librustc_trans/type_of.rs @@ -57,7 +57,9 @@ fn uncached_llvm_type<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, ty::TyClosure(..) | ty::TyGenerator(..) | ty::TyAdt(..) | - ty::TyDynamic(..) | + // FIXME(eddyb) producing readable type names for trait objects can result + // in problematically distinct types due to HRTB and subtyping (see #47638). + // ty::TyDynamic(..) | ty::TyForeign(..) | ty::TyStr => { let mut name = String::with_capacity(32); diff --git a/src/libstd/io/error.rs b/src/libstd/io/error.rs index f0b41f30251e0..bdd675e6e2b85 100644 --- a/src/libstd/io/error.rs +++ b/src/libstd/io/error.rs @@ -292,8 +292,8 @@ impl Error { /// # if cfg!(target_os = "linux") { /// use std::io; /// - /// let error = io::Error::from_raw_os_error(98); - /// assert_eq!(error.kind(), io::ErrorKind::AddrInUse); + /// let error = io::Error::from_raw_os_error(22); + /// assert_eq!(error.kind(), io::ErrorKind::InvalidInput); /// # } /// ``` /// @@ -303,8 +303,8 @@ impl Error { /// # if cfg!(windows) { /// use std::io; /// - /// let error = io::Error::from_raw_os_error(10048); - /// assert_eq!(error.kind(), io::ErrorKind::AddrInUse); + /// let error = io::Error::from_raw_os_error(10022); + /// assert_eq!(error.kind(), io::ErrorKind::InvalidInput); /// # } /// ``` #[stable(feature = "rust1", since = "1.0.0")] diff --git a/src/rustllvm/PassWrapper.cpp b/src/rustllvm/PassWrapper.cpp index b2f1229891d26..06d1301d70003 100644 --- a/src/rustllvm/PassWrapper.cpp +++ b/src/rustllvm/PassWrapper.cpp @@ -836,6 +836,10 @@ struct LLVMRustThinLTOData { StringMap ImportLists; StringMap ExportLists; StringMap ModuleToDefinedGVSummaries; + +#if LLVM_VERSION_GE(7, 0) + LLVMRustThinLTOData() : Index(/* isPerformingAnalysis = */ false) {} +#endif }; // Just an argument to the `LLVMRustCreateThinLTOData` function below. @@ -918,7 +922,14 @@ LLVMRustCreateThinLTOData(LLVMRustThinLTOModule *modules, // // This is copied from `lib/LTO/ThinLTOCodeGenerator.cpp` #if LLVM_VERSION_GE(5, 0) +#if LLVM_VERSION_GE(7, 0) + auto deadIsPrevailing = [&](GlobalValue::GUID G) { + return PrevailingType::Unknown; + }; + computeDeadSymbols(Ret->Index, Ret->GUIDPreservedSymbols, deadIsPrevailing); +#else computeDeadSymbols(Ret->Index, Ret->GUIDPreservedSymbols); +#endif ComputeCrossModuleImport( Ret->Index, Ret->ModuleToDefinedGVSummaries, diff --git a/src/test/codegen/function-arguments.rs b/src/test/codegen/function-arguments.rs index f8945a6ee8d93..0e98d3f9050a8 100644 --- a/src/test/codegen/function-arguments.rs +++ b/src/test/codegen/function-arguments.rs @@ -122,13 +122,13 @@ pub fn unsafe_slice(_: &[UnsafeInner]) { pub fn str(_: &[u8]) { } -// CHECK: @trait_borrow(%"core::ops::drop::Drop"* nonnull %arg0.0, {}* noalias nonnull readonly %arg0.1) +// CHECK: @trait_borrow({}* nonnull %arg0.0, {}* noalias nonnull readonly %arg0.1) // FIXME #25759 This should also have `nocapture` #[no_mangle] pub fn trait_borrow(_: &Drop) { } -// CHECK: @trait_box(%"core::ops::drop::Drop"* noalias nonnull, {}* noalias nonnull readonly) +// CHECK: @trait_box({}* noalias nonnull, {}* noalias nonnull readonly) #[no_mangle] pub fn trait_box(_: Box) { } diff --git a/src/test/compile-fail/associated-const-type-parameter-arms.rs b/src/test/compile-fail/associated-const-type-parameter-arms.rs index 52bb4a1b463b4..630a234fa6641 100644 --- a/src/test/compile-fail/associated-const-type-parameter-arms.rs +++ b/src/test/compile-fail/associated-const-type-parameter-arms.rs @@ -16,6 +16,7 @@ pub trait Foo { } struct Abc; + impl Foo for Abc { const X: EFoo = EFoo::B; } @@ -27,8 +28,10 @@ impl Foo for Def { pub fn test(arg: EFoo) { match arg { - A::X => println!("A::X"), //~ error: statics cannot be referenced in patterns [E0158] - B::X => println!("B::X"), //~ error: statics cannot be referenced in patterns [E0158] + A::X => println!("A::X"), + //~^ error: associated consts cannot be referenced in patterns [E0158] + B::X => println!("B::X"), + //~^ error: associated consts cannot be referenced in patterns [E0158] _ => (), } } diff --git a/src/test/run-make/stdin-non-utf8/Makefile b/src/test/run-make/stdin-non-utf8/Makefile new file mode 100644 index 0000000000000..7948c442616e3 --- /dev/null +++ b/src/test/run-make/stdin-non-utf8/Makefile @@ -0,0 +1,6 @@ +-include ../tools.mk + +all: + cp non-utf8 $(TMPDIR)/non-utf.rs + cat $(TMPDIR)/non-utf.rs | $(RUSTC) - 2>&1 \ + | $(CGREP) "error: couldn't read from stdin, as it did not contain valid UTF-8" diff --git a/src/test/run-make/stdin-non-utf8/non-utf8 b/src/test/run-make/stdin-non-utf8/non-utf8 new file mode 100644 index 0000000000000..bc87051a85299 --- /dev/null +++ b/src/test/run-make/stdin-non-utf8/non-utf8 @@ -0,0 +1 @@ +Ò diff --git a/src/test/run-pass/issue-47638.rs b/src/test/run-pass/issue-47638.rs new file mode 100644 index 0000000000000..6f627b2a3c137 --- /dev/null +++ b/src/test/run-pass/issue-47638.rs @@ -0,0 +1,18 @@ +// 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. + +fn id<'c, 'b>(f: &'c &'b Fn(&i32)) -> &'c &'b Fn(&'static i32) { + f +} + +fn main() { + let f: &Fn(&i32) = &|x| {}; + id(&f); +} diff --git a/src/test/run-pass/sse2.rs b/src/test/run-pass/sse2.rs index c2414e5ff5d96..22469b2fde058 100644 --- a/src/test/run-pass/sse2.rs +++ b/src/test/run-pass/sse2.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// min-llvm-version 4.0 +// no-system-llvm -- needs MCSubtargetInfo::getFeatureTable() // ignore-cloudabi no std::env #![feature(cfg_target_feature)] diff --git a/src/test/ui/blind-item-item-shadow.stderr b/src/test/ui/blind-item-item-shadow.stderr index 855b3799eb5db..d3588be266975 100644 --- a/src/test/ui/blind-item-item-shadow.stderr +++ b/src/test/ui/blind-item-item-shadow.stderr @@ -10,8 +10,8 @@ error[E0255]: the name `foo` is defined multiple times = note: `foo` must be defined only once in the type namespace of this module help: You can use `as` to change the binding name of the import | -13 | use foo::foo as Otherfoo; - | ^^^^^^^^^^^^^^^^^^^^ +13 | use foo::foo as other_foo; + | ^^^^^^^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/double-import.stderr b/src/test/ui/double-import.stderr index fcd3f2696f200..2a0f9ee34f2be 100644 --- a/src/test/ui/double-import.stderr +++ b/src/test/ui/double-import.stderr @@ -9,8 +9,8 @@ error[E0252]: the name `foo` is defined multiple times = note: `foo` must be defined only once in the value namespace of this module help: You can use `as` to change the binding name of the import | -23 | use sub2::foo as Otherfoo; //~ ERROR the name `foo` is defined multiple times - | ^^^^^^^^^^^^^^^^^^^^^ +23 | use sub2::foo as other_foo; //~ ERROR the name `foo` is defined multiple times + | ^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/imports/duplicate.stderr b/src/test/ui/imports/duplicate.stderr index a74401314a18c..6e5b91a11c900 100644 --- a/src/test/ui/imports/duplicate.stderr +++ b/src/test/ui/imports/duplicate.stderr @@ -9,8 +9,8 @@ error[E0252]: the name `foo` is defined multiple times = note: `foo` must be defined only once in the value namespace of this module help: You can use `as` to change the binding name of the import | -25 | use a::foo as Otherfoo; //~ ERROR the name `foo` is defined multiple times - | ^^^^^^^^^^^^^^^^^^ +25 | use a::foo as other_foo; //~ ERROR the name `foo` is defined multiple times + | ^^^^^^^^^^^^^^^^^^^ error[E0659]: `foo` is ambiguous --> $DIR/duplicate.rs:56:9 diff --git a/src/test/ui/issue-26886.stderr b/src/test/ui/issue-26886.stderr index cb2eca87068f8..e6424e535ee32 100644 --- a/src/test/ui/issue-26886.stderr +++ b/src/test/ui/issue-26886.stderr @@ -24,8 +24,8 @@ error[E0252]: the name `sync` is defined multiple times = note: `sync` must be defined only once in the type namespace of this module help: You can use `as` to change the binding name of the import | -14 | use std::sync as Othersync; //~ ERROR the name `sync` is defined multiple times - | ^^^^^^^^^^^^^^^^^^^^^^ +14 | use std::sync as other_sync; //~ ERROR the name `sync` is defined multiple times + | ^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 2 previous errors diff --git a/src/test/ui/issue-47706-trait.rs b/src/test/ui/issue-47706-trait.rs new file mode 100644 index 0000000000000..86a9da49a054a --- /dev/null +++ b/src/test/ui/issue-47706-trait.rs @@ -0,0 +1,16 @@ +// 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. + +trait T { + fn f(&self, _: ()) { + None::<()>.map(Self::f); + } + //~^^ ERROR function is expected to take a single 0-tuple as argument +} diff --git a/src/test/ui/issue-47706-trait.stderr b/src/test/ui/issue-47706-trait.stderr new file mode 100644 index 0000000000000..320e98dee4acf --- /dev/null +++ b/src/test/ui/issue-47706-trait.stderr @@ -0,0 +1,12 @@ +error[E0601]: main function not found + +error[E0593]: function is expected to take a single 0-tuple as argument, but it takes 2 distinct arguments + --> $DIR/issue-47706-trait.rs:13:20 + | +12 | fn f(&self, _: ()) { + | ------------------ takes 2 distinct arguments +13 | None::<()>.map(Self::f); + | ^^^ expected function that takes a single 0-tuple as argument + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/resolve-conflict-item-vs-import.stderr b/src/test/ui/resolve-conflict-item-vs-import.stderr index 03ef66681e440..e2245b8a8b10a 100644 --- a/src/test/ui/resolve-conflict-item-vs-import.stderr +++ b/src/test/ui/resolve-conflict-item-vs-import.stderr @@ -10,8 +10,8 @@ error[E0255]: the name `transmute` is defined multiple times = note: `transmute` must be defined only once in the value namespace of this module help: You can use `as` to change the binding name of the import | -11 | use std::mem::transmute as Othertransmute; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +11 | use std::mem::transmute as other_transmute; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/suggestions/issue-45799-bad-extern-crate-rename-suggestion-formatting.stderr b/src/test/ui/suggestions/issue-45799-bad-extern-crate-rename-suggestion-formatting.stderr index d2ac15f7ffcb3..01dba62a8511d 100644 --- a/src/test/ui/suggestions/issue-45799-bad-extern-crate-rename-suggestion-formatting.stderr +++ b/src/test/ui/suggestions/issue-45799-bad-extern-crate-rename-suggestion-formatting.stderr @@ -7,7 +7,7 @@ error[E0259]: the name `std` is defined multiple times = note: `std` must be defined only once in the type namespace of this module help: You can use `as` to change the binding name of the import | -11 | extern crate std as Otherstd; +11 | extern crate std as other_std; | error: aborting due to previous error diff --git a/src/test/ui/use-mod.stderr b/src/test/ui/use-mod.stderr index bb64909e64a0c..1c9f306f493db 100644 --- a/src/test/ui/use-mod.stderr +++ b/src/test/ui/use-mod.stderr @@ -25,7 +25,7 @@ error[E0252]: the name `bar` is defined multiple times = note: `bar` must be defined only once in the type namespace of this module help: You can use `as` to change the binding name of the import | -15 | self as Otherbar +15 | self as other_bar | error: aborting due to 3 previous errors