From cbe9f33b8bb94b262f91bc8c6f61a7f6518164b4 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Tue, 9 Oct 2018 23:10:25 -0700 Subject: std: Implement TLS for wasm32-unknown-unknown This adds an implementation of thread local storage for the `wasm32-unknown-unknown` target when the `atomics` feature is implemented. This, however, comes with a notable caveat of that it requires a new feature of the standard library, `wasm-bindgen-threads`, to be enabled. Thread local storage for wasm (when `atomics` are enabled and there's actually more than one thread) is powered by the assumption that an external entity can fill in some information for us. It's not currently clear who will fill in this information nor whose responsibility it should be long-term. In the meantime there's a strategy being gamed out in the `wasm-bindgen` project specifically, and the hope is that we can continue to test and iterate on the standard library without committing to a particular strategy yet. As to the details of `wasm-bindgen`'s strategy, LLVM doesn't currently have the ability to emit custom `global` values (thread locals in a `WebAssembly.Module`) so we leverage the `wasm-bindgen` CLI tool to do it for us. To that end we have a few intrinsics, assuming two global values: * `__wbindgen_current_id` - gets the current thread id as a 32-bit integer. It's `wasm-bindgen`'s responsibility to initialize this per-thread and then inform libstd of the id. Currently `wasm-bindgen` performs this initialization as part of the `start` function. * `__wbindgen_tcb_{get,set}` - in addition to a thread id it's assumed that there's a global available for simply storing a pointer's worth of information (a thread control block, which currently only contains thread local storage). This would ideally be a native `global` injected by LLVM, but we don't have a great way to support that right now. To reiterate, this is all intended to be unstable and purely intended for testing out Rust on the web with threads. The story is very likely to change in the future and we want to make sure that we're able to do that! --- src/libstd/Cargo.toml | 9 +++++ src/libstd/sys/wasm/mutex_atomics.rs | 23 ++++++------- src/libstd/sys/wasm/thread.rs | 46 +++++++++++++++++++++++++ src/libstd/sys/wasm/thread_local_atomics.rs | 53 +++++++++++++++++++++++++---- src/libstd/thread/local.rs | 14 +++++--- src/libstd/thread/mod.rs | 2 +- 6 files changed, 122 insertions(+), 25 deletions(-) (limited to 'src') diff --git a/src/libstd/Cargo.toml b/src/libstd/Cargo.toml index bcdd1b4b088..cd1e3438fc3 100644 --- a/src/libstd/Cargo.toml +++ b/src/libstd/Cargo.toml @@ -48,4 +48,13 @@ jemalloc = ["alloc_jemalloc"] force_alloc_system = [] panic-unwind = ["panic_unwind"] profiler = ["profiler_builtins"] + +# An off-by-default feature which enables a linux-syscall-like ABI for libstd to +# interoperate with the host environment. Currently not well documented and +# requires rebuilding the standard library to use it. wasm_syscall = [] + +# An off-by-default features to enable libstd to assume that wasm-bindgen is in +# the environment for hooking up some thread-related information like the +# current thread id and accessing/getting the current thread's TCB +wasm-bindgen-threads = [] diff --git a/src/libstd/sys/wasm/mutex_atomics.rs b/src/libstd/sys/wasm/mutex_atomics.rs index ced6c17ef96..762e807096f 100644 --- a/src/libstd/sys/wasm/mutex_atomics.rs +++ b/src/libstd/sys/wasm/mutex_atomics.rs @@ -11,7 +11,8 @@ use arch::wasm32::atomic; use cell::UnsafeCell; use mem; -use sync::atomic::{AtomicUsize, AtomicU64, Ordering::SeqCst}; +use sync::atomic::{AtomicUsize, AtomicU32, Ordering::SeqCst}; +use sys::thread; pub struct Mutex { locked: AtomicUsize, @@ -70,7 +71,7 @@ impl Mutex { } pub struct ReentrantMutex { - owner: AtomicU64, + owner: AtomicU32, recursions: UnsafeCell, } @@ -91,7 +92,7 @@ unsafe impl Sync for ReentrantMutex {} impl ReentrantMutex { pub unsafe fn uninitialized() -> ReentrantMutex { ReentrantMutex { - owner: AtomicU64::new(0), + owner: AtomicU32::new(0), recursions: UnsafeCell::new(0), } } @@ -101,20 +102,20 @@ impl ReentrantMutex { } pub unsafe fn lock(&self) { - let me = thread_id(); + let me = thread::my_id(); while let Err(owner) = self._try_lock(me) { - let val = atomic::wait_i64(self.ptr(), owner as i64, -1); + let val = atomic::wait_i32(self.ptr(), owner as i32, -1); debug_assert!(val == 0 || val == 1); } } #[inline] pub unsafe fn try_lock(&self) -> bool { - self._try_lock(thread_id()).is_ok() + self._try_lock(thread::my_id()).is_ok() } #[inline] - unsafe fn _try_lock(&self, id: u64) -> Result<(), u64> { + unsafe fn _try_lock(&self, id: u32) -> Result<(), u32> { let id = id.checked_add(1).unwrap(); // make sure `id` isn't 0 match self.owner.compare_exchange(0, id, SeqCst, SeqCst) { // we transitioned from unlocked to locked @@ -153,11 +154,7 @@ impl ReentrantMutex { } #[inline] - fn ptr(&self) -> *mut i64 { - &self.owner as *const AtomicU64 as *mut i64 + fn ptr(&self) -> *mut i32 { + &self.owner as *const AtomicU32 as *mut i32 } } - -fn thread_id() -> u64 { - panic!("thread ids not implemented on wasm with atomics yet") -} diff --git a/src/libstd/sys/wasm/thread.rs b/src/libstd/sys/wasm/thread.rs index bef6c1f3490..4ad89c42b92 100644 --- a/src/libstd/sys/wasm/thread.rs +++ b/src/libstd/sys/wasm/thread.rs @@ -69,3 +69,49 @@ pub mod guard { pub unsafe fn init() -> Option { None } pub unsafe fn deinit() {} } + +cfg_if! { + if #[cfg(all(target_feature = "atomics", feature = "wasm-bindgen-threads"))] { + #[link(wasm_import_module = "__wbindgen_thread_xform__")] + extern { + fn __wbindgen_current_id() -> u32; + fn __wbindgen_tcb_get() -> u32; + fn __wbindgen_tcb_set(ptr: u32); + } + pub fn my_id() -> u32 { + unsafe { __wbindgen_current_id() } + } + + // These are currently only ever used in `thread_local_atomics.rs`, if + // you'd like to use them be sure to update that and make sure everyone + // agrees what's what. + pub fn tcb_get() -> *mut u8 { + use mem; + assert_eq!(mem::size_of::<*mut u8>(), mem::size_of::()); + unsafe { __wbindgen_tcb_get() as *mut u8 } + } + + pub fn tcb_set(ptr: *mut u8) { + unsafe { __wbindgen_tcb_set(ptr as u32); } + } + + // FIXME: still need something for hooking exiting a thread to free + // data... + + } else if #[cfg(target_feature = "atomics")] { + pub fn my_id() -> u32 { + panic!("thread ids not implemented on wasm with atomics yet") + } + + pub fn tcb_get() -> *mut u8 { + panic!("thread local data not implemented on wasm with atomics yet") + } + + pub fn tcb_set(ptr: *mut u8) { + panic!("thread local data not implemented on wasm with atomics yet") + } + } else { + // stubbed out because no functions actually access these intrinsics + // unless atomics are enabled + } +} diff --git a/src/libstd/sys/wasm/thread_local_atomics.rs b/src/libstd/sys/wasm/thread_local_atomics.rs index 1394013b4a3..acfe60719f2 100644 --- a/src/libstd/sys/wasm/thread_local_atomics.rs +++ b/src/libstd/sys/wasm/thread_local_atomics.rs @@ -8,22 +8,61 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use sys::thread; +use sync::atomic::{AtomicUsize, Ordering::SeqCst}; + +const MAX_KEYS: usize = 128; +static NEXT_KEY: AtomicUsize = AtomicUsize::new(0); + +struct ThreadControlBlock { + keys: [*mut u8; MAX_KEYS], +} + +impl ThreadControlBlock { + fn new() -> ThreadControlBlock { + ThreadControlBlock { + keys: [0 as *mut u8; MAX_KEYS], + } + } + + fn get() -> *mut ThreadControlBlock { + let ptr = thread::tcb_get(); + if !ptr.is_null() { + return ptr as *mut ThreadControlBlock + } + let tcb = Box::into_raw(Box::new(ThreadControlBlock::new())); + thread::tcb_set(tcb as *mut u8); + tcb + } +} + pub type Key = usize; -pub unsafe fn create(_dtor: Option) -> Key { - panic!("TLS on wasm with atomics not implemented yet"); +pub unsafe fn create(dtor: Option) -> Key { + drop(dtor); // FIXME: need to figure out how to hook thread exit to run this + let key = NEXT_KEY.fetch_add(1, SeqCst); + if key >= MAX_KEYS { + NEXT_KEY.store(MAX_KEYS, SeqCst); + panic!("cannot allocate space for more TLS keys"); + } + // offset by 1 so we never hand out 0. This is currently required by + // `sys_common/thread_local.rs` where it can't cope with keys of value 0 + // because it messes up the atomic management. + return key + 1 } -pub unsafe fn set(_key: Key, _value: *mut u8) { - panic!("TLS on wasm with atomics not implemented yet"); +pub unsafe fn set(key: Key, value: *mut u8) { + (*ThreadControlBlock::get()).keys[key - 1] = value; } -pub unsafe fn get(_key: Key) -> *mut u8 { - panic!("TLS on wasm with atomics not implemented yet"); +pub unsafe fn get(key: Key) -> *mut u8 { + (*ThreadControlBlock::get()).keys[key - 1] } pub unsafe fn destroy(_key: Key) { - panic!("TLS on wasm with atomics not implemented yet"); + // FIXME: should implement this somehow, this isn't typically called but it + // can be called if two threads race to initialize a TLS slot and one ends + // up not being needed. } #[inline] diff --git a/src/libstd/thread/local.rs b/src/libstd/thread/local.rs index a170abb2628..59f100fad1b 100644 --- a/src/libstd/thread/local.rs +++ b/src/libstd/thread/local.rs @@ -172,16 +172,22 @@ macro_rules! __thread_local_inner { &'static $crate::cell::UnsafeCell< $crate::option::Option<$t>>> { - #[cfg(target_arch = "wasm32")] + #[cfg(all(target_arch = "wasm32", not(target_feature = "atomics")))] static __KEY: $crate::thread::__StaticLocalKeyInner<$t> = $crate::thread::__StaticLocalKeyInner::new(); #[thread_local] - #[cfg(all(target_thread_local, not(target_arch = "wasm32")))] + #[cfg(all( + target_thread_local, + not(all(target_arch = "wasm32", not(target_feature = "atomics"))), + ))] static __KEY: $crate::thread::__FastLocalKeyInner<$t> = $crate::thread::__FastLocalKeyInner::new(); - #[cfg(all(not(target_thread_local), not(target_arch = "wasm32")))] + #[cfg(all( + not(target_thread_local), + not(all(target_arch = "wasm32", not(target_feature = "atomics"))), + ))] static __KEY: $crate::thread::__OsLocalKeyInner<$t> = $crate::thread::__OsLocalKeyInner::new(); @@ -302,7 +308,7 @@ impl LocalKey { /// On some platforms like wasm32 there's no threads, so no need to generate /// thread locals and we can instead just use plain statics! #[doc(hidden)] -#[cfg(target_arch = "wasm32")] +#[cfg(all(target_arch = "wasm32", not(target_feature = "atomics")))] pub mod statik { use cell::UnsafeCell; use fmt; diff --git a/src/libstd/thread/mod.rs b/src/libstd/thread/mod.rs index c8d54a63946..796b2bd3eed 100644 --- a/src/libstd/thread/mod.rs +++ b/src/libstd/thread/mod.rs @@ -203,7 +203,7 @@ pub use self::local::{LocalKey, AccessError}; // where available, but both are needed. #[unstable(feature = "libstd_thread_internals", issue = "0")] -#[cfg(target_arch = "wasm32")] +#[cfg(all(target_arch = "wasm32", not(target_feature = "atomics")))] #[doc(hidden)] pub use self::local::statik::Key as __StaticLocalKeyInner; #[unstable(feature = "libstd_thread_internals", issue = "0")] #[cfg(target_thread_local)] -- cgit 1.4.1-3-g733a5 From 2ecce7ccc5d74eb3d6b0ff400b2a19944e2ae51a Mon Sep 17 00:00:00 2001 From: David Wood Date: Thu, 11 Oct 2018 19:36:51 +0200 Subject: Extend lang items to assert correct target. This commit extends the existing lang items functionality to assert that the `#[lang_item]` attribute is only found on the appropriate item for any given lang item. That is, language items representing traits must only ever have their corresponding attribute placed on a trait, for example. --- src/librustc/diagnostics.rs | 18 +- src/librustc/hir/check_attr.rs | 74 +++-- src/librustc/middle/lang_items.rs | 304 +++++++++++---------- src/test/ui/error-codes/E0152.rs | 2 +- src/test/ui/error-codes/E0152.stderr | 4 +- src/test/ui/error-codes/E0718.rs | 17 ++ src/test/ui/error-codes/E0718.stderr | 9 + .../panic-handler/panic-handler-wrong-location.rs | 18 ++ .../panic-handler-wrong-location.stderr | 11 + 9 files changed, 295 insertions(+), 162 deletions(-) create mode 100644 src/test/ui/error-codes/E0718.rs create mode 100644 src/test/ui/error-codes/E0718.stderr create mode 100644 src/test/ui/panic-handler/panic-handler-wrong-location.rs create mode 100644 src/test/ui/panic-handler/panic-handler-wrong-location.stderr (limited to 'src') diff --git a/src/librustc/diagnostics.rs b/src/librustc/diagnostics.rs index 84afdd53cf4..1d21a5cf79d 100644 --- a/src/librustc/diagnostics.rs +++ b/src/librustc/diagnostics.rs @@ -637,8 +637,8 @@ Erroneous code example: ```compile_fail,E0152 #![feature(lang_items)] -#[lang = "panic_impl"] -struct Foo; // error: duplicate lang item found: `panic_impl` +#[lang = "arc"] +struct Foo; // error: duplicate lang item found: `arc` ``` Lang items are already implemented in the standard library. Unless you are @@ -2116,6 +2116,20 @@ struct Foo; ``` "##, +E0718: r##" +This error indicates that a `#[lang = ".."]` attribute was placed +on the wrong type of item. + +Examples of erroneous code: + +```compile_fail,E0718 +#![feature(lang_items)] + +#[lang = "arc"] +static X: u32 = 42; +``` +"##, + } diff --git a/src/librustc/hir/check_attr.rs b/src/librustc/hir/check_attr.rs index b23a50ef1a4..020012d756a 100644 --- a/src/librustc/hir/check_attr.rs +++ b/src/librustc/hir/check_attr.rs @@ -14,40 +14,80 @@ //! conflicts between multiple such attributes attached to the same //! item. -use syntax_pos::Span; -use ty::TyCtxt; - use hir; use hir::intravisit::{self, Visitor, NestedVisitorMap}; +use ty::TyCtxt; +use std::fmt::{self, Display}; +use syntax_pos::Span; #[derive(Copy, Clone, PartialEq)] -enum Target { +pub(crate) enum Target { + ExternCrate, + Use, + Static, + Const, Fn, + Closure, + Mod, + ForeignMod, + GlobalAsm, + Ty, + Existential, + Enum, Struct, Union, - Enum, - Const, - ForeignMod, + Trait, + TraitAlias, + Impl, Expression, Statement, - Closure, - Static, - Trait, - Other, +} + +impl Display for Target { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{}", match *self { + Target::ExternCrate => "extern crate", + Target::Use => "use", + Target::Static => "static item", + Target::Const => "constant item", + Target::Fn => "function", + Target::Closure => "closure", + Target::Mod => "module", + Target::ForeignMod => "foreign module", + Target::GlobalAsm => "global asm", + Target::Ty => "type alias", + Target::Existential => "existential type", + Target::Enum => "enum", + Target::Struct => "struct", + Target::Union => "union", + Target::Trait => "trait", + Target::TraitAlias => "trait alias", + Target::Impl => "item", + Target::Expression => "expression", + Target::Statement => "statement", + }) + } } impl Target { - fn from_item(item: &hir::Item) -> Target { + pub(crate) fn from_item(item: &hir::Item) -> Target { match item.node { + hir::ItemKind::ExternCrate(..) => Target::ExternCrate, + hir::ItemKind::Use(..) => Target::Use, + hir::ItemKind::Static(..) => Target::Static, + hir::ItemKind::Const(..) => Target::Const, hir::ItemKind::Fn(..) => Target::Fn, + hir::ItemKind::Mod(..) => Target::Mod, + hir::ItemKind::ForeignMod(..) => Target::ForeignMod, + hir::ItemKind::GlobalAsm(..) => Target::GlobalAsm, + hir::ItemKind::Ty(..) => Target::Ty, + hir::ItemKind::Existential(..) => Target::Existential, + hir::ItemKind::Enum(..) => Target::Enum, hir::ItemKind::Struct(..) => Target::Struct, hir::ItemKind::Union(..) => Target::Union, - hir::ItemKind::Enum(..) => Target::Enum, - hir::ItemKind::Const(..) => Target::Const, - hir::ItemKind::ForeignMod(..) => Target::ForeignMod, - hir::ItemKind::Static(..) => Target::Static, hir::ItemKind::Trait(..) => Target::Trait, - _ => Target::Other, + hir::ItemKind::TraitAlias(..) => Target::TraitAlias, + hir::ItemKind::Impl(..) => Target::Impl, } } } diff --git a/src/librustc/middle/lang_items.rs b/src/librustc/middle/lang_items.rs index 0bd816b3e55..c5d028c1735 100644 --- a/src/librustc/middle/lang_items.rs +++ b/src/librustc/middle/lang_items.rs @@ -22,6 +22,7 @@ pub use self::LangItem::*; use hir::def_id::DefId; +use hir::check_attr::Target; use ty::{self, TyCtxt}; use middle::weak_lang_items; use util::nodemap::FxHashMap; @@ -36,7 +37,7 @@ use hir; // So you probably just want to nip down to the end. macro_rules! language_item_table { ( - $( $variant:ident, $name:expr, $method:ident; )* + $( $variant:ident, $name:expr, $method:ident, $target:path; )* ) => { enum_from_u32! { @@ -96,26 +97,49 @@ impl LanguageItems { struct LanguageItemCollector<'a, 'tcx: 'a> { items: LanguageItems, - tcx: TyCtxt<'a, 'tcx, 'tcx>, - - item_refs: FxHashMap<&'static str, usize>, + item_refs: FxHashMap<&'static str, (usize, Target)>, } impl<'a, 'v, 'tcx> ItemLikeVisitor<'v> for LanguageItemCollector<'a, 'tcx> { fn visit_item(&mut self, item: &hir::Item) { if let Some((value, span)) = extract(&item.attrs) { - let item_index = self.item_refs.get(&*value.as_str()).cloned(); - - if let Some(item_index) = item_index { - let def_id = self.tcx.hir.local_def_id(item.id); - self.collect_item(item_index, def_id); - } else { - let mut err = struct_span_err!(self.tcx.sess, span, E0522, - "definition of an unknown language item: `{}`", - value); - err.span_label(span, format!("definition of unknown language item `{}`", value)); - err.emit(); + let actual_target = Target::from_item(item); + match self.item_refs.get(&*value.as_str()).cloned() { + // Known lang item with attribute on correct target. + Some((item_index, expected_target)) if actual_target == expected_target => { + let def_id = self.tcx.hir.local_def_id(item.id); + self.collect_item(item_index, def_id); + }, + // Known lang item with attribute on incorrect target. + Some((_, expected_target)) => { + let mut err = struct_span_err!( + self.tcx.sess, span, E0718, + "`{}` language item must be applied to a {}", + value, expected_target, + ); + err.span_label( + span, + format!( + "attribute should be applied to a {}, not a {}", + expected_target, actual_target, + ), + ); + err.emit(); + }, + // Unknown lang item. + _ => { + let mut err = struct_span_err!( + self.tcx.sess, span, E0522, + "definition of an unknown language item: `{}`", + value + ); + err.span_label( + span, + format!("definition of unknown language item `{}`", value) + ); + err.emit(); + }, } } } @@ -133,7 +157,7 @@ impl<'a, 'tcx> LanguageItemCollector<'a, 'tcx> { fn new(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> LanguageItemCollector<'a, 'tcx> { let mut item_refs = FxHashMap(); - $( item_refs.insert($name, $variant as usize); )* + $( item_refs.insert($name, ($variant as usize, $target)); )* LanguageItemCollector { tcx, @@ -210,84 +234,84 @@ pub fn collect<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> LanguageItems { } language_item_table! { -// Variant name, Name, Method name; - CharImplItem, "char", char_impl; - StrImplItem, "str", str_impl; - SliceImplItem, "slice", slice_impl; - SliceU8ImplItem, "slice_u8", slice_u8_impl; - StrAllocImplItem, "str_alloc", str_alloc_impl; - SliceAllocImplItem, "slice_alloc", slice_alloc_impl; - SliceU8AllocImplItem, "slice_u8_alloc", slice_u8_alloc_impl; - ConstPtrImplItem, "const_ptr", const_ptr_impl; - MutPtrImplItem, "mut_ptr", mut_ptr_impl; - I8ImplItem, "i8", i8_impl; - I16ImplItem, "i16", i16_impl; - I32ImplItem, "i32", i32_impl; - I64ImplItem, "i64", i64_impl; - I128ImplItem, "i128", i128_impl; - IsizeImplItem, "isize", isize_impl; - U8ImplItem, "u8", u8_impl; - U16ImplItem, "u16", u16_impl; - U32ImplItem, "u32", u32_impl; - U64ImplItem, "u64", u64_impl; - U128ImplItem, "u128", u128_impl; - UsizeImplItem, "usize", usize_impl; - F32ImplItem, "f32", f32_impl; - F64ImplItem, "f64", f64_impl; - F32RuntimeImplItem, "f32_runtime", f32_runtime_impl; - F64RuntimeImplItem, "f64_runtime", f64_runtime_impl; - - SizedTraitLangItem, "sized", sized_trait; - UnsizeTraitLangItem, "unsize", unsize_trait; - CopyTraitLangItem, "copy", copy_trait; - CloneTraitLangItem, "clone", clone_trait; - SyncTraitLangItem, "sync", sync_trait; - FreezeTraitLangItem, "freeze", freeze_trait; - - DropTraitLangItem, "drop", drop_trait; - - CoerceUnsizedTraitLangItem, "coerce_unsized", coerce_unsized_trait; - - AddTraitLangItem, "add", add_trait; - SubTraitLangItem, "sub", sub_trait; - MulTraitLangItem, "mul", mul_trait; - DivTraitLangItem, "div", div_trait; - RemTraitLangItem, "rem", rem_trait; - NegTraitLangItem, "neg", neg_trait; - NotTraitLangItem, "not", not_trait; - BitXorTraitLangItem, "bitxor", bitxor_trait; - BitAndTraitLangItem, "bitand", bitand_trait; - BitOrTraitLangItem, "bitor", bitor_trait; - ShlTraitLangItem, "shl", shl_trait; - ShrTraitLangItem, "shr", shr_trait; - AddAssignTraitLangItem, "add_assign", add_assign_trait; - SubAssignTraitLangItem, "sub_assign", sub_assign_trait; - MulAssignTraitLangItem, "mul_assign", mul_assign_trait; - DivAssignTraitLangItem, "div_assign", div_assign_trait; - RemAssignTraitLangItem, "rem_assign", rem_assign_trait; - BitXorAssignTraitLangItem, "bitxor_assign", bitxor_assign_trait; - BitAndAssignTraitLangItem, "bitand_assign", bitand_assign_trait; - BitOrAssignTraitLangItem, "bitor_assign", bitor_assign_trait; - ShlAssignTraitLangItem, "shl_assign", shl_assign_trait; - ShrAssignTraitLangItem, "shr_assign", shr_assign_trait; - IndexTraitLangItem, "index", index_trait; - IndexMutTraitLangItem, "index_mut", index_mut_trait; - - UnsafeCellTypeLangItem, "unsafe_cell", unsafe_cell_type; - - DerefTraitLangItem, "deref", deref_trait; - DerefMutTraitLangItem, "deref_mut", deref_mut_trait; - - FnTraitLangItem, "fn", fn_trait; - FnMutTraitLangItem, "fn_mut", fn_mut_trait; - FnOnceTraitLangItem, "fn_once", fn_once_trait; - - GeneratorStateLangItem, "generator_state", gen_state; - GeneratorTraitLangItem, "generator", gen_trait; - - EqTraitLangItem, "eq", eq_trait; - PartialOrdTraitLangItem, "partial_ord", partial_ord_trait; - OrdTraitLangItem, "ord", ord_trait; +// Variant name, Name, Method name, Target; + CharImplItem, "char", char_impl, Target::Impl; + StrImplItem, "str", str_impl, Target::Impl; + SliceImplItem, "slice", slice_impl, Target::Impl; + SliceU8ImplItem, "slice_u8", slice_u8_impl, Target::Impl; + StrAllocImplItem, "str_alloc", str_alloc_impl, Target::Impl; + SliceAllocImplItem, "slice_alloc", slice_alloc_impl, Target::Impl; + SliceU8AllocImplItem, "slice_u8_alloc", slice_u8_alloc_impl, Target::Impl; + ConstPtrImplItem, "const_ptr", const_ptr_impl, Target::Impl; + MutPtrImplItem, "mut_ptr", mut_ptr_impl, Target::Impl; + I8ImplItem, "i8", i8_impl, Target::Impl; + I16ImplItem, "i16", i16_impl, Target::Impl; + I32ImplItem, "i32", i32_impl, Target::Impl; + I64ImplItem, "i64", i64_impl, Target::Impl; + I128ImplItem, "i128", i128_impl, Target::Impl; + IsizeImplItem, "isize", isize_impl, Target::Impl; + U8ImplItem, "u8", u8_impl, Target::Impl; + U16ImplItem, "u16", u16_impl, Target::Impl; + U32ImplItem, "u32", u32_impl, Target::Impl; + U64ImplItem, "u64", u64_impl, Target::Impl; + U128ImplItem, "u128", u128_impl, Target::Impl; + UsizeImplItem, "usize", usize_impl, Target::Impl; + F32ImplItem, "f32", f32_impl, Target::Impl; + F64ImplItem, "f64", f64_impl, Target::Impl; + F32RuntimeImplItem, "f32_runtime", f32_runtime_impl, Target::Impl; + F64RuntimeImplItem, "f64_runtime", f64_runtime_impl, Target::Impl; + + SizedTraitLangItem, "sized", sized_trait, Target::Trait; + UnsizeTraitLangItem, "unsize", unsize_trait, Target::Trait; + CopyTraitLangItem, "copy", copy_trait, Target::Trait; + CloneTraitLangItem, "clone", clone_trait, Target::Trait; + SyncTraitLangItem, "sync", sync_trait, Target::Trait; + FreezeTraitLangItem, "freeze", freeze_trait, Target::Trait; + + DropTraitLangItem, "drop", drop_trait, Target::Trait; + + CoerceUnsizedTraitLangItem, "coerce_unsized", coerce_unsized_trait, Target::Trait; + + AddTraitLangItem, "add", add_trait, Target::Trait; + SubTraitLangItem, "sub", sub_trait, Target::Trait; + MulTraitLangItem, "mul", mul_trait, Target::Trait; + DivTraitLangItem, "div", div_trait, Target::Trait; + RemTraitLangItem, "rem", rem_trait, Target::Trait; + NegTraitLangItem, "neg", neg_trait, Target::Trait; + NotTraitLangItem, "not", not_trait, Target::Trait; + BitXorTraitLangItem, "bitxor", bitxor_trait, Target::Trait; + BitAndTraitLangItem, "bitand", bitand_trait, Target::Trait; + BitOrTraitLangItem, "bitor", bitor_trait, Target::Trait; + ShlTraitLangItem, "shl", shl_trait, Target::Trait; + ShrTraitLangItem, "shr", shr_trait, Target::Trait; + AddAssignTraitLangItem, "add_assign", add_assign_trait, Target::Trait; + SubAssignTraitLangItem, "sub_assign", sub_assign_trait, Target::Trait; + MulAssignTraitLangItem, "mul_assign", mul_assign_trait, Target::Trait; + DivAssignTraitLangItem, "div_assign", div_assign_trait, Target::Trait; + RemAssignTraitLangItem, "rem_assign", rem_assign_trait, Target::Trait; + BitXorAssignTraitLangItem, "bitxor_assign", bitxor_assign_trait, Target::Trait; + BitAndAssignTraitLangItem, "bitand_assign", bitand_assign_trait, Target::Trait; + BitOrAssignTraitLangItem, "bitor_assign", bitor_assign_trait, Target::Trait; + ShlAssignTraitLangItem, "shl_assign", shl_assign_trait, Target::Trait; + ShrAssignTraitLangItem, "shr_assign", shr_assign_trait, Target::Trait; + IndexTraitLangItem, "index", index_trait, Target::Trait; + IndexMutTraitLangItem, "index_mut", index_mut_trait, Target::Trait; + + UnsafeCellTypeLangItem, "unsafe_cell", unsafe_cell_type, Target::Struct; + + DerefTraitLangItem, "deref", deref_trait, Target::Trait; + DerefMutTraitLangItem, "deref_mut", deref_mut_trait, Target::Trait; + + FnTraitLangItem, "fn", fn_trait, Target::Trait; + FnMutTraitLangItem, "fn_mut", fn_mut_trait, Target::Trait; + FnOnceTraitLangItem, "fn_once", fn_once_trait, Target::Trait; + + GeneratorStateLangItem, "generator_state", gen_state, Target::Enum; + GeneratorTraitLangItem, "generator", gen_trait, Target::Trait; + + EqTraitLangItem, "eq", eq_trait, Target::Trait; + PartialOrdTraitLangItem, "partial_ord", partial_ord_trait, Target::Trait; + OrdTraitLangItem, "ord", ord_trait, Target::Trait; // A number of panic-related lang items. The `panic` item corresponds to // divide-by-zero and various panic cases with `match`. The @@ -298,68 +322,68 @@ language_item_table! { // defined to use it, but a final product is required to define it // somewhere. Additionally, there are restrictions on crates that use a weak // lang item, but do not have it defined. - PanicFnLangItem, "panic", panic_fn; - PanicBoundsCheckFnLangItem, "panic_bounds_check", panic_bounds_check_fn; - PanicInfoLangItem, "panic_info", panic_info; - PanicImplLangItem, "panic_impl", panic_impl; + PanicFnLangItem, "panic", panic_fn, Target::Fn; + PanicBoundsCheckFnLangItem, "panic_bounds_check", panic_bounds_check_fn, Target::Fn; + PanicInfoLangItem, "panic_info", panic_info, Target::Struct; + PanicImplLangItem, "panic_impl", panic_impl, Target::Fn; // Libstd panic entry point. Necessary for const eval to be able to catch it - BeginPanicFnLangItem, "begin_panic", begin_panic_fn; + BeginPanicFnLangItem, "begin_panic", begin_panic_fn, Target::Fn; - ExchangeMallocFnLangItem, "exchange_malloc", exchange_malloc_fn; - BoxFreeFnLangItem, "box_free", box_free_fn; - DropInPlaceFnLangItem, "drop_in_place", drop_in_place_fn; - OomLangItem, "oom", oom; - AllocLayoutLangItem, "alloc_layout", alloc_layout; + ExchangeMallocFnLangItem, "exchange_malloc", exchange_malloc_fn, Target::Fn; + BoxFreeFnLangItem, "box_free", box_free_fn, Target::Fn; + DropInPlaceFnLangItem, "drop_in_place", drop_in_place_fn, Target::Fn; + OomLangItem, "oom", oom, Target::Fn; + AllocLayoutLangItem, "alloc_layout", alloc_layout, Target::Struct; - StartFnLangItem, "start", start_fn; + StartFnLangItem, "start", start_fn, Target::Fn; - EhPersonalityLangItem, "eh_personality", eh_personality; - EhUnwindResumeLangItem, "eh_unwind_resume", eh_unwind_resume; - MSVCTryFilterLangItem, "msvc_try_filter", msvc_try_filter; + EhPersonalityLangItem, "eh_personality", eh_personality, Target::Fn; + EhUnwindResumeLangItem, "eh_unwind_resume", eh_unwind_resume, Target::Fn; + MSVCTryFilterLangItem, "msvc_try_filter", msvc_try_filter, Target::Static; - OwnedBoxLangItem, "owned_box", owned_box; + OwnedBoxLangItem, "owned_box", owned_box, Target::Struct; - PhantomDataItem, "phantom_data", phantom_data; + PhantomDataItem, "phantom_data", phantom_data, Target::Struct; - ManuallyDropItem, "manually_drop", manually_drop; + ManuallyDropItem, "manually_drop", manually_drop, Target::Struct; - DebugTraitLangItem, "debug_trait", debug_trait; + DebugTraitLangItem, "debug_trait", debug_trait, Target::Trait; // A lang item for each of the 128-bit operators we can optionally lower. - I128AddFnLangItem, "i128_add", i128_add_fn; - U128AddFnLangItem, "u128_add", u128_add_fn; - I128SubFnLangItem, "i128_sub", i128_sub_fn; - U128SubFnLangItem, "u128_sub", u128_sub_fn; - I128MulFnLangItem, "i128_mul", i128_mul_fn; - U128MulFnLangItem, "u128_mul", u128_mul_fn; - I128DivFnLangItem, "i128_div", i128_div_fn; - U128DivFnLangItem, "u128_div", u128_div_fn; - I128RemFnLangItem, "i128_rem", i128_rem_fn; - U128RemFnLangItem, "u128_rem", u128_rem_fn; - I128ShlFnLangItem, "i128_shl", i128_shl_fn; - U128ShlFnLangItem, "u128_shl", u128_shl_fn; - I128ShrFnLangItem, "i128_shr", i128_shr_fn; - U128ShrFnLangItem, "u128_shr", u128_shr_fn; + I128AddFnLangItem, "i128_add", i128_add_fn, Target::Fn; + U128AddFnLangItem, "u128_add", u128_add_fn, Target::Fn; + I128SubFnLangItem, "i128_sub", i128_sub_fn, Target::Fn; + U128SubFnLangItem, "u128_sub", u128_sub_fn, Target::Fn; + I128MulFnLangItem, "i128_mul", i128_mul_fn, Target::Fn; + U128MulFnLangItem, "u128_mul", u128_mul_fn, Target::Fn; + I128DivFnLangItem, "i128_div", i128_div_fn, Target::Fn; + U128DivFnLangItem, "u128_div", u128_div_fn, Target::Fn; + I128RemFnLangItem, "i128_rem", i128_rem_fn, Target::Fn; + U128RemFnLangItem, "u128_rem", u128_rem_fn, Target::Fn; + I128ShlFnLangItem, "i128_shl", i128_shl_fn, Target::Fn; + U128ShlFnLangItem, "u128_shl", u128_shl_fn, Target::Fn; + I128ShrFnLangItem, "i128_shr", i128_shr_fn, Target::Fn; + U128ShrFnLangItem, "u128_shr", u128_shr_fn, Target::Fn; // And overflow versions for the operators that are checkable. // While MIR calls these Checked*, they return (T,bool), not Option. - I128AddoFnLangItem, "i128_addo", i128_addo_fn; - U128AddoFnLangItem, "u128_addo", u128_addo_fn; - I128SuboFnLangItem, "i128_subo", i128_subo_fn; - U128SuboFnLangItem, "u128_subo", u128_subo_fn; - I128MuloFnLangItem, "i128_mulo", i128_mulo_fn; - U128MuloFnLangItem, "u128_mulo", u128_mulo_fn; - I128ShloFnLangItem, "i128_shlo", i128_shlo_fn; - U128ShloFnLangItem, "u128_shlo", u128_shlo_fn; - I128ShroFnLangItem, "i128_shro", i128_shro_fn; - U128ShroFnLangItem, "u128_shro", u128_shro_fn; + I128AddoFnLangItem, "i128_addo", i128_addo_fn, Target::Fn; + U128AddoFnLangItem, "u128_addo", u128_addo_fn, Target::Fn; + I128SuboFnLangItem, "i128_subo", i128_subo_fn, Target::Fn; + U128SuboFnLangItem, "u128_subo", u128_subo_fn, Target::Fn; + I128MuloFnLangItem, "i128_mulo", i128_mulo_fn, Target::Fn; + U128MuloFnLangItem, "u128_mulo", u128_mulo_fn, Target::Fn; + I128ShloFnLangItem, "i128_shlo", i128_shlo_fn, Target::Fn; + U128ShloFnLangItem, "u128_shlo", u128_shlo_fn, Target::Fn; + I128ShroFnLangItem, "i128_shro", i128_shro_fn, Target::Fn; + U128ShroFnLangItem, "u128_shro", u128_shro_fn, Target::Fn; // Align offset for stride != 1, must not panic. - AlignOffsetLangItem, "align_offset", align_offset_fn; + AlignOffsetLangItem, "align_offset", align_offset_fn, Target::Fn; - TerminationTraitLangItem, "termination", termination; + TerminationTraitLangItem, "termination", termination, Target::Trait; - Arc, "arc", arc; - Rc, "rc", rc; + Arc, "arc", arc, Target::Struct; + Rc, "rc", rc, Target::Struct; } impl<'a, 'tcx, 'gcx> TyCtxt<'a, 'tcx, 'gcx> { diff --git a/src/test/ui/error-codes/E0152.rs b/src/test/ui/error-codes/E0152.rs index 8fbad7b3ff3..96a4d51bd24 100644 --- a/src/test/ui/error-codes/E0152.rs +++ b/src/test/ui/error-codes/E0152.rs @@ -10,7 +10,7 @@ #![feature(lang_items)] -#[lang = "panic_impl"] +#[lang = "arc"] struct Foo; //~ ERROR E0152 fn main() { diff --git a/src/test/ui/error-codes/E0152.stderr b/src/test/ui/error-codes/E0152.stderr index c7f5f362efb..a0530f24de6 100644 --- a/src/test/ui/error-codes/E0152.stderr +++ b/src/test/ui/error-codes/E0152.stderr @@ -1,10 +1,10 @@ -error[E0152]: duplicate lang item found: `panic_impl`. +error[E0152]: duplicate lang item found: `arc`. --> $DIR/E0152.rs:14:1 | LL | struct Foo; //~ ERROR E0152 | ^^^^^^^^^^^ | - = note: first defined in crate `std`. + = note: first defined in crate `alloc`. error: aborting due to previous error diff --git a/src/test/ui/error-codes/E0718.rs b/src/test/ui/error-codes/E0718.rs new file mode 100644 index 00000000000..ce74e35ac6b --- /dev/null +++ b/src/test/ui/error-codes/E0718.rs @@ -0,0 +1,17 @@ +// Copyright 2013 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. + +#![feature(lang_items)] + +// Arc is expected to be a struct, so this will error. +#[lang = "arc"] +static X: u32 = 42; + +fn main() {} diff --git a/src/test/ui/error-codes/E0718.stderr b/src/test/ui/error-codes/E0718.stderr new file mode 100644 index 00000000000..8ce721d30a1 --- /dev/null +++ b/src/test/ui/error-codes/E0718.stderr @@ -0,0 +1,9 @@ +error[E0718]: `arc` language item must be applied to a struct + --> $DIR/E0718.rs:14:1 + | +LL | #[lang = "arc"] + | ^^^^^^^^^^^^^^^ attribute should be applied to a struct, not a static item + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0718`. diff --git a/src/test/ui/panic-handler/panic-handler-wrong-location.rs b/src/test/ui/panic-handler/panic-handler-wrong-location.rs new file mode 100644 index 00000000000..04e02682bc1 --- /dev/null +++ b/src/test/ui/panic-handler/panic-handler-wrong-location.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. + +// compile-flags:-C panic=abort + +#![no_std] +#![no_main] + +#[panic_handler] +#[no_mangle] +static X: u32 = 42; diff --git a/src/test/ui/panic-handler/panic-handler-wrong-location.stderr b/src/test/ui/panic-handler/panic-handler-wrong-location.stderr new file mode 100644 index 00000000000..f761e26b86e --- /dev/null +++ b/src/test/ui/panic-handler/panic-handler-wrong-location.stderr @@ -0,0 +1,11 @@ +error[E0718]: `panic_impl` language item must be applied to a function + --> $DIR/panic-handler-wrong-location.rs:16:1 + | +LL | #[panic_handler] + | ^^^^^^^^^^^^^^^^ attribute should be applied to a function, not a static item + +error: `#[panic_handler]` function required, but not found + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0718`. -- cgit 1.4.1-3-g733a5 From 5bfe08fc718cd8ecfaa5696261b5eea07a2a5d96 Mon Sep 17 00:00:00 2001 From: ljedrz Date: Fri, 12 Oct 2018 13:55:35 +0200 Subject: rustc/driver: simplify profile::trace::cons --- src/librustc_driver/profile/trace.rs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/librustc_driver/profile/trace.rs b/src/librustc_driver/profile/trace.rs index e329b037d22..7896195a742 100644 --- a/src/librustc_driver/profile/trace.rs +++ b/src/librustc_driver/profile/trace.rs @@ -43,18 +43,18 @@ pub struct QueryMetric { pub dur_total: Duration, } +fn cons(s: &str) -> String { + let first = s.split(|d| d == '(' || d == '{').next(); + assert!(first.is_some() && first != Some("")); + first.unwrap().to_owned() +} + pub fn cons_of_query_msg(q: &trace::Query) -> String { - let s = format!("{:?}", q.msg); - let cons: Vec<&str> = s.split(|d| d == '(' || d == '{').collect(); - assert!(cons.len() > 0 && cons[0] != ""); - cons[0].to_string() + cons(&format!("{:?}", q.msg)) } pub fn cons_of_key(k: &DepNode) -> String { - let s = format!("{:?}", k); - let cons: Vec<&str> = s.split(|d| d == '(' || d == '{').collect(); - assert!(cons.len() > 0 && cons[0] != ""); - cons[0].to_string() + cons(&format!("{:?}", k)) } // First return value is text; second return value is a CSS class -- cgit 1.4.1-3-g733a5 From 39753c89737265a15497b496e621bd9f5bed2f3e Mon Sep 17 00:00:00 2001 From: ljedrz Date: Fri, 12 Oct 2018 14:01:25 +0200 Subject: rustc/driver: improve macro calls --- src/librustc_driver/driver.rs | 2 +- src/librustc_driver/lib.rs | 2 +- src/librustc_driver/pretty.rs | 2 +- src/librustc_driver/profile/mod.rs | 15 ++++++--------- src/librustc_driver/profile/trace.rs | 34 ++++++++++++++++------------------ 5 files changed, 25 insertions(+), 30 deletions(-) (limited to 'src') diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index 7fb66ea97f2..ca1291670d0 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -1472,7 +1472,7 @@ fn write_out_deps(sess: &Session, outputs: &OutputFilenames, out_filenames: &[Pa .collect(); let mut file = fs::File::create(&deps_filename)?; for path in out_filenames { - write!(file, "{}: {}\n\n", path.display(), files.join(" "))?; + writeln!(file, "{}: {}\n", path.display(), files.join(" "))?; } // Emit a fake target for each input file to the compilation. This diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index 4405c0aef90..981c4148f88 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -579,7 +579,7 @@ pub fn set_sigpipe_handler() { unsafe { // Set the SIGPIPE signal handler, so that an EPIPE // will cause rustc to terminate, as expected. - assert!(libc::signal(libc::SIGPIPE, libc::SIG_DFL) != libc::SIG_ERR); + assert_ne!(libc::signal(libc::SIGPIPE, libc::SIG_DFL), libc::SIG_ERR); } } diff --git a/src/librustc_driver/pretty.rs b/src/librustc_driver/pretty.rs index 7e395f1e9a9..1a53d61a3c1 100644 --- a/src/librustc_driver/pretty.rs +++ b/src/librustc_driver/pretty.rs @@ -855,7 +855,7 @@ fn print_flowgraph<'a, 'tcx, W: Write>(variants: Vec, break n.body(); } let parent = tcx.hir.get_parent_node(node_id); - assert!(node_id != parent); + assert_ne!(node_id, parent); node_id = parent; } } diff --git a/src/librustc_driver/profile/mod.rs b/src/librustc_driver/profile/mod.rs index 2ec85e1c27f..cb2fc57643c 100644 --- a/src/librustc_driver/profile/mod.rs +++ b/src/librustc_driver/profile/mod.rs @@ -109,17 +109,14 @@ fn profile_queries_thread(r:Receiver) { let counts_path = format!("{}.counts.txt", params.path); let mut counts_file = File::create(&counts_path).unwrap(); - write!(html_file, "\n").unwrap(); - write!(html_file, - "\n\n", - "profile_queries.css").unwrap(); - write!(html_file, "\n").unwrap(); - write!(html_file, "\n").unwrap(); - write!(html_file, "\n").unwrap(); + writeln!(html_file, "\n\n").unwrap(); trace::write_traces(&mut html_file, &mut counts_file, &frame.traces); - write!(html_file, "\n\n").unwrap(); + writeln!(html_file, "\n").unwrap(); let ack_path = format!("{}.ack", params.path); let ack_file = File::create(&ack_path).unwrap(); diff --git a/src/librustc_driver/profile/trace.rs b/src/librustc_driver/profile/trace.rs index 7896195a742..6cb728c4d58 100644 --- a/src/librustc_driver/profile/trace.rs +++ b/src/librustc_driver/profile/trace.rs @@ -130,22 +130,20 @@ fn write_traces_rec(file: &mut File, traces: &[Rec], total: Duration, depth: usi let fraction = duration_div(t.dur_total, total); let percent = fraction * 100.0; let (frc_text, frc_css_classes) = html_of_fraction(fraction); - write!(file, "
\n", - depth, - t.extent.len(), - /* Heuristic for 'important' CSS class: */ - if t.extent.len() > 5 || percent >= 1.0 { - " important" } - else { "" }, - eff_css_classes, - dur_css_classes, - frc_css_classes, + writeln!(file, "
", + depth, + t.extent.len(), + /* Heuristic for 'important' CSS class: */ + if t.extent.len() > 5 || percent >= 1.0 { " important" } else { "" }, + eff_css_classes, + dur_css_classes, + frc_css_classes, ).unwrap(); - write!(file, "
{}
\n", eff_text).unwrap(); - write!(file, "
{}
\n", dur_text).unwrap(); - write!(file, "
{}
\n", frc_text).unwrap(); + writeln!(file, "
{}
", eff_text).unwrap(); + writeln!(file, "
{}
", dur_text).unwrap(); + writeln!(file, "
{}
", frc_text).unwrap(); write_traces_rec(file, &t.extent, total, depth + 1); - write!(file, "
\n").unwrap(); + writeln!(file, "
").unwrap(); } } @@ -209,10 +207,10 @@ pub fn write_counts(count_file: &mut File, counts: &mut FxHashMap>(); data.sort_by_key(|k| Reverse(k.3)); for (cons, count, dur_total, dur_self) in data { - write!(count_file, "{}, {}, {}, {}\n", - cons, count, - duration_to_secs_str(dur_total), - duration_to_secs_str(dur_self) + writeln!(count_file, "{}, {}, {}, {}", + cons, count, + duration_to_secs_str(dur_total), + duration_to_secs_str(dur_self) ).unwrap(); } } -- cgit 1.4.1-3-g733a5 From 146fbc6a96b50a4eccd13b8908f36d7ce2f6af9f Mon Sep 17 00:00:00 2001 From: memoryruins Date: Fri, 12 Oct 2018 12:42:33 -0400 Subject: Add test for issue #54966 Closes #54966 --- src/test/ui/issues/issue-54966.rs | 6 ++++++ src/test/ui/issues/issue-54966.stderr | 9 +++++++++ 2 files changed, 15 insertions(+) create mode 100644 src/test/ui/issues/issue-54966.rs create mode 100644 src/test/ui/issues/issue-54966.stderr (limited to 'src') diff --git a/src/test/ui/issues/issue-54966.rs b/src/test/ui/issues/issue-54966.rs new file mode 100644 index 00000000000..0ed3c4b3ca9 --- /dev/null +++ b/src/test/ui/issues/issue-54966.rs @@ -0,0 +1,6 @@ +// issue-54966: ICE returning an unknown type with impl FnMut + +fn generate_duration() -> Oper {} +//~^ ERROR cannot find type `Oper` in this scope + +fn main() {} diff --git a/src/test/ui/issues/issue-54966.stderr b/src/test/ui/issues/issue-54966.stderr new file mode 100644 index 00000000000..aa9a61cb592 --- /dev/null +++ b/src/test/ui/issues/issue-54966.stderr @@ -0,0 +1,9 @@ +error[E0412]: cannot find type `Oper` in this scope + --> $DIR/issue-54966.rs:3:27 + | +LL | fn generate_duration() -> Oper {} + | ^^^^ not found in this scope + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0412`. -- cgit 1.4.1-3-g733a5 From 0e268d9e898f76c16fd82d13ef47eca521374789 Mon Sep 17 00:00:00 2001 From: Andy Russell Date: Fri, 12 Oct 2018 13:07:39 -0400 Subject: add test for #24421 Fixes #24421. --- src/test/ui/closure-expected-type/README.md | 1 - src/test/ui/closure-expected-type/issue-24421.rs | 20 ++++++++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) delete mode 100644 src/test/ui/closure-expected-type/README.md create mode 100644 src/test/ui/closure-expected-type/issue-24421.rs (limited to 'src') diff --git a/src/test/ui/closure-expected-type/README.md b/src/test/ui/closure-expected-type/README.md deleted file mode 100644 index 9995b00a9a7..00000000000 --- a/src/test/ui/closure-expected-type/README.md +++ /dev/null @@ -1 +0,0 @@ -See `src/test/run-pass/closure-expected-type`. diff --git a/src/test/ui/closure-expected-type/issue-24421.rs b/src/test/ui/closure-expected-type/issue-24421.rs new file mode 100644 index 00000000000..b3c50a74a32 --- /dev/null +++ b/src/test/ui/closure-expected-type/issue-24421.rs @@ -0,0 +1,20 @@ +// 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. + +// compile-pass + +fn test(f: F) {} + +fn main() { + test(|x, y | {}); + test(|x:&u64, y:&u64| {}); + test(|x:&u64, y | {}); + test(|x, y:&u64| {}); +} -- cgit 1.4.1-3-g733a5 From b041a79f267d61b01bd339f6f01e48bcdf2a56ab Mon Sep 17 00:00:00 2001 From: memoryruins Date: Fri, 12 Oct 2018 12:43:13 -0400 Subject: Add test for issue #52240 Closes #52240 --- src/test/ui/issues/issue-52240.rs | 16 ++++++++++++++++ src/test/ui/issues/issue-52240.stderr | 9 +++++++++ 2 files changed, 25 insertions(+) create mode 100644 src/test/ui/issues/issue-52240.rs create mode 100644 src/test/ui/issues/issue-52240.stderr (limited to 'src') diff --git a/src/test/ui/issues/issue-52240.rs b/src/test/ui/issues/issue-52240.rs new file mode 100644 index 00000000000..9ac7e9905da --- /dev/null +++ b/src/test/ui/issues/issue-52240.rs @@ -0,0 +1,16 @@ +// issue-52240: Can turn immutable into mut with `ref mut` + +enum Foo { + Bar(i32), +} + +fn main() { + let arr = vec!(Foo::Bar(0)); + if let (Some(Foo::Bar(ref mut val)), _) = (&arr.get(0), 0) { + //~^ ERROR cannot borrow field of immutable binding as mutable + *val = 9001; + } + match arr[0] { + Foo::Bar(ref s) => println!("{}", s) + } +} diff --git a/src/test/ui/issues/issue-52240.stderr b/src/test/ui/issues/issue-52240.stderr new file mode 100644 index 00000000000..c2c2524816d --- /dev/null +++ b/src/test/ui/issues/issue-52240.stderr @@ -0,0 +1,9 @@ +error[E0596]: cannot borrow field of immutable binding as mutable + --> $DIR/issue-52240.rs:9:27 + | +LL | if let (Some(Foo::Bar(ref mut val)), _) = (&arr.get(0), 0) { + | ^^^^^^^^^^^ cannot mutably borrow field of immutable binding + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0596`. -- cgit 1.4.1-3-g733a5 From ba446d72be0231ffcd4e4b0d0fc645078480fd19 Mon Sep 17 00:00:00 2001 From: memoryruins Date: Fri, 12 Oct 2018 14:33:38 -0400 Subject: Add nll stderr to #52240 --- src/test/ui/issues/issue-52240.nll.stderr | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 src/test/ui/issues/issue-52240.nll.stderr (limited to 'src') diff --git a/src/test/ui/issues/issue-52240.nll.stderr b/src/test/ui/issues/issue-52240.nll.stderr new file mode 100644 index 00000000000..69b663b17d3 --- /dev/null +++ b/src/test/ui/issues/issue-52240.nll.stderr @@ -0,0 +1,9 @@ +error[E0596]: cannot borrow data in a `&` reference as mutable + --> $DIR/issue-52240.rs:9:27 + | +LL | if let (Some(Foo::Bar(ref mut val)), _) = (&arr.get(0), 0) { + | ^^^^^^^^^^^ cannot borrow as mutable + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0596`. -- cgit 1.4.1-3-g733a5 From 9562b69b4f270a824b9f54203ed69427f8833fe9 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Fri, 12 Oct 2018 17:04:31 -0700 Subject: rustc: Allow targets to specify SIMD args are by-val The upcoming SIMD support in the wasm target is unique from the other platforms where it's either unconditionally available or not available, there's no halfway where a subsection of the program can use it but no other parts of the program can use it. In this world it's valid for wasm SIMD args to always be passed by value and there's no need to pass them by reference. This commit adds a new custom target specification option `simd_types_indirect` which defaults to `true`, but the wasm backend disables this and sets it to `false`. --- src/librustc_codegen_llvm/abi.rs | 5 ++++- src/librustc_target/spec/mod.rs | 9 +++++++++ src/librustc_target/spec/wasm32_unknown_unknown.rs | 6 ++++++ 3 files changed, 19 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/librustc_codegen_llvm/abi.rs b/src/librustc_codegen_llvm/abi.rs index c8e8d0dc84e..7b93d3e795e 100644 --- a/src/librustc_codegen_llvm/abi.rs +++ b/src/librustc_codegen_llvm/abi.rs @@ -536,7 +536,10 @@ impl<'tcx> FnTypeExt<'tcx> for FnType<'tcx, Ty<'tcx>> { // Note that the platform intrinsic ABI is exempt here as // that's how we connect up to LLVM and it's unstable // anyway, we control all calls to it in libstd. - layout::Abi::Vector { .. } if abi != Abi::PlatformIntrinsic => { + layout::Abi::Vector { .. } + if abi != Abi::PlatformIntrinsic && + cx.sess().target.target.options.simd_types_indirect => + { arg.make_indirect(); return } diff --git a/src/librustc_target/spec/mod.rs b/src/librustc_target/spec/mod.rs index 9c0f945326d..9ee4582fabf 100644 --- a/src/librustc_target/spec/mod.rs +++ b/src/librustc_target/spec/mod.rs @@ -680,6 +680,12 @@ pub struct TargetOptions { /// typically because the platform needs to unwind for things like stack /// unwinders. pub requires_uwtable: bool, + + /// Whether or not SIMD types are passed by reference in the Rust ABI, + /// typically required if a target can be compiled with a mixed set of + /// target features. This is `true` by default, and `false` for targets like + /// wasm32 where the whole program either has simd or not. + pub simd_types_indirect: bool, } impl Default for TargetOptions { @@ -760,6 +766,7 @@ impl Default for TargetOptions { embed_bitcode: false, emit_debug_gdb_scripts: true, requires_uwtable: false, + simd_types_indirect: true, } } } @@ -1041,6 +1048,7 @@ impl Target { key!(embed_bitcode, bool); key!(emit_debug_gdb_scripts, bool); key!(requires_uwtable, bool); + key!(simd_types_indirect, 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()) { @@ -1250,6 +1258,7 @@ impl ToJson for Target { target_option_val!(embed_bitcode); target_option_val!(emit_debug_gdb_scripts); target_option_val!(requires_uwtable); + target_option_val!(simd_types_indirect); if default.abi_blacklist != self.options.abi_blacklist { d.insert("abi-blacklist".to_string(), self.options.abi_blacklist.iter() diff --git a/src/librustc_target/spec/wasm32_unknown_unknown.rs b/src/librustc_target/spec/wasm32_unknown_unknown.rs index c0455ceb839..46353068bd0 100644 --- a/src/librustc_target/spec/wasm32_unknown_unknown.rs +++ b/src/librustc_target/spec/wasm32_unknown_unknown.rs @@ -54,6 +54,12 @@ pub fn target() -> Result { linker: Some("rust-lld".to_owned()), lld_flavor: LldFlavor::Wasm, + // No need for indirection here, simd types can always be passed by + // value as the whole module either has simd or not, which is different + // from x86 (for example) where programs can have functions that don't + // enable simd features. + simd_types_indirect: false, + .. Default::default() }; Ok(Target { -- cgit 1.4.1-3-g733a5 From ab91a6b4df04a60cf19682b1f016848d3e4784ad Mon Sep 17 00:00:00 2001 From: "Zack M. Davis" Date: Thu, 11 Oct 2018 23:10:37 -0700 Subject: `#[must_use]` for associated functions is supposed to actually work MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In the comments of (closed, defunct) pull request #54884, Mazdak "Centril" Farrokhzad noted that must-use annotations didn't work on an associated function (what other communities might call a "static method"). Subsequent logging revealed that in this case we have a `Def::Method`, whereas the lint pass was only matching on `Def::Fn`. (One could argue that those def-names are thereby misleading—must-use for self-ful methods have always worked—but documenting or reworking that can be left to another day.) --- src/liballoc/rc.rs | 4 ++-- src/liballoc/sync.rs | 4 ++-- src/librustc_lint/unused.rs | 9 +++++---- src/test/run-pass/resolve-pseudo-shadowing.rs | 2 +- src/test/ui/fn_must_use.rs | 8 ++++++++ src/test/ui/fn_must_use.stderr | 20 +++++++++++++------- 6 files changed, 31 insertions(+), 16 deletions(-) (limited to 'src') diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs index 915b8e7787e..40bb2faa362 100644 --- a/src/liballoc/rc.rs +++ b/src/liballoc/rc.rs @@ -867,7 +867,7 @@ impl Clone for Rc { /// /// let five = Rc::new(5); /// - /// Rc::clone(&five); + /// let _ = Rc::clone(&five); /// ``` #[inline] fn clone(&self) -> Rc { @@ -1304,7 +1304,7 @@ impl Clone for Weak { /// /// let weak_five = Rc::downgrade(&Rc::new(5)); /// - /// Weak::clone(&weak_five); + /// let _ = Weak::clone(&weak_five); /// ``` #[inline] fn clone(&self) -> Weak { diff --git a/src/liballoc/sync.rs b/src/liballoc/sync.rs index 9e245fbd7bb..35935861fb1 100644 --- a/src/liballoc/sync.rs +++ b/src/liballoc/sync.rs @@ -713,7 +713,7 @@ impl Clone for Arc { /// /// let five = Arc::new(5); /// - /// Arc::clone(&five); + /// let _ = Arc::clone(&five); /// ``` #[inline] fn clone(&self) -> Arc { @@ -1135,7 +1135,7 @@ impl Clone for Weak { /// /// let weak_five = Arc::downgrade(&Arc::new(5)); /// - /// Weak::clone(&weak_five); + /// let _ = Weak::clone(&weak_five); /// ``` #[inline] fn clone(&self) -> Weak { diff --git a/src/librustc_lint/unused.rs b/src/librustc_lint/unused.rs index ec3c310c63c..7d178d20967 100644 --- a/src/librustc_lint/unused.rs +++ b/src/librustc_lint/unused.rs @@ -80,10 +80,11 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedResults { match callee.node { hir::ExprKind::Path(ref qpath) => { let def = cx.tables.qpath_def(qpath, callee.hir_id); - if let Def::Fn(_) = def { - Some(def) - } else { // `Def::Local` if it was a closure, for which we - None // do not currently support must-use linting + match def { + Def::Fn(_) | Def::Method(_) => Some(def), + // `Def::Local` if it was a closure, for which we + // do not currently support must-use linting + _ => None } }, _ => None diff --git a/src/test/run-pass/resolve-pseudo-shadowing.rs b/src/test/run-pass/resolve-pseudo-shadowing.rs index 071279ae7d8..bf6e686bb7b 100644 --- a/src/test/run-pass/resolve-pseudo-shadowing.rs +++ b/src/test/run-pass/resolve-pseudo-shadowing.rs @@ -12,7 +12,7 @@ fn check(_c: Clone) { fn check2() { - <() as std::clone::Clone>::clone(&()); + let _ = <() as std::clone::Clone>::clone(&()); } check2(); } diff --git a/src/test/ui/fn_must_use.rs b/src/test/ui/fn_must_use.rs index def23046db2..e3e20bc89b4 100644 --- a/src/test/ui/fn_must_use.rs +++ b/src/test/ui/fn_must_use.rs @@ -22,6 +22,11 @@ impl MyStruct { fn need_to_use_this_method_value(&self) -> usize { self.n } + + #[must_use] + fn need_to_use_this_associated_function_value() -> isize { + -1 + } } trait EvenNature { @@ -66,6 +71,9 @@ fn main() { m.is_even(); // trait method! //~^ WARN unused return value + MyStruct::need_to_use_this_associated_function_value(); + //~^ WARN unused return value + m.replace(3); // won't warn (annotation needs to be in trait definition) // comparison methods are `must_use` diff --git a/src/test/ui/fn_must_use.stderr b/src/test/ui/fn_must_use.stderr index b5bad22f3dc..1bce8abbbf0 100644 --- a/src/test/ui/fn_must_use.stderr +++ b/src/test/ui/fn_must_use.stderr @@ -1,5 +1,5 @@ warning: unused return value of `need_to_use_this_value` which must be used - --> $DIR/fn_must_use.rs:60:5 + --> $DIR/fn_must_use.rs:65:5 | LL | need_to_use_this_value(); //~ WARN unused return value | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -12,39 +12,45 @@ LL | #![warn(unused_must_use)] = note: it's important warning: unused return value of `MyStruct::need_to_use_this_method_value` which must be used - --> $DIR/fn_must_use.rs:65:5 + --> $DIR/fn_must_use.rs:70:5 | LL | m.need_to_use_this_method_value(); //~ WARN unused return value | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused return value of `EvenNature::is_even` which must be used - --> $DIR/fn_must_use.rs:66:5 + --> $DIR/fn_must_use.rs:71:5 | LL | m.is_even(); // trait method! | ^^^^^^^^^^^^ | = note: no side effects +warning: unused return value of `MyStruct::need_to_use_this_associated_function_value` which must be used + --> $DIR/fn_must_use.rs:74:5 + | +LL | MyStruct::need_to_use_this_associated_function_value(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + warning: unused return value of `std::cmp::PartialEq::eq` which must be used - --> $DIR/fn_must_use.rs:72:5 + --> $DIR/fn_must_use.rs:80:5 | LL | 2.eq(&3); //~ WARN unused return value | ^^^^^^^^^ warning: unused return value of `std::cmp::PartialEq::eq` which must be used - --> $DIR/fn_must_use.rs:73:5 + --> $DIR/fn_must_use.rs:81:5 | LL | m.eq(&n); //~ WARN unused return value | ^^^^^^^^^ warning: unused comparison which must be used - --> $DIR/fn_must_use.rs:76:5 + --> $DIR/fn_must_use.rs:84:5 | LL | 2 == 3; //~ WARN unused comparison | ^^^^^^ warning: unused comparison which must be used - --> $DIR/fn_must_use.rs:77:5 + --> $DIR/fn_must_use.rs:85:5 | LL | m == n; //~ WARN unused comparison | ^^^^^^ -- cgit 1.4.1-3-g733a5 From 9a1de086e4e5d46259c46128d17848cabbe7b8de Mon Sep 17 00:00:00 2001 From: ljedrz Date: Fri, 12 Oct 2018 14:14:03 +0200 Subject: rustc/driver: improve/remove allocations --- src/librustc_driver/driver.rs | 12 ++++++------ src/librustc_driver/lib.rs | 27 ++++++++++++--------------- src/librustc_driver/profile/trace.rs | 23 ++++++++++++----------- 3 files changed, 30 insertions(+), 32 deletions(-) (limited to 'src') diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index ca1291670d0..248cf549d81 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -1586,9 +1586,8 @@ pub fn collect_crate_types(session: &Session, attrs: &[ast::Attribute]) -> Vec Vec CrateDisambiguator { diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index 981c4148f88..8d886d8c040 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -137,9 +137,7 @@ pub mod target_features { codegen_backend: &dyn CodegenBackend) { let tf = Symbol::intern("target_feature"); - for feat in codegen_backend.target_features(sess) { - cfg.insert((tf, Some(feat))); - } + cfg.extend(codegen_backend.target_features(sess).into_iter().map(|feat| (tf, Some(feat)))); if sess.crt_static_feature() { cfg.insert((tf, Some(Symbol::intern("crt-static")))); @@ -997,7 +995,7 @@ impl RustcDefaultCalls { input: &Input) -> Compilation { let r = matches.opt_strs("Z"); - if r.contains(&("ls".to_string())) { + if r.iter().any(|s| *s == "ls") { match input { &Input::File(ref ifile) => { let path = &(*ifile); @@ -1085,8 +1083,7 @@ impl RustcDefaultCalls { let allow_unstable_cfg = UnstableFeatures::from_environment() .is_nightly_build(); - let mut cfgs = Vec::new(); - for &(name, ref value) in sess.parse_sess.config.iter() { + let mut cfgs = sess.parse_sess.config.iter().filter_map(|&(name, ref value)| { let gated_cfg = GatedCfg::gate(&ast::MetaItem { ident: ast::Path::from_ident(ast::Ident::with_empty_ctxt(name)), node: ast::MetaItemKind::Word, @@ -1105,16 +1102,16 @@ impl RustcDefaultCalls { let value = value.as_ref().map(|s| s.as_ref()); if name != "target_feature" || value != Some("crt-static") { if !allow_unstable_cfg && gated_cfg.is_some() { - continue; + return None } } - cfgs.push(if let Some(value) = value { - format!("{}=\"{}\"", name, value) + if let Some(value) = value { + Some(format!("{}=\"{}\"", name, value)) } else { - name.to_string() - }); - } + Some(name.to_string()) + } + }).collect::>(); cfgs.sort(); for cfg in cfgs { @@ -1177,7 +1174,7 @@ fn usage(verbose: bool, include_unstable_options: bool) { for option in groups.iter().filter(|x| include_unstable_options || x.is_stable()) { (option.apply)(&mut options); } - let message = "Usage: rustc [OPTIONS] INPUT".to_string(); + let message = "Usage: rustc [OPTIONS] INPUT"; let nightly_help = if nightly_options::is_nightly_build() { "\n -Z help Print internal options for debugging rustc" } else { @@ -1192,7 +1189,7 @@ fn usage(verbose: bool, include_unstable_options: bool) { -C help Print codegen options -W help \ Print 'lint' options and default settings{}{}\n", - options.usage(&message), + options.usage(message), nightly_help, verbose_help); } @@ -1463,7 +1460,7 @@ pub fn handle_options(args: &[String]) -> Option { "the --no-stack-check flag is deprecated and does nothing"); } - if cg_flags.contains(&"passes=list".to_string()) { + if cg_flags.iter().any(|x| *x == "passes=list") { get_codegen_sysroot("llvm")().print_passes(); return None; } diff --git a/src/librustc_driver/profile/trace.rs b/src/librustc_driver/profile/trace.rs index 6cb728c4d58..8c065038d4b 100644 --- a/src/librustc_driver/profile/trace.rs +++ b/src/librustc_driver/profile/trace.rs @@ -89,18 +89,18 @@ fn html_of_duration(_start: &Instant, dur: &Duration) -> (String, String) { ) } -fn html_of_fraction(frac: f64) -> (String, String) { +fn html_of_fraction(frac: f64) -> (String, &'static str) { let css = { - if frac > 0.50 { "frac-50".to_string() } - else if frac > 0.40 { "frac-40".to_string() } - else if frac > 0.30 { "frac-30".to_string() } - else if frac > 0.20 { "frac-20".to_string() } - else if frac > 0.10 { "frac-10".to_string() } - else if frac > 0.05 { "frac-05".to_string() } - else if frac > 0.02 { "frac-02".to_string() } - else if frac > 0.01 { "frac-01".to_string() } - else if frac > 0.001 { "frac-001".to_string() } - else { "frac-0".to_string() } + if frac > 0.50 { "frac-50" } + else if frac > 0.40 { "frac-40" } + else if frac > 0.30 { "frac-30" } + else if frac > 0.20 { "frac-20" } + else if frac > 0.10 { "frac-10" } + else if frac > 0.05 { "frac-05" } + else if frac > 0.02 { "frac-02" } + else if frac > 0.01 { "frac-01" } + else if frac > 0.001 { "frac-001" } + else { "frac-0" } }; let percent = frac * 100.0; if percent > 0.1 { (format!("{:.1}%", percent), css) } @@ -148,6 +148,7 @@ fn write_traces_rec(file: &mut File, traces: &[Rec], total: Duration, depth: usi } fn compute_counts_rec(counts: &mut FxHashMap, traces: &[Rec]) { + counts.reserve(traces.len()); for t in traces.iter() { match t.effect { Effect::TimeBegin(ref msg) => { -- cgit 1.4.1-3-g733a5 From 2c482d8d41a7c4424583f2abe62be85b188ddeb8 Mon Sep 17 00:00:00 2001 From: ljedrz Date: Fri, 12 Oct 2018 14:16:06 +0200 Subject: rustc/driver: use Cow where applicable --- src/librustc_driver/lib.rs | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index 8d886d8c040..a01e2d4f845 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -90,6 +90,7 @@ use rustc_codegen_utils::codegen_backend::CodegenBackend; use serialize::json::ToJson; use std::any::Any; +use std::borrow::Cow; use std::cmp::max; use std::default::Default; use std::env::consts::{DLL_PREFIX, DLL_SUFFIX}; @@ -1678,25 +1679,25 @@ pub fn monitor(f: F) -> Result<(), CompilationFail errors::Level::Bug); } - let mut xs = vec![ - "the compiler unexpectedly panicked. this is a bug.".to_string(), - format!("we would appreciate a bug report: {}", BUG_REPORT_URL), + let mut xs: Vec> = vec![ + "the compiler unexpectedly panicked. this is a bug.".into(), + format!("we would appreciate a bug report: {}", BUG_REPORT_URL).into(), format!("rustc {} running on {}", option_env!("CFG_VERSION").unwrap_or("unknown_version"), - config::host_triple()), + config::host_triple()).into(), ]; if let Some((flags, excluded_cargo_defaults)) = extra_compiler_flags() { - xs.push(format!("compiler flags: {}", flags.join(" "))); + xs.push(format!("compiler flags: {}", flags.join(" ")).into()); if excluded_cargo_defaults { - xs.push("some of the compiler flags provided by cargo are hidden".to_string()); + xs.push("some of the compiler flags provided by cargo are hidden".into()); } } for note in &xs { handler.emit(&MultiSpan::new(), - ¬e, + note, errors::Level::Note); } -- cgit 1.4.1-3-g733a5 From d599f5bf611018849452d5bb65c0087e1bc81a12 Mon Sep 17 00:00:00 2001 From: ljedrz Date: Fri, 12 Oct 2018 14:21:56 +0200 Subject: rustc/driver: improve common patterns --- src/librustc_driver/driver.rs | 20 +++++------- src/librustc_driver/lib.rs | 61 ++++++++++++++---------------------- src/librustc_driver/profile/mod.rs | 4 +-- src/librustc_driver/profile/trace.rs | 6 +--- 4 files changed, 33 insertions(+), 58 deletions(-) (limited to 'src') diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index 248cf549d81..4d42b8315ea 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -1484,15 +1484,12 @@ fn write_out_deps(sess: &Session, outputs: &OutputFilenames, out_filenames: &[Pa Ok(()) })(); - match result { - Ok(()) => {} - Err(e) => { - sess.fatal(&format!( - "error writing dependencies to `{}`: {}", - deps_filename.display(), - e - )); - } + if let Err(e) = result { + sess.fatal(&format!( + "error writing dependencies to `{}`: {}", + deps_filename.display(), + e + )); } } @@ -1650,10 +1647,7 @@ pub fn build_output_filenames( // "-" as input file will cause the parser to read from stdin so we // have to make up a name // We want to toss everything after the final '.' - let dirpath = match *odir { - Some(ref d) => d.clone(), - None => PathBuf::new(), - }; + let dirpath = (*odir).as_ref().cloned().unwrap_or_else(|| PathBuf::new()); // If a crate name is present, we use it as the link name let stem = sess.opts diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index a01e2d4f845..1fd2021b1e7 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -224,15 +224,10 @@ fn load_backend_from_dylib(path: &Path) -> fn() -> Box { // available for future dynamic libraries opened. This is currently used by // loading LLVM and then making its symbols available for other dynamic // libraries. - let lib = match DynamicLibrary::open_global_now(path) { - Ok(lib) => lib, - Err(err) => { - let err = format!("couldn't load codegen backend {:?}: {:?}", - path, - err); - early_error(ErrorOutputType::default(), &err); - } - }; + let lib = DynamicLibrary::open_global_now(path).unwrap_or_else(|err| { + let err = format!("couldn't load codegen backend {:?}: {:?}", path, err); + early_error(ErrorOutputType::default(), &err); + }); unsafe { match lib.symbol("__rustc_codegen_backend") { Ok(f) => { @@ -337,28 +332,22 @@ fn get_codegen_sysroot(backend_name: &str) -> fn() -> Box { f.exists() }) .next(); - let sysroot = match sysroot { - Some(path) => path, - None => { - let candidates = sysroot_candidates.iter() - .map(|p| p.display().to_string()) - .collect::>() - .join("\n* "); - let err = format!("failed to find a `codegen-backends` folder \ - in the sysroot candidates:\n* {}", candidates); - early_error(ErrorOutputType::default(), &err); - } - }; + let sysroot = sysroot.unwrap_or_else(|| { + let candidates = sysroot_candidates.iter() + .map(|p| p.display().to_string()) + .collect::>() + .join("\n* "); + let err = format!("failed to find a `codegen-backends` folder \ + in the sysroot candidates:\n* {}", candidates); + early_error(ErrorOutputType::default(), &err); + }); info!("probing {} for a codegen backend", sysroot.display()); - let d = match sysroot.read_dir() { - Ok(d) => d, - Err(e) => { - let err = format!("failed to load default codegen backend, couldn't \ - read `{}`: {}", sysroot.display(), e); - early_error(ErrorOutputType::default(), &err); - } - }; + let d = sysroot.read_dir().unwrap_or_else(|e| { + let err = format!("failed to load default codegen backend, couldn't \ + read `{}`: {}", sysroot.display(), e); + early_error(ErrorOutputType::default(), &err); + }); let mut file: Option = None; @@ -1055,10 +1044,8 @@ impl RustcDefaultCalls { Sysroot => println!("{}", sess.sysroot().display()), TargetSpec => println!("{}", sess.target.target.to_json().pretty()), FileNames | CrateName => { - let input = match input { - Some(input) => input, - None => early_error(ErrorOutputType::default(), "no input file provided"), - }; + let input = input.unwrap_or_else(|| + early_error(ErrorOutputType::default(), "no input file provided")); let attrs = attrs.as_ref().unwrap(); let t_outputs = driver::build_output_filenames(input, odir, ofile, attrs, sess); let id = rustc_codegen_utils::link::find_crate_name(Some(sess), attrs, input); @@ -1406,10 +1393,8 @@ pub fn handle_options(args: &[String]) -> Option { for option in config::rustc_optgroups() { (option.apply)(&mut options); } - let matches = match options.parse(args) { - Ok(m) => m, - Err(f) => early_error(ErrorOutputType::default(), &f.to_string()), - }; + let matches = options.parse(args).unwrap_or_else(|f| + early_error(ErrorOutputType::default(), &f.to_string())); // For all options we just parsed, we check a few aspects: // @@ -1631,7 +1616,7 @@ fn extra_compiler_flags() -> Option<(Vec, bool)> { } } - if result.len() > 0 { + if !result.is_empty() { Some((result, excluded_cargo_defaults)) } else { None diff --git a/src/librustc_driver/profile/mod.rs b/src/librustc_driver/profile/mod.rs index cb2fc57643c..9016e0d0fe7 100644 --- a/src/librustc_driver/profile/mod.rs +++ b/src/librustc_driver/profile/mod.rs @@ -90,7 +90,7 @@ fn profile_queries_thread(r:Receiver) { match msg { ProfileQueriesMsg::Halt => return, ProfileQueriesMsg::Dump(params) => { - assert!(stack.len() == 0); + assert!(stack.is_empty()); assert!(frame.parse_st == ParseState::Clear); { // write log of all messages @@ -141,7 +141,7 @@ fn profile_queries_thread(r:Receiver) { ProfileQueriesMsg::QueryBegin(span,querymsg)) => { let start = Instant::now(); frame.parse_st = ParseState::HaveQuery - (Query{span:span, msg:querymsg}, start) + (Query { span, msg: querymsg }, start) }, (ParseState::Clear, ProfileQueriesMsg::CacheHit) => { diff --git a/src/librustc_driver/profile/trace.rs b/src/librustc_driver/profile/trace.rs index 8c065038d4b..121be04bbb1 100644 --- a/src/librustc_driver/profile/trace.rs +++ b/src/librustc_driver/profile/trace.rs @@ -108,11 +108,7 @@ fn html_of_fraction(frac: f64) -> (String, &'static str) { } fn total_duration(traces: &[Rec]) -> Duration { - let mut sum : Duration = Duration::new(0,0); - for t in traces.iter() { - sum += t.dur_total; - } - return sum + Duration::new(0, 0) + traces.iter().map(|t| t.dur_total).sum() } fn duration_div(nom: Duration, den: Duration) -> f64 { -- cgit 1.4.1-3-g733a5 From 9b01b51560125338b6594f9919485e6084bee77d Mon Sep 17 00:00:00 2001 From: ljedrz Date: Fri, 12 Oct 2018 14:24:38 +0200 Subject: rustc/driver: remove lifetimes from consts --- src/librustc_driver/lib.rs | 23 ++++++++--------------- 1 file changed, 8 insertions(+), 15 deletions(-) (limited to 'src') diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index 1fd2021b1e7..e56ffb20a90 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -152,21 +152,14 @@ pub const EXIT_SUCCESS: isize = 0; /// Exit status code used for compilation failures and invalid flags. pub const EXIT_FAILURE: isize = 1; -const BUG_REPORT_URL: &'static str = "https://github.com/rust-lang/rust/blob/master/CONTRIBUTING.\ - md#bug-reports"; - -const ICE_REPORT_COMPILER_FLAGS: &'static [&'static str] = &[ - "Z", - "C", - "crate-type", -]; -const ICE_REPORT_COMPILER_FLAGS_EXCLUDE: &'static [&'static str] = &[ - "metadata", - "extra-filename", -]; -const ICE_REPORT_COMPILER_FLAGS_STRIP_VALUE: &'static [&'static str] = &[ - "incremental", -]; +const BUG_REPORT_URL: &str = "https://github.com/rust-lang/rust/blob/master/CONTRIBUTING.\ + md#bug-reports"; + +const ICE_REPORT_COMPILER_FLAGS: &[&str] = &["Z", "C", "crate-type"]; + +const ICE_REPORT_COMPILER_FLAGS_EXCLUDE: &[&str] = &["metadata", "extra-filename"]; + +const ICE_REPORT_COMPILER_FLAGS_STRIP_VALUE: &[&str] = &["incremental"]; pub fn abort_on_err(result: Result, sess: &Session) -> T { match result { -- cgit 1.4.1-3-g733a5 From 292cc1e36fcace60fac19c35b61bb20ab145b057 Mon Sep 17 00:00:00 2001 From: ljedrz Date: Fri, 12 Oct 2018 14:28:06 +0200 Subject: rustc/driver: don't sort base if it only has one element --- src/librustc_driver/driver.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index 4d42b8315ea..688e083ac47 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -1578,9 +1578,10 @@ pub fn collect_crate_types(session: &Session, attrs: &[ast::Attribute]) -> Vec Date: Fri, 12 Oct 2018 14:32:56 +0200 Subject: rustc/driver: remove explicit return, add explicit None --- src/librustc_driver/driver.rs | 2 +- src/librustc_driver/lib.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index 688e083ac47..040f835bf5e 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -1548,7 +1548,7 @@ pub fn collect_crate_types(session: &Session, attrs: &[ast::Attribute]) -> Vec { + None => { session .struct_span_err(a.span, "`crate_type` requires a value") .note("for example: `#![crate_type=\"lib\"]`") diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index e56ffb20a90..8ec88c9d8f6 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -997,7 +997,7 @@ impl RustcDefaultCalls { return Compilation::Stop; } - return Compilation::Continue; + Compilation::Continue } -- cgit 1.4.1-3-g733a5 From d838a7fcca93034dcb50914ca242a6973a7c3ac2 Mon Sep 17 00:00:00 2001 From: ljedrz Date: Fri, 12 Oct 2018 14:35:07 +0200 Subject: rustc/driver: unwrap_or_else with function calls --- src/librustc_driver/driver.rs | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index 040f835bf5e..976a50e9d69 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -44,7 +44,7 @@ use serialize::json; use std::any::Any; use std::env; -use std::ffi::{OsStr, OsString}; +use std::ffi::OsString; use std::fs; use std::io::{self, Write}; use std::iter; @@ -1648,14 +1648,14 @@ pub fn build_output_filenames( // "-" as input file will cause the parser to read from stdin so we // have to make up a name // We want to toss everything after the final '.' - let dirpath = (*odir).as_ref().cloned().unwrap_or_else(|| PathBuf::new()); + let dirpath = (*odir).as_ref().cloned().unwrap_or_default(); // If a crate name is present, we use it as the link name let stem = sess.opts .crate_name .clone() .or_else(|| attr::find_crate_name(attrs).map(|n| n.to_string())) - .unwrap_or(input.filestem()); + .unwrap_or_else(|| input.filestem()); OutputFilenames { out_directory: dirpath, @@ -1688,13 +1688,11 @@ pub fn build_output_filenames( sess.warn("ignoring -C extra-filename flag due to -o flag"); } - let cur_dir = Path::new(""); - OutputFilenames { - out_directory: out_file.parent().unwrap_or(cur_dir).to_path_buf(), + out_directory: out_file.parent().unwrap_or_else(|| Path::new("")).to_path_buf(), out_filestem: out_file .file_stem() - .unwrap_or(OsStr::new("")) + .unwrap_or_default() .to_str() .unwrap() .to_string(), -- cgit 1.4.1-3-g733a5 From b03a82cfca27c11fabc19e4146d6583b3cd320ae Mon Sep 17 00:00:00 2001 From: ljedrz Date: Fri, 12 Oct 2018 14:36:10 +0200 Subject: rustc/driver: whitespace & formatting fixes --- src/librustc_driver/driver.rs | 14 ++++++---- src/librustc_driver/lib.rs | 44 +++++++++++++---------------- src/librustc_driver/pretty.rs | 54 ++++++++++++++++++------------------ src/librustc_driver/profile/mod.rs | 24 ++++++++-------- src/librustc_driver/profile/trace.rs | 37 +++++++++++++----------- 5 files changed, 87 insertions(+), 86 deletions(-) (limited to 'src') diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index 976a50e9d69..b4f95b915eb 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -1021,6 +1021,7 @@ where .cloned() .collect(); missing_fragment_specifiers.sort(); + for span in missing_fragment_specifiers { let lint = lint::builtin::MISSING_FRAGMENT_SPECIFIER; let msg = "missing fragment specifier"; @@ -1517,6 +1518,7 @@ pub fn collect_crate_types(session: &Session, attrs: &[ast::Attribute]) -> Vec Vec(run_compiler: F) -> isize } None => { let emitter = - errors::emitter::EmitterWriter::stderr(errors::ColorConfig::Auto, - None, - true, - false); + errors::emitter::EmitterWriter::stderr( + errors::ColorConfig::Auto, + None, + true, + false + ); let handler = errors::Handler::with_emitter(true, false, Box::new(emitter)); handler.emit(&MultiSpan::new(), - "aborting due to previous error(s)", - errors::Level::Fatal); + "aborting due to previous error(s)", + errors::Level::Fatal); panic::resume_unwind(Box::new(errors::FatalErrorMarker)); } } @@ -316,9 +318,8 @@ fn get_codegen_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) - .with_file_name(option_env!("CFG_CODEGEN_BACKENDS_DIR") - .unwrap_or("codegen-backends")) + sysroot.join(libdir).with_file_name( + option_env!("CFG_CODEGEN_BACKENDS_DIR").unwrap_or("codegen-backends")) }) .filter(|f| { info!("codegen backend candidate: {}", f.display()); @@ -360,8 +361,8 @@ fn get_codegen_sysroot(backend_name: &str) -> fn() -> Box { } if let Some(ref prev) = file { let err = format!("duplicate codegen backends found\n\ - first: {}\n\ - second: {}\n\ + first: {}\n\ + second: {}\n\ ", prev.display(), path.display()); early_error(ErrorOutputType::default(), &err); } @@ -373,7 +374,7 @@ fn get_codegen_sysroot(backend_name: &str) -> fn() -> Box { None => { let err = format!("failed to load default codegen backend for `{}`, \ no appropriate codegen dylib found in `{}`", - backend_name, sysroot.display()); + backend_name, sysroot.display()); early_error(ErrorOutputType::default(), &err); } } @@ -1010,7 +1011,7 @@ impl RustcDefaultCalls { use rustc::session::config::PrintRequest::*; // PrintRequest::NativeStaticLibs is special - printed during linking // (empty iterator returns true) - if sess.opts.prints.iter().all(|&p| p==PrintRequest::NativeStaticLibs) { + if sess.opts.prints.iter().all(|&p| p == PrintRequest::NativeStaticLibs) { return Compilation::Continue; } @@ -1054,10 +1055,7 @@ impl RustcDefaultCalls { &id, &t_outputs ); - println!("{}", - fname.file_name() - .unwrap() - .to_string_lossy()); + println!("{}", fname.file_name().unwrap().to_string_lossy()); } } Cfg => { @@ -1129,9 +1127,8 @@ fn commit_date_str() -> Option<&'static str> { pub fn version(binary: &str, matches: &getopts::Matches) { let verbose = matches.opt_present("verbose"); - println!("{} {}", - binary, - option_env!("CFG_VERSION").unwrap_or("unknown version")); + println!("{} {}", binary, option_env!("CFG_VERSION").unwrap_or("unknown version")); + if verbose { fn unw(x: Option<&str>) -> &str { x.unwrap_or("unknown") @@ -1252,8 +1249,6 @@ Available lint options: print_lints(builtin); - - let max_name_len = max("warnings".len(), plugin_groups.iter() .chain(&builtin_groups) @@ -1429,6 +1424,7 @@ pub fn handle_options(args: &[String]) -> Option { } let cg_flags = matches.opt_strs("C"); + if cg_flags.iter().any(|x| *x == "help") { describe_codegen_flags(); return None; @@ -1477,7 +1473,7 @@ pub fn in_named_rustc_thread(name: String, f: F) -> Result(name: String, f: F) -> Result(&self, - sess: &'tcx Session, - hir_map: Option<&hir_map::Map<'tcx>>, - f: F) - -> A + sess: &'tcx Session, + hir_map: Option<&hir_map::Map<'tcx>>, + f: F) + -> A where F: FnOnce(&dyn PrinterSupport) -> A { match *self { @@ -198,17 +198,18 @@ impl PpSourceMode { _ => panic!("Should use call_with_pp_support_hir"), } } - fn call_with_pp_support_hir<'tcx, A, F>(&self, - sess: &'tcx Session, - cstore: &'tcx CStore, - hir_map: &hir_map::Map<'tcx>, - analysis: &ty::CrateAnalysis, - resolutions: &Resolutions, - arenas: &'tcx AllArenas<'tcx>, - output_filenames: &OutputFilenames, - id: &str, - f: F) - -> A + fn call_with_pp_support_hir<'tcx, A, F>( + &self, + sess: &'tcx Session, + cstore: &'tcx CStore, + hir_map: &hir_map::Map<'tcx>, + analysis: &ty::CrateAnalysis, + resolutions: &Resolutions, + arenas: &'tcx AllArenas<'tcx>, + output_filenames: &OutputFilenames, + id: &str, + f: F + ) -> A where F: FnOnce(&dyn HirPrinterSupport, &hir::Crate) -> A { match *self { @@ -952,18 +953,17 @@ pub fn print_after_parsing(sess: &Session, // Silently ignores an identified node. let out: &mut dyn Write = &mut out; s.call_with_pp_support(sess, None, move |annotation| { - debug!("pretty printing source code {:?}", s); - let sess = annotation.sess(); - pprust::print_crate(sess.source_map(), - &sess.parse_sess, - krate, - src_name, - &mut rdr, - box out, - annotation.pp_ann(), - false) - }) - .unwrap() + debug!("pretty printing source code {:?}", s); + let sess = annotation.sess(); + pprust::print_crate(sess.source_map(), + &sess.parse_sess, + krate, + src_name, + &mut rdr, + box out, + annotation.pp_ann(), + false) + }).unwrap() } else { unreachable!(); }; diff --git a/src/librustc_driver/profile/mod.rs b/src/librustc_driver/profile/mod.rs index 9016e0d0fe7..d334a9476ce 100644 --- a/src/librustc_driver/profile/mod.rs +++ b/src/librustc_driver/profile/mod.rs @@ -23,7 +23,7 @@ pub fn begin(sess: &Session) { use std::sync::mpsc::{channel}; let (tx, rx) = channel(); if profq_set_chan(sess, tx) { - thread::spawn(move||profile_queries_thread(rx)); + thread::spawn(move || profile_queries_thread(rx)); } } @@ -34,11 +34,12 @@ pub fn begin(sess: &Session) { pub fn dump(sess: &Session, path: String) { use std::sync::mpsc::{channel}; let (tx, rx) = channel(); - let params = ProfQDumpParams{ - path, ack:tx, + let params = ProfQDumpParams { + path, + ack: tx, // FIXME: Add another compiler flag to toggle whether this log // is written; false for now - dump_profq_msg_log:true, + dump_profq_msg_log: true, }; profq_msg(sess, ProfileQueriesMsg::Dump(params)); let _ = rx.recv().unwrap(); @@ -63,20 +64,20 @@ struct StackFrame { } fn total_duration(traces: &[trace::Rec]) -> Duration { - let mut sum : Duration = Duration::new(0,0); + let mut sum : Duration = Duration::new(0, 0); for t in traces.iter() { sum += t.dur_total; } return sum } // profiling thread; retains state (in local variables) and dump traces, upon request. -fn profile_queries_thread(r:Receiver) { +fn profile_queries_thread(r: Receiver) { use self::trace::*; use std::fs::File; use std::time::{Instant}; - let mut profq_msgs : Vec = vec![]; - let mut frame : StackFrame = StackFrame{ parse_st:ParseState::Clear, traces:vec![] }; - let mut stack : Vec = vec![]; + let mut profq_msgs: Vec = vec![]; + let mut frame: StackFrame = StackFrame { parse_st: ParseState::Clear, traces: vec![] }; + let mut stack: Vec = vec![]; loop { let msg = r.recv(); if let Err(_recv_err) = msg { @@ -138,7 +139,7 @@ fn profile_queries_thread(r:Receiver) { // Parse State: Clear (ParseState::Clear, - ProfileQueriesMsg::QueryBegin(span,querymsg)) => { + ProfileQueriesMsg::QueryBegin(span, querymsg)) => { let start = Instant::now(); frame.parse_st = ParseState::HaveQuery (Query { span, msg: querymsg }, start) @@ -284,8 +285,6 @@ fn profile_queries_thread(r:Receiver) { frame = StackFrame{parse_st:ParseState::Clear, traces:vec![]}; }, - // - // // Parse errors: (ParseState::HaveQuery(q,_), @@ -307,7 +306,6 @@ fn profile_queries_thread(r:Receiver) { unreachable!() }, } - } } } diff --git a/src/librustc_driver/profile/trace.rs b/src/librustc_driver/profile/trace.rs index 121be04bbb1..9589ae2a8db 100644 --- a/src/librustc_driver/profile/trace.rs +++ b/src/librustc_driver/profile/trace.rs @@ -84,9 +84,7 @@ pub fn html_of_effect(eff: &Effect) -> (String, String) { // First return value is text; second return value is a CSS class fn html_of_duration(_start: &Instant, dur: &Duration) -> (String, String) { use rustc::util::common::duration_to_secs_str; - (duration_to_secs_str(dur.clone()), - String::new() - ) + (duration_to_secs_str(dur.clone()), String::new()) } fn html_of_fraction(frac: f64) -> (String, &'static str) { @@ -103,8 +101,12 @@ fn html_of_fraction(frac: f64) -> (String, &'static str) { else { "frac-0" } }; let percent = frac * 100.0; - if percent > 0.1 { (format!("{:.1}%", percent), css) } - else { ("< 0.1%".to_string(), css) } + + if percent > 0.1 { + (format!("{:.1}%", percent), css) + } else { + ("< 0.1%".to_string(), css) + } } fn total_duration(traces: &[Rec]) -> Duration { @@ -149,40 +151,42 @@ fn compute_counts_rec(counts: &mut FxHashMap, traces: &[Rec] match t.effect { Effect::TimeBegin(ref msg) => { let qm = match counts.get(msg) { - Some(_qm) => { panic!("TimeBegin with non-unique, repeat message") } - None => QueryMetric{ + Some(_qm) => panic!("TimeBegin with non-unique, repeat message"), + None => QueryMetric { count: 1, dur_self: t.dur_self, dur_total: t.dur_total, - }}; + } + }; counts.insert(msg.clone(), qm); }, Effect::TaskBegin(ref key) => { let cons = cons_of_key(key); let qm = match counts.get(&cons) { Some(qm) => - QueryMetric{ + QueryMetric { count: qm.count + 1, dur_self: qm.dur_self + t.dur_self, dur_total: qm.dur_total + t.dur_total, }, - None => QueryMetric{ + None => QueryMetric { count: 1, dur_self: t.dur_self, dur_total: t.dur_total, - }}; + } + }; counts.insert(cons, qm); }, Effect::QueryBegin(ref qmsg, ref _cc) => { let qcons = cons_of_query_msg(qmsg); let qm = match counts.get(&qcons) { Some(qm) => - QueryMetric{ + QueryMetric { count: qm.count + 1, dur_total: qm.dur_total + t.dur_total, dur_self: qm.dur_self + t.dur_self }, - None => QueryMetric{ + None => QueryMetric { count: 1, dur_total: t.dur_total, dur_self: t.dur_self, @@ -195,13 +199,14 @@ fn compute_counts_rec(counts: &mut FxHashMap, traces: &[Rec] } } -pub fn write_counts(count_file: &mut File, counts: &mut FxHashMap) { +pub fn write_counts(count_file: &mut File, counts: &mut FxHashMap) { use rustc::util::common::duration_to_secs_str; use std::cmp::Reverse; let mut data = counts.iter().map(|(ref cons, ref qm)| (cons.clone(), qm.count.clone(), qm.dur_total.clone(), qm.dur_self.clone()) ).collect::>(); + data.sort_by_key(|k| Reverse(k.3)); for (cons, count, dur_total, dur_self) in data { writeln!(count_file, "{}, {}, {}, {}", @@ -218,12 +223,12 @@ pub fn write_traces(html_file: &mut File, counts_file: &mut File, traces: &[Rec] compute_counts_rec(&mut counts, traces); write_counts(counts_file, &mut counts); - let total : Duration = total_duration(traces); + let total: Duration = total_duration(traces); write_traces_rec(html_file, traces, total, 0) } pub fn write_style(html_file: &mut File) { - write!(html_file,"{}", " + write!(html_file, "{}", " body { font-family: sans-serif; background: black; -- cgit 1.4.1-3-g733a5 From 78aaa3e5468f7e23267659b99b20f9ef33cdad44 Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Sat, 13 Oct 2018 11:32:49 +0200 Subject: Check the invariant for `principal` inside the method --- src/librustc/traits/coherence.rs | 10 ++---- src/librustc/traits/select.rs | 27 +++++--------- src/librustc/ty/error.rs | 3 +- src/librustc/ty/fast_reject.rs | 2 +- src/librustc/ty/item_path.rs | 2 +- src/librustc/ty/sty.rs | 16 ++++----- src/librustc/ty/wf.rs | 2 +- src/librustc/util/ppaux.rs | 20 +++++------ src/librustc_codegen_llvm/context.rs | 2 +- src/librustc_codegen_llvm/debuginfo/metadata.rs | 7 +--- src/librustc_codegen_llvm/debuginfo/type_names.rs | 14 ++++---- src/librustc_codegen_llvm/meth.rs | 24 ++++++------- src/librustc_mir/interpret/cast.rs | 2 +- src/librustc_mir/monomorphize/collector.rs | 30 ++++++++-------- src/librustc_mir/monomorphize/item.rs | 13 +++---- src/librustc_privacy/lib.rs | 7 ++-- src/librustc_typeck/check/cast.rs | 4 +-- src/librustc_typeck/check/closure.rs | 4 +-- src/librustc_typeck/check/method/confirm.rs | 2 +- src/librustc_typeck/check/method/probe.rs | 7 ++-- src/librustc_typeck/check/method/suggest.rs | 3 +- src/librustc_typeck/coherence/inherent_impls.rs | 4 +-- src/librustc_typeck/coherence/mod.rs | 5 ++- src/librustc_typeck/outlives/implicit_infer.rs | 43 +++++++++++------------ src/librustc_typeck/variance/constraints.rs | 10 +++--- 25 files changed, 112 insertions(+), 151 deletions(-) (limited to 'src') diff --git a/src/librustc/traits/coherence.rs b/src/librustc/traits/coherence.rs index 7add8ef05ee..817e9ffcbb5 100644 --- a/src/librustc/traits/coherence.rs +++ b/src/librustc/traits/coherence.rs @@ -418,9 +418,7 @@ fn fundamental_ty(tcx: TyCtxt<'_, '_, '_>, ty: Ty<'_>) -> bool { match ty.sty { ty::Ref(..) => true, ty::Adt(def, _) => def.is_fundamental(), - ty::Dynamic(ref data, ..) => { - data.principal().map_or(false, |p| tcx.has_attr(p.def_id(), "fundamental")) - } + ty::Dynamic(ref data, ..) => tcx.has_attr(data.principal().def_id(), "fundamental"), _ => false } } @@ -467,11 +465,7 @@ fn ty_is_local_constructor(ty: Ty<'_>, in_crate: InCrate) -> bool { ty::Adt(def, _) => def_id_is_local(def.did, in_crate), ty::Foreign(did) => def_id_is_local(did, in_crate), - ty::Dynamic(ref tt, ..) => { - tt.principal().map_or(false, |p| - def_id_is_local(p.def_id(), in_crate) - ) - } + ty::Dynamic(ref tt, ..) => def_id_is_local(tt.principal().def_id(), in_crate), ty::Error => true, diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs index 82d881e10b1..8e8024e51da 100644 --- a/src/librustc/traits/select.rs +++ b/src/librustc/traits/select.rs @@ -2088,10 +2088,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { return; } - match data.principal() { - Some(p) => p.with_self_ty(this.tcx(), self_ty), - None => return, - } + data.principal().with_self_ty(this.tcx(), self_ty) } ty::Infer(ty::TyVar(_)) => { debug!("assemble_candidates_from_object_ty: ambiguous"); @@ -2183,15 +2180,10 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { // // We always upcast when we can because of reason // #2 (region bounds). - match (data_a.principal(), data_b.principal()) { - (Some(a), Some(b)) => { - a.def_id() == b.def_id() - && data_b.auto_traits() - // All of a's auto traits need to be in b's auto traits. - .all(|b| data_a.auto_traits().any(|a| a == b)) - } - _ => false, - } + data_a.principal().def_id() == data_b.principal().def_id() + && data_b.auto_traits() + // All of a's auto traits need to be in b's auto traits. + .all(|b| data_a.auto_traits().any(|a| a == b)) } // T -> Trait. @@ -2981,7 +2973,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { .shallow_resolve(*obligation.self_ty().skip_binder()); let poly_trait_ref = match self_ty.sty { ty::Dynamic(ref data, ..) => { - data.principal().unwrap().with_self_ty(self.tcx(), self_ty) + data.principal().with_self_ty(self.tcx(), self_ty) } _ => span_bug!(obligation.cause.span, "object candidate with non-object"), }; @@ -3244,10 +3236,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { (&ty::Dynamic(ref data_a, r_a), &ty::Dynamic(ref data_b, r_b)) => { // See assemble_candidates_for_unsizing for more info. let existential_predicates = data_a.map_bound(|data_a| { - let principal = data_a.principal(); - let iter = principal - .into_iter() - .map(ty::ExistentialPredicate::Trait) + let iter = iter::once(ty::ExistentialPredicate::Trait(data_a.principal())) .chain( data_a .projection_bounds() @@ -3285,7 +3274,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { // T -> Trait. (_, &ty::Dynamic(ref data, r)) => { let mut object_dids = data.auto_traits() - .chain(data.principal().map(|p| p.def_id())); + .chain(iter::once(data.principal().def_id())); if let Some(did) = object_dids.find(|did| !tcx.is_object_safe(*did)) { return Err(TraitNotObjectSafe(did)); } diff --git a/src/librustc/ty/error.rs b/src/librustc/ty/error.rs index 3123f0fbe31..d886d5ed204 100644 --- a/src/librustc/ty/error.rs +++ b/src/librustc/ty/error.rs @@ -208,8 +208,7 @@ impl<'a, 'gcx, 'lcx, 'tcx> ty::TyS<'tcx> { ty::FnDef(..) => "fn item".into(), ty::FnPtr(_) => "fn pointer".into(), ty::Dynamic(ref inner, ..) => { - inner.principal().map_or_else(|| "trait".into(), - |p| format!("trait {}", tcx.item_path_str(p.def_id())).into()) + format!("trait {}", tcx.item_path_str(inner.principal().def_id())).into() } ty::Closure(..) => "closure".into(), ty::Generator(..) => "generator".into(), diff --git a/src/librustc/ty/fast_reject.rs b/src/librustc/ty/fast_reject.rs index 0f68e7aba4d..e6aaf8b1bb2 100644 --- a/src/librustc/ty/fast_reject.rs +++ b/src/librustc/ty/fast_reject.rs @@ -78,7 +78,7 @@ pub fn simplify_type<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>, ty::Array(..) | ty::Slice(_) => Some(ArraySimplifiedType), ty::RawPtr(_) => Some(PtrSimplifiedType), ty::Dynamic(ref trait_info, ..) => { - trait_info.principal().map(|p| TraitSimplifiedType(p.def_id())) + Some(TraitSimplifiedType(trait_info.principal().def_id())) } ty::Ref(_, ty, _) => { // since we introduce auto-refs during method lookup, we diff --git a/src/librustc/ty/item_path.rs b/src/librustc/ty/item_path.rs index ab081324036..c4a25971da3 100644 --- a/src/librustc/ty/item_path.rs +++ b/src/librustc/ty/item_path.rs @@ -436,7 +436,7 @@ pub fn characteristic_def_id_of_type(ty: Ty<'_>) -> Option { match ty.sty { ty::Adt(adt_def, _) => Some(adt_def.did), - ty::Dynamic(data, ..) => data.principal().map(|p| p.def_id()), + ty::Dynamic(data, ..) => Some(data.principal().def_id()), ty::Array(subty, _) | ty::Slice(subty) => characteristic_def_id_of_type(subty), diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs index 145c122e75d..cc6e6b2861e 100644 --- a/src/librustc/ty/sty.rs +++ b/src/librustc/ty/sty.rs @@ -559,10 +559,10 @@ impl<'a, 'gcx, 'tcx> Binder> { impl<'tcx> serialize::UseSpecializedDecodable for &'tcx List> {} impl<'tcx> List> { - pub fn principal(&self) -> Option> { - match self.get(0) { - Some(&ExistentialPredicate::Trait(tr)) => Some(tr), - _ => None, + pub fn principal(&self) -> ExistentialTraitRef<'tcx> { + match self[0] { + ExistentialPredicate::Trait(tr) => tr, + other => bug!("first predicate is {:?}", other), } } @@ -589,8 +589,8 @@ impl<'tcx> List> { } impl<'tcx> Binder<&'tcx List>> { - pub fn principal(&self) -> Option> { - self.skip_binder().principal().map(Binder::bind) + pub fn principal(&self) -> PolyExistentialTraitRef<'tcx> { + Binder::bind(self.skip_binder().principal()) } #[inline] @@ -1825,9 +1825,7 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> { } Dynamic(ref obj, region) => { let mut v = vec![region]; - if let Some(p) = obj.principal() { - v.extend(p.skip_binder().substs.regions()); - } + v.extend(obj.principal().skip_binder().substs.regions()); v } Adt(_, substs) | Opaque(_, substs) => { diff --git a/src/librustc/ty/wf.rs b/src/librustc/ty/wf.rs index 7af838845cd..27747970f76 100644 --- a/src/librustc/ty/wf.rs +++ b/src/librustc/ty/wf.rs @@ -387,7 +387,7 @@ impl<'a, 'gcx, 'tcx> WfPredicates<'a, 'gcx, 'tcx> { let cause = self.cause(traits::MiscObligation); let component_traits = - data.auto_traits().chain(data.principal().map(|p| p.def_id())); + data.auto_traits().chain(once(data.principal().def_id())); self.out.extend( component_traits.map(|did| traits::Obligation::new( cause.clone(), diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index 33534ab27f1..f3b5503b8d0 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -621,16 +621,16 @@ define_print! { // Use a type that can't appear in defaults of type parameters. let dummy_self = tcx.mk_infer(ty::FreshTy(0)); - if let Some(p) = self.principal() { - let principal = tcx.lift(&p).expect("could not lift TraitRef for printing") - .with_self_ty(tcx, dummy_self); - let projections = self.projection_bounds().map(|p| { - tcx.lift(&p) - .expect("could not lift projection for printing") - .with_self_ty(tcx, dummy_self) - }).collect::>(); - cx.parameterized(f, principal.substs, principal.def_id, &projections)?; - } + let principal = tcx + .lift(&self.principal()) + .expect("could not lift TraitRef for printing") + .with_self_ty(tcx, dummy_self); + let projections = self.projection_bounds().map(|p| { + tcx.lift(&p) + .expect("could not lift projection for printing") + .with_self_ty(tcx, dummy_self) + }).collect::>(); + cx.parameterized(f, principal.substs, principal.def_id, &projections)?; // Builtin bounds. for did in self.auto_traits() { diff --git a/src/librustc_codegen_llvm/context.rs b/src/librustc_codegen_llvm/context.rs index 578018c7adc..e6197423738 100644 --- a/src/librustc_codegen_llvm/context.rs +++ b/src/librustc_codegen_llvm/context.rs @@ -59,7 +59,7 @@ pub struct CodegenCx<'a, 'tcx: 'a> { /// Cache instances of monomorphic and polymorphic items pub instances: RefCell, &'a Value>>, /// Cache generated vtables - pub vtables: RefCell, Option>), + pub vtables: RefCell, ty::PolyExistentialTraitRef<'tcx>), &'a Value>>, /// Cache of constant strings, pub const_cstr_cache: RefCell>, diff --git a/src/librustc_codegen_llvm/debuginfo/metadata.rs b/src/librustc_codegen_llvm/debuginfo/metadata.rs index 706568b5446..6eff086a2ba 100644 --- a/src/librustc_codegen_llvm/debuginfo/metadata.rs +++ b/src/librustc_codegen_llvm/debuginfo/metadata.rs @@ -435,12 +435,7 @@ fn trait_pointer_metadata( // But it does not describe the trait's methods. let containing_scope = match trait_type.sty { - ty::Dynamic(ref data, ..) => if let Some(principal) = data.principal() { - let def_id = principal.def_id(); - Some(get_namespace_for_item(cx, def_id)) - } else { - NO_SCOPE_METADATA - }, + ty::Dynamic(ref data, ..) => Some(get_namespace_for_item(cx, data.principal().def_id())), _ => { bug!("debuginfo: Unexpected trait-object type in \ trait_pointer_metadata(): {:?}", diff --git a/src/librustc_codegen_llvm/debuginfo/type_names.rs b/src/librustc_codegen_llvm/debuginfo/type_names.rs index 2f110fd552a..06b9318a5e8 100644 --- a/src/librustc_codegen_llvm/debuginfo/type_names.rs +++ b/src/librustc_codegen_llvm/debuginfo/type_names.rs @@ -116,14 +116,12 @@ pub fn push_debuginfo_type_name<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, } }, ty::Dynamic(ref trait_data, ..) => { - if let Some(principal) = trait_data.principal() { - let principal = cx.tcx.normalize_erasing_late_bound_regions( - ty::ParamEnv::reveal_all(), - &principal, - ); - push_item_name(cx, principal.def_id, false, output); - push_type_params(cx, principal.substs, output); - } + let principal = cx.tcx.normalize_erasing_late_bound_regions( + ty::ParamEnv::reveal_all(), + &trait_data.principal(), + ); + push_item_name(cx, principal.def_id, false, output); + push_type_params(cx, principal.substs, output); }, ty::FnDef(..) | ty::FnPtr(_) => { let sig = t.fn_sig(cx.tcx); diff --git a/src/librustc_codegen_llvm/meth.rs b/src/librustc_codegen_llvm/meth.rs index 8a1159bc477..db06b87f44e 100644 --- a/src/librustc_codegen_llvm/meth.rs +++ b/src/librustc_codegen_llvm/meth.rs @@ -72,7 +72,7 @@ impl<'a, 'tcx> VirtualIndex { pub fn get_vtable( cx: &CodegenCx<'ll, 'tcx>, ty: Ty<'tcx>, - trait_ref: Option>, + trait_ref: ty::PolyExistentialTraitRef<'tcx>, ) -> &'ll Value { let tcx = cx.tcx; @@ -86,23 +86,19 @@ pub fn get_vtable( // Not in the cache. Build it. let nullptr = C_null(Type::i8p(cx)); + let methods = tcx.vtable_methods(trait_ref.with_self_ty(tcx, ty)); + let methods = methods.iter().cloned().map(|opt_mth| { + opt_mth.map_or(nullptr, |(def_id, substs)| { + callee::resolve_and_get_fn(cx, def_id, substs) + }) + }); + let (size, align) = cx.size_and_align_of(ty); - let mut components: Vec<_> = [ + let components: Vec<_> = [ callee::get_fn(cx, monomorphize::resolve_drop_in_place(cx.tcx, ty)), C_usize(cx, size.bytes()), C_usize(cx, align.abi()) - ].iter().cloned().collect(); - - if let Some(trait_ref) = trait_ref { - let trait_ref = trait_ref.with_self_ty(tcx, ty); - let methods = tcx.vtable_methods(trait_ref); - let methods = methods.iter().cloned().map(|opt_mth| { - opt_mth.map_or(nullptr, |(def_id, substs)| { - callee::resolve_and_get_fn(cx, def_id, substs) - }) - }); - components.extend(methods); - } + ].iter().cloned().chain(methods).collect(); let vtable_const = C_struct(cx, &components, false); let align = cx.data_layout().pointer_align; diff --git a/src/librustc_mir/interpret/cast.rs b/src/librustc_mir/interpret/cast.rs index bfc7e6801fc..32ce16212e4 100644 --- a/src/librustc_mir/interpret/cast.rs +++ b/src/librustc_mir/interpret/cast.rs @@ -326,7 +326,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> } (_, &ty::Dynamic(ref data, _)) => { // Initial cast from sized to dyn trait - let trait_ref = data.principal().unwrap().with_self_ty( + let trait_ref = data.principal().with_self_ty( *self.tcx, src_pointee_ty, ); diff --git a/src/librustc_mir/monomorphize/collector.rs b/src/librustc_mir/monomorphize/collector.rs index 29f16762944..dd83d3157ba 100644 --- a/src/librustc_mir/monomorphize/collector.rs +++ b/src/librustc_mir/monomorphize/collector.rs @@ -907,22 +907,20 @@ fn create_mono_items_for_vtable_methods<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, !impl_ty.needs_subst() && !impl_ty.has_escaping_regions()); if let ty::Dynamic(ref trait_ty, ..) = trait_ty.sty { - if let Some(principal) = trait_ty.principal() { - let poly_trait_ref = principal.with_self_ty(tcx, impl_ty); - assert!(!poly_trait_ref.has_escaping_regions()); - - // Walk all methods of the trait, including those of its supertraits - let methods = tcx.vtable_methods(poly_trait_ref); - let methods = methods.iter().cloned().filter_map(|method| method) - .map(|(def_id, substs)| ty::Instance::resolve( - tcx, - ty::ParamEnv::reveal_all(), - def_id, - substs).unwrap()) - .filter(|&instance| should_monomorphize_locally(tcx, &instance)) - .map(|instance| create_fn_mono_item(instance)); - output.extend(methods); - } + let poly_trait_ref = trait_ty.principal().with_self_ty(tcx, impl_ty); + assert!(!poly_trait_ref.has_escaping_regions()); + + // Walk all methods of the trait, including those of its supertraits + let methods = tcx.vtable_methods(poly_trait_ref); + let methods = methods.iter().cloned().filter_map(|method| method) + .map(|(def_id, substs)| ty::Instance::resolve( + tcx, + ty::ParamEnv::reveal_all(), + def_id, + substs).unwrap()) + .filter(|&instance| should_monomorphize_locally(tcx, &instance)) + .map(|instance| create_fn_mono_item(instance)); + output.extend(methods); // Also add the destructor visit_drop_use(tcx, impl_ty, false, output); } diff --git a/src/librustc_mir/monomorphize/item.rs b/src/librustc_mir/monomorphize/item.rs index f0ea93bfffd..4c4d56c8938 100644 --- a/src/librustc_mir/monomorphize/item.rs +++ b/src/librustc_mir/monomorphize/item.rs @@ -320,12 +320,13 @@ impl<'a, 'tcx> DefPathBasedNames<'a, 'tcx> { output.push(']'); }, ty::Dynamic(ref trait_data, ..) => { - if let Some(principal) = trait_data.principal() { - self.push_def_path(principal.def_id(), output); - self.push_type_params(principal.skip_binder().substs, - trait_data.projection_bounds(), - output); - } + let principal = trait_data.principal(); + self.push_def_path(principal.def_id(), output); + self.push_type_params( + principal.skip_binder().substs, + trait_data.projection_bounds(), + output, + ); }, ty::Foreign(did) => self.push_def_path(did, output), ty::FnDef(..) | diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs index 60679d6d430..989851bb1b9 100644 --- a/src/librustc_privacy/lib.rs +++ b/src/librustc_privacy/lib.rs @@ -93,8 +93,7 @@ impl<'a, 'tcx> EmbargoVisitor<'a, 'tcx> { let ty_def_id = match self.tcx.type_of(item_def_id).sty { ty::Adt(adt, _) => adt.did, ty::Foreign(did) => did, - ty::Dynamic(ref obj, ..) if obj.principal().is_some() => - obj.principal().unwrap().def_id(), + ty::Dynamic(ref obj, ..) => obj.principal().def_id(), ty::Projection(ref proj) => proj.trait_ref(self.tcx).def_id, _ => return Some(AccessLevel::Public) }; @@ -484,7 +483,7 @@ impl<'b, 'a, 'tcx> TypeVisitor<'tcx> for ReachEverythingInTheInterfaceVisitor<'b let ty_def_id = match ty.sty { ty::Adt(adt, _) => Some(adt.did), ty::Foreign(did) => Some(did), - ty::Dynamic(ref obj, ..) => obj.principal().map(|p| p.def_id()), + ty::Dynamic(ref obj, ..) => Some(obj.principal().def_id()), ty::Projection(ref proj) => Some(proj.item_def_id), ty::FnDef(def_id, ..) | ty::Closure(def_id, ..) | @@ -1456,7 +1455,7 @@ impl<'a, 'tcx: 'a> TypeVisitor<'tcx> for SearchInterfaceForPrivateItemsVisitor<' let ty_def_id = match ty.sty { ty::Adt(adt, _) => Some(adt.did), ty::Foreign(did) => Some(did), - ty::Dynamic(ref obj, ..) => obj.principal().map(|p| p.def_id()), + ty::Dynamic(ref obj, ..) => Some(obj.principal().def_id()), ty::Projection(ref proj) => { if self.required_visibility == ty::Visibility::Invisible { // Conservatively approximate the whole type alias as public without diff --git a/src/librustc_typeck/check/cast.rs b/src/librustc_typeck/check/cast.rs index 285fed9544d..e0ee26cba08 100644 --- a/src/librustc_typeck/check/cast.rs +++ b/src/librustc_typeck/check/cast.rs @@ -73,7 +73,7 @@ enum PointerKind<'tcx> { /// No metadata attached, ie pointer to sized type or foreign type Thin, /// A trait object - Vtable(Option), + Vtable(DefId), /// Slice Length, /// The unsize info of this projection @@ -105,7 +105,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { Ok(match t.sty { ty::Slice(_) | ty::Str => Some(PointerKind::Length), ty::Dynamic(ref tty, ..) => - Some(PointerKind::Vtable(tty.principal().map(|p| p.def_id()))), + Some(PointerKind::Vtable(tty.principal().def_id())), ty::Adt(def, substs) if def.is_struct() => { match def.non_enum_variant().fields.last() { None => Some(PointerKind::Thin), diff --git a/src/librustc_typeck/check/closure.rs b/src/librustc_typeck/check/closure.rs index 202789d1d8a..940fa4d3916 100644 --- a/src/librustc_typeck/check/closure.rs +++ b/src/librustc_typeck/check/closure.rs @@ -198,9 +198,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { self.deduce_sig_from_projection(None, &pb) }) .next(); - let kind = object_type - .principal() - .and_then(|p| self.tcx.lang_items().fn_trait_kind(p.def_id())); + let kind = self.tcx.lang_items().fn_trait_kind(object_type.principal().def_id()); (sig, kind) } ty::Infer(ty::TyVar(vid)) => self.deduce_expectations_from_obligations(vid), diff --git a/src/librustc_typeck/check/method/confirm.rs b/src/librustc_typeck/check/method/confirm.rs index 4e5488b432d..75f5bf74c6a 100644 --- a/src/librustc_typeck/check/method/confirm.rs +++ b/src/librustc_typeck/check/method/confirm.rs @@ -290,7 +290,7 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> { .include_raw_pointers() .filter_map(|(ty, _)| match ty.sty { - ty::Dynamic(ref data, ..) => data.principal().map(|p| closure(self, ty, p)), + ty::Dynamic(ref data, ..) => Some(closure(self, ty, data.principal())), _ => None, } ) diff --git a/src/librustc_typeck/check/method/probe.rs b/src/librustc_typeck/check/method/probe.rs index ec4483204f0..ae02cd64c38 100644 --- a/src/librustc_typeck/check/method/probe.rs +++ b/src/librustc_typeck/check/method/probe.rs @@ -452,10 +452,9 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> { match self_ty.sty { ty::Dynamic(ref data, ..) => { - if let Some(p) = data.principal() { - self.assemble_inherent_candidates_from_object(self_ty, p); - self.assemble_inherent_impl_candidates_for_type(p.def_id()); - } + let p = data.principal(); + self.assemble_inherent_candidates_from_object(self_ty, p); + self.assemble_inherent_impl_candidates_for_type(p.def_id()); } ty::Adt(def, _) => { self.assemble_inherent_impl_candidates_for_type(def.did); diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs index 28b9dcb9bfd..2006796a100 100644 --- a/src/librustc_typeck/check/method/suggest.rs +++ b/src/librustc_typeck/check/method/suggest.rs @@ -663,8 +663,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { ty::Adt(def, _) => def.did.is_local(), ty::Foreign(did) => did.is_local(), - ty::Dynamic(ref tr, ..) => tr.principal() - .map_or(false, |p| p.def_id().is_local()), + ty::Dynamic(ref tr, ..) => tr.principal().def_id().is_local(), ty::Param(_) => true, diff --git a/src/librustc_typeck/coherence/inherent_impls.rs b/src/librustc_typeck/coherence/inherent_impls.rs index 1955a709dbf..ec979dea4fd 100644 --- a/src/librustc_typeck/coherence/inherent_impls.rs +++ b/src/librustc_typeck/coherence/inherent_impls.rs @@ -108,8 +108,8 @@ impl<'a, 'tcx, 'v> ItemLikeVisitor<'v> for InherentCollect<'a, 'tcx> { ty::Foreign(did) => { self.check_def_id(item, did); } - ty::Dynamic(ref data, ..) if data.principal().is_some() => { - self.check_def_id(item, data.principal().unwrap().def_id()); + ty::Dynamic(ref data, ..) => { + self.check_def_id(item, data.principal().def_id()); } ty::Char => { self.check_primitive_impl(def_id, diff --git a/src/librustc_typeck/coherence/mod.rs b/src/librustc_typeck/coherence/mod.rs index 616ca97a7a7..9b17654d469 100644 --- a/src/librustc_typeck/coherence/mod.rs +++ b/src/librustc_typeck/coherence/mod.rs @@ -181,13 +181,12 @@ fn check_impl_overlap<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, node_id: ast::NodeI // This is something like impl Trait1 for Trait2. Illegal // if Trait1 is a supertrait of Trait2 or Trait2 is not object safe. - if data.principal().map_or(true, |p| !tcx.is_object_safe(p.def_id())) { + if !tcx.is_object_safe(data.principal().def_id()) { // This is an error, but it will be reported by wfcheck. Ignore it here. // This is tested by `coherence-impl-trait-for-trait-object-safe.rs`. } else { let mut supertrait_def_ids = - traits::supertrait_def_ids(tcx, - data.principal().unwrap().def_id()); + traits::supertrait_def_ids(tcx, data.principal().def_id()); if supertrait_def_ids.any(|d| d == trait_def_id) { let sp = tcx.sess.source_map().def_span(tcx.span_of_impl(impl_def_id).unwrap()); struct_span_err!(tcx.sess, diff --git a/src/librustc_typeck/outlives/implicit_infer.rs b/src/librustc_typeck/outlives/implicit_infer.rs index 254146c0ef3..132da8f5cea 100644 --- a/src/librustc_typeck/outlives/implicit_infer.rs +++ b/src/librustc_typeck/outlives/implicit_infer.rs @@ -203,28 +203,27 @@ fn insert_required_predicates_to_be_wf<'tcx>( debug!("Dynamic"); debug!("field_ty = {}", &field_ty); debug!("ty in field = {}", &ty); - if let Some(ex_trait_ref) = obj.principal() { - // Here, we are passing the type `usize` as a - // placeholder value with the function - // `with_self_ty`, since there is no concrete type - // `Self` for a `dyn Trait` at this - // stage. Therefore when checking explicit - // predicates in `check_explicit_predicates` we - // need to ignore checking the explicit_map for - // Self type. - let substs = ex_trait_ref - .with_self_ty(tcx, tcx.types.usize) - .skip_binder() - .substs; - check_explicit_predicates( - tcx, - &ex_trait_ref.skip_binder().def_id, - substs, - required_predicates, - explicit_map, - IgnoreSelfTy(true), - ); - } + let ex_trait_ref = obj.principal(); + // Here, we are passing the type `usize` as a + // placeholder value with the function + // `with_self_ty`, since there is no concrete type + // `Self` for a `dyn Trait` at this + // stage. Therefore when checking explicit + // predicates in `check_explicit_predicates` we + // need to ignore checking the explicit_map for + // Self type. + let substs = ex_trait_ref + .with_self_ty(tcx, tcx.types.usize) + .skip_binder() + .substs; + check_explicit_predicates( + tcx, + &ex_trait_ref.skip_binder().def_id, + substs, + required_predicates, + explicit_map, + IgnoreSelfTy(true), + ); } ty::Projection(obj) => { diff --git a/src/librustc_typeck/variance/constraints.rs b/src/librustc_typeck/variance/constraints.rs index 32a591777db..3e523c0c7f5 100644 --- a/src/librustc_typeck/variance/constraints.rs +++ b/src/librustc_typeck/variance/constraints.rs @@ -311,11 +311,11 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> { let contra = self.contravariant(variance); self.add_constraints_from_region(current, r, contra); - if let Some(p) = data.principal() { - let poly_trait_ref = p.with_self_ty(self.tcx(), self.tcx().types.err); - self.add_constraints_from_trait_ref( - current, *poly_trait_ref.skip_binder(), variance); - } + let poly_trait_ref = data + .principal() + .with_self_ty(self.tcx(), self.tcx().types.err); + self.add_constraints_from_trait_ref( + current, *poly_trait_ref.skip_binder(), variance); for projection in data.projection_bounds() { self.add_constraints_from_ty( -- cgit 1.4.1-3-g733a5 From ce61be81be589f05f40cee2ead6b867b789306a6 Mon Sep 17 00:00:00 2001 From: Matthias Krüger Date: Thu, 11 Oct 2018 13:53:32 +0200 Subject: submodules: update clippy from 32b1d1fc to 9d337313 Changes: Remove now-useless `allow(unknown_lints)` Stabilize tool lints Use `impl Iterator` in arg position in clippy_dev Fix fn_to_numeric_cast_with_truncation suppression Limit commutative assign op lint to primitive types Clarify code Fix #2937 Fix cast_possible_wrap and cast_sign_loss warnings Fix cast_possible_truncation warnings Fixes #2925 cmp_owned false positive if_let_redundant_pattern_matching: use Span.to() instead of Span.with_hi() to fix crash. Improve diagnostics in case of lifetime elision (closes #3284) Fix items_after_statements for `const`s Fix items_after_statements for sub-functions Fix items_after_statements for `use` statements Don't suggest cloned() for map Box deref Fix excessive_precision false positive Fix FP in `fn_to_numeric_cast_with_truncation` new_without_default should not warn about unsafe new fix command to manually test an example Add license to README Adding more detail to filter_map lint documentation. additional people Add license header to other files Add license header to Rust files Relicense clippy Document relicensing process Fix util/export.py to include lints from methods --- src/tools/clippy | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/tools/clippy b/src/tools/clippy index 32b1d1fc157..9d3373137b7 160000 --- a/src/tools/clippy +++ b/src/tools/clippy @@ -1 +1 @@ -Subproject commit 32b1d1fc157f71ed2f10b60fe28abe087a743618 +Subproject commit 9d3373137b74a403281b293b19ab9346773af073 -- cgit 1.4.1-3-g733a5 From 2e84e9c09daf3e4b6d43cb7b302d4663e40d0a08 Mon Sep 17 00:00:00 2001 From: Matthias Krüger Date: Thu, 11 Oct 2018 14:03:21 +0200 Subject: submodules: update rls from 15d4d4a to 440a985 Changes: Apply Clippy lints Respect build_dir when creating external build plans Fix Windows tests Implement external build plan Detect manifest diagnostic position for toml::de::Error Fix std::sync hover doc expectation Apply CI specific long timeout Propagate cargo errors as manifest diagnostics Add test for use statement function completions Refactor cmd test `within_timeout` Avoid stdout-writer/rls process exit race Improve cmd test "no shutdown response" error message Add RUST_BACKTRACE=1 to ci env Improve cmd test timeout reliability Fix use statement function suggestions Revert "Revert "Remove "edition" Cargo feature (it's stable now)"" Add build_wait() tests Automatically tune wait_to_build Rework cmd tests Fixes #54697 --- src/Cargo.lock | 7 ++++--- src/tools/rls | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/Cargo.lock b/src/Cargo.lock index abe736a4fe6..5d626cc79b4 100644 --- a/src/Cargo.lock +++ b/src/Cargo.lock @@ -1649,7 +1649,7 @@ dependencies = [ [[package]] name = "racer" -version = "2.1.6" +version = "2.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1797,7 +1797,7 @@ dependencies = [ "log 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "ordslice 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "racer 2.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "racer 2.1.7 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", "rayon 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "regex 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1814,6 +1814,7 @@ dependencies = [ "serde 1.0.75 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.75 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.31 (registry+https://github.com/rust-lang/crates.io-index)", + "toml 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "walkdir 2.2.5 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -3319,7 +3320,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a" "checksum quote 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9949cfe66888ffe1d53e6ec9d9f3b70714083854be20fd5e271b232a017401e8" "checksum quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)" = "dd636425967c33af890042c483632d33fa7a18f19ad1d7ea72e8998c6ef8dea5" -"checksum racer 2.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "99e820b7f7701c834c3f6f8226f388c19c0ea948a3ef79ddc96aa7398b5ba87a" +"checksum racer 2.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "0beefbfaed799c3554021a48856113ad53862311395f6d75376192884ba5fbe6" "checksum rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8356f47b32624fef5b3301c1be97e5944ecdd595409cc5da11d05f211db6cfbd" "checksum rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e464cd887e869cddcae8792a4ee31d23c7edd516700695608f5b98c67ee0131c" "checksum rand_core 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "edecf0f94da5551fc9b492093e30b041a891657db7940ee221f9d2f66e82eef2" diff --git a/src/tools/rls b/src/tools/rls index 15d4d4a5b0c..440a9855b73 160000 --- a/src/tools/rls +++ b/src/tools/rls @@ -1 +1 @@ -Subproject commit 15d4d4a5b0cf3c0155195f3322cc7a61148e5567 +Subproject commit 440a9855b73b6bf9b5345cf3a79565566f6ef345 -- cgit 1.4.1-3-g733a5 From ab4e697d0b70b80b85255962b5fb5a027929e9c9 Mon Sep 17 00:00:00 2001 From: Matthias Krüger Date: Mon, 8 Oct 2018 21:05:14 +0200 Subject: submodules: update cargo from ad6e5c00 to 5dbac988 Changes: Switch to use crates-io as the registry name and don't include publish when registry is not specified fix redundant pkgid generation validate some basic properties of a valid resolve Detail dep name in invalid version error Fix dashes in rename dependencies. Bump flate2 to 1.0.3 Add default in config document Add support for providing a default registry Add support for registry to new and init use impl Iterator instead of custom types in `source` let jetbrains reorder some impls to match the definition use impl Iterator instead of custom types in resolver and graph remove Graph::sort as it is unused fmt Bump libgit2-sys to 0.7.9 Switch to use registry Allow registry option for cargo install. Second attempt at fixing msys terminal width. Try to improve "version not found" error Fix typo --- src/Cargo.lock | 14 +++++++------- src/tools/cargo | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/Cargo.lock b/src/Cargo.lock index 5d626cc79b4..52314b0ac89 100644 --- a/src/Cargo.lock +++ b/src/Cargo.lock @@ -204,7 +204,7 @@ dependencies = [ "env_logger 0.5.12 (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.2 (registry+https://github.com/rust-lang/crates.io-index)", + "flate2 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", "fs2 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "fwdansi 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "git2 0.7.5 (registry+https://github.com/rust-lang/crates.io-index)", @@ -737,7 +737,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "flate2" -version = "1.0.2" +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)", @@ -959,7 +959,7 @@ version = "0.0.0" dependencies = [ "clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)", "error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", - "flate2 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "flate2 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "rayon 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "tar 0.4.16 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1890,7 +1890,7 @@ dependencies = [ "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "chalk-engine 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", - "flate2 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "flate2 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", "fmt_macros 0.0.0", "graphviz 0.0.0", "jobserver 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2134,7 +2134,7 @@ dependencies = [ name = "rustc_codegen_utils" version = "0.0.0" dependencies = [ - "flate2 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "flate2 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", "rustc 0.0.0", "rustc_data_structures 0.0.0", @@ -2277,7 +2277,7 @@ dependencies = [ name = "rustc_metadata" version = "0.0.0" dependencies = [ - "flate2 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "flate2 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", "proc_macro 0.0.0", "rustc 0.0.0", @@ -3223,7 +3223,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum failure_derive 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "946d0e98a50d9831f5d589038d2ca7f8f455b1c21028c0db0e84116a12696426" "checksum filetime 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "da4b9849e77b13195302c174324b5ba73eec9b236b24c221a61000daefb95c5f" "checksum fixedbitset 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "86d4de0081402f5e88cdac65c8dcdcc73118c1a7a465e2a05f0da05843a8ea33" -"checksum flate2 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "37847f133aae7acf82bb9577ccd8bda241df836787642654286e79679826a54b" +"checksum flate2 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4af030962d89d62aa52cd9492083b1cd9b2d1a77764878102a6c0f86b4d5444d" "checksum fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2fad85553e09a6f881f739c29f0b00b0f01357c743266d478b68951ce23285f3" "checksum foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" "checksum foreign-types-shared 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" diff --git a/src/tools/cargo b/src/tools/cargo index ad6e5c0037d..5dbac988851 160000 --- a/src/tools/cargo +++ b/src/tools/cargo @@ -1 +1 @@ -Subproject commit ad6e5c0037d88602a1c95051e42b392ed5ffcbe8 +Subproject commit 5dbac98885199bbd7c0f189d7405b5523434d1e3 -- cgit 1.4.1-3-g733a5 From 585490d816b219dac781f763c2e3e4d2028b68ab Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Sat, 13 Oct 2018 19:41:27 +0200 Subject: Also adjust rustdoc to the principal changes --- src/librustdoc/clean/mod.rs | 73 ++++++++++++++++++++++----------------------- 1 file changed, 35 insertions(+), 38 deletions(-) (limited to 'src') diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index ddabef96c7c..2ba1f103971 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -2632,47 +2632,44 @@ impl<'tcx> Clean for Ty<'tcx> { } } ty::Dynamic(ref obj, ref reg) => { - if let Some(principal) = obj.principal() { - let did = principal.def_id(); + let principal = obj.principal(); + let did = principal.def_id(); + inline::record_extern_fqn(cx, did, TypeKind::Trait); + + let mut typarams = vec![]; + reg.clean(cx).map(|b| typarams.push(GenericBound::Outlives(b))); + for did in obj.auto_traits() { + let empty = cx.tcx.intern_substs(&[]); + let path = external_path(cx, &cx.tcx.item_name(did).as_str(), + Some(did), false, vec![], empty); inline::record_extern_fqn(cx, did, TypeKind::Trait); + let bound = GenericBound::TraitBound(PolyTrait { + trait_: ResolvedPath { + path, + typarams: None, + did, + is_generic: false, + }, + generic_params: Vec::new(), + }, hir::TraitBoundModifier::None); + typarams.push(bound); + } - let mut typarams = vec![]; - reg.clean(cx).map(|b| typarams.push(GenericBound::Outlives(b))); - for did in obj.auto_traits() { - let empty = cx.tcx.intern_substs(&[]); - let path = external_path(cx, &cx.tcx.item_name(did).as_str(), - Some(did), false, vec![], empty); - inline::record_extern_fqn(cx, did, TypeKind::Trait); - let bound = GenericBound::TraitBound(PolyTrait { - trait_: ResolvedPath { - path, - typarams: None, - did, - is_generic: false, - }, - generic_params: Vec::new(), - }, hir::TraitBoundModifier::None); - typarams.push(bound); - } - - let mut bindings = vec![]; - for pb in obj.projection_bounds() { - bindings.push(TypeBinding { - name: cx.tcx.associated_item(pb.item_def_id()).ident.name.clean(cx), - ty: pb.skip_binder().ty.clean(cx) - }); - } + let mut bindings = vec![]; + for pb in obj.projection_bounds() { + bindings.push(TypeBinding { + name: cx.tcx.associated_item(pb.item_def_id()).ident.name.clean(cx), + ty: pb.skip_binder().ty.clean(cx) + }); + } - let path = external_path(cx, &cx.tcx.item_name(did).as_str(), Some(did), - false, bindings, principal.skip_binder().substs); - ResolvedPath { - path, - typarams: Some(typarams), - did, - is_generic: false, - } - } else { - Never + let path = external_path(cx, &cx.tcx.item_name(did).as_str(), Some(did), + false, bindings, principal.skip_binder().substs); + ResolvedPath { + path, + typarams: Some(typarams), + did, + is_generic: false, } } ty::Tuple(ref t) => Tuple(t.clean(cx)), -- cgit 1.4.1-3-g733a5 From 9c651b3b317575cd9241e8bee343116c9fb81bc7 Mon Sep 17 00:00:00 2001 From: Matthias Krüger Date: Sat, 13 Oct 2018 20:38:49 +0200 Subject: bootstrap: update clippy license locations which changed due to relicensing. --- src/bootstrap/dist.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index c25f94357f2..cf79d4f777a 100644 --- a/src/bootstrap/dist.rs +++ b/src/bootstrap/dist.rs @@ -1263,14 +1263,16 @@ impl Step for Clippy { builder.install(&cargoclippy, &image.join("bin"), 0o755); let doc = image.join("share/doc/clippy"); builder.install(&src.join("README.md"), &doc, 0o644); - builder.install(&src.join("LICENSE"), &doc, 0o644); + builder.install(&src.join("LICENSE-APACHE"), &doc, 0o644); + builder.install(&src.join("LICENSE-MIT"), &doc, 0o644); // Prepare the overlay let overlay = tmp.join("clippy-overlay"); drop(fs::remove_dir_all(&overlay)); t!(fs::create_dir_all(&overlay)); builder.install(&src.join("README.md"), &overlay, 0o644); - builder.install(&src.join("LICENSE"), &doc, 0o644); + builder.install(&src.join("LICENSE-APACHE"), &doc, 0o644); + builder.install(&src.join("LICENSE-MIT"), &doc, 0o644); builder.create(&overlay.join("version"), &version); // Generate the installer tarball -- cgit 1.4.1-3-g733a5 From 2bb85b236a39faa1c4fa198e85a6d0c3ef2a0eba Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Sat, 13 Oct 2018 21:20:36 +0200 Subject: doc: fix sentence structure in std::fmt --- src/liballoc/fmt.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/liballoc/fmt.rs b/src/liballoc/fmt.rs index b49ec0ae252..a2e68a223f1 100644 --- a/src/liballoc/fmt.rs +++ b/src/liballoc/fmt.rs @@ -152,7 +152,7 @@ //! Additionally, the return value of this function is [`fmt::Result`] which is a //! type alias of [`Result`]`<(), `[`std::fmt::Error`]`>`. Formatting implementations //! should ensure that they propagate errors from the [`Formatter`][`Formatter`] (e.g., when -//! calling [`write!`]) however, they should never return errors spuriously. That +//! calling [`write!`]). However, they should never return errors spuriously. That //! is, a formatting implementation must and may only return an error if the //! passed-in [`Formatter`] returns an error. This is because, contrary to what //! the function signature might suggest, string formatting is an infallible -- cgit 1.4.1-3-g733a5 From da1c75c3a6666e94d087cd55d0709328ce906442 Mon Sep 17 00:00:00 2001 From: Matthias Krüger Date: Sat, 13 Oct 2018 23:33:10 +0200 Subject: boostrap: dist: if a file cannot be installed because it does not exist, print its name in the error message. --- src/bootstrap/lib.rs | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src') diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs index 247727762d1..c09de02ab51 100644 --- a/src/bootstrap/lib.rs +++ b/src/bootstrap/lib.rs @@ -1288,6 +1288,9 @@ impl Build { t!(fs::create_dir_all(dstdir)); drop(fs::remove_file(&dst)); { + if !src.exists() { + panic!("Error: File \"{}\" not found!", src.display()); + } let mut s = t!(fs::File::open(&src)); let mut d = t!(fs::File::create(&dst)); io::copy(&mut s, &mut d).expect("failed to copy"); -- cgit 1.4.1-3-g733a5 From 2cdd9f8e52b267f02d1dacad4862823f341951a4 Mon Sep 17 00:00:00 2001 From: Matthias Krüger Date: Sun, 14 Oct 2018 00:47:24 +0200 Subject: bump bootstrap compiler to rustc beta 2018-10-13 beta was switched to bootstrap from stable 1.29.2 since 1.29.2 got the aliasing bug workaround. For extra sanity we should probably bootstrap from a beta that was built with these fixed appied in the host compiler. --- src/stage0.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/stage0.txt b/src/stage0.txt index f0967d1ba8a..6e931a84bac 100644 --- a/src/stage0.txt +++ b/src/stage0.txt @@ -12,7 +12,7 @@ # source tarball for a stable release you'll likely see `1.x.0` for rustc and # `0.x.0` for Cargo where they were released on `date`. -date: 2018-09-23 +date: 2018-10-13 rustc: beta cargo: beta -- cgit 1.4.1-3-g733a5 From 406cbf1a39c99ef7b7f329a44f1d1c7af7a8ecda Mon Sep 17 00:00:00 2001 From: Donato Sciarra Date: Fri, 12 Oct 2018 00:34:26 +0200 Subject: Support underscore as constant name Issue: 54912 --- src/libsyntax/feature_gate.rs | 10 +++++ src/libsyntax/parse/parser.rs | 8 +++- src/test/ui/feature-gate-underscore_const_names.rs | 24 ++++++++++++ .../ui/feature-gate-underscore_const_names.stderr | 16 ++++++++ src/test/ui/underscore_const_names.rs | 43 ++++++++++++++++++++++ 5 files changed, 100 insertions(+), 1 deletion(-) create mode 100644 src/test/ui/feature-gate-underscore_const_names.rs create mode 100644 src/test/ui/feature-gate-underscore_const_names.stderr create mode 100644 src/test/ui/underscore_const_names.rs (limited to 'src') diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index b86b92fb29e..84122688c83 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -499,6 +499,9 @@ declare_features! ( // #[cfg_attr(predicate, multiple, attributes, here)] (active, cfg_attr_multi, "1.31.0", Some(54881), None), + + // Allows `const _: TYPE = VALUE` + (active, underscore_const_names, "1.31.0", Some(54912), None), ); declare_features! ( @@ -1583,6 +1586,13 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { } } + ast::ItemKind::Const(_,_) => { + if i.ident.name == "_" { + gate_feature_post!(&self, underscore_const_names, i.span, + "naming constants with `_` is unstable"); + } + } + ast::ItemKind::ForeignMod(ref foreign_module) => { self.check_abi(foreign_module.abi, i.span); } diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index b5896f37c00..c7089a295fc 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -6346,7 +6346,13 @@ impl<'a> Parser<'a> { } fn parse_item_const(&mut self, m: Option) -> PResult<'a, ItemInfo> { - let id = self.parse_ident()?; + let id = match self.token { + token::Ident(ident, false) if ident.name == keywords::Underscore.name() => { + self.bump(); // `_` + ident.gensym() + }, + _ => self.parse_ident()?, + }; self.expect(&token::Colon)?; let ty = self.parse_ty()?; self.expect(&token::Eq)?; diff --git a/src/test/ui/feature-gate-underscore_const_names.rs b/src/test/ui/feature-gate-underscore_const_names.rs new file mode 100644 index 00000000000..b283e286514 --- /dev/null +++ b/src/test/ui/feature-gate-underscore_const_names.rs @@ -0,0 +1,24 @@ +// Copyright 2012-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. +#![feature(const_let)] + +trait Trt {} +struct Str {} + +impl Trt for Str {} + +const _ : () = { + use std::marker::PhantomData; + struct ImplementsTrait(PhantomData); + let _ = ImplementsTrait::(PhantomData); + () +}; + +fn main() {} diff --git a/src/test/ui/feature-gate-underscore_const_names.stderr b/src/test/ui/feature-gate-underscore_const_names.stderr new file mode 100644 index 00000000000..ab90ef8f11f --- /dev/null +++ b/src/test/ui/feature-gate-underscore_const_names.stderr @@ -0,0 +1,16 @@ +error[E0658]: naming constants with `_` is unstable (see issue #54912) + --> $DIR/feature-gate-underscore_const_names.rs:17:1 + | +LL | / const _ : () = { +LL | | use std::marker::PhantomData; +LL | | struct ImplementsTrait(PhantomData); +LL | | let _ = ImplementsTrait::(PhantomData); +LL | | () +LL | | }; + | |__^ + | + = help: add #![feature(underscore_const_names)] to the crate attributes to enable + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/underscore_const_names.rs b/src/test/ui/underscore_const_names.rs new file mode 100644 index 00000000000..8d31fd0b1e9 --- /dev/null +++ b/src/test/ui/underscore_const_names.rs @@ -0,0 +1,43 @@ +// Copyright 2012-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. + +// compile-pass + +#![feature(const_let)] +#![feature(underscore_const_names)] + +trait Trt {} +struct Str {} +impl Trt for Str {} + +macro_rules! check_impl { + ($struct:ident,$trait:ident) => { + const _ : () = { + use std::marker::PhantomData; + struct ImplementsTrait(PhantomData); + let _ = ImplementsTrait::<$struct>(PhantomData); + () + }; + } +} + +#[deny(unused)] +const _ : () = (); + +const _ : i32 = 42; +const _ : Str = Str{}; + +check_impl!(Str, Trt); +check_impl!(Str, Trt); + +fn main() { + check_impl!(Str, Trt); + check_impl!(Str, Trt); +} -- cgit 1.4.1-3-g733a5 From ad04cb72f9eb2f88c9a3f597c1daaa686481f677 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 14 Oct 2018 11:33:50 +0200 Subject: update miri --- src/tools/miri | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/tools/miri b/src/tools/miri index 26f9d617c34..8b14b033684 160000 --- a/src/tools/miri +++ b/src/tools/miri @@ -1 +1 @@ -Subproject commit 26f9d617c347185433b77c481a5c50c55d9b72ce +Subproject commit 8b14b03368429e6ee2a8ac0e0c876505606ab1f1 -- cgit 1.4.1-3-g733a5 From 69eaa11633b1279d4f2edb734e541f545d583b0a Mon Sep 17 00:00:00 2001 From: Wesley Wiser Date: Thu, 11 Oct 2018 21:28:20 -0400 Subject: [mir-inlining] Don't inline virtual calls Prior to this change, the test case would output `1` instead of `2` like it should. --- src/librustc_mir/transform/inline.rs | 23 ++++++++++++++++------- src/test/mir-opt/inline-trait-method.rs | 31 +++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 7 deletions(-) create mode 100644 src/test/mir-opt/inline-trait-method.rs (limited to 'src') diff --git a/src/librustc_mir/transform/inline.rs b/src/librustc_mir/transform/inline.rs index 040ee35632c..5963f1a481c 100644 --- a/src/librustc_mir/transform/inline.rs +++ b/src/librustc_mir/transform/inline.rs @@ -19,7 +19,7 @@ use rustc_data_structures::indexed_vec::{Idx, IndexVec}; use rustc::mir::*; use rustc::mir::visit::*; -use rustc::ty::{self, Instance, Ty, TyCtxt}; +use rustc::ty::{self, Instance, InstanceDef, Ty, TyCtxt}; use rustc::ty::subst::{Subst,Substs}; use std::collections::VecDeque; @@ -100,12 +100,21 @@ impl<'a, 'tcx> Inliner<'a, 'tcx> { param_env, callee_def_id, substs) { - callsites.push_back(CallSite { - callee: instance.def_id(), - substs: instance.substs, - bb, - location: terminator.source_info - }); + let is_virtual = + if let InstanceDef::Virtual(..) = instance.def { + true + } else { + false + }; + + if !is_virtual { + callsites.push_back(CallSite { + callee: instance.def_id(), + substs: instance.substs, + bb, + location: terminator.source_info + }); + } } } } diff --git a/src/test/mir-opt/inline-trait-method.rs b/src/test/mir-opt/inline-trait-method.rs new file mode 100644 index 00000000000..0f79f43ee2d --- /dev/null +++ b/src/test/mir-opt/inline-trait-method.rs @@ -0,0 +1,31 @@ +// compile-flags: -Z span_free_formats + +fn main() { + println!("{}", test(&())); +} + +fn test(x: &dyn X) -> u32 { + x.y() +} + +trait X { + fn y(&self) -> u32 { + 1 + } +} + +impl X for () { + fn y(&self) -> u32 { + 2 + } +} + +// END RUST SOURCE +// START rustc.test.Inline.after.mir +// ... +// bb0: { +// ... +// _0 = const X::y(move _2) -> bb1; +// } +// ... +// END rustc.test.Inline.after.mir -- cgit 1.4.1-3-g733a5