Auto merge of #47900 - kennytm:rollup, r=kennytm
Rollup of 16 pull requests - Successful merges: #47838, #47840, #47844, #47874, #47875, #47876, #47884, #47886, #47889, #47890, #47891, #47795, #47677, #47893, #47895, #47552 - Failed merges:
This commit is contained in:
commit
8ccab7eed5
43 changed files with 320 additions and 48 deletions
|
|
@ -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.
|
||||
///
|
||||
|
|
|
|||
|
|
@ -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() {
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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<T: Debug> Debug for [T] {
|
|||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl Debug for () {
|
||||
#[inline]
|
||||
fn fmt(&self, f: &mut Formatter) -> Result {
|
||||
f.pad("()")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<I> Iterator for StepBy<I> where I: Iterator {
|
|||
(f(inner_hint.0), inner_hint.1.map(f))
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn nth(&mut self, mut n: usize) -> Option<Self::Item> {
|
||||
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.
|
||||
|
|
|
|||
|
|
@ -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<Self::Item> { Some(21) }
|
||||
fn nth(&mut self, n: usize) -> Option<Self::Item> {
|
||||
self.0 += n as Bigger + 1;
|
||||
Some(42)
|
||||
}
|
||||
}
|
||||
|
||||
let mut it = Test(0);
|
||||
let root = usize::MAX >> (::std::mem::size_of::<usize>() * 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() {
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -343,6 +343,7 @@ define_maps! { <'tcx>
|
|||
-> (Arc<DefIdSet>, Arc<Vec<Arc<CodegenUnit<'tcx>>>>),
|
||||
[] fn export_name: ExportName(DefId) -> Option<Symbol>,
|
||||
[] 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<CodegenUnit<'tcx>>,
|
||||
[] fn compile_codegen_unit: CompileCodegenUnit(InternedString) -> Stats,
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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( )
|
||||
}
|
||||
})
|
||||
|
|
|
|||
|
|
@ -83,6 +83,9 @@ pub fn target() -> Result<Target, String> {
|
|||
// performing LTO with compiler-builtins.
|
||||
no_builtins: true,
|
||||
|
||||
// no dynamic linking, no need for default visibility!
|
||||
default_hidden_visibility: true,
|
||||
|
||||
.. Default::default()
|
||||
};
|
||||
Ok(Target {
|
||||
|
|
|
|||
|
|
@ -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> {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -290,7 +290,7 @@ fn get_trans_sysroot(backend_name: &str) -> fn() -> Box<TransCrate> {
|
|||
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());
|
||||
|
|
@ -457,10 +457,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),
|
||||
},
|
||||
};
|
||||
|
|
@ -471,6 +474,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));
|
||||
|
|
@ -513,17 +523,22 @@ fn make_output(matches: &getopts::Matches) -> (Option<PathBuf>, Option<PathBuf>)
|
|||
}
|
||||
|
||||
// Extract input (string or file and optional path) from matches.
|
||||
fn make_input(free_matches: &[String]) -> Option<(Input, Option<PathBuf>)> {
|
||||
fn make_input(free_matches: &[String]) -> Option<(Input, Option<PathBuf>, Option<io::Error>)> {
|
||||
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
|
||||
|
|
|
|||
|
|
@ -290,6 +290,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(),
|
||||
|
|
|
|||
|
|
@ -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
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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(),
|
||||
|
|
|
|||
|
|
@ -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 =
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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")]
|
||||
|
|
|
|||
|
|
@ -836,6 +836,10 @@ struct LLVMRustThinLTOData {
|
|||
StringMap<FunctionImporter::ImportMapTy> ImportLists;
|
||||
StringMap<FunctionImporter::ExportSetTy> ExportLists;
|
||||
StringMap<GVSummaryMapTy> 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,
|
||||
|
|
|
|||
|
|
@ -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<Drop>) {
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<A: Foo, B: Foo>(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]
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
|
|
|
|||
6
src/test/run-make/stdin-non-utf8/Makefile
Normal file
6
src/test/run-make/stdin-non-utf8/Makefile
Normal file
|
|
@ -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"
|
||||
1
src/test/run-make/stdin-non-utf8/non-utf8
Normal file
1
src/test/run-make/stdin-non-utf8/non-utf8
Normal file
|
|
@ -0,0 +1 @@
|
|||
<EFBFBD>
|
||||
18
src/test/run-pass/issue-47638.rs
Normal file
18
src/test/run-pass/issue-47638.rs
Normal file
|
|
@ -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 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
fn id<'c, 'b>(f: &'c &'b Fn(&i32)) -> &'c &'b Fn(&'static i32) {
|
||||
f
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let f: &Fn(&i32) = &|x| {};
|
||||
id(&f);
|
||||
}
|
||||
|
|
@ -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)]
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
16
src/test/ui/issue-47706-trait.rs
Normal file
16
src/test/ui/issue-47706-trait.rs
Normal file
|
|
@ -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 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
trait T {
|
||||
fn f(&self, _: ()) {
|
||||
None::<()>.map(Self::f);
|
||||
}
|
||||
//~^^ ERROR function is expected to take a single 0-tuple as argument
|
||||
}
|
||||
12
src/test/ui/issue-47706-trait.stderr
Normal file
12
src/test/ui/issue-47706-trait.stderr
Normal file
|
|
@ -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
|
||||
|
||||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue