From 7cae9e8c88e468e94c157d9aaee4b8e3cf90b9a4 Mon Sep 17 00:00:00 2001 From: maekawatoshiki Date: Fri, 31 Jul 2020 18:50:11 +0900 Subject: [PATCH 01/33] `#![deny(unsafe_op_in_unsafe_fn)]` in sys/hermit --- library/std/src/sys/hermit/alloc.rs | 25 ++++--- library/std/src/sys/hermit/args.rs | 16 +++-- library/std/src/sys/hermit/condvar.rs | 34 +++++++--- library/std/src/sys/hermit/fd.rs | 1 + library/std/src/sys/hermit/mod.rs | 22 ++++-- library/std/src/sys/hermit/mutex.rs | 26 ++++--- library/std/src/sys/hermit/os.rs | 2 + library/std/src/sys/hermit/rwlock.rs | 68 ++++++++++++------- library/std/src/sys/hermit/thread.rs | 21 +++--- .../std/src/sys/hermit/thread_local_dtor.rs | 7 +- 10 files changed, 147 insertions(+), 75 deletions(-) diff --git a/library/std/src/sys/hermit/alloc.rs b/library/std/src/sys/hermit/alloc.rs index d153914e77e10..04446172197f7 100644 --- a/library/std/src/sys/hermit/alloc.rs +++ b/library/std/src/sys/hermit/alloc.rs @@ -1,3 +1,5 @@ +#![deny(unsafe_op_in_unsafe_fn)] + use crate::alloc::{GlobalAlloc, Layout, System}; use crate::ptr; use crate::sys::hermit::abi; @@ -6,26 +8,33 @@ use crate::sys::hermit::abi; unsafe impl GlobalAlloc for System { #[inline] unsafe fn alloc(&self, layout: Layout) -> *mut u8 { - abi::malloc(layout.size(), layout.align()) + // SAFETY: The safety contract for `malloc` must be upheld by the caller. + unsafe { abi::malloc(layout.size(), layout.align()) } } unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut u8 { - let addr = abi::malloc(layout.size(), layout.align()); + // SAFETY: The safety contract for `malloc` must be upheld by the caller. + // Also, `addr` must be valid for writes of `layout.size() * size_of::()` bytes. + unsafe { + let addr = abi::malloc(layout.size(), layout.align()); - if !addr.is_null() { - ptr::write_bytes(addr, 0x00, layout.size()); - } + if !addr.is_null() { + ptr::write_bytes(addr, 0x00, layout.size()); + } - addr + addr + } } #[inline] unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) { - abi::free(ptr, layout.size(), layout.align()) + // SAFETY: The safety contract for `free` must be upheld by the caller. + unsafe { abi::free(ptr, layout.size(), layout.align()) } } #[inline] unsafe fn realloc(&self, ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8 { - abi::realloc(ptr, layout.size(), layout.align(), new_size) + // SAFETY: The safety contract for `realloc` must be upheld by the caller. + unsafe { abi::realloc(ptr, layout.size(), layout.align(), new_size) } } } diff --git a/library/std/src/sys/hermit/args.rs b/library/std/src/sys/hermit/args.rs index 72c1b8511cac8..dd8830599c37e 100644 --- a/library/std/src/sys/hermit/args.rs +++ b/library/std/src/sys/hermit/args.rs @@ -1,15 +1,17 @@ +#![deny(unsafe_op_in_unsafe_fn)] + use crate::ffi::OsString; use crate::marker::PhantomData; use crate::vec; /// One-time global initialization. pub unsafe fn init(argc: isize, argv: *const *const u8) { - imp::init(argc, argv) + unsafe { imp::init(argc, argv) } } /// One-time global cleanup. pub unsafe fn cleanup() { - imp::cleanup() + unsafe { imp::cleanup() } } /// Returns the command line arguments @@ -65,14 +67,18 @@ mod imp { pub unsafe fn init(argc: isize, argv: *const *const u8) { let _guard = LOCK.lock(); - ARGC = argc; - ARGV = argv; + unsafe { + ARGC = argc; + ARGV = argv; + } } pub unsafe fn cleanup() { let _guard = LOCK.lock(); ARGC = 0; - ARGV = ptr::null(); + unsafe { + ARGV = ptr::null(); + } } pub fn args() -> Args { diff --git a/library/std/src/sys/hermit/condvar.rs b/library/std/src/sys/hermit/condvar.rs index 52c8c3b17e826..662dc9394a36f 100644 --- a/library/std/src/sys/hermit/condvar.rs +++ b/library/std/src/sys/hermit/condvar.rs @@ -1,3 +1,5 @@ +#![deny(unsafe_op_in_unsafe_fn)] + use crate::ffi::c_void; use crate::ptr; use crate::sync::atomic::{AtomicUsize, Ordering::SeqCst}; @@ -23,33 +25,43 @@ impl Condvar { } pub unsafe fn init(&mut self) { - let _ = abi::sem_init(&mut self.sem1 as *mut *const c_void, 0); - let _ = abi::sem_init(&mut self.sem2 as *mut *const c_void, 0); + unsafe { + let _ = abi::sem_init(&mut self.sem1 as *mut *const c_void, 0); + let _ = abi::sem_init(&mut self.sem2 as *mut *const c_void, 0); + } } pub unsafe fn notify_one(&self) { if self.counter.load(SeqCst) > 0 { self.counter.fetch_sub(1, SeqCst); - abi::sem_post(self.sem1); - abi::sem_timedwait(self.sem2, 0); + unsafe { + abi::sem_post(self.sem1); + abi::sem_timedwait(self.sem2, 0); + } } } pub unsafe fn notify_all(&self) { let counter = self.counter.swap(0, SeqCst); for _ in 0..counter { - abi::sem_post(self.sem1); + unsafe { + abi::sem_post(self.sem1); + } } for _ in 0..counter { - abi::sem_timedwait(self.sem2, 0); + unsafe { + abi::sem_timedwait(self.sem2, 0); + } } } pub unsafe fn wait(&self, mutex: &Mutex) { self.counter.fetch_add(1, SeqCst); mutex.unlock(); - abi::sem_timedwait(self.sem1, 0); - abi::sem_post(self.sem2); + unsafe { + abi::sem_timedwait(self.sem1, 0); + abi::sem_post(self.sem2); + } mutex.lock(); } @@ -58,7 +70,9 @@ impl Condvar { } pub unsafe fn destroy(&self) { - let _ = abi::sem_destroy(self.sem1); - let _ = abi::sem_destroy(self.sem2); + unsafe { + let _ = abi::sem_destroy(self.sem1); + let _ = abi::sem_destroy(self.sem2); + } } } diff --git a/library/std/src/sys/hermit/fd.rs b/library/std/src/sys/hermit/fd.rs index 97d1a38b41ab1..2914e5ad3dbe2 100644 --- a/library/std/src/sys/hermit/fd.rs +++ b/library/std/src/sys/hermit/fd.rs @@ -1,3 +1,4 @@ +#![deny(unsafe_op_in_unsafe_fn)] #![unstable(reason = "not public", issue = "none", feature = "fd")] use crate::io::{self, ErrorKind, Read}; diff --git a/library/std/src/sys/hermit/mod.rs b/library/std/src/sys/hermit/mod.rs index 675b82ceb775f..0e4504020df42 100644 --- a/library/std/src/sys/hermit/mod.rs +++ b/library/std/src/sys/hermit/mod.rs @@ -13,6 +13,8 @@ //! compiling for wasm. That way it's a compile time error for something that's //! guaranteed to be a runtime error! +#![deny(unsafe_op_in_unsafe_fn)] + use crate::intrinsics; use crate::os::raw::c_char; @@ -62,8 +64,12 @@ pub enum Void {} pub unsafe fn strlen(start: *const c_char) -> usize { let mut str = start; - while *str != 0 { - str = str.offset(1); + // SAFETY: The safety contract for `*str != 0` must be upheld by the caller. + // `start` must not be null. + unsafe { + while *str != 0 { + str = str.offset(1); + } } (str as usize) - (start as usize) @@ -111,13 +117,15 @@ pub unsafe extern "C" fn runtime_entry( fn main(argc: isize, argv: *const *const c_char) -> i32; } - // initialize environment - os::init_environment(env as *const *const i8); + unsafe { + // initialize environment + os::init_environment(env as *const *const i8); - let result = main(argc as isize, argv); + let result = main(argc as isize, argv); - run_dtors(); - abi::exit(result); + run_dtors(); + abi::exit(result); + } } pub fn decode_error_kind(errno: i32) -> ErrorKind { diff --git a/library/std/src/sys/hermit/mutex.rs b/library/std/src/sys/hermit/mutex.rs index 3d4813209cbc4..bcb2554ab2927 100644 --- a/library/std/src/sys/hermit/mutex.rs +++ b/library/std/src/sys/hermit/mutex.rs @@ -1,3 +1,5 @@ +#![deny(unsafe_op_in_unsafe_fn)] + use crate::ffi::c_void; use crate::ptr; use crate::sys::hermit::abi; @@ -16,28 +18,34 @@ impl Mutex { #[inline] pub unsafe fn init(&mut self) { - let _ = abi::sem_init(&mut self.inner as *mut *const c_void, 1); + unsafe { + let _ = abi::sem_init(&mut self.inner as *mut *const c_void, 1); + } } #[inline] pub unsafe fn lock(&self) { - let _ = abi::sem_timedwait(self.inner, 0); + unsafe { + let _ = abi::sem_timedwait(self.inner, 0); + } } #[inline] pub unsafe fn unlock(&self) { - let _ = abi::sem_post(self.inner); + unsafe { + let _ = abi::sem_post(self.inner); + } } #[inline] pub unsafe fn try_lock(&self) -> bool { - let result = abi::sem_trywait(self.inner); + let result = unsafe { abi::sem_trywait(self.inner) }; result == 0 } #[inline] pub unsafe fn destroy(&self) { - let _ = abi::sem_destroy(self.inner); + let _ = unsafe { abi::sem_destroy(self.inner) }; } } @@ -52,12 +60,12 @@ impl ReentrantMutex { #[inline] pub unsafe fn init(&self) { - let _ = abi::recmutex_init(&self.inner as *const *const c_void as *mut _); + let _ = unsafe { abi::recmutex_init(&self.inner as *const *const c_void as *mut _) }; } #[inline] pub unsafe fn lock(&self) { - let _ = abi::recmutex_lock(self.inner); + let _ = unsafe { abi::recmutex_lock(self.inner) }; } #[inline] @@ -67,11 +75,11 @@ impl ReentrantMutex { #[inline] pub unsafe fn unlock(&self) { - let _ = abi::recmutex_unlock(self.inner); + let _ = unsafe { abi::recmutex_unlock(self.inner) }; } #[inline] pub unsafe fn destroy(&self) { - let _ = abi::recmutex_destroy(self.inner); + let _ = unsafe { abi::recmutex_destroy(self.inner) }; } } diff --git a/library/std/src/sys/hermit/os.rs b/library/std/src/sys/hermit/os.rs index 78eabf8f81e98..d95940c9a76c8 100644 --- a/library/std/src/sys/hermit/os.rs +++ b/library/std/src/sys/hermit/os.rs @@ -1,3 +1,5 @@ +#![deny(unsafe_op_in_unsafe_fn)] + use crate::collections::HashMap; use crate::error::Error as StdError; use crate::ffi::{CStr, OsStr, OsString}; diff --git a/library/std/src/sys/hermit/rwlock.rs b/library/std/src/sys/hermit/rwlock.rs index 06442e925f4c8..a6c7bcc7641fc 100644 --- a/library/std/src/sys/hermit/rwlock.rs +++ b/library/std/src/sys/hermit/rwlock.rs @@ -1,3 +1,5 @@ +#![deny(unsafe_op_in_unsafe_fn)] + use crate::cell::UnsafeCell; use crate::sys::condvar::Condvar; use crate::sys::mutex::Mutex; @@ -32,62 +34,76 @@ impl RWLock { #[inline] pub unsafe fn read(&self) { - self.lock.lock(); - while !(*self.state.get()).inc_readers() { - self.cond.wait(&self.lock); + unsafe { + self.lock.lock(); + while !(*self.state.get()).inc_readers() { + self.cond.wait(&self.lock); + } + self.lock.unlock(); } - self.lock.unlock(); } #[inline] pub unsafe fn try_read(&self) -> bool { - self.lock.lock(); - let ok = (*self.state.get()).inc_readers(); - self.lock.unlock(); + unsafe { + self.lock.lock(); + let ok = (*self.state.get()).inc_readers(); + self.lock.unlock(); + } return ok; } #[inline] pub unsafe fn write(&self) { - self.lock.lock(); - while !(*self.state.get()).inc_writers() { - self.cond.wait(&self.lock); + unsafe { + self.lock.lock(); + while !(*self.state.get()).inc_writers() { + self.cond.wait(&self.lock); + } } self.lock.unlock(); } #[inline] pub unsafe fn try_write(&self) -> bool { - self.lock.lock(); - let ok = (*self.state.get()).inc_writers(); - self.lock.unlock(); + unsafe { + self.lock.lock(); + let ok = (*self.state.get()).inc_writers(); + self.lock.unlock(); + } return ok; } #[inline] pub unsafe fn read_unlock(&self) { - self.lock.lock(); - let notify = (*self.state.get()).dec_readers(); - self.lock.unlock(); - if notify { - // FIXME: should only wake up one of these some of the time - self.cond.notify_all(); + unsafe { + self.lock.lock(); + let notify = (*self.state.get()).dec_readers(); + self.lock.unlock(); + if notify { + // FIXME: should only wake up one of these some of the time + self.cond.notify_all(); + } } } #[inline] pub unsafe fn write_unlock(&self) { - self.lock.lock(); - (*self.state.get()).dec_writers(); - self.lock.unlock(); - // FIXME: should only wake up one of these some of the time - self.cond.notify_all(); + unsafe { + self.lock.lock(); + (*self.state.get()).dec_writers(); + self.lock.unlock(); + // FIXME: should only wake up one of these some of the time + self.cond.notify_all(); + } } #[inline] pub unsafe fn destroy(&self) { - self.lock.destroy(); - self.cond.destroy(); + unsafe { + self.lock.destroy(); + self.cond.destroy(); + } } } diff --git a/library/std/src/sys/hermit/thread.rs b/library/std/src/sys/hermit/thread.rs index e11afed668728..7c52112a80c2d 100644 --- a/library/std/src/sys/hermit/thread.rs +++ b/library/std/src/sys/hermit/thread.rs @@ -1,4 +1,5 @@ #![allow(dead_code)] +#![deny(unsafe_op_in_unsafe_fn)] use crate::ffi::CStr; use crate::io; @@ -25,18 +26,22 @@ impl Thread { core_id: isize, ) -> io::Result { let p = Box::into_raw(box p); - let tid = abi::spawn2( - thread_start, - p as usize, - abi::Priority::into(abi::NORMAL_PRIO), - stack, - core_id, - ); + let tid = unsafe { + abi::spawn2( + thread_start, + p as usize, + abi::Priority::into(abi::NORMAL_PRIO), + stack, + core_id, + ) + }; return if tid == 0 { // The thread failed to start and as a result p was not consumed. Therefore, it is // safe to reconstruct the box so that it gets deallocated. - drop(Box::from_raw(p)); + unsafe { + drop(Box::from_raw(p)); + } Err(io::Error::new(io::ErrorKind::Other, "Unable to create thread!")) } else { Ok(Thread { tid: tid }) diff --git a/library/std/src/sys/hermit/thread_local_dtor.rs b/library/std/src/sys/hermit/thread_local_dtor.rs index 9b683fce15748..7998dd3cb4347 100644 --- a/library/std/src/sys/hermit/thread_local_dtor.rs +++ b/library/std/src/sys/hermit/thread_local_dtor.rs @@ -1,5 +1,6 @@ #![cfg(target_thread_local)] #![unstable(feature = "thread_local_internals", issue = "none")] +#![deny(unsafe_op_in_unsafe_fn)] // Simplify dtor registration by using a list of destructors. // The this solution works like the implementation of macOS and @@ -19,7 +20,8 @@ pub unsafe fn register_dtor(t: *mut u8, dtor: unsafe extern "C" fn(*mut u8)) { DTORS.set(Box::into_raw(v)); } - let list: &mut List = &mut *DTORS.get(); + // SAFETY: `DTORS.get()` is not null. + let list: &mut List = unsafe { &mut *DTORS.get() }; list.push((t, dtor)); } @@ -27,7 +29,8 @@ pub unsafe fn register_dtor(t: *mut u8, dtor: unsafe extern "C" fn(*mut u8)) { pub unsafe fn run_dtors() { let mut ptr = DTORS.replace(ptr::null_mut()); while !ptr.is_null() { - let list = Box::from_raw(ptr); + // SAFETY: `ptr` is not null. + let list = unsafe { Box::from_raw(ptr) }; for (ptr, dtor) in list.into_iter() { dtor(ptr); } From 3a46cca4aeb2f5c0dcbc9e982d915c519c44f783 Mon Sep 17 00:00:00 2001 From: maekawatoshiki Date: Fri, 21 Aug 2020 14:14:58 +0900 Subject: [PATCH 02/33] Revert "`#![deny(unsafe_op_in_unsafe_fn)]` in sys/hermit" This reverts commit 7cae9e8c88e468e94c157d9aaee4b8e3cf90b9a4. --- library/std/src/sys/hermit/alloc.rs | 25 +++---- library/std/src/sys/hermit/args.rs | 16 ++--- library/std/src/sys/hermit/condvar.rs | 34 +++------- library/std/src/sys/hermit/fd.rs | 1 - library/std/src/sys/hermit/mod.rs | 22 ++---- library/std/src/sys/hermit/mutex.rs | 26 +++---- library/std/src/sys/hermit/os.rs | 2 - library/std/src/sys/hermit/rwlock.rs | 68 +++++++------------ library/std/src/sys/hermit/thread.rs | 21 +++--- .../std/src/sys/hermit/thread_local_dtor.rs | 7 +- 10 files changed, 75 insertions(+), 147 deletions(-) diff --git a/library/std/src/sys/hermit/alloc.rs b/library/std/src/sys/hermit/alloc.rs index 04446172197f7..d153914e77e10 100644 --- a/library/std/src/sys/hermit/alloc.rs +++ b/library/std/src/sys/hermit/alloc.rs @@ -1,5 +1,3 @@ -#![deny(unsafe_op_in_unsafe_fn)] - use crate::alloc::{GlobalAlloc, Layout, System}; use crate::ptr; use crate::sys::hermit::abi; @@ -8,33 +6,26 @@ use crate::sys::hermit::abi; unsafe impl GlobalAlloc for System { #[inline] unsafe fn alloc(&self, layout: Layout) -> *mut u8 { - // SAFETY: The safety contract for `malloc` must be upheld by the caller. - unsafe { abi::malloc(layout.size(), layout.align()) } + abi::malloc(layout.size(), layout.align()) } unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut u8 { - // SAFETY: The safety contract for `malloc` must be upheld by the caller. - // Also, `addr` must be valid for writes of `layout.size() * size_of::()` bytes. - unsafe { - let addr = abi::malloc(layout.size(), layout.align()); - - if !addr.is_null() { - ptr::write_bytes(addr, 0x00, layout.size()); - } + let addr = abi::malloc(layout.size(), layout.align()); - addr + if !addr.is_null() { + ptr::write_bytes(addr, 0x00, layout.size()); } + + addr } #[inline] unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) { - // SAFETY: The safety contract for `free` must be upheld by the caller. - unsafe { abi::free(ptr, layout.size(), layout.align()) } + abi::free(ptr, layout.size(), layout.align()) } #[inline] unsafe fn realloc(&self, ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8 { - // SAFETY: The safety contract for `realloc` must be upheld by the caller. - unsafe { abi::realloc(ptr, layout.size(), layout.align(), new_size) } + abi::realloc(ptr, layout.size(), layout.align(), new_size) } } diff --git a/library/std/src/sys/hermit/args.rs b/library/std/src/sys/hermit/args.rs index dd8830599c37e..72c1b8511cac8 100644 --- a/library/std/src/sys/hermit/args.rs +++ b/library/std/src/sys/hermit/args.rs @@ -1,17 +1,15 @@ -#![deny(unsafe_op_in_unsafe_fn)] - use crate::ffi::OsString; use crate::marker::PhantomData; use crate::vec; /// One-time global initialization. pub unsafe fn init(argc: isize, argv: *const *const u8) { - unsafe { imp::init(argc, argv) } + imp::init(argc, argv) } /// One-time global cleanup. pub unsafe fn cleanup() { - unsafe { imp::cleanup() } + imp::cleanup() } /// Returns the command line arguments @@ -67,18 +65,14 @@ mod imp { pub unsafe fn init(argc: isize, argv: *const *const u8) { let _guard = LOCK.lock(); - unsafe { - ARGC = argc; - ARGV = argv; - } + ARGC = argc; + ARGV = argv; } pub unsafe fn cleanup() { let _guard = LOCK.lock(); ARGC = 0; - unsafe { - ARGV = ptr::null(); - } + ARGV = ptr::null(); } pub fn args() -> Args { diff --git a/library/std/src/sys/hermit/condvar.rs b/library/std/src/sys/hermit/condvar.rs index 662dc9394a36f..52c8c3b17e826 100644 --- a/library/std/src/sys/hermit/condvar.rs +++ b/library/std/src/sys/hermit/condvar.rs @@ -1,5 +1,3 @@ -#![deny(unsafe_op_in_unsafe_fn)] - use crate::ffi::c_void; use crate::ptr; use crate::sync::atomic::{AtomicUsize, Ordering::SeqCst}; @@ -25,43 +23,33 @@ impl Condvar { } pub unsafe fn init(&mut self) { - unsafe { - let _ = abi::sem_init(&mut self.sem1 as *mut *const c_void, 0); - let _ = abi::sem_init(&mut self.sem2 as *mut *const c_void, 0); - } + let _ = abi::sem_init(&mut self.sem1 as *mut *const c_void, 0); + let _ = abi::sem_init(&mut self.sem2 as *mut *const c_void, 0); } pub unsafe fn notify_one(&self) { if self.counter.load(SeqCst) > 0 { self.counter.fetch_sub(1, SeqCst); - unsafe { - abi::sem_post(self.sem1); - abi::sem_timedwait(self.sem2, 0); - } + abi::sem_post(self.sem1); + abi::sem_timedwait(self.sem2, 0); } } pub unsafe fn notify_all(&self) { let counter = self.counter.swap(0, SeqCst); for _ in 0..counter { - unsafe { - abi::sem_post(self.sem1); - } + abi::sem_post(self.sem1); } for _ in 0..counter { - unsafe { - abi::sem_timedwait(self.sem2, 0); - } + abi::sem_timedwait(self.sem2, 0); } } pub unsafe fn wait(&self, mutex: &Mutex) { self.counter.fetch_add(1, SeqCst); mutex.unlock(); - unsafe { - abi::sem_timedwait(self.sem1, 0); - abi::sem_post(self.sem2); - } + abi::sem_timedwait(self.sem1, 0); + abi::sem_post(self.sem2); mutex.lock(); } @@ -70,9 +58,7 @@ impl Condvar { } pub unsafe fn destroy(&self) { - unsafe { - let _ = abi::sem_destroy(self.sem1); - let _ = abi::sem_destroy(self.sem2); - } + let _ = abi::sem_destroy(self.sem1); + let _ = abi::sem_destroy(self.sem2); } } diff --git a/library/std/src/sys/hermit/fd.rs b/library/std/src/sys/hermit/fd.rs index 2914e5ad3dbe2..97d1a38b41ab1 100644 --- a/library/std/src/sys/hermit/fd.rs +++ b/library/std/src/sys/hermit/fd.rs @@ -1,4 +1,3 @@ -#![deny(unsafe_op_in_unsafe_fn)] #![unstable(reason = "not public", issue = "none", feature = "fd")] use crate::io::{self, ErrorKind, Read}; diff --git a/library/std/src/sys/hermit/mod.rs b/library/std/src/sys/hermit/mod.rs index 0e4504020df42..675b82ceb775f 100644 --- a/library/std/src/sys/hermit/mod.rs +++ b/library/std/src/sys/hermit/mod.rs @@ -13,8 +13,6 @@ //! compiling for wasm. That way it's a compile time error for something that's //! guaranteed to be a runtime error! -#![deny(unsafe_op_in_unsafe_fn)] - use crate::intrinsics; use crate::os::raw::c_char; @@ -64,12 +62,8 @@ pub enum Void {} pub unsafe fn strlen(start: *const c_char) -> usize { let mut str = start; - // SAFETY: The safety contract for `*str != 0` must be upheld by the caller. - // `start` must not be null. - unsafe { - while *str != 0 { - str = str.offset(1); - } + while *str != 0 { + str = str.offset(1); } (str as usize) - (start as usize) @@ -117,15 +111,13 @@ pub unsafe extern "C" fn runtime_entry( fn main(argc: isize, argv: *const *const c_char) -> i32; } - unsafe { - // initialize environment - os::init_environment(env as *const *const i8); + // initialize environment + os::init_environment(env as *const *const i8); - let result = main(argc as isize, argv); + let result = main(argc as isize, argv); - run_dtors(); - abi::exit(result); - } + run_dtors(); + abi::exit(result); } pub fn decode_error_kind(errno: i32) -> ErrorKind { diff --git a/library/std/src/sys/hermit/mutex.rs b/library/std/src/sys/hermit/mutex.rs index bcb2554ab2927..3d4813209cbc4 100644 --- a/library/std/src/sys/hermit/mutex.rs +++ b/library/std/src/sys/hermit/mutex.rs @@ -1,5 +1,3 @@ -#![deny(unsafe_op_in_unsafe_fn)] - use crate::ffi::c_void; use crate::ptr; use crate::sys::hermit::abi; @@ -18,34 +16,28 @@ impl Mutex { #[inline] pub unsafe fn init(&mut self) { - unsafe { - let _ = abi::sem_init(&mut self.inner as *mut *const c_void, 1); - } + let _ = abi::sem_init(&mut self.inner as *mut *const c_void, 1); } #[inline] pub unsafe fn lock(&self) { - unsafe { - let _ = abi::sem_timedwait(self.inner, 0); - } + let _ = abi::sem_timedwait(self.inner, 0); } #[inline] pub unsafe fn unlock(&self) { - unsafe { - let _ = abi::sem_post(self.inner); - } + let _ = abi::sem_post(self.inner); } #[inline] pub unsafe fn try_lock(&self) -> bool { - let result = unsafe { abi::sem_trywait(self.inner) }; + let result = abi::sem_trywait(self.inner); result == 0 } #[inline] pub unsafe fn destroy(&self) { - let _ = unsafe { abi::sem_destroy(self.inner) }; + let _ = abi::sem_destroy(self.inner); } } @@ -60,12 +52,12 @@ impl ReentrantMutex { #[inline] pub unsafe fn init(&self) { - let _ = unsafe { abi::recmutex_init(&self.inner as *const *const c_void as *mut _) }; + let _ = abi::recmutex_init(&self.inner as *const *const c_void as *mut _); } #[inline] pub unsafe fn lock(&self) { - let _ = unsafe { abi::recmutex_lock(self.inner) }; + let _ = abi::recmutex_lock(self.inner); } #[inline] @@ -75,11 +67,11 @@ impl ReentrantMutex { #[inline] pub unsafe fn unlock(&self) { - let _ = unsafe { abi::recmutex_unlock(self.inner) }; + let _ = abi::recmutex_unlock(self.inner); } #[inline] pub unsafe fn destroy(&self) { - let _ = unsafe { abi::recmutex_destroy(self.inner) }; + let _ = abi::recmutex_destroy(self.inner); } } diff --git a/library/std/src/sys/hermit/os.rs b/library/std/src/sys/hermit/os.rs index d95940c9a76c8..78eabf8f81e98 100644 --- a/library/std/src/sys/hermit/os.rs +++ b/library/std/src/sys/hermit/os.rs @@ -1,5 +1,3 @@ -#![deny(unsafe_op_in_unsafe_fn)] - use crate::collections::HashMap; use crate::error::Error as StdError; use crate::ffi::{CStr, OsStr, OsString}; diff --git a/library/std/src/sys/hermit/rwlock.rs b/library/std/src/sys/hermit/rwlock.rs index a6c7bcc7641fc..06442e925f4c8 100644 --- a/library/std/src/sys/hermit/rwlock.rs +++ b/library/std/src/sys/hermit/rwlock.rs @@ -1,5 +1,3 @@ -#![deny(unsafe_op_in_unsafe_fn)] - use crate::cell::UnsafeCell; use crate::sys::condvar::Condvar; use crate::sys::mutex::Mutex; @@ -34,76 +32,62 @@ impl RWLock { #[inline] pub unsafe fn read(&self) { - unsafe { - self.lock.lock(); - while !(*self.state.get()).inc_readers() { - self.cond.wait(&self.lock); - } - self.lock.unlock(); + self.lock.lock(); + while !(*self.state.get()).inc_readers() { + self.cond.wait(&self.lock); } + self.lock.unlock(); } #[inline] pub unsafe fn try_read(&self) -> bool { - unsafe { - self.lock.lock(); - let ok = (*self.state.get()).inc_readers(); - self.lock.unlock(); - } + self.lock.lock(); + let ok = (*self.state.get()).inc_readers(); + self.lock.unlock(); return ok; } #[inline] pub unsafe fn write(&self) { - unsafe { - self.lock.lock(); - while !(*self.state.get()).inc_writers() { - self.cond.wait(&self.lock); - } + self.lock.lock(); + while !(*self.state.get()).inc_writers() { + self.cond.wait(&self.lock); } self.lock.unlock(); } #[inline] pub unsafe fn try_write(&self) -> bool { - unsafe { - self.lock.lock(); - let ok = (*self.state.get()).inc_writers(); - self.lock.unlock(); - } + self.lock.lock(); + let ok = (*self.state.get()).inc_writers(); + self.lock.unlock(); return ok; } #[inline] pub unsafe fn read_unlock(&self) { - unsafe { - self.lock.lock(); - let notify = (*self.state.get()).dec_readers(); - self.lock.unlock(); - if notify { - // FIXME: should only wake up one of these some of the time - self.cond.notify_all(); - } + self.lock.lock(); + let notify = (*self.state.get()).dec_readers(); + self.lock.unlock(); + if notify { + // FIXME: should only wake up one of these some of the time + self.cond.notify_all(); } } #[inline] pub unsafe fn write_unlock(&self) { - unsafe { - self.lock.lock(); - (*self.state.get()).dec_writers(); - self.lock.unlock(); - // FIXME: should only wake up one of these some of the time - self.cond.notify_all(); - } + self.lock.lock(); + (*self.state.get()).dec_writers(); + self.lock.unlock(); + // FIXME: should only wake up one of these some of the time + self.cond.notify_all(); } #[inline] pub unsafe fn destroy(&self) { - unsafe { - self.lock.destroy(); - self.cond.destroy(); - } + self.lock.destroy(); + self.cond.destroy(); } } diff --git a/library/std/src/sys/hermit/thread.rs b/library/std/src/sys/hermit/thread.rs index 7c52112a80c2d..e11afed668728 100644 --- a/library/std/src/sys/hermit/thread.rs +++ b/library/std/src/sys/hermit/thread.rs @@ -1,5 +1,4 @@ #![allow(dead_code)] -#![deny(unsafe_op_in_unsafe_fn)] use crate::ffi::CStr; use crate::io; @@ -26,22 +25,18 @@ impl Thread { core_id: isize, ) -> io::Result { let p = Box::into_raw(box p); - let tid = unsafe { - abi::spawn2( - thread_start, - p as usize, - abi::Priority::into(abi::NORMAL_PRIO), - stack, - core_id, - ) - }; + let tid = abi::spawn2( + thread_start, + p as usize, + abi::Priority::into(abi::NORMAL_PRIO), + stack, + core_id, + ); return if tid == 0 { // The thread failed to start and as a result p was not consumed. Therefore, it is // safe to reconstruct the box so that it gets deallocated. - unsafe { - drop(Box::from_raw(p)); - } + drop(Box::from_raw(p)); Err(io::Error::new(io::ErrorKind::Other, "Unable to create thread!")) } else { Ok(Thread { tid: tid }) diff --git a/library/std/src/sys/hermit/thread_local_dtor.rs b/library/std/src/sys/hermit/thread_local_dtor.rs index 7998dd3cb4347..9b683fce15748 100644 --- a/library/std/src/sys/hermit/thread_local_dtor.rs +++ b/library/std/src/sys/hermit/thread_local_dtor.rs @@ -1,6 +1,5 @@ #![cfg(target_thread_local)] #![unstable(feature = "thread_local_internals", issue = "none")] -#![deny(unsafe_op_in_unsafe_fn)] // Simplify dtor registration by using a list of destructors. // The this solution works like the implementation of macOS and @@ -20,8 +19,7 @@ pub unsafe fn register_dtor(t: *mut u8, dtor: unsafe extern "C" fn(*mut u8)) { DTORS.set(Box::into_raw(v)); } - // SAFETY: `DTORS.get()` is not null. - let list: &mut List = unsafe { &mut *DTORS.get() }; + let list: &mut List = &mut *DTORS.get(); list.push((t, dtor)); } @@ -29,8 +27,7 @@ pub unsafe fn register_dtor(t: *mut u8, dtor: unsafe extern "C" fn(*mut u8)) { pub unsafe fn run_dtors() { let mut ptr = DTORS.replace(ptr::null_mut()); while !ptr.is_null() { - // SAFETY: `ptr` is not null. - let list = unsafe { Box::from_raw(ptr) }; + let list = Box::from_raw(ptr); for (ptr, dtor) in list.into_iter() { dtor(ptr); } From d94258e83ed5c873200b9ba3314144ef9251ebf9 Mon Sep 17 00:00:00 2001 From: maekawatoshiki Date: Fri, 21 Aug 2020 14:20:59 +0900 Subject: [PATCH 03/33] Add `#![allow(unsafe_op_in_unsafe_fn)]` in sys/hermit --- library/std/src/sys/hermit/alloc.rs | 2 ++ library/std/src/sys/hermit/args.rs | 2 ++ library/std/src/sys/hermit/condvar.rs | 2 ++ library/std/src/sys/hermit/fd.rs | 1 + library/std/src/sys/hermit/mod.rs | 2 ++ library/std/src/sys/hermit/mutex.rs | 2 ++ library/std/src/sys/hermit/os.rs | 2 ++ library/std/src/sys/hermit/rwlock.rs | 2 ++ library/std/src/sys/hermit/thread.rs | 1 + library/std/src/sys/hermit/thread_local_dtor.rs | 1 + 10 files changed, 17 insertions(+) diff --git a/library/std/src/sys/hermit/alloc.rs b/library/std/src/sys/hermit/alloc.rs index d153914e77e10..cebe317de5678 100644 --- a/library/std/src/sys/hermit/alloc.rs +++ b/library/std/src/sys/hermit/alloc.rs @@ -1,3 +1,5 @@ +#![allow(unsafe_op_in_unsafe_fn)] + use crate::alloc::{GlobalAlloc, Layout, System}; use crate::ptr; use crate::sys::hermit::abi; diff --git a/library/std/src/sys/hermit/args.rs b/library/std/src/sys/hermit/args.rs index 72c1b8511cac8..194d94805724b 100644 --- a/library/std/src/sys/hermit/args.rs +++ b/library/std/src/sys/hermit/args.rs @@ -1,3 +1,5 @@ +#![allow(unsafe_op_in_unsafe_fn)] + use crate::ffi::OsString; use crate::marker::PhantomData; use crate::vec; diff --git a/library/std/src/sys/hermit/condvar.rs b/library/std/src/sys/hermit/condvar.rs index 52c8c3b17e826..a69ab2d643cd2 100644 --- a/library/std/src/sys/hermit/condvar.rs +++ b/library/std/src/sys/hermit/condvar.rs @@ -1,3 +1,5 @@ +#![allow(unsafe_op_in_unsafe_fn)] + use crate::ffi::c_void; use crate::ptr; use crate::sync::atomic::{AtomicUsize, Ordering::SeqCst}; diff --git a/library/std/src/sys/hermit/fd.rs b/library/std/src/sys/hermit/fd.rs index 97d1a38b41ab1..fcdf1f058b162 100644 --- a/library/std/src/sys/hermit/fd.rs +++ b/library/std/src/sys/hermit/fd.rs @@ -1,4 +1,5 @@ #![unstable(reason = "not public", issue = "none", feature = "fd")] +#![allow(unsafe_op_in_unsafe_fn)] use crate::io::{self, ErrorKind, Read}; use crate::mem; diff --git a/library/std/src/sys/hermit/mod.rs b/library/std/src/sys/hermit/mod.rs index 675b82ceb775f..17a2cdf6bf8fa 100644 --- a/library/std/src/sys/hermit/mod.rs +++ b/library/std/src/sys/hermit/mod.rs @@ -13,6 +13,8 @@ //! compiling for wasm. That way it's a compile time error for something that's //! guaranteed to be a runtime error! +#![allow(unsafe_op_in_unsafe_fn)] + use crate::intrinsics; use crate::os::raw::c_char; diff --git a/library/std/src/sys/hermit/mutex.rs b/library/std/src/sys/hermit/mutex.rs index 3d4813209cbc4..6af1854e7041c 100644 --- a/library/std/src/sys/hermit/mutex.rs +++ b/library/std/src/sys/hermit/mutex.rs @@ -1,3 +1,5 @@ +#![allow(unsafe_op_in_unsafe_fn)] + use crate::ffi::c_void; use crate::ptr; use crate::sys::hermit::abi; diff --git a/library/std/src/sys/hermit/os.rs b/library/std/src/sys/hermit/os.rs index 78eabf8f81e98..ca0ffb7524d29 100644 --- a/library/std/src/sys/hermit/os.rs +++ b/library/std/src/sys/hermit/os.rs @@ -1,3 +1,5 @@ +#![allow(unsafe_op_in_unsafe_fn)] + use crate::collections::HashMap; use crate::error::Error as StdError; use crate::ffi::{CStr, OsStr, OsString}; diff --git a/library/std/src/sys/hermit/rwlock.rs b/library/std/src/sys/hermit/rwlock.rs index 06442e925f4c8..5672118188b37 100644 --- a/library/std/src/sys/hermit/rwlock.rs +++ b/library/std/src/sys/hermit/rwlock.rs @@ -1,3 +1,5 @@ +#![allow(unsafe_op_in_unsafe_fn)] + use crate::cell::UnsafeCell; use crate::sys::condvar::Condvar; use crate::sys::mutex::Mutex; diff --git a/library/std/src/sys/hermit/thread.rs b/library/std/src/sys/hermit/thread.rs index e11afed668728..22fe57f38d23e 100644 --- a/library/std/src/sys/hermit/thread.rs +++ b/library/std/src/sys/hermit/thread.rs @@ -1,4 +1,5 @@ #![allow(dead_code)] +#![allow(unsafe_op_in_unsafe_fn)] use crate::ffi::CStr; use crate::io; diff --git a/library/std/src/sys/hermit/thread_local_dtor.rs b/library/std/src/sys/hermit/thread_local_dtor.rs index 9b683fce15748..178788057a176 100644 --- a/library/std/src/sys/hermit/thread_local_dtor.rs +++ b/library/std/src/sys/hermit/thread_local_dtor.rs @@ -1,5 +1,6 @@ #![cfg(target_thread_local)] #![unstable(feature = "thread_local_internals", issue = "none")] +#![allow(unsafe_op_in_unsafe_fn)] // Simplify dtor registration by using a list of destructors. // The this solution works like the implementation of macOS and From 14158f551474d4114b9a2a583b0bf6c2502ad166 Mon Sep 17 00:00:00 2001 From: maekawatoshiki Date: Thu, 8 Oct 2020 22:13:14 +0900 Subject: [PATCH 04/33] Remove #![allow(unsafe_op_in_unsafe_fn)] except for mod.rs --- library/std/src/sys/hermit/alloc.rs | 2 -- library/std/src/sys/hermit/args.rs | 2 -- library/std/src/sys/hermit/condvar.rs | 2 -- library/std/src/sys/hermit/fd.rs | 1 - library/std/src/sys/hermit/mutex.rs | 2 -- library/std/src/sys/hermit/os.rs | 2 -- library/std/src/sys/hermit/rwlock.rs | 2 -- library/std/src/sys/hermit/thread.rs | 1 - library/std/src/sys/hermit/thread_local_dtor.rs | 1 - 9 files changed, 15 deletions(-) diff --git a/library/std/src/sys/hermit/alloc.rs b/library/std/src/sys/hermit/alloc.rs index cebe317de5678..d153914e77e10 100644 --- a/library/std/src/sys/hermit/alloc.rs +++ b/library/std/src/sys/hermit/alloc.rs @@ -1,5 +1,3 @@ -#![allow(unsafe_op_in_unsafe_fn)] - use crate::alloc::{GlobalAlloc, Layout, System}; use crate::ptr; use crate::sys::hermit::abi; diff --git a/library/std/src/sys/hermit/args.rs b/library/std/src/sys/hermit/args.rs index 194d94805724b..72c1b8511cac8 100644 --- a/library/std/src/sys/hermit/args.rs +++ b/library/std/src/sys/hermit/args.rs @@ -1,5 +1,3 @@ -#![allow(unsafe_op_in_unsafe_fn)] - use crate::ffi::OsString; use crate::marker::PhantomData; use crate::vec; diff --git a/library/std/src/sys/hermit/condvar.rs b/library/std/src/sys/hermit/condvar.rs index a69ab2d643cd2..52c8c3b17e826 100644 --- a/library/std/src/sys/hermit/condvar.rs +++ b/library/std/src/sys/hermit/condvar.rs @@ -1,5 +1,3 @@ -#![allow(unsafe_op_in_unsafe_fn)] - use crate::ffi::c_void; use crate::ptr; use crate::sync::atomic::{AtomicUsize, Ordering::SeqCst}; diff --git a/library/std/src/sys/hermit/fd.rs b/library/std/src/sys/hermit/fd.rs index fcdf1f058b162..97d1a38b41ab1 100644 --- a/library/std/src/sys/hermit/fd.rs +++ b/library/std/src/sys/hermit/fd.rs @@ -1,5 +1,4 @@ #![unstable(reason = "not public", issue = "none", feature = "fd")] -#![allow(unsafe_op_in_unsafe_fn)] use crate::io::{self, ErrorKind, Read}; use crate::mem; diff --git a/library/std/src/sys/hermit/mutex.rs b/library/std/src/sys/hermit/mutex.rs index 6af1854e7041c..3d4813209cbc4 100644 --- a/library/std/src/sys/hermit/mutex.rs +++ b/library/std/src/sys/hermit/mutex.rs @@ -1,5 +1,3 @@ -#![allow(unsafe_op_in_unsafe_fn)] - use crate::ffi::c_void; use crate::ptr; use crate::sys::hermit::abi; diff --git a/library/std/src/sys/hermit/os.rs b/library/std/src/sys/hermit/os.rs index ca0ffb7524d29..78eabf8f81e98 100644 --- a/library/std/src/sys/hermit/os.rs +++ b/library/std/src/sys/hermit/os.rs @@ -1,5 +1,3 @@ -#![allow(unsafe_op_in_unsafe_fn)] - use crate::collections::HashMap; use crate::error::Error as StdError; use crate::ffi::{CStr, OsStr, OsString}; diff --git a/library/std/src/sys/hermit/rwlock.rs b/library/std/src/sys/hermit/rwlock.rs index 5672118188b37..06442e925f4c8 100644 --- a/library/std/src/sys/hermit/rwlock.rs +++ b/library/std/src/sys/hermit/rwlock.rs @@ -1,5 +1,3 @@ -#![allow(unsafe_op_in_unsafe_fn)] - use crate::cell::UnsafeCell; use crate::sys::condvar::Condvar; use crate::sys::mutex::Mutex; diff --git a/library/std/src/sys/hermit/thread.rs b/library/std/src/sys/hermit/thread.rs index 22fe57f38d23e..e11afed668728 100644 --- a/library/std/src/sys/hermit/thread.rs +++ b/library/std/src/sys/hermit/thread.rs @@ -1,5 +1,4 @@ #![allow(dead_code)] -#![allow(unsafe_op_in_unsafe_fn)] use crate::ffi::CStr; use crate::io; diff --git a/library/std/src/sys/hermit/thread_local_dtor.rs b/library/std/src/sys/hermit/thread_local_dtor.rs index 178788057a176..9b683fce15748 100644 --- a/library/std/src/sys/hermit/thread_local_dtor.rs +++ b/library/std/src/sys/hermit/thread_local_dtor.rs @@ -1,6 +1,5 @@ #![cfg(target_thread_local)] #![unstable(feature = "thread_local_internals", issue = "none")] -#![allow(unsafe_op_in_unsafe_fn)] // Simplify dtor registration by using a list of destructors. // The this solution works like the implementation of macOS and From b3246e0cb10a6a32e8f652312985d36581f77c19 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Tue, 29 Sep 2020 19:46:32 -0400 Subject: [PATCH 05/33] Set the proper sysroot for clippy Clippy does its own runtime detection of the sysroot, which was incorrect in this case (it used the beta sysroot). This overrides the sysroot to use `stage0-sysroot` instead. - Get `x.py clippy` to work on nightly - Give a nice error message if nightly clippy isn't installed --- src/bootstrap/builder.rs | 41 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 39 insertions(+), 2 deletions(-) diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index dc4243a76d5da..c0578dea1cd5c 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -850,7 +850,40 @@ impl<'a> Builder<'a> { cargo.args(s.split_whitespace()); } rustflags.env("RUSTFLAGS_BOOTSTRAP"); - rustflags.arg("--cfg=bootstrap"); + if cmd == "clippy" { + // clippy overwrites any sysroot we pass on the command line. + // Tell it to use the appropriate sysroot instead. + // NOTE: this can't be fixed in clippy because we explicitly don't set `RUSTC`, + // so it has no way of knowing the sysroot. + rustflags.arg("--sysroot"); + rustflags.arg( + self.sysroot(compiler) + .as_os_str() + .to_str() + .expect("sysroot must be valid UTF-8"), + ); + // Only run clippy on a very limited subset of crates (in particular, not build scripts). + cargo.arg("-Zunstable-options"); + // Explicitly does *not* set `--cfg=bootstrap`, since we're using a nightly clippy. + let host_version = Command::new("rustc").arg("--version").output().map_err(|_| ()); + if let Err(_) = host_version.and_then(|output| { + if output.status.success() + && t!(std::str::from_utf8(&output.stdout)).contains("nightly") + { + Ok(output) + } else { + Err(()) + } + }) { + eprintln!( + "error: `x.py clippy` requires a nightly host `rustc` toolchain with the `clippy` component" + ); + eprintln!("help: try `rustup default nightly`"); + std::process::exit(1); + } + } else { + rustflags.arg("--cfg=bootstrap"); + } } if self.config.rust_new_symbol_mangling { @@ -975,7 +1008,6 @@ impl<'a> Builder<'a> { // src/bootstrap/bin/{rustc.rs,rustdoc.rs} cargo .env("RUSTBUILD_NATIVE_DIR", self.native_dir(target)) - .env("RUSTC", self.out.join("bootstrap/debug/rustc")) .env("RUSTC_REAL", self.rustc(compiler)) .env("RUSTC_STAGE", stage.to_string()) .env("RUSTC_SYSROOT", &sysroot) @@ -991,6 +1023,11 @@ impl<'a> Builder<'a> { ) .env("RUSTC_ERROR_METADATA_DST", self.extended_error_dir()) .env("RUSTC_BREAK_ON_ICE", "1"); + // Clippy support is a hack and uses the default `cargo-clippy` in path. + // Don't override RUSTC so that the `cargo-clippy` in path will be run. + if cmd != "clippy" { + cargo.env("RUSTC", self.out.join("bootstrap/debug/rustc")); + } // Dealing with rpath here is a little special, so let's go into some // detail. First off, `-rpath` is a linker option on Unix platforms From 51f8076403b69d803b1feb4624ba86a92417cdeb Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Tue, 29 Sep 2020 20:24:14 -0400 Subject: [PATCH 06/33] Add --fix support to `x.py clippy` --- src/bootstrap/builder.rs | 4 ++-- src/bootstrap/check.rs | 28 +++++++++++++++++----------- src/bootstrap/flags.rs | 6 +++++- 3 files changed, 24 insertions(+), 14 deletions(-) diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index c0578dea1cd5c..a2759b205d75f 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -371,7 +371,7 @@ impl<'a> Builder<'a> { tool::CargoMiri, native::Lld ), - Kind::Check | Kind::Clippy | Kind::Fix | Kind::Format => describe!( + Kind::Check | Kind::Clippy { .. } | Kind::Fix | Kind::Format => describe!( check::Std, check::Rustc, check::Rustdoc, @@ -540,7 +540,7 @@ impl<'a> Builder<'a> { let (kind, paths) = match build.config.cmd { Subcommand::Build { ref paths } => (Kind::Build, &paths[..]), Subcommand::Check { ref paths, all_targets: _ } => (Kind::Check, &paths[..]), - Subcommand::Clippy { ref paths } => (Kind::Clippy, &paths[..]), + Subcommand::Clippy { ref paths, .. } => (Kind::Clippy, &paths[..]), Subcommand::Fix { ref paths } => (Kind::Fix, &paths[..]), Subcommand::Doc { ref paths, .. } => (Kind::Doc, &paths[..]), Subcommand::Test { ref paths, .. } => (Kind::Test, &paths[..]), diff --git a/src/bootstrap/check.rs b/src/bootstrap/check.rs index 443a490e342d5..c8363bbc7f771 100644 --- a/src/bootstrap/check.rs +++ b/src/bootstrap/check.rs @@ -7,9 +7,8 @@ use crate::tool::{prepare_tool_cargo, SourceType}; use crate::INTERNER; use crate::{ builder::{Builder, Kind, RunConfig, ShouldRun, Step}, - Subcommand, }; -use crate::{Compiler, Mode}; +use crate::{Compiler, Mode, Subcommand}; use std::path::PathBuf; #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] @@ -17,10 +16,17 @@ pub struct Std { pub target: TargetSelection, } -fn args(kind: Kind) -> Vec { - match kind { - Kind::Clippy => vec!["--".to_owned(), "--cap-lints".to_owned(), "warn".to_owned()], - _ => Vec::new(), +/// Returns args for the subcommand itself (not for cargo) +fn args(builder: &Builder<'_>) -> Vec { + if let Subcommand::Clippy { fix, .. } = builder.config.cmd { + let mut args = vec!["--".to_owned(), "--cap-lints".to_owned(), "warn".to_owned()]; + if fix { + args.insert(0, "--fix".to_owned()); + args.insert(0, "-Zunstable-options".to_owned()); + } + args + } else { + vec![] } } @@ -62,7 +68,7 @@ impl Step for Std { run_cargo( builder, cargo, - args(builder.kind), + args(builder), &libstd_stamp(builder, compiler, target), vec![], true, @@ -104,7 +110,7 @@ impl Step for Std { run_cargo( builder, cargo, - args(builder.kind), + args(builder), &libstd_test_stamp(builder, compiler, target), vec![], true, @@ -165,7 +171,7 @@ impl Step for Rustc { run_cargo( builder, cargo, - args(builder.kind), + args(builder), &librustc_stamp(builder, compiler, target), vec![], true, @@ -220,7 +226,7 @@ impl Step for CodegenBackend { run_cargo( builder, cargo, - args(builder.kind), + args(builder), &codegen_backend_stamp(builder, compiler, target, backend), vec![], true, @@ -278,7 +284,7 @@ macro_rules! tool_check_step { run_cargo( builder, cargo, - args(builder.kind), + args(builder), &stamp(builder, compiler, target), vec![], true, diff --git a/src/bootstrap/flags.rs b/src/bootstrap/flags.rs index 3834e50e3fa11..dbfcf4df9b4be 100644 --- a/src/bootstrap/flags.rs +++ b/src/bootstrap/flags.rs @@ -55,6 +55,7 @@ pub enum Subcommand { paths: Vec, }, Clippy { + fix: bool, paths: Vec, }, Fix { @@ -273,6 +274,9 @@ To learn more about a subcommand, run `./x.py -h`", "bench" => { opts.optmulti("", "test-args", "extra arguments", "ARGS"); } + "clippy" => { + opts.optflag("", "fix", "automatically apply lint suggestions"); + } "doc" => { opts.optflag("", "open", "open the docs in a browser"); } @@ -513,7 +517,7 @@ Arguments: "check" | "c" => { Subcommand::Check { paths, all_targets: matches.opt_present("all-targets") } } - "clippy" => Subcommand::Clippy { paths }, + "clippy" => Subcommand::Clippy { paths, fix: matches.opt_present("fix") }, "fix" => Subcommand::Fix { paths }, "test" | "t" => Subcommand::Test { paths, From bdbb54297ab5375f024517873a8b8a60e789b31a Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Sat, 10 Oct 2020 00:47:15 -0400 Subject: [PATCH 07/33] x.py fmt --- src/bootstrap/check.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/bootstrap/check.rs b/src/bootstrap/check.rs index c8363bbc7f771..b88dca0a9ed34 100644 --- a/src/bootstrap/check.rs +++ b/src/bootstrap/check.rs @@ -1,13 +1,11 @@ //! Implementation of compiling the compiler and standard library, in "check"-based modes. +use crate::builder::{Builder, Kind, RunConfig, ShouldRun, Step}; use crate::cache::Interned; use crate::compile::{add_to_sysroot, run_cargo, rustc_cargo, rustc_cargo_env, std_cargo}; use crate::config::TargetSelection; use crate::tool::{prepare_tool_cargo, SourceType}; use crate::INTERNER; -use crate::{ - builder::{Builder, Kind, RunConfig, ShouldRun, Step}, -}; use crate::{Compiler, Mode, Subcommand}; use std::path::PathBuf; From 31ecd2a124ff9c466c9661862aa0a0ad2d48d1a1 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Sat, 10 Oct 2020 01:11:01 -0400 Subject: [PATCH 08/33] Allow using clippy with either beta or nightly Not 100% sure this will _always_ work, but it works currently. --- src/bootstrap/builder.rs | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index a2759b205d75f..532949e47a17a 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -866,20 +866,22 @@ impl<'a> Builder<'a> { cargo.arg("-Zunstable-options"); // Explicitly does *not* set `--cfg=bootstrap`, since we're using a nightly clippy. let host_version = Command::new("rustc").arg("--version").output().map_err(|_| ()); - if let Err(_) = host_version.and_then(|output| { + let output = host_version.and_then(|output| { if output.status.success() - && t!(std::str::from_utf8(&output.stdout)).contains("nightly") { Ok(output) } else { Err(()) } - }) { + }).unwrap_or_else(|_| { eprintln!( - "error: `x.py clippy` requires a nightly host `rustc` toolchain with the `clippy` component" + "error: `x.py clippy` requires a host `rustc` toolchain with the `clippy` component" ); - eprintln!("help: try `rustup default nightly`"); + eprintln!("help: try `rustup component add clippy`"); std::process::exit(1); + }); + if !t!(std::str::from_utf8(&output.stdout)).contains("nightly") { + rustflags.arg("--cfg=bootstrap"); } } else { rustflags.arg("--cfg=bootstrap"); From e099138eb6274b8450fbbb3c1fec0389337eb992 Mon Sep 17 00:00:00 2001 From: Stein Somers Date: Mon, 26 Oct 2020 23:31:45 +0100 Subject: [PATCH 09/33] BTreeMap: stop mistaking node for an orderly place --- .../alloc/src/collections/btree/map/tests.rs | 26 +++++++++++-- .../alloc/src/collections/btree/node/tests.rs | 37 ------------------- 2 files changed, 22 insertions(+), 41 deletions(-) diff --git a/library/alloc/src/collections/btree/map/tests.rs b/library/alloc/src/collections/btree/map/tests.rs index adb94972f5bb6..f6921e67636d9 100644 --- a/library/alloc/src/collections/btree/map/tests.rs +++ b/library/alloc/src/collections/btree/map/tests.rs @@ -42,7 +42,7 @@ fn test_all_refs<'a, T: 'a>(dummy: &mut T, iter: impl Iterator } } -impl<'a, K: 'a, V: 'a> BTreeMap { +impl BTreeMap { /// Panics if the map (or the code navigating it) is corrupted. fn check(&self) where @@ -54,14 +54,14 @@ impl<'a, K: 'a, V: 'a> BTreeMap { assert!(root_node.ascend().is_err()); root_node.assert_back_pointers(); - let counted = root_node.assert_ascending(); - assert_eq!(self.length, counted); assert_eq!(self.length, root_node.calc_length()); root_node.assert_min_len(if root_node.height() > 0 { 1 } else { 0 }); } else { assert_eq!(self.length, 0); } + + self.assert_ascending(); } /// Returns the height of the root, if any. @@ -79,10 +79,28 @@ impl<'a, K: 'a, V: 'a> BTreeMap { String::from("not yet allocated") } } + + /// Asserts that the keys are in strictly ascending order. + fn assert_ascending(&self) + where + K: Copy + Debug + Ord, + { + let mut num_seen = 0; + let mut keys = self.keys(); + if let Some(mut previous) = keys.next() { + num_seen = 1; + for next in keys { + assert!(previous < next, "{:?} >= {:?}", previous, next); + previous = next; + num_seen += 1; + } + } + assert_eq!(num_seen, self.len()); + } } impl<'a, K: 'a, V: 'a> NodeRef, K, V, marker::LeafOrInternal> { - pub fn assert_min_len(self, min_len: usize) { + fn assert_min_len(self, min_len: usize) { assert!(self.len() >= min_len, "{} < {}", self.len(), min_len); if let node::ForceResult::Internal(node) = self.force() { for idx in 0..=node.len() { diff --git a/library/alloc/src/collections/btree/node/tests.rs b/library/alloc/src/collections/btree/node/tests.rs index d6527057c5d77..38c75de34eeeb 100644 --- a/library/alloc/src/collections/btree/node/tests.rs +++ b/library/alloc/src/collections/btree/node/tests.rs @@ -17,43 +17,6 @@ impl<'a, K: 'a, V: 'a> NodeRef, K, V, marker::LeafOrInternal> } } - /// Asserts that the keys are in strictly ascending order. - /// Returns how many keys it encountered. - pub fn assert_ascending(self) -> usize - where - K: Copy + Debug + Ord, - { - struct SeriesChecker { - num_seen: usize, - previous: Option, - } - impl SeriesChecker { - fn is_ascending(&mut self, next: T) { - if let Some(previous) = self.previous { - assert!(previous < next, "{:?} >= {:?}", previous, next); - } - self.previous = Some(next); - self.num_seen += 1; - } - } - - let mut checker = SeriesChecker { num_seen: 0, previous: None }; - self.visit_nodes_in_order(|pos| match pos { - navigate::Position::Leaf(node) => { - for idx in 0..node.len() { - let key = *unsafe { node.key_at(idx) }; - checker.is_ascending(key); - } - } - navigate::Position::InternalKV(kv) => { - let key = *kv.into_kv().0; - checker.is_ascending(key); - } - navigate::Position::Internal(_) => {} - }); - checker.num_seen - } - pub fn dump_keys(self) -> String where K: Debug, From b0df3f76dc70eba57d6e0665fa6ccac89b25d3aa Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Wed, 28 Oct 2020 09:05:45 +0100 Subject: [PATCH 10/33] fix some incorrect aliasing in the BTree --- library/alloc/src/collections/btree/node.rs | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/library/alloc/src/collections/btree/node.rs b/library/alloc/src/collections/btree/node.rs index c8d3de9e5cd5c..433074027e7f7 100644 --- a/library/alloc/src/collections/btree/node.rs +++ b/library/alloc/src/collections/btree/node.rs @@ -1608,15 +1608,19 @@ pub mod marker { unsafe fn slice_insert(slice: &mut [T], idx: usize, val: T) { unsafe { - ptr::copy(slice.as_ptr().add(idx), slice.as_mut_ptr().add(idx + 1), slice.len() - idx); - ptr::write(slice.get_unchecked_mut(idx), val); + let len = slice.len(); + let slice_ptr = slice.as_mut_ptr(); + ptr::copy(slice_ptr.add(idx), slice_ptr.add(idx + 1), len - idx); + ptr::write(slice_ptr.add(idx), val); } } unsafe fn slice_remove(slice: &mut [T], idx: usize) -> T { unsafe { - let ret = ptr::read(slice.get_unchecked(idx)); - ptr::copy(slice.as_ptr().add(idx + 1), slice.as_mut_ptr().add(idx), slice.len() - idx - 1); + let len = slice.len(); + let slice_ptr = slice.as_mut_ptr(); + let ret = ptr::read(slice_ptr.add(idx)); + ptr::copy(slice_ptr.add(idx + 1), slice_ptr.add(idx), len - idx - 1); ret } } From 1e737249afa1219205f6cc182ce975ffe94f06f9 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Wed, 28 Oct 2020 23:38:31 -0400 Subject: [PATCH 11/33] Allow using 1/2/3/4 for `x.py setup` options This undocumented feature allows you to typo 'a' as '1'. --- src/bootstrap/setup.rs | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/bootstrap/setup.rs b/src/bootstrap/setup.rs index c6e1c99564c09..0945ceee6cee0 100644 --- a/src/bootstrap/setup.rs +++ b/src/bootstrap/setup.rs @@ -127,14 +127,17 @@ pub fn setup(src_path: &Path, profile: Profile) { // Used to get the path for `Subcommand::Setup` pub fn interactive_path() -> io::Result { - fn abbrev_all() -> impl Iterator { - ('a'..).map(|c| c.to_string()).zip(Profile::all()) + fn abbrev_all() -> impl Iterator { + ('a'..) + .zip(1..) + .map(|(letter, number)| (letter.to_string(), number.to_string())) + .zip(Profile::all()) } fn parse_with_abbrev(input: &str) -> Result { let input = input.trim().to_lowercase(); - for (letter, profile) in abbrev_all() { - if input == letter { + for ((letter, number), profile) in abbrev_all() { + if input == letter || input == number { return Ok(profile); } } @@ -142,13 +145,13 @@ pub fn interactive_path() -> io::Result { } println!("Welcome to the Rust project! What do you want to do with x.py?"); - for (letter, profile) in abbrev_all() { + for ((letter, _), profile) in abbrev_all() { println!("{}) {}: {}", letter, profile, profile.purpose()); } let template = loop { print!( "Please choose one ({}): ", - abbrev_all().map(|(l, _)| l).collect::>().join("/") + abbrev_all().map(|((l, _), _)| l).collect::>().join("/") ); io::stdout().flush()?; let mut input = String::new(); From be01d54f07b9c56d2426ddaebaea499575479b38 Mon Sep 17 00:00:00 2001 From: Stein Somers Date: Thu, 29 Oct 2020 20:51:39 +0100 Subject: [PATCH 12/33] BTreeMap: document a curious assumption in test cases --- library/alloc/src/collections/btree/map/tests.rs | 1 + library/alloc/src/collections/btree/mod.rs | 1 + library/alloc/src/collections/btree/set/tests.rs | 1 + 3 files changed, 3 insertions(+) diff --git a/library/alloc/src/collections/btree/map/tests.rs b/library/alloc/src/collections/btree/map/tests.rs index adb94972f5bb6..710aa2adfecbd 100644 --- a/library/alloc/src/collections/btree/map/tests.rs +++ b/library/alloc/src/collections/btree/map/tests.rs @@ -1661,6 +1661,7 @@ create_append_test!(test_append_239, 239); create_append_test!(test_append_1700, 1700); fn rand_data(len: usize) -> Vec<(u32, u32)> { + assert!(len * 2 <= 70029); // from that point on numbers repeat let mut rng = DeterministicRng::new(); Vec::from_iter((0..len).map(|_| (rng.next(), rng.next()))) } diff --git a/library/alloc/src/collections/btree/mod.rs b/library/alloc/src/collections/btree/mod.rs index 4c07795bd70cd..7bf1706dd6d57 100644 --- a/library/alloc/src/collections/btree/mod.rs +++ b/library/alloc/src/collections/btree/mod.rs @@ -49,6 +49,7 @@ impl DeterministicRng { DeterministicRng { x: 0x193a6754, y: 0xa8a7d469, z: 0x97830e05, w: 0x113ba7bb } } + /// Guarantees that the first 70029 results are unique. fn next(&mut self) -> u32 { let x = self.x; let t = x ^ (x << 11); diff --git a/library/alloc/src/collections/btree/set/tests.rs b/library/alloc/src/collections/btree/set/tests.rs index 9267435728216..eb3feef09e51e 100644 --- a/library/alloc/src/collections/btree/set/tests.rs +++ b/library/alloc/src/collections/btree/set/tests.rs @@ -680,6 +680,7 @@ fn test_first_last() { } fn rand_data(len: usize) -> Vec { + assert!(len <= 70029); // from that point on numbers repeat let mut rng = DeterministicRng::new(); Vec::from_iter((0..len).map(|_| rng.next())) } From d2bc8a92e672443b156cdc71dd4cc32ef6035ab3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Mi=C4=85sko?= Date: Tue, 3 Nov 2020 00:00:00 +0000 Subject: [PATCH 13/33] inliner: Use substs_for_mir_body Changes from 68965 extended the kind of instances that are being inlined. For some of those, the `instance_mir` returns a MIR body that is already expressed in terms of the types found in substitution array, and doesn't need further substitution. Use `substs_for_mir_body` to take that into account. --- .../rustc_codegen_cranelift/src/common.rs | 12 ++--- compiler/rustc_codegen_ssa/src/mir/mod.rs | 14 ++--- compiler/rustc_middle/src/ty/instance.rs | 27 +++++++++- .../rustc_mir/src/interpret/eval_context.rs | 6 +-- .../rustc_mir/src/monomorphize/collector.rs | 10 ++-- compiler/rustc_mir/src/transform/inline.rs | 24 ++++----- src/test/mir-opt/inline/inline-shims.rs | 12 +++++ .../inline/inline_shims.clone.Inline.diff | 26 ++++++++++ .../inline/inline_shims.drop.Inline.diff | 52 +++++++++++++++++++ 9 files changed, 141 insertions(+), 42 deletions(-) create mode 100644 src/test/mir-opt/inline/inline-shims.rs create mode 100644 src/test/mir-opt/inline/inline_shims.clone.Inline.diff create mode 100644 src/test/mir-opt/inline/inline_shims.drop.Inline.diff diff --git a/compiler/rustc_codegen_cranelift/src/common.rs b/compiler/rustc_codegen_cranelift/src/common.rs index 13c62add41a3b..cc0e7d50d8080 100644 --- a/compiler/rustc_codegen_cranelift/src/common.rs +++ b/compiler/rustc_codegen_cranelift/src/common.rs @@ -361,13 +361,11 @@ impl<'tcx, M: Module> FunctionCx<'_, 'tcx, M> { where T: TypeFoldable<'tcx> + Copy, { - if let Some(substs) = self.instance.substs_for_mir_body() { - self.tcx - .subst_and_normalize_erasing_regions(substs, ty::ParamEnv::reveal_all(), value) - } else { - self.tcx - .normalize_erasing_regions(ty::ParamEnv::reveal_all(), *value) - } + self.instance.subst_mir_and_normalize_erasing_regions( + self.tcx, + ty::ParamEnv::reveal_all(), + value + ) } pub(crate) fn clif_type(&self, ty: Ty<'tcx>) -> Option { diff --git a/compiler/rustc_codegen_ssa/src/mir/mod.rs b/compiler/rustc_codegen_ssa/src/mir/mod.rs index 84e82e88e8eea..01fd1681593e8 100644 --- a/compiler/rustc_codegen_ssa/src/mir/mod.rs +++ b/compiler/rustc_codegen_ssa/src/mir/mod.rs @@ -92,15 +92,11 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { T: Copy + TypeFoldable<'tcx>, { debug!("monomorphize: self.instance={:?}", self.instance); - if let Some(substs) = self.instance.substs_for_mir_body() { - self.cx.tcx().subst_and_normalize_erasing_regions( - substs, - ty::ParamEnv::reveal_all(), - &value, - ) - } else { - self.cx.tcx().normalize_erasing_regions(ty::ParamEnv::reveal_all(), *value) - } + self.instance.subst_mir_and_normalize_erasing_regions( + self.cx.tcx(), + ty::ParamEnv::reveal_all(), + value, + ) } } diff --git a/compiler/rustc_middle/src/ty/instance.rs b/compiler/rustc_middle/src/ty/instance.rs index 8b3fb87507061..306cebd9cb722 100644 --- a/compiler/rustc_middle/src/ty/instance.rs +++ b/compiler/rustc_middle/src/ty/instance.rs @@ -1,6 +1,6 @@ use crate::middle::codegen_fn_attrs::CodegenFnAttrFlags; use crate::ty::print::{FmtPrinter, Printer}; -use crate::ty::subst::InternalSubsts; +use crate::ty::subst::{InternalSubsts, Subst}; use crate::ty::{self, SubstsRef, Ty, TyCtxt, TypeFoldable}; use rustc_errors::ErrorReported; use rustc_hir::def::Namespace; @@ -470,10 +470,33 @@ impl<'tcx> Instance<'tcx> { /// This function returns `Some(substs)` in the former case and `None` otherwise -- i.e., if /// this function returns `None`, then the MIR body does not require substitution during /// codegen. - pub fn substs_for_mir_body(&self) -> Option> { + fn substs_for_mir_body(&self) -> Option> { if self.def.has_polymorphic_mir_body() { Some(self.substs) } else { None } } + pub fn subst_mir(&self, tcx: TyCtxt<'tcx>, v: &T) -> T + where + T: TypeFoldable<'tcx> + Copy, + { + if let Some(substs) = self.substs_for_mir_body() { v.subst(tcx, substs) } else { *v } + } + + pub fn subst_mir_and_normalize_erasing_regions( + &self, + tcx: TyCtxt<'tcx>, + param_env: ty::ParamEnv<'tcx>, + v: &T, + ) -> T + where + T: TypeFoldable<'tcx> + Clone, + { + if let Some(substs) = self.substs_for_mir_body() { + tcx.subst_and_normalize_erasing_regions(substs, param_env, v) + } else { + tcx.normalize_erasing_regions(param_env, v.clone()) + } + } + /// Returns a new `Instance` where generic parameters in `instance.substs` are replaced by /// identify parameters if they are determined to be unused in `instance.def`. pub fn polymorphize(self, tcx: TyCtxt<'tcx>) -> Self { diff --git a/compiler/rustc_mir/src/interpret/eval_context.rs b/compiler/rustc_mir/src/interpret/eval_context.rs index ec1195d3703b4..aba1cf38d4630 100644 --- a/compiler/rustc_mir/src/interpret/eval_context.rs +++ b/compiler/rustc_mir/src/interpret/eval_context.rs @@ -507,11 +507,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { frame: &Frame<'mir, 'tcx, M::PointerTag, M::FrameExtra>, value: T, ) -> T { - if let Some(substs) = frame.instance.substs_for_mir_body() { - self.tcx.subst_and_normalize_erasing_regions(substs, self.param_env, &value) - } else { - self.tcx.normalize_erasing_regions(self.param_env, value) - } + frame.instance.subst_mir_and_normalize_erasing_regions(*self.tcx, self.param_env, &value) } /// The `substs` are assumed to already be in our interpreter "universe" (param_env). diff --git a/compiler/rustc_mir/src/monomorphize/collector.rs b/compiler/rustc_mir/src/monomorphize/collector.rs index 417176564b92d..938181abff244 100644 --- a/compiler/rustc_mir/src/monomorphize/collector.rs +++ b/compiler/rustc_mir/src/monomorphize/collector.rs @@ -543,11 +543,11 @@ impl<'a, 'tcx> MirNeighborCollector<'a, 'tcx> { T: TypeFoldable<'tcx>, { debug!("monomorphize: self.instance={:?}", self.instance); - if let Some(substs) = self.instance.substs_for_mir_body() { - self.tcx.subst_and_normalize_erasing_regions(substs, ty::ParamEnv::reveal_all(), &value) - } else { - self.tcx.normalize_erasing_regions(ty::ParamEnv::reveal_all(), value) - } + self.instance.subst_mir_and_normalize_erasing_regions( + self.tcx, + ty::ParamEnv::reveal_all(), + &value, + ) } } diff --git a/compiler/rustc_mir/src/transform/inline.rs b/compiler/rustc_mir/src/transform/inline.rs index 5407226e386cb..37679c24454af 100644 --- a/compiler/rustc_mir/src/transform/inline.rs +++ b/compiler/rustc_mir/src/transform/inline.rs @@ -6,7 +6,6 @@ use rustc_index::vec::Idx; use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs}; use rustc_middle::mir::visit::*; use rustc_middle::mir::*; -use rustc_middle::ty::subst::Subst; use rustc_middle::ty::{self, ConstKind, Instance, InstanceDef, ParamEnv, Ty, TyCtxt}; use rustc_span::{hygiene::ExpnKind, ExpnData, Span}; use rustc_target::spec::abi::Abi; @@ -128,17 +127,15 @@ impl Inliner<'tcx> { self.tcx.instance_mir(callsite.callee.def) }; - let callee_body: &Body<'tcx> = &*callee_body; - - let callee_body = if self.consider_optimizing(callsite, callee_body) { - self.tcx.subst_and_normalize_erasing_regions( - &callsite.callee.substs, - self.param_env, - callee_body, - ) - } else { + if !self.consider_optimizing(callsite, &callee_body) { continue; - }; + } + + let callee_body = callsite.callee.subst_mir_and_normalize_erasing_regions( + self.tcx, + self.param_env, + callee_body, + ); // Copy only unevaluated constants from the callee_body into the caller_body. // Although we are only pushing `ConstKind::Unevaluated` consts to @@ -317,7 +314,7 @@ impl Inliner<'tcx> { work_list.push(target); // If the place doesn't actually need dropping, treat it like // a regular goto. - let ty = place.ty(callee_body, tcx).subst(tcx, callsite.callee.substs).ty; + let ty = callsite.callee.subst_mir(self.tcx, &place.ty(callee_body, tcx).ty); if ty.needs_drop(tcx, self.param_env) { cost += CALL_PENALTY; if let Some(unwind) = unwind { @@ -379,8 +376,7 @@ impl Inliner<'tcx> { let ptr_size = tcx.data_layout.pointer_size.bytes(); for v in callee_body.vars_and_temps_iter() { - let v = &callee_body.local_decls[v]; - let ty = v.ty.subst(tcx, callsite.callee.substs); + let ty = callsite.callee.subst_mir(self.tcx, &callee_body.local_decls[v].ty); // Cost of the var is the size in machine-words, if we know // it. if let Some(size) = type_size_of(tcx, self.param_env, ty) { diff --git a/src/test/mir-opt/inline/inline-shims.rs b/src/test/mir-opt/inline/inline-shims.rs new file mode 100644 index 0000000000000..6e84bd731799b --- /dev/null +++ b/src/test/mir-opt/inline/inline-shims.rs @@ -0,0 +1,12 @@ +#![crate_type = "lib"] + +// EMIT_MIR inline_shims.clone.Inline.diff +pub fn clone(f: fn(A, B)) -> fn(A, B) { + f.clone() +} + +// EMIT_MIR inline_shims.drop.Inline.diff +pub fn drop(a: *mut Vec, b: *mut Option) { + unsafe { std::ptr::drop_in_place(a) } + unsafe { std::ptr::drop_in_place(b) } +} diff --git a/src/test/mir-opt/inline/inline_shims.clone.Inline.diff b/src/test/mir-opt/inline/inline_shims.clone.Inline.diff new file mode 100644 index 0000000000000..5917f4ccab24e --- /dev/null +++ b/src/test/mir-opt/inline/inline_shims.clone.Inline.diff @@ -0,0 +1,26 @@ +- // MIR for `clone` before Inline ++ // MIR for `clone` after Inline + + fn clone(_1: fn(A, B)) -> fn(A, B) { + debug f => _1; // in scope 0 at $DIR/inline-shims.rs:4:20: 4:21 + let mut _0: fn(A, B); // return place in scope 0 at $DIR/inline-shims.rs:4:36: 4:44 + let mut _2: &fn(A, B); // in scope 0 at $DIR/inline-shims.rs:5:5: 5:6 ++ scope 1 (inlined ::clone - shim(fn(A, B))) { // at $DIR/inline-shims.rs:5:5: 5:14 ++ } + + bb0: { + StorageLive(_2); // scope 0 at $DIR/inline-shims.rs:5:5: 5:6 + _2 = &_1; // scope 0 at $DIR/inline-shims.rs:5:5: 5:6 +- _0 = ::clone(move _2) -> bb1; // scope 0 at $DIR/inline-shims.rs:5:5: 5:14 +- // mir::Constant +- // + span: $DIR/inline-shims.rs:5:7: 5:12 +- // + literal: Const { ty: for<'r> fn(&'r fn(A, B)) -> fn(A, B) {::clone}, val: Value(Scalar()) } +- } +- +- bb1: { ++ _0 = (*_2); // scope 1 at $DIR/inline-shims.rs:5:5: 5:14 + StorageDead(_2); // scope 0 at $DIR/inline-shims.rs:5:13: 5:14 + return; // scope 0 at $DIR/inline-shims.rs:6:2: 6:2 + } + } + diff --git a/src/test/mir-opt/inline/inline_shims.drop.Inline.diff b/src/test/mir-opt/inline/inline_shims.drop.Inline.diff new file mode 100644 index 0000000000000..1b22ac100fe56 --- /dev/null +++ b/src/test/mir-opt/inline/inline_shims.drop.Inline.diff @@ -0,0 +1,52 @@ +- // MIR for `drop` before Inline ++ // MIR for `drop` after Inline + + fn drop(_1: *mut Vec, _2: *mut Option) -> () { + debug a => _1; // in scope 0 at $DIR/inline-shims.rs:9:19: 9:20 + debug b => _2; // in scope 0 at $DIR/inline-shims.rs:9:35: 9:36 + let mut _0: (); // return place in scope 0 at $DIR/inline-shims.rs:9:54: 9:54 + let _3: (); // in scope 0 at $DIR/inline-shims.rs:10:14: 10:40 + let mut _4: *mut std::vec::Vec; // in scope 0 at $DIR/inline-shims.rs:10:38: 10:39 + let mut _5: *mut std::option::Option; // in scope 0 at $DIR/inline-shims.rs:11:38: 11:39 + scope 1 { + } + scope 2 { ++ scope 3 (inlined drop_in_place::> - shim(Some(Option))) { // at $DIR/inline-shims.rs:11:14: 11:40 ++ let mut _6: isize; // in scope 3 at $DIR/inline-shims.rs:11:14: 11:40 ++ let mut _7: isize; // in scope 3 at $DIR/inline-shims.rs:11:14: 11:40 ++ } + } + + bb0: { + StorageLive(_3); // scope 0 at $DIR/inline-shims.rs:10:5: 10:42 + StorageLive(_4); // scope 1 at $DIR/inline-shims.rs:10:38: 10:39 + _4 = _1; // scope 1 at $DIR/inline-shims.rs:10:38: 10:39 + _3 = drop_in_place::>(move _4) -> bb1; // scope 1 at $DIR/inline-shims.rs:10:14: 10:40 + // mir::Constant + // + span: $DIR/inline-shims.rs:10:14: 10:37 + // + literal: Const { ty: unsafe fn(*mut std::vec::Vec) {std::intrinsics::drop_in_place::>}, val: Value(Scalar()) } + } + + bb1: { + StorageDead(_4); // scope 1 at $DIR/inline-shims.rs:10:39: 10:40 + StorageDead(_3); // scope 0 at $DIR/inline-shims.rs:10:41: 10:42 + StorageLive(_5); // scope 2 at $DIR/inline-shims.rs:11:38: 11:39 + _5 = _2; // scope 2 at $DIR/inline-shims.rs:11:38: 11:39 +- _0 = drop_in_place::>(move _5) -> bb2; // scope 2 at $DIR/inline-shims.rs:11:14: 11:40 +- // mir::Constant +- // + span: $DIR/inline-shims.rs:11:14: 11:37 +- // + literal: Const { ty: unsafe fn(*mut std::option::Option) {std::intrinsics::drop_in_place::>}, val: Value(Scalar()) } ++ _6 = discriminant((*_5)); // scope 3 at $DIR/inline-shims.rs:11:14: 11:40 ++ switchInt(move _6) -> [0_isize: bb2, otherwise: bb3]; // scope 3 at $DIR/inline-shims.rs:11:14: 11:40 + } + + bb2: { + StorageDead(_5); // scope 2 at $DIR/inline-shims.rs:11:39: 11:40 + return; // scope 0 at $DIR/inline-shims.rs:12:2: 12:2 ++ } ++ ++ bb3: { ++ drop((((*_5) as Some).0: B)) -> bb2; // scope 3 at $DIR/inline-shims.rs:11:14: 11:40 + } + } + From 29803670304bfad1c46502dfb71af6dd12953b5d Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 12 Oct 2020 18:28:57 +0200 Subject: [PATCH 14/33] Add new lint for automatic_links improvements --- compiler/rustc_lint/src/lib.rs | 3 +- compiler/rustc_lint_defs/src/builtin.rs | 12 +++ src/librustdoc/core.rs | 2 + src/librustdoc/passes/automatic_links.rs | 93 ++++++++++++++++++++++++ src/librustdoc/passes/mod.rs | 5 ++ 5 files changed, 114 insertions(+), 1 deletion(-) create mode 100644 src/librustdoc/passes/automatic_links.rs diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs index 7297a6de42046..0da3ece167e97 100644 --- a/compiler/rustc_lint/src/lib.rs +++ b/compiler/rustc_lint/src/lib.rs @@ -67,7 +67,7 @@ use rustc_hir::def_id::LocalDefId; use rustc_middle::ty::query::Providers; use rustc_middle::ty::TyCtxt; use rustc_session::lint::builtin::{ - BARE_TRAIT_OBJECTS, BROKEN_INTRA_DOC_LINKS, ELIDED_LIFETIMES_IN_PATHS, + AUTOMATIC_LINKS, BARE_TRAIT_OBJECTS, BROKEN_INTRA_DOC_LINKS, ELIDED_LIFETIMES_IN_PATHS, EXPLICIT_OUTLIVES_REQUIREMENTS, INVALID_CODEBLOCK_ATTRIBUTES, INVALID_HTML_TAGS, MISSING_DOC_CODE_EXAMPLES, PRIVATE_DOC_TESTS, }; @@ -313,6 +313,7 @@ fn register_builtins(store: &mut LintStore, no_interleave_lints: bool) { add_lint_group!( "rustdoc", + AUTOMATIC_LINKS, BROKEN_INTRA_DOC_LINKS, PRIVATE_INTRA_DOC_LINKS, INVALID_CODEBLOCK_ATTRIBUTES, diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index a1b7c13e4c0f0..3fc9c096696ba 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -1890,6 +1890,17 @@ declare_lint! { "detects invalid HTML tags in doc comments" } +declare_lint! { + /// The `automatic_links` lint detects when a URL/email address could be + /// written using only brackets. This is a `rustdoc` only lint, see the + /// documentation in the [rustdoc book]. + /// + /// [rustdoc book]: ../../../rustdoc/lints.html#automatic_links + pub AUTOMATIC_LINKS, + Allow, + "detects URLs/email adresses that could be written using only brackets" +} + declare_lint! { /// The `where_clauses_object_safety` lint detects for [object safety] of /// [where clauses]. @@ -2795,6 +2806,7 @@ declare_lint_pass! { MISSING_DOC_CODE_EXAMPLES, INVALID_HTML_TAGS, PRIVATE_DOC_TESTS, + AUTOMATIC_LINKS, WHERE_CLAUSES_OBJECT_SAFETY, PROC_MACRO_DERIVE_RESOLUTION_FALLBACK, MACRO_USE_EXTERN_CRATE, diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 45a84c4fb30d3..f834be84d4c59 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -330,11 +330,13 @@ pub fn run_core( let invalid_codeblock_attributes_name = rustc_lint::builtin::INVALID_CODEBLOCK_ATTRIBUTES.name; let invalid_html_tags = rustc_lint::builtin::INVALID_HTML_TAGS.name; let renamed_and_removed_lints = rustc_lint::builtin::RENAMED_AND_REMOVED_LINTS.name; + let automatic_links = rustc_lint::builtin::AUTOMATIC_LINKS.name; let unknown_lints = rustc_lint::builtin::UNKNOWN_LINTS.name; // In addition to those specific lints, we also need to allow those given through // command line, otherwise they'll get ignored and we don't want that. let lints_to_show = vec![ + automatic_links.to_owned(), intra_link_resolution_failure_name.to_owned(), missing_docs.to_owned(), missing_doc_example.to_owned(), diff --git a/src/librustdoc/passes/automatic_links.rs b/src/librustdoc/passes/automatic_links.rs new file mode 100644 index 0000000000000..79542241326da --- /dev/null +++ b/src/librustdoc/passes/automatic_links.rs @@ -0,0 +1,93 @@ +use super::{span_of_attrs, Pass}; +use crate::clean::*; +use crate::core::DocContext; +use crate::fold::DocFolder; +use crate::html::markdown::opts; +use pulldown_cmark::{Event, Parser, Tag}; +use rustc_feature::UnstableFeatures; +use rustc_session::lint; + +pub const CHECK_AUTOMATIC_LINKS: Pass = Pass { + name: "check-automatic-links", + run: check_automatic_links, + description: "detects URLS/email addresses that could be written using brackets", +}; + +struct AutomaticLinksLinter<'a, 'tcx> { + cx: &'a DocContext<'tcx>, +} + +impl<'a, 'tcx> AutomaticLinksLinter<'a, 'tcx> { + fn new(cx: &'a DocContext<'tcx>) -> Self { + AutomaticLinksLinter { cx } + } +} + +pub fn check_automatic_links(krate: Crate, cx: &DocContext<'_>) -> Crate { + if !UnstableFeatures::from_environment().is_nightly_build() { + krate + } else { + let mut coll = AutomaticLinksLinter::new(cx); + + coll.fold_crate(krate) + } +} + +impl<'a, 'tcx> DocFolder for AutomaticLinksLinter<'a, 'tcx> { + fn fold_item(&mut self, item: Item) -> Option { + let hir_id = match self.cx.as_local_hir_id(item.def_id) { + Some(hir_id) => hir_id, + None => { + // If non-local, no need to check anything. + return self.fold_item_recur(item); + } + }; + let dox = item.attrs.collapsed_doc_value().unwrap_or_default(); + if !dox.is_empty() { + let cx = &self.cx; + + let p = Parser::new_ext(&dox, opts()).into_offset_iter(); + + let mut title = String::new(); + let mut in_link = false; + + for (event, range) in p { + match event { + Event::Start(Tag::Link(..)) => in_link = true, + Event::End(Tag::Link(_, url, _)) => { + in_link = false; + if url.as_ref() != title { + continue; + } + let sp = match super::source_span_for_markdown_range( + cx, + &dox, + &range, + &item.attrs, + ) { + Some(sp) => sp, + None => span_of_attrs(&item.attrs).unwrap_or(item.source.span()), + }; + cx.tcx.struct_span_lint_hir( + lint::builtin::AUTOMATIC_LINKS, + hir_id, + sp, + |lint| { + lint.build("Unneeded long form for URL") + .help(&format!("Try with `<{}>` instead", url)) + .emit() + }, + ); + title.clear(); + } + Event::Text(s) if in_link => { + title.push_str(&s); + } + _ => {} + } + } + } + + self.fold_item_recur(item) + } +} diff --git a/src/librustdoc/passes/mod.rs b/src/librustdoc/passes/mod.rs index 2591650e3f97f..48dc52c955006 100644 --- a/src/librustdoc/passes/mod.rs +++ b/src/librustdoc/passes/mod.rs @@ -11,6 +11,9 @@ use crate::core::DocContext; mod stripper; pub use stripper::*; +mod automatic_links; +pub use self::automatic_links::CHECK_AUTOMATIC_LINKS; + mod collapse_docs; pub use self::collapse_docs::COLLAPSE_DOCS; @@ -90,6 +93,7 @@ pub const PASSES: &[Pass] = &[ COLLECT_TRAIT_IMPLS, CALCULATE_DOC_COVERAGE, CHECK_INVALID_HTML_TAGS, + CHECK_AUTOMATIC_LINKS, ]; /// The list of passes run by default. @@ -105,6 +109,7 @@ pub const DEFAULT_PASSES: &[ConditionalPass] = &[ ConditionalPass::always(CHECK_CODE_BLOCK_SYNTAX), ConditionalPass::always(CHECK_INVALID_HTML_TAGS), ConditionalPass::always(PROPAGATE_DOC_CFG), + ConditionalPass::always(CHECK_AUTOMATIC_LINKS), ]; /// The list of default passes run when `--doc-coverage` is passed to rustdoc. From a54f04373382b085837f5f835569d238bf6049e1 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 12 Oct 2020 18:29:38 +0200 Subject: [PATCH 15/33] Add documentation for automatic_links lint --- compiler/rustc_lint_defs/src/builtin.rs | 6 ++-- src/doc/rustdoc/src/lints.md | 40 +++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index 3fc9c096696ba..1294dd9d68583 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -1892,13 +1892,13 @@ declare_lint! { declare_lint! { /// The `automatic_links` lint detects when a URL/email address could be - /// written using only brackets. This is a `rustdoc` only lint, see the - /// documentation in the [rustdoc book]. + /// written using only angle brackets. This is a `rustdoc` only lint, see + /// the documentation in the [rustdoc book]. /// /// [rustdoc book]: ../../../rustdoc/lints.html#automatic_links pub AUTOMATIC_LINKS, Allow, - "detects URLs/email adresses that could be written using only brackets" + "detects URLs/email adresses that could be written using only angle brackets" } declare_lint! { diff --git a/src/doc/rustdoc/src/lints.md b/src/doc/rustdoc/src/lints.md index cb9099cd50bee..2c10f6c06a93a 100644 --- a/src/doc/rustdoc/src/lints.md +++ b/src/doc/rustdoc/src/lints.md @@ -285,3 +285,43 @@ warning: unclosed HTML tag `h1` warning: 2 warnings emitted ``` + +## automatic_links + +This link is **allowed by default** and is **nightly-only**. It detects links +which could use the "automatic" link syntax. For example: + +```rust +#![warn(automatic_links)] + +/// [http://a.com](http://a.com) +/// [http://b.com] +/// +/// [http://b.com]: http://b.com +pub fn foo() {} +``` + +Which will give: + +```text +error: Unneeded long form for URL + --> foo.rs:3:5 + | +3 | /// [http://a.com](http://a.com) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: the lint level is defined here + --> foo.rs:1:9 + | +1 | #![deny(automatic_links)] + | ^^^^^^^^^^^^^^^ + = help: Try with `` instead + +error: Unneeded long form for URL + --> foo.rs:5:5 + | +5 | /// [http://b.com] + | ^^^^^^^^^^^^^^ + | + = help: Try with `` instead +``` From 6bc8965c418e90c135ee90554108bd0bdbe0a8d8 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 12 Oct 2020 18:29:56 +0200 Subject: [PATCH 16/33] Add tests for automatic_links lint --- src/test/rustdoc-ui/automatic-links.rs | 17 ++++++++++++++++ src/test/rustdoc-ui/automatic-links.stderr | 23 ++++++++++++++++++++++ 2 files changed, 40 insertions(+) create mode 100644 src/test/rustdoc-ui/automatic-links.rs create mode 100644 src/test/rustdoc-ui/automatic-links.stderr diff --git a/src/test/rustdoc-ui/automatic-links.rs b/src/test/rustdoc-ui/automatic-links.rs new file mode 100644 index 0000000000000..9273b854aee1d --- /dev/null +++ b/src/test/rustdoc-ui/automatic-links.rs @@ -0,0 +1,17 @@ +#![deny(automatic_links)] + +/// [http://a.com](http://a.com) +//~^ ERROR Unneeded long form for URL +/// [http://b.com] +//~^ ERROR Unneeded long form for URL +/// +/// [http://b.com]: http://b.com +/// +/// [http://c.com][http://c.com] +pub fn a() {} + +/// [a](http://a.com) +/// [b] +/// +/// [b]: http://b.com +pub fn everything_is_fine_here() {} diff --git a/src/test/rustdoc-ui/automatic-links.stderr b/src/test/rustdoc-ui/automatic-links.stderr new file mode 100644 index 0000000000000..2922fedb238cb --- /dev/null +++ b/src/test/rustdoc-ui/automatic-links.stderr @@ -0,0 +1,23 @@ +error: Unneeded long form for URL + --> $DIR/automatic-links.rs:3:5 + | +LL | /// [http://a.com](http://a.com) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: the lint level is defined here + --> $DIR/automatic-links.rs:1:9 + | +LL | #![deny(automatic_links)] + | ^^^^^^^^^^^^^^^ + = help: Try with `` instead + +error: Unneeded long form for URL + --> $DIR/automatic-links.rs:5:5 + | +LL | /// [http://b.com] + | ^^^^^^^^^^^^^^ + | + = help: Try with `` instead + +error: aborting due to 2 previous errors + From f467b8d77c7b991ce214e0e5ff9b13c01812c8a7 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 13 Oct 2020 15:46:34 +0200 Subject: [PATCH 17/33] Extend automatic_links lint to take into account URLs without link syntax --- Cargo.lock | 1 + src/doc/rustdoc/src/lints.md | 22 +++--- src/librustdoc/Cargo.toml | 1 + src/librustdoc/passes/automatic_links.rs | 89 +++++++++++++++------- src/test/rustdoc-ui/automatic-links.rs | 9 ++- src/test/rustdoc-ui/automatic-links.stderr | 17 +++-- 6 files changed, 94 insertions(+), 45 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3d40ded19dd5a..3a1dae971cc19 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4297,6 +4297,7 @@ dependencies = [ "itertools 0.9.0", "minifier", "pulldown-cmark 0.8.0", + "regex", "rustc-rayon", "serde", "serde_json", diff --git a/src/doc/rustdoc/src/lints.md b/src/doc/rustdoc/src/lints.md index 2c10f6c06a93a..a85aa882af891 100644 --- a/src/doc/rustdoc/src/lints.md +++ b/src/doc/rustdoc/src/lints.md @@ -294,6 +294,7 @@ which could use the "automatic" link syntax. For example: ```rust #![warn(automatic_links)] +/// http://hello.rs /// [http://a.com](http://a.com) /// [http://b.com] /// @@ -304,24 +305,27 @@ pub fn foo() {} Which will give: ```text -error: Unneeded long form for URL +warning: won't be a link as is --> foo.rs:3:5 | -3 | /// [http://a.com](http://a.com) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +3 | /// http://hello.rs + | ^^^^^^^^^^^^^^^ help: use an automatic link instead: `` | note: the lint level is defined here --> foo.rs:1:9 | -1 | #![deny(automatic_links)] +1 | #![warn(automatic_links)] | ^^^^^^^^^^^^^^^ - = help: Try with `` instead -error: Unneeded long form for URL +warning: unneeded long form for URL + --> foo.rs:4:5 + | +4 | /// [http://a.com](http://a.com) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `` + +warning: unneeded long form for URL --> foo.rs:5:5 | 5 | /// [http://b.com] - | ^^^^^^^^^^^^^^ - | - = help: Try with `` instead + | ^^^^^^^^^^^^^^ help: use an automatic link instead: `` ``` diff --git a/src/librustdoc/Cargo.toml b/src/librustdoc/Cargo.toml index a40a44fe27da3..b0f5bac6abd0f 100644 --- a/src/librustdoc/Cargo.toml +++ b/src/librustdoc/Cargo.toml @@ -16,6 +16,7 @@ serde_json = "1.0" smallvec = "1.0" tempfile = "3" itertools = "0.9" +regex = "1" [dev-dependencies] expect-test = "1.0" diff --git a/src/librustdoc/passes/automatic_links.rs b/src/librustdoc/passes/automatic_links.rs index 79542241326da..11c1a4d0bfba8 100644 --- a/src/librustdoc/passes/automatic_links.rs +++ b/src/librustdoc/passes/automatic_links.rs @@ -3,23 +3,55 @@ use crate::clean::*; use crate::core::DocContext; use crate::fold::DocFolder; use crate::html::markdown::opts; -use pulldown_cmark::{Event, Parser, Tag}; +use core::ops::Range; +use pulldown_cmark::{Event, LinkType, Parser, Tag}; +use regex::Regex; +use rustc_errors::Applicability; use rustc_feature::UnstableFeatures; use rustc_session::lint; pub const CHECK_AUTOMATIC_LINKS: Pass = Pass { name: "check-automatic-links", run: check_automatic_links, - description: "detects URLS/email addresses that could be written using brackets", + description: "detects URLS/email addresses that could be written using angle brackets", }; +const URL_REGEX: &str = + r"https?://(www\.)?[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,4}\b([-a-zA-Z0-9@:%_\+.~#?&//=]*)"; + struct AutomaticLinksLinter<'a, 'tcx> { cx: &'a DocContext<'tcx>, + regex: Regex, } impl<'a, 'tcx> AutomaticLinksLinter<'a, 'tcx> { fn new(cx: &'a DocContext<'tcx>) -> Self { - AutomaticLinksLinter { cx } + AutomaticLinksLinter { cx, regex: Regex::new(URL_REGEX).expect("failed to build regex") } + } + + fn find_raw_urls( + &self, + text: &str, + range: Range, + f: &impl Fn(&DocContext<'_>, &str, &str, Range), + ) { + for (pos, c) in text.char_indices() { + // For now, we only check "full" URLs. + if c == 'h' { + let text = &text[pos..]; + if text.starts_with("http://") || text.starts_with("https://") { + if let Some(m) = self.regex.find(text) { + let url = &text[..m.end()]; + f( + self.cx, + "won't be a link as is", + url, + Range { start: range.start + pos, end: range.start + pos + m.end() }, + ) + } + } + } + } } } @@ -44,45 +76,48 @@ impl<'a, 'tcx> DocFolder for AutomaticLinksLinter<'a, 'tcx> { }; let dox = item.attrs.collapsed_doc_value().unwrap_or_default(); if !dox.is_empty() { - let cx = &self.cx; + let report_diag = |cx: &DocContext<'_>, msg: &str, url: &str, range: Range| { + let sp = super::source_span_for_markdown_range(cx, &dox, &range, &item.attrs) + .or_else(|| span_of_attrs(&item.attrs)) + .unwrap_or(item.source.span()); + cx.tcx.struct_span_lint_hir(lint::builtin::AUTOMATIC_LINKS, hir_id, sp, |lint| { + lint.build(msg) + .span_suggestion( + sp, + "use an automatic link instead", + format!("<{}>", url), + Applicability::MachineApplicable, + ) + .emit() + }); + }; let p = Parser::new_ext(&dox, opts()).into_offset_iter(); let mut title = String::new(); let mut in_link = false; + let mut ignore = false; for (event, range) in p { match event { - Event::Start(Tag::Link(..)) => in_link = true, + Event::Start(Tag::Link(kind, _, _)) => { + in_link = true; + ignore = matches!(kind, LinkType::Autolink | LinkType::Email); + } Event::End(Tag::Link(_, url, _)) => { in_link = false; - if url.as_ref() != title { - continue; + if url.as_ref() == title && !ignore { + report_diag(self.cx, "unneeded long form for URL", &url, range); } - let sp = match super::source_span_for_markdown_range( - cx, - &dox, - &range, - &item.attrs, - ) { - Some(sp) => sp, - None => span_of_attrs(&item.attrs).unwrap_or(item.source.span()), - }; - cx.tcx.struct_span_lint_hir( - lint::builtin::AUTOMATIC_LINKS, - hir_id, - sp, - |lint| { - lint.build("Unneeded long form for URL") - .help(&format!("Try with `<{}>` instead", url)) - .emit() - }, - ); title.clear(); + ignore = false; } Event::Text(s) if in_link => { - title.push_str(&s); + if !ignore { + title.push_str(&s); + } } + Event::Text(s) => self.find_raw_urls(&s, range, &report_diag), _ => {} } } diff --git a/src/test/rustdoc-ui/automatic-links.rs b/src/test/rustdoc-ui/automatic-links.rs index 9273b854aee1d..f9dbe67e5b1da 100644 --- a/src/test/rustdoc-ui/automatic-links.rs +++ b/src/test/rustdoc-ui/automatic-links.rs @@ -1,15 +1,20 @@ #![deny(automatic_links)] /// [http://a.com](http://a.com) -//~^ ERROR Unneeded long form for URL +//~^ ERROR unneeded long form for URL /// [http://b.com] -//~^ ERROR Unneeded long form for URL +//~^ ERROR unneeded long form for URL /// /// [http://b.com]: http://b.com /// /// [http://c.com][http://c.com] pub fn a() {} +/// https://somewhere.com?hello=12 +//~^ ERROR won't be a link as is +pub fn c() {} + +/// /// [a](http://a.com) /// [b] /// diff --git a/src/test/rustdoc-ui/automatic-links.stderr b/src/test/rustdoc-ui/automatic-links.stderr index 2922fedb238cb..d2c0c51d7a472 100644 --- a/src/test/rustdoc-ui/automatic-links.stderr +++ b/src/test/rustdoc-ui/automatic-links.stderr @@ -1,23 +1,26 @@ -error: Unneeded long form for URL +error: unneeded long form for URL --> $DIR/automatic-links.rs:3:5 | LL | /// [http://a.com](http://a.com) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `` | note: the lint level is defined here --> $DIR/automatic-links.rs:1:9 | LL | #![deny(automatic_links)] | ^^^^^^^^^^^^^^^ - = help: Try with `` instead -error: Unneeded long form for URL +error: unneeded long form for URL --> $DIR/automatic-links.rs:5:5 | LL | /// [http://b.com] - | ^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^ help: use an automatic link instead: `` + +error: won't be a link as is + --> $DIR/automatic-links.rs:13:5 | - = help: Try with `` instead +LL | /// https://somewhere.com?hello=12 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `` -error: aborting due to 2 previous errors +error: aborting due to 3 previous errors From 7f839b2ece86b3b5db89673fc402348c71db42f4 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 14 Oct 2020 15:11:55 +0200 Subject: [PATCH 18/33] Improve automatic_links globally --- compiler/rustc_lint_defs/src/builtin.rs | 10 +-- src/doc/rustdoc/src/lints.md | 13 +-- src/librustdoc/passes/automatic_links.rs | 37 ++++---- src/test/rustdoc-ui/automatic-links.rs | 40 ++++++++- src/test/rustdoc-ui/automatic-links.stderr | 100 ++++++++++++++++++++- 5 files changed, 163 insertions(+), 37 deletions(-) diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index 1294dd9d68583..b6e6307a40f30 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -1891,14 +1891,14 @@ declare_lint! { } declare_lint! { - /// The `automatic_links` lint detects when a URL/email address could be - /// written using only angle brackets. This is a `rustdoc` only lint, see - /// the documentation in the [rustdoc book]. + /// The `automatic_links` lint detects when a URL could be written using + /// only angle brackets. This is a `rustdoc` only lint, see the + /// documentation in the [rustdoc book]. /// /// [rustdoc book]: ../../../rustdoc/lints.html#automatic_links pub AUTOMATIC_LINKS, - Allow, - "detects URLs/email adresses that could be written using only angle brackets" + Warn, + "detects URLs that could be written using only angle brackets" } declare_lint! { diff --git a/src/doc/rustdoc/src/lints.md b/src/doc/rustdoc/src/lints.md index a85aa882af891..68ea828bfc1e5 100644 --- a/src/doc/rustdoc/src/lints.md +++ b/src/doc/rustdoc/src/lints.md @@ -288,12 +288,10 @@ warning: 2 warnings emitted ## automatic_links -This link is **allowed by default** and is **nightly-only**. It detects links -which could use the "automatic" link syntax. For example: +This lint is **nightly-only** and **warns by default**. It detects links which +could use the "automatic" link syntax. For example: ```rust -#![warn(automatic_links)] - /// http://hello.rs /// [http://a.com](http://a.com) /// [http://b.com] @@ -305,17 +303,12 @@ pub fn foo() {} Which will give: ```text -warning: won't be a link as is +warning: this URL is not a hyperlink --> foo.rs:3:5 | 3 | /// http://hello.rs | ^^^^^^^^^^^^^^^ help: use an automatic link instead: `` | -note: the lint level is defined here - --> foo.rs:1:9 - | -1 | #![warn(automatic_links)] - | ^^^^^^^^^^^^^^^ warning: unneeded long form for URL --> foo.rs:4:5 diff --git a/src/librustdoc/passes/automatic_links.rs b/src/librustdoc/passes/automatic_links.rs index 11c1a4d0bfba8..816d2fd15eee5 100644 --- a/src/librustdoc/passes/automatic_links.rs +++ b/src/librustdoc/passes/automatic_links.rs @@ -13,11 +13,15 @@ use rustc_session::lint; pub const CHECK_AUTOMATIC_LINKS: Pass = Pass { name: "check-automatic-links", run: check_automatic_links, - description: "detects URLS/email addresses that could be written using angle brackets", + description: "detects URLS that could be written using angle brackets", }; -const URL_REGEX: &str = - r"https?://(www\.)?[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,4}\b([-a-zA-Z0-9@:%_\+.~#?&//=]*)"; +const URL_REGEX: &str = concat!( + r"https?://", // url scheme + r"([-a-zA-Z0-9@:%._\+~#=]{2,256}\.)+", // one or more subdomains + r"[a-zA-Z]{2,4}", // root domain + r"\b([-a-zA-Z0-9@:%_\+.~#?&//=]*)" // optional query or url fragments +); struct AutomaticLinksLinter<'a, 'tcx> { cx: &'a DocContext<'tcx>, @@ -35,22 +39,16 @@ impl<'a, 'tcx> AutomaticLinksLinter<'a, 'tcx> { range: Range, f: &impl Fn(&DocContext<'_>, &str, &str, Range), ) { - for (pos, c) in text.char_indices() { - // For now, we only check "full" URLs. - if c == 'h' { - let text = &text[pos..]; - if text.starts_with("http://") || text.starts_with("https://") { - if let Some(m) = self.regex.find(text) { - let url = &text[..m.end()]; - f( - self.cx, - "won't be a link as is", - url, - Range { start: range.start + pos, end: range.start + pos + m.end() }, - ) - } - } - } + // For now, we only check "full" URLs (meaning, starting with "http://" or "https://"). + for match_ in self.regex.find_iter(&text) { + let url = match_.as_str(); + let url_range = match_.range(); + f( + self.cx, + "this URL is not a hyperlink", + url, + Range { start: range.start + url_range.start, end: range.start + url_range.end }, + ); } } } @@ -106,6 +104,7 @@ impl<'a, 'tcx> DocFolder for AutomaticLinksLinter<'a, 'tcx> { } Event::End(Tag::Link(_, url, _)) => { in_link = false; + // NOTE: links cannot be nested, so we don't need to check `kind` if url.as_ref() == title && !ignore { report_diag(self.cx, "unneeded long form for URL", &url, range); } diff --git a/src/test/rustdoc-ui/automatic-links.rs b/src/test/rustdoc-ui/automatic-links.rs index f9dbe67e5b1da..27eb4e4a646ce 100644 --- a/src/test/rustdoc-ui/automatic-links.rs +++ b/src/test/rustdoc-ui/automatic-links.rs @@ -10,8 +10,40 @@ /// [http://c.com][http://c.com] pub fn a() {} +/// https://somewhere.com +//~^ ERROR this URL is not a hyperlink +/// https://somewhere.com/a +//~^ ERROR this URL is not a hyperlink +/// https://www.somewhere.com +//~^ ERROR this URL is not a hyperlink +/// https://www.somewhere.com/a +//~^ ERROR this URL is not a hyperlink +/// https://subdomain.example.com +//~^ ERROR not a hyperlink +/// https://somewhere.com? +//~^ ERROR this URL is not a hyperlink +/// https://somewhere.com/a? +//~^ ERROR this URL is not a hyperlink /// https://somewhere.com?hello=12 -//~^ ERROR won't be a link as is +//~^ ERROR this URL is not a hyperlink +/// https://somewhere.com/a?hello=12 +//~^ ERROR this URL is not a hyperlink +/// https://example.com?hello=12#xyz +//~^ ERROR this URL is not a hyperlink +/// https://example.com/a?hello=12#xyz +//~^ ERROR this URL is not a hyperlink +/// https://example.com#xyz +//~^ ERROR this URL is not a hyperlink +/// https://example.com/a#xyz +//~^ ERROR this URL is not a hyperlink +/// https://somewhere.com?hello=12&bye=11 +//~^ ERROR this URL is not a hyperlink +/// https://somewhere.com/a?hello=12&bye=11 +//~^ ERROR this URL is not a hyperlink +/// https://somewhere.com?hello=12&bye=11#xyz +//~^ ERROR this URL is not a hyperlink +/// hey! https://somewhere.com/a?hello=12&bye=11#xyz +//~^ ERROR this URL is not a hyperlink pub fn c() {} /// @@ -20,3 +52,9 @@ pub fn c() {} /// /// [b]: http://b.com pub fn everything_is_fine_here() {} + +#[allow(automatic_links)] +pub mod foo { + /// https://somewhere.com/a?hello=12&bye=11#xyz + pub fn bar() {} +} diff --git a/src/test/rustdoc-ui/automatic-links.stderr b/src/test/rustdoc-ui/automatic-links.stderr index d2c0c51d7a472..00e210aaaa22d 100644 --- a/src/test/rustdoc-ui/automatic-links.stderr +++ b/src/test/rustdoc-ui/automatic-links.stderr @@ -16,11 +16,107 @@ error: unneeded long form for URL LL | /// [http://b.com] | ^^^^^^^^^^^^^^ help: use an automatic link instead: `` -error: won't be a link as is +error: this URL is not a hyperlink --> $DIR/automatic-links.rs:13:5 | +LL | /// https://somewhere.com + | ^^^^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `` + +error: this URL is not a hyperlink + --> $DIR/automatic-links.rs:15:5 + | +LL | /// https://somewhere.com/a + | ^^^^^^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `` + +error: this URL is not a hyperlink + --> $DIR/automatic-links.rs:17:5 + | +LL | /// https://www.somewhere.com + | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `` + +error: this URL is not a hyperlink + --> $DIR/automatic-links.rs:19:5 + | +LL | /// https://www.somewhere.com/a + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `` + +error: this URL is not a hyperlink + --> $DIR/automatic-links.rs:21:5 + | +LL | /// https://subdomain.example.com + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `` + +error: this URL is not a hyperlink + --> $DIR/automatic-links.rs:23:5 + | +LL | /// https://somewhere.com? + | ^^^^^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `` + +error: this URL is not a hyperlink + --> $DIR/automatic-links.rs:25:5 + | +LL | /// https://somewhere.com/a? + | ^^^^^^^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `` + +error: this URL is not a hyperlink + --> $DIR/automatic-links.rs:27:5 + | LL | /// https://somewhere.com?hello=12 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `` -error: aborting due to 3 previous errors +error: this URL is not a hyperlink + --> $DIR/automatic-links.rs:29:5 + | +LL | /// https://somewhere.com/a?hello=12 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `` + +error: this URL is not a hyperlink + --> $DIR/automatic-links.rs:31:5 + | +LL | /// https://example.com?hello=12#xyz + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `` + +error: this URL is not a hyperlink + --> $DIR/automatic-links.rs:33:5 + | +LL | /// https://example.com/a?hello=12#xyz + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `` + +error: this URL is not a hyperlink + --> $DIR/automatic-links.rs:35:5 + | +LL | /// https://example.com#xyz + | ^^^^^^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `` + +error: this URL is not a hyperlink + --> $DIR/automatic-links.rs:37:5 + | +LL | /// https://example.com/a#xyz + | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `` + +error: this URL is not a hyperlink + --> $DIR/automatic-links.rs:39:5 + | +LL | /// https://somewhere.com?hello=12&bye=11 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `` + +error: this URL is not a hyperlink + --> $DIR/automatic-links.rs:41:5 + | +LL | /// https://somewhere.com/a?hello=12&bye=11 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `` + +error: this URL is not a hyperlink + --> $DIR/automatic-links.rs:43:5 + | +LL | /// https://somewhere.com?hello=12&bye=11#xyz + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `` + +error: this URL is not a hyperlink + --> $DIR/automatic-links.rs:45:10 + | +LL | /// hey! https://somewhere.com/a?hello=12&bye=11#xyz + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `` + +error: aborting due to 19 previous errors From 55b4d21e25a63ad36c5e6dcfd9106ae44ba6c75e Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 14 Oct 2020 17:35:43 +0200 Subject: [PATCH 19/33] Fix automatic_links warnings --- compiler/rustc_target/src/spec/crt_objects.rs | 2 +- compiler/rustc_target/src/spec/mod.rs | 2 +- compiler/rustc_target/src/spec/wasm32_unknown_unknown.rs | 2 +- compiler/rustc_target/src/spec/wasm32_wasi.rs | 2 +- library/core/src/intrinsics.rs | 2 +- library/core/src/lib.rs | 1 + library/core/src/num/dec2flt/mod.rs | 2 +- library/core/src/slice/sort.rs | 2 +- 8 files changed, 8 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_target/src/spec/crt_objects.rs b/compiler/rustc_target/src/spec/crt_objects.rs index 8991691a9a30c..76c0bf419e8c4 100644 --- a/compiler/rustc_target/src/spec/crt_objects.rs +++ b/compiler/rustc_target/src/spec/crt_objects.rs @@ -3,7 +3,7 @@ //! //! Table of CRT objects for popular toolchains. //! The `crtx` ones are generally distributed with libc and the `begin/end` ones with gcc. -//! See https://dev.gentoo.org/~vapier/crt.txt for some more details. +//! See for some more details. //! //! | Pre-link CRT objects | glibc | musl | bionic | mingw | wasi | //! |----------------------|------------------------|------------------------|------------------|-------------------|------| diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index ba9e2f7fa0648..d3c5a9433d08e 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -950,7 +950,7 @@ pub struct TargetOptions { /// The MergeFunctions pass is generally useful, but some targets may need /// to opt out. The default is "aliases". /// - /// Workaround for: https://github.com/rust-lang/rust/issues/57356 + /// Workaround for: pub merge_functions: MergeFunctions, /// Use platform dependent mcount function diff --git a/compiler/rustc_target/src/spec/wasm32_unknown_unknown.rs b/compiler/rustc_target/src/spec/wasm32_unknown_unknown.rs index 19609b0d496f2..1ef0a81937849 100644 --- a/compiler/rustc_target/src/spec/wasm32_unknown_unknown.rs +++ b/compiler/rustc_target/src/spec/wasm32_unknown_unknown.rs @@ -8,7 +8,7 @@ //! (e.g. trying to create a TCP stream or something like that). //! //! This target is more or less managed by the Rust and WebAssembly Working -//! Group nowadays at https://github.com/rustwasm. +//! Group nowadays at . use super::wasm32_base; use super::{LinkerFlavor, LldFlavor, Target}; diff --git a/compiler/rustc_target/src/spec/wasm32_wasi.rs b/compiler/rustc_target/src/spec/wasm32_wasi.rs index 26e0722fcf0c2..8c2bb9208291d 100644 --- a/compiler/rustc_target/src/spec/wasm32_wasi.rs +++ b/compiler/rustc_target/src/spec/wasm32_wasi.rs @@ -7,7 +7,7 @@ //! intended to empower WebAssembly binaries with native capabilities such as //! filesystem access, network access, etc. //! -//! You can see more about the proposal at https://wasi.dev +//! You can see more about the proposal at . //! //! The Rust target definition here is interesting in a few ways. We want to //! serve two use cases here with this target: diff --git a/library/core/src/intrinsics.rs b/library/core/src/intrinsics.rs index 3e5d7caa2fe5d..3570cab0022e8 100644 --- a/library/core/src/intrinsics.rs +++ b/library/core/src/intrinsics.rs @@ -9,7 +9,7 @@ //! This includes changes in the stability of the constness. //! //! In order to make an intrinsic usable at compile-time, one needs to copy the implementation -//! from https://github.com/rust-lang/miri/blob/master/src/shims/intrinsics.rs to +//! from to //! `compiler/rustc_mir/src/interpret/intrinsics.rs` and add a //! `#[rustc_const_unstable(feature = "foo", issue = "01234")]` to the intrinsic. //! diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index b89ec93834fcc..09dbde2c121f6 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -287,6 +287,7 @@ pub mod primitive; unused_imports, unsafe_op_in_unsafe_fn )] +#[cfg_attr(not(bootstrap), allow(automatic_links))] // FIXME: This annotation should be moved into rust-lang/stdarch after clashing_extern_declarations is // merged. It currently cannot because bootstrap fails as the lint hasn't been defined yet. #[allow(clashing_extern_declarations)] diff --git a/library/core/src/num/dec2flt/mod.rs b/library/core/src/num/dec2flt/mod.rs index 6f3a3a867450d..039112e9f3468 100644 --- a/library/core/src/num/dec2flt/mod.rs +++ b/library/core/src/num/dec2flt/mod.rs @@ -33,7 +33,7 @@ //! //! Primarily, this module and its children implement the algorithms described in: //! "How to Read Floating Point Numbers Accurately" by William D. Clinger, -//! available online: http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.45.4152 +//! available online: //! //! In addition, there are numerous helper functions that are used in the paper but not available //! in Rust (or at least in core). Our version is additionally complicated by the need to handle diff --git a/library/core/src/slice/sort.rs b/library/core/src/slice/sort.rs index 71d2c2c9b2f4c..2a7693d27efa2 100644 --- a/library/core/src/slice/sort.rs +++ b/library/core/src/slice/sort.rs @@ -1,7 +1,7 @@ //! Slice sorting //! //! This module contains a sorting algorithm based on Orson Peters' pattern-defeating quicksort, -//! published at: https://github.com/orlp/pdqsort +//! published at: //! //! Unstable sorting is compatible with libcore because it doesn't allocate memory, unlike our //! stable sorting implementation. From 60caf51b0de940705e7679a26343f6dcbe470a54 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sat, 17 Oct 2020 16:38:49 +0200 Subject: [PATCH 20/33] Rename automatic_links to url_improvements --- compiler/rustc_lint/src/lib.rs | 6 +++--- compiler/rustc_lint_defs/src/builtin.rs | 8 ++++---- library/core/src/lib.rs | 2 +- src/doc/rustdoc/src/lints.md | 2 +- src/librustdoc/core.rs | 4 ++-- src/librustdoc/passes/mod.rs | 8 ++++---- ...automatic_links.rs => url_improvements.rs} | 20 +++++++++---------- ...automatic-links.rs => url-improvements.rs} | 4 ++-- ...c-links.stderr => url-improvements.stderr} | 4 ++-- 9 files changed, 29 insertions(+), 29 deletions(-) rename src/librustdoc/passes/{automatic_links.rs => url_improvements.rs} (86%) rename src/test/rustdoc-ui/{automatic-links.rs => url-improvements.rs} (96%) rename src/test/rustdoc-ui/{automatic-links.stderr => url-improvements.stderr} (98%) diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs index 0da3ece167e97..ad353bb28c99d 100644 --- a/compiler/rustc_lint/src/lib.rs +++ b/compiler/rustc_lint/src/lib.rs @@ -67,9 +67,9 @@ use rustc_hir::def_id::LocalDefId; use rustc_middle::ty::query::Providers; use rustc_middle::ty::TyCtxt; use rustc_session::lint::builtin::{ - AUTOMATIC_LINKS, BARE_TRAIT_OBJECTS, BROKEN_INTRA_DOC_LINKS, ELIDED_LIFETIMES_IN_PATHS, + BARE_TRAIT_OBJECTS, BROKEN_INTRA_DOC_LINKS, ELIDED_LIFETIMES_IN_PATHS, EXPLICIT_OUTLIVES_REQUIREMENTS, INVALID_CODEBLOCK_ATTRIBUTES, INVALID_HTML_TAGS, - MISSING_DOC_CODE_EXAMPLES, PRIVATE_DOC_TESTS, + MISSING_DOC_CODE_EXAMPLES, PRIVATE_DOC_TESTS, URL_IMPROVEMENTS, }; use rustc_span::symbol::{Ident, Symbol}; use rustc_span::Span; @@ -313,7 +313,7 @@ fn register_builtins(store: &mut LintStore, no_interleave_lints: bool) { add_lint_group!( "rustdoc", - AUTOMATIC_LINKS, + URL_IMPROVEMENTS, BROKEN_INTRA_DOC_LINKS, PRIVATE_INTRA_DOC_LINKS, INVALID_CODEBLOCK_ATTRIBUTES, diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index b6e6307a40f30..c74680c172fe6 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -1891,12 +1891,12 @@ declare_lint! { } declare_lint! { - /// The `automatic_links` lint detects when a URL could be written using + /// The `url_improvements` lint detects when a URL could be written using /// only angle brackets. This is a `rustdoc` only lint, see the /// documentation in the [rustdoc book]. /// - /// [rustdoc book]: ../../../rustdoc/lints.html#automatic_links - pub AUTOMATIC_LINKS, + /// [rustdoc book]: ../../../rustdoc/lints.html#url_improvements + pub URL_IMPROVEMENTS, Warn, "detects URLs that could be written using only angle brackets" } @@ -2806,7 +2806,7 @@ declare_lint_pass! { MISSING_DOC_CODE_EXAMPLES, INVALID_HTML_TAGS, PRIVATE_DOC_TESTS, - AUTOMATIC_LINKS, + URL_IMPROVEMENTS, WHERE_CLAUSES_OBJECT_SAFETY, PROC_MACRO_DERIVE_RESOLUTION_FALLBACK, MACRO_USE_EXTERN_CRATE, diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index 09dbde2c121f6..8596d52ceaeb1 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -287,7 +287,7 @@ pub mod primitive; unused_imports, unsafe_op_in_unsafe_fn )] -#[cfg_attr(not(bootstrap), allow(automatic_links))] +#[cfg_attr(not(bootstrap), allow(url_improvements))] // FIXME: This annotation should be moved into rust-lang/stdarch after clashing_extern_declarations is // merged. It currently cannot because bootstrap fails as the lint hasn't been defined yet. #[allow(clashing_extern_declarations)] diff --git a/src/doc/rustdoc/src/lints.md b/src/doc/rustdoc/src/lints.md index 68ea828bfc1e5..7db9c93852da8 100644 --- a/src/doc/rustdoc/src/lints.md +++ b/src/doc/rustdoc/src/lints.md @@ -286,7 +286,7 @@ warning: unclosed HTML tag `h1` warning: 2 warnings emitted ``` -## automatic_links +## url_improvements This lint is **nightly-only** and **warns by default**. It detects links which could use the "automatic" link syntax. For example: diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index f834be84d4c59..85d73a30e4b68 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -330,13 +330,12 @@ pub fn run_core( let invalid_codeblock_attributes_name = rustc_lint::builtin::INVALID_CODEBLOCK_ATTRIBUTES.name; let invalid_html_tags = rustc_lint::builtin::INVALID_HTML_TAGS.name; let renamed_and_removed_lints = rustc_lint::builtin::RENAMED_AND_REMOVED_LINTS.name; - let automatic_links = rustc_lint::builtin::AUTOMATIC_LINKS.name; + let url_improvements = rustc_lint::builtin::URL_IMPROVEMENTS.name; let unknown_lints = rustc_lint::builtin::UNKNOWN_LINTS.name; // In addition to those specific lints, we also need to allow those given through // command line, otherwise they'll get ignored and we don't want that. let lints_to_show = vec![ - automatic_links.to_owned(), intra_link_resolution_failure_name.to_owned(), missing_docs.to_owned(), missing_doc_example.to_owned(), @@ -346,6 +345,7 @@ pub fn run_core( invalid_html_tags.to_owned(), renamed_and_removed_lints.to_owned(), unknown_lints.to_owned(), + url_improvements.to_owned(), ]; let (lint_opts, lint_caps) = init_lints(lints_to_show, lint_opts, |lint| { diff --git a/src/librustdoc/passes/mod.rs b/src/librustdoc/passes/mod.rs index 48dc52c955006..fa8bd24efa9e2 100644 --- a/src/librustdoc/passes/mod.rs +++ b/src/librustdoc/passes/mod.rs @@ -11,8 +11,8 @@ use crate::core::DocContext; mod stripper; pub use stripper::*; -mod automatic_links; -pub use self::automatic_links::CHECK_AUTOMATIC_LINKS; +mod url_improvements; +pub use self::url_improvements::CHECK_URL_IMPROVEMENTS; mod collapse_docs; pub use self::collapse_docs::COLLAPSE_DOCS; @@ -93,7 +93,7 @@ pub const PASSES: &[Pass] = &[ COLLECT_TRAIT_IMPLS, CALCULATE_DOC_COVERAGE, CHECK_INVALID_HTML_TAGS, - CHECK_AUTOMATIC_LINKS, + CHECK_URL_IMPROVEMENTS, ]; /// The list of passes run by default. @@ -109,7 +109,7 @@ pub const DEFAULT_PASSES: &[ConditionalPass] = &[ ConditionalPass::always(CHECK_CODE_BLOCK_SYNTAX), ConditionalPass::always(CHECK_INVALID_HTML_TAGS), ConditionalPass::always(PROPAGATE_DOC_CFG), - ConditionalPass::always(CHECK_AUTOMATIC_LINKS), + ConditionalPass::always(CHECK_URL_IMPROVEMENTS), ]; /// The list of default passes run when `--doc-coverage` is passed to rustdoc. diff --git a/src/librustdoc/passes/automatic_links.rs b/src/librustdoc/passes/url_improvements.rs similarity index 86% rename from src/librustdoc/passes/automatic_links.rs rename to src/librustdoc/passes/url_improvements.rs index 816d2fd15eee5..d191a89948ae9 100644 --- a/src/librustdoc/passes/automatic_links.rs +++ b/src/librustdoc/passes/url_improvements.rs @@ -10,9 +10,9 @@ use rustc_errors::Applicability; use rustc_feature::UnstableFeatures; use rustc_session::lint; -pub const CHECK_AUTOMATIC_LINKS: Pass = Pass { - name: "check-automatic-links", - run: check_automatic_links, +pub const CHECK_URL_IMPROVEMENTS: Pass = Pass { + name: "check-url-improvements", + run: check_url_improvements, description: "detects URLS that could be written using angle brackets", }; @@ -23,14 +23,14 @@ const URL_REGEX: &str = concat!( r"\b([-a-zA-Z0-9@:%_\+.~#?&//=]*)" // optional query or url fragments ); -struct AutomaticLinksLinter<'a, 'tcx> { +struct UrlImprovementsLinter<'a, 'tcx> { cx: &'a DocContext<'tcx>, regex: Regex, } -impl<'a, 'tcx> AutomaticLinksLinter<'a, 'tcx> { +impl<'a, 'tcx> UrlImprovementsLinter<'a, 'tcx> { fn new(cx: &'a DocContext<'tcx>) -> Self { - AutomaticLinksLinter { cx, regex: Regex::new(URL_REGEX).expect("failed to build regex") } + UrlImprovementsLinter { cx, regex: Regex::new(URL_REGEX).expect("failed to build regex") } } fn find_raw_urls( @@ -53,17 +53,17 @@ impl<'a, 'tcx> AutomaticLinksLinter<'a, 'tcx> { } } -pub fn check_automatic_links(krate: Crate, cx: &DocContext<'_>) -> Crate { +pub fn check_url_improvements(krate: Crate, cx: &DocContext<'_>) -> Crate { if !UnstableFeatures::from_environment().is_nightly_build() { krate } else { - let mut coll = AutomaticLinksLinter::new(cx); + let mut coll = UrlImprovementsLinter::new(cx); coll.fold_crate(krate) } } -impl<'a, 'tcx> DocFolder for AutomaticLinksLinter<'a, 'tcx> { +impl<'a, 'tcx> DocFolder for UrlImprovementsLinter<'a, 'tcx> { fn fold_item(&mut self, item: Item) -> Option { let hir_id = match self.cx.as_local_hir_id(item.def_id) { Some(hir_id) => hir_id, @@ -78,7 +78,7 @@ impl<'a, 'tcx> DocFolder for AutomaticLinksLinter<'a, 'tcx> { let sp = super::source_span_for_markdown_range(cx, &dox, &range, &item.attrs) .or_else(|| span_of_attrs(&item.attrs)) .unwrap_or(item.source.span()); - cx.tcx.struct_span_lint_hir(lint::builtin::AUTOMATIC_LINKS, hir_id, sp, |lint| { + cx.tcx.struct_span_lint_hir(lint::builtin::URL_IMPROVEMENTS, hir_id, sp, |lint| { lint.build(msg) .span_suggestion( sp, diff --git a/src/test/rustdoc-ui/automatic-links.rs b/src/test/rustdoc-ui/url-improvements.rs similarity index 96% rename from src/test/rustdoc-ui/automatic-links.rs rename to src/test/rustdoc-ui/url-improvements.rs index 27eb4e4a646ce..761ec31feca95 100644 --- a/src/test/rustdoc-ui/automatic-links.rs +++ b/src/test/rustdoc-ui/url-improvements.rs @@ -1,4 +1,4 @@ -#![deny(automatic_links)] +#![deny(url_improvements)] /// [http://a.com](http://a.com) //~^ ERROR unneeded long form for URL @@ -53,7 +53,7 @@ pub fn c() {} /// [b]: http://b.com pub fn everything_is_fine_here() {} -#[allow(automatic_links)] +#[allow(url_improvements)] pub mod foo { /// https://somewhere.com/a?hello=12&bye=11#xyz pub fn bar() {} diff --git a/src/test/rustdoc-ui/automatic-links.stderr b/src/test/rustdoc-ui/url-improvements.stderr similarity index 98% rename from src/test/rustdoc-ui/automatic-links.stderr rename to src/test/rustdoc-ui/url-improvements.stderr index 00e210aaaa22d..7ef287dfd11ad 100644 --- a/src/test/rustdoc-ui/automatic-links.stderr +++ b/src/test/rustdoc-ui/url-improvements.stderr @@ -7,8 +7,8 @@ LL | /// [http://a.com](http://a.com) note: the lint level is defined here --> $DIR/automatic-links.rs:1:9 | -LL | #![deny(automatic_links)] - | ^^^^^^^^^^^^^^^ +LL | #![deny(url_improvements)] + | ^^^^^^^^^^^^^^^^ error: unneeded long form for URL --> $DIR/automatic-links.rs:5:5 From fce2be0ea7b90fb9ba1a1704454b36307c9b8c07 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sat, 17 Oct 2020 16:43:13 +0200 Subject: [PATCH 21/33] Update URLs used in the lint example --- src/doc/rustdoc/src/lints.md | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/src/doc/rustdoc/src/lints.md b/src/doc/rustdoc/src/lints.md index 7db9c93852da8..a89c094bf4c6b 100644 --- a/src/doc/rustdoc/src/lints.md +++ b/src/doc/rustdoc/src/lints.md @@ -292,11 +292,11 @@ This lint is **nightly-only** and **warns by default**. It detects links which could use the "automatic" link syntax. For example: ```rust -/// http://hello.rs -/// [http://a.com](http://a.com) -/// [http://b.com] +/// http://example.org +/// [http://example.com](http://example.com) +/// [http://example.net] /// -/// [http://b.com]: http://b.com +/// [http://example.com]: http://example.com pub fn foo() {} ``` @@ -304,21 +304,22 @@ Which will give: ```text warning: this URL is not a hyperlink - --> foo.rs:3:5 + --> foo.rs:1:5 | -3 | /// http://hello.rs - | ^^^^^^^^^^^^^^^ help: use an automatic link instead: `` +1 | /// http://example.org + | ^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `` | + = note: `#[warn(url_improvements)]` on by default warning: unneeded long form for URL - --> foo.rs:4:5 + --> foo.rs:2:5 | -4 | /// [http://a.com](http://a.com) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `` +2 | /// [http://example.com](http://example.com) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `` -warning: unneeded long form for URL - --> foo.rs:5:5 +warning: this URL is not a hyperlink + --> foo.rs:3:6 | -5 | /// [http://b.com] - | ^^^^^^^^^^^^^^ help: use an automatic link instead: `` +3 | /// [http://example.net] + | ^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `` ``` From 1fb404bebe9e7d228859a26b7e40340438d0c427 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sat, 17 Oct 2020 23:58:46 +0200 Subject: [PATCH 22/33] Don't check for URLs inside codeblocks --- src/librustdoc/passes/url_improvements.rs | 50 ++++++++++++--------- src/test/rustdoc-ui/url-improvements.rs | 4 ++ src/test/rustdoc-ui/url-improvements.stderr | 40 ++++++++--------- 3 files changed, 54 insertions(+), 40 deletions(-) diff --git a/src/librustdoc/passes/url_improvements.rs b/src/librustdoc/passes/url_improvements.rs index d191a89948ae9..a5d555eb19dca 100644 --- a/src/librustdoc/passes/url_improvements.rs +++ b/src/librustdoc/passes/url_improvements.rs @@ -90,33 +90,43 @@ impl<'a, 'tcx> DocFolder for UrlImprovementsLinter<'a, 'tcx> { }); }; - let p = Parser::new_ext(&dox, opts()).into_offset_iter(); + let mut p = Parser::new_ext(&dox, opts()).into_offset_iter(); - let mut title = String::new(); - let mut in_link = false; - let mut ignore = false; - - for (event, range) in p { + while let Some((event, range)) = p.next() { match event { Event::Start(Tag::Link(kind, _, _)) => { - in_link = true; - ignore = matches!(kind, LinkType::Autolink | LinkType::Email); - } - Event::End(Tag::Link(_, url, _)) => { - in_link = false; - // NOTE: links cannot be nested, so we don't need to check `kind` - if url.as_ref() == title && !ignore { - report_diag(self.cx, "unneeded long form for URL", &url, range); + let ignore = matches!(kind, LinkType::Autolink | LinkType::Email); + let mut title = String::new(); + + while let Some((event, range)) = p.next() { + match event { + Event::End(Tag::Link(_, url, _)) => { + // NOTE: links cannot be nested, so we don't need to check `kind` + if url.as_ref() == title && !ignore { + report_diag( + self.cx, + "unneeded long form for URL", + &url, + range, + ); + } + break; + } + Event::Text(s) if !ignore => title.push_str(&s), + _ => {} + } } - title.clear(); - ignore = false; } - Event::Text(s) if in_link => { - if !ignore { - title.push_str(&s); + Event::Text(s) => self.find_raw_urls(&s, range, &report_diag), + Event::Start(Tag::CodeBlock(_)) => { + // We don't want to check the text inside the code blocks. + while let Some((event, _)) = p.next() { + match event { + Event::End(Tag::CodeBlock(_)) => break, + _ => {} + } } } - Event::Text(s) => self.find_raw_urls(&s, range, &report_diag), _ => {} } } diff --git a/src/test/rustdoc-ui/url-improvements.rs b/src/test/rustdoc-ui/url-improvements.rs index 761ec31feca95..81fd0ba7d512d 100644 --- a/src/test/rustdoc-ui/url-improvements.rs +++ b/src/test/rustdoc-ui/url-improvements.rs @@ -51,6 +51,10 @@ pub fn c() {} /// [b] /// /// [b]: http://b.com +/// +/// ``` +/// This link should not be linted: http://example.com +/// ``` pub fn everything_is_fine_here() {} #[allow(url_improvements)] diff --git a/src/test/rustdoc-ui/url-improvements.stderr b/src/test/rustdoc-ui/url-improvements.stderr index 7ef287dfd11ad..e8ed2331dd84c 100644 --- a/src/test/rustdoc-ui/url-improvements.stderr +++ b/src/test/rustdoc-ui/url-improvements.stderr @@ -1,119 +1,119 @@ error: unneeded long form for URL - --> $DIR/automatic-links.rs:3:5 + --> $DIR/url-improvements.rs:3:5 | LL | /// [http://a.com](http://a.com) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `` | note: the lint level is defined here - --> $DIR/automatic-links.rs:1:9 + --> $DIR/url-improvements.rs:1:9 | LL | #![deny(url_improvements)] | ^^^^^^^^^^^^^^^^ error: unneeded long form for URL - --> $DIR/automatic-links.rs:5:5 + --> $DIR/url-improvements.rs:5:5 | LL | /// [http://b.com] | ^^^^^^^^^^^^^^ help: use an automatic link instead: `` error: this URL is not a hyperlink - --> $DIR/automatic-links.rs:13:5 + --> $DIR/url-improvements.rs:13:5 | LL | /// https://somewhere.com | ^^^^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `` error: this URL is not a hyperlink - --> $DIR/automatic-links.rs:15:5 + --> $DIR/url-improvements.rs:15:5 | LL | /// https://somewhere.com/a | ^^^^^^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `` error: this URL is not a hyperlink - --> $DIR/automatic-links.rs:17:5 + --> $DIR/url-improvements.rs:17:5 | LL | /// https://www.somewhere.com | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `` error: this URL is not a hyperlink - --> $DIR/automatic-links.rs:19:5 + --> $DIR/url-improvements.rs:19:5 | LL | /// https://www.somewhere.com/a | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `` error: this URL is not a hyperlink - --> $DIR/automatic-links.rs:21:5 + --> $DIR/url-improvements.rs:21:5 | LL | /// https://subdomain.example.com | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `` error: this URL is not a hyperlink - --> $DIR/automatic-links.rs:23:5 + --> $DIR/url-improvements.rs:23:5 | LL | /// https://somewhere.com? | ^^^^^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `` error: this URL is not a hyperlink - --> $DIR/automatic-links.rs:25:5 + --> $DIR/url-improvements.rs:25:5 | LL | /// https://somewhere.com/a? | ^^^^^^^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `` error: this URL is not a hyperlink - --> $DIR/automatic-links.rs:27:5 + --> $DIR/url-improvements.rs:27:5 | LL | /// https://somewhere.com?hello=12 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `` error: this URL is not a hyperlink - --> $DIR/automatic-links.rs:29:5 + --> $DIR/url-improvements.rs:29:5 | LL | /// https://somewhere.com/a?hello=12 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `` error: this URL is not a hyperlink - --> $DIR/automatic-links.rs:31:5 + --> $DIR/url-improvements.rs:31:5 | LL | /// https://example.com?hello=12#xyz | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `` error: this URL is not a hyperlink - --> $DIR/automatic-links.rs:33:5 + --> $DIR/url-improvements.rs:33:5 | LL | /// https://example.com/a?hello=12#xyz | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `` error: this URL is not a hyperlink - --> $DIR/automatic-links.rs:35:5 + --> $DIR/url-improvements.rs:35:5 | LL | /// https://example.com#xyz | ^^^^^^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `` error: this URL is not a hyperlink - --> $DIR/automatic-links.rs:37:5 + --> $DIR/url-improvements.rs:37:5 | LL | /// https://example.com/a#xyz | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `` error: this URL is not a hyperlink - --> $DIR/automatic-links.rs:39:5 + --> $DIR/url-improvements.rs:39:5 | LL | /// https://somewhere.com?hello=12&bye=11 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `` error: this URL is not a hyperlink - --> $DIR/automatic-links.rs:41:5 + --> $DIR/url-improvements.rs:41:5 | LL | /// https://somewhere.com/a?hello=12&bye=11 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `` error: this URL is not a hyperlink - --> $DIR/automatic-links.rs:43:5 + --> $DIR/url-improvements.rs:43:5 | LL | /// https://somewhere.com?hello=12&bye=11#xyz | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `` error: this URL is not a hyperlink - --> $DIR/automatic-links.rs:45:10 + --> $DIR/url-improvements.rs:45:10 | LL | /// hey! https://somewhere.com/a?hello=12&bye=11#xyz | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `` From 6be97e225099cc59dc63f6fc01af7c525d0334df Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sat, 31 Oct 2020 13:46:28 +0100 Subject: [PATCH 23/33] Improve lint even more --- src/librustdoc/passes/url_improvements.rs | 9 +++++---- src/test/rustdoc-ui/url-improvements.rs | 2 ++ 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/librustdoc/passes/url_improvements.rs b/src/librustdoc/passes/url_improvements.rs index a5d555eb19dca..f09c44b41c976 100644 --- a/src/librustdoc/passes/url_improvements.rs +++ b/src/librustdoc/passes/url_improvements.rs @@ -19,8 +19,8 @@ pub const CHECK_URL_IMPROVEMENTS: Pass = Pass { const URL_REGEX: &str = concat!( r"https?://", // url scheme r"([-a-zA-Z0-9@:%._\+~#=]{2,256}\.)+", // one or more subdomains - r"[a-zA-Z]{2,4}", // root domain - r"\b([-a-zA-Z0-9@:%_\+.~#?&//=]*)" // optional query or url fragments + r"[a-zA-Z]{2,63}", // root domain + r"\b([-a-zA-Z0-9@:%_\+.~#?&/=]*)" // optional query or url fragments ); struct UrlImprovementsLinter<'a, 'tcx> { @@ -101,8 +101,9 @@ impl<'a, 'tcx> DocFolder for UrlImprovementsLinter<'a, 'tcx> { while let Some((event, range)) = p.next() { match event { Event::End(Tag::Link(_, url, _)) => { - // NOTE: links cannot be nested, so we don't need to check `kind` - if url.as_ref() == title && !ignore { + // NOTE: links cannot be nested, so we don't need to + // check `kind` + if url.as_ref() == title && !ignore && self.regex.matches(url) { report_diag( self.cx, "unneeded long form for URL", diff --git a/src/test/rustdoc-ui/url-improvements.rs b/src/test/rustdoc-ui/url-improvements.rs index 81fd0ba7d512d..b7b1c26cd6deb 100644 --- a/src/test/rustdoc-ui/url-improvements.rs +++ b/src/test/rustdoc-ui/url-improvements.rs @@ -55,6 +55,8 @@ pub fn c() {} /// ``` /// This link should not be linted: http://example.com /// ``` +/// +/// [should_not.lint](should_not.lint) pub fn everything_is_fine_here() {} #[allow(url_improvements)] From 9d114506c68ce717503d0fa1eb335db5c80c195f Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sat, 31 Oct 2020 15:14:44 +0100 Subject: [PATCH 24/33] Rename lint to non_autolinks --- compiler/rustc_lint/src/lib.rs | 4 ++-- compiler/rustc_lint_defs/src/builtin.rs | 8 +++---- library/core/src/lib.rs | 2 +- src/doc/rustdoc/src/lints.md | 4 ++-- src/librustdoc/core.rs | 4 ++-- src/librustdoc/passes/mod.rs | 8 +++---- .../{url_improvements.rs => non_autolinks.rs} | 23 ++++++++++--------- src/test/rustdoc-ui/url-improvements.rs | 10 ++++---- src/test/rustdoc-ui/url-improvements.stderr | 12 +++++----- 9 files changed, 38 insertions(+), 37 deletions(-) rename src/librustdoc/passes/{url_improvements.rs => non_autolinks.rs} (88%) diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs index ad353bb28c99d..24bfdad970a1c 100644 --- a/compiler/rustc_lint/src/lib.rs +++ b/compiler/rustc_lint/src/lib.rs @@ -69,7 +69,7 @@ use rustc_middle::ty::TyCtxt; use rustc_session::lint::builtin::{ BARE_TRAIT_OBJECTS, BROKEN_INTRA_DOC_LINKS, ELIDED_LIFETIMES_IN_PATHS, EXPLICIT_OUTLIVES_REQUIREMENTS, INVALID_CODEBLOCK_ATTRIBUTES, INVALID_HTML_TAGS, - MISSING_DOC_CODE_EXAMPLES, PRIVATE_DOC_TESTS, URL_IMPROVEMENTS, + MISSING_DOC_CODE_EXAMPLES, NON_AUTOLINKS, PRIVATE_DOC_TESTS, }; use rustc_span::symbol::{Ident, Symbol}; use rustc_span::Span; @@ -313,7 +313,7 @@ fn register_builtins(store: &mut LintStore, no_interleave_lints: bool) { add_lint_group!( "rustdoc", - URL_IMPROVEMENTS, + NON_AUTOLINKS, BROKEN_INTRA_DOC_LINKS, PRIVATE_INTRA_DOC_LINKS, INVALID_CODEBLOCK_ATTRIBUTES, diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index c74680c172fe6..ff7a145c2668d 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -1891,12 +1891,12 @@ declare_lint! { } declare_lint! { - /// The `url_improvements` lint detects when a URL could be written using + /// The `non_autolinks` lint detects when a URL could be written using /// only angle brackets. This is a `rustdoc` only lint, see the /// documentation in the [rustdoc book]. /// - /// [rustdoc book]: ../../../rustdoc/lints.html#url_improvements - pub URL_IMPROVEMENTS, + /// [rustdoc book]: ../../../rustdoc/lints.html#non_autolinks + pub NON_AUTOLINKS, Warn, "detects URLs that could be written using only angle brackets" } @@ -2806,7 +2806,7 @@ declare_lint_pass! { MISSING_DOC_CODE_EXAMPLES, INVALID_HTML_TAGS, PRIVATE_DOC_TESTS, - URL_IMPROVEMENTS, + NON_AUTOLINKS, WHERE_CLAUSES_OBJECT_SAFETY, PROC_MACRO_DERIVE_RESOLUTION_FALLBACK, MACRO_USE_EXTERN_CRATE, diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index 8596d52ceaeb1..069e6e7e71881 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -287,7 +287,7 @@ pub mod primitive; unused_imports, unsafe_op_in_unsafe_fn )] -#[cfg_attr(not(bootstrap), allow(url_improvements))] +#[cfg_attr(not(bootstrap), allow(non_autolinks))] // FIXME: This annotation should be moved into rust-lang/stdarch after clashing_extern_declarations is // merged. It currently cannot because bootstrap fails as the lint hasn't been defined yet. #[allow(clashing_extern_declarations)] diff --git a/src/doc/rustdoc/src/lints.md b/src/doc/rustdoc/src/lints.md index a89c094bf4c6b..41292b3d83841 100644 --- a/src/doc/rustdoc/src/lints.md +++ b/src/doc/rustdoc/src/lints.md @@ -286,7 +286,7 @@ warning: unclosed HTML tag `h1` warning: 2 warnings emitted ``` -## url_improvements +## non_autolinks This lint is **nightly-only** and **warns by default**. It detects links which could use the "automatic" link syntax. For example: @@ -309,7 +309,7 @@ warning: this URL is not a hyperlink 1 | /// http://example.org | ^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `` | - = note: `#[warn(url_improvements)]` on by default + = note: `#[warn(non_autolinks)]` on by default warning: unneeded long form for URL --> foo.rs:2:5 diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 85d73a30e4b68..5cb7a32cf0cbc 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -330,7 +330,7 @@ pub fn run_core( let invalid_codeblock_attributes_name = rustc_lint::builtin::INVALID_CODEBLOCK_ATTRIBUTES.name; let invalid_html_tags = rustc_lint::builtin::INVALID_HTML_TAGS.name; let renamed_and_removed_lints = rustc_lint::builtin::RENAMED_AND_REMOVED_LINTS.name; - let url_improvements = rustc_lint::builtin::URL_IMPROVEMENTS.name; + let non_autolinks = rustc_lint::builtin::NON_AUTOLINKS.name; let unknown_lints = rustc_lint::builtin::UNKNOWN_LINTS.name; // In addition to those specific lints, we also need to allow those given through @@ -345,7 +345,7 @@ pub fn run_core( invalid_html_tags.to_owned(), renamed_and_removed_lints.to_owned(), unknown_lints.to_owned(), - url_improvements.to_owned(), + non_autolinks.to_owned(), ]; let (lint_opts, lint_caps) = init_lints(lints_to_show, lint_opts, |lint| { diff --git a/src/librustdoc/passes/mod.rs b/src/librustdoc/passes/mod.rs index fa8bd24efa9e2..047a73835c8eb 100644 --- a/src/librustdoc/passes/mod.rs +++ b/src/librustdoc/passes/mod.rs @@ -11,8 +11,8 @@ use crate::core::DocContext; mod stripper; pub use stripper::*; -mod url_improvements; -pub use self::url_improvements::CHECK_URL_IMPROVEMENTS; +mod non_autolinks; +pub use self::non_autolinks::CHECK_NON_AUTOLINKS; mod collapse_docs; pub use self::collapse_docs::COLLAPSE_DOCS; @@ -93,7 +93,7 @@ pub const PASSES: &[Pass] = &[ COLLECT_TRAIT_IMPLS, CALCULATE_DOC_COVERAGE, CHECK_INVALID_HTML_TAGS, - CHECK_URL_IMPROVEMENTS, + CHECK_NON_AUTOLINKS, ]; /// The list of passes run by default. @@ -109,7 +109,7 @@ pub const DEFAULT_PASSES: &[ConditionalPass] = &[ ConditionalPass::always(CHECK_CODE_BLOCK_SYNTAX), ConditionalPass::always(CHECK_INVALID_HTML_TAGS), ConditionalPass::always(PROPAGATE_DOC_CFG), - ConditionalPass::always(CHECK_URL_IMPROVEMENTS), + ConditionalPass::always(CHECK_NON_AUTOLINKS), ]; /// The list of default passes run when `--doc-coverage` is passed to rustdoc. diff --git a/src/librustdoc/passes/url_improvements.rs b/src/librustdoc/passes/non_autolinks.rs similarity index 88% rename from src/librustdoc/passes/url_improvements.rs rename to src/librustdoc/passes/non_autolinks.rs index f09c44b41c976..4a8fc7fc6181e 100644 --- a/src/librustdoc/passes/url_improvements.rs +++ b/src/librustdoc/passes/non_autolinks.rs @@ -10,9 +10,9 @@ use rustc_errors::Applicability; use rustc_feature::UnstableFeatures; use rustc_session::lint; -pub const CHECK_URL_IMPROVEMENTS: Pass = Pass { - name: "check-url-improvements", - run: check_url_improvements, +pub const CHECK_NON_AUTOLINKS: Pass = Pass { + name: "check-non-autolinks", + run: check_non_autolinks, description: "detects URLS that could be written using angle brackets", }; @@ -23,14 +23,14 @@ const URL_REGEX: &str = concat!( r"\b([-a-zA-Z0-9@:%_\+.~#?&/=]*)" // optional query or url fragments ); -struct UrlImprovementsLinter<'a, 'tcx> { +struct NonAutolinksLinter<'a, 'tcx> { cx: &'a DocContext<'tcx>, regex: Regex, } -impl<'a, 'tcx> UrlImprovementsLinter<'a, 'tcx> { +impl<'a, 'tcx> NonAutolinksLinter<'a, 'tcx> { fn new(cx: &'a DocContext<'tcx>) -> Self { - UrlImprovementsLinter { cx, regex: Regex::new(URL_REGEX).expect("failed to build regex") } + Self { cx, regex: Regex::new(URL_REGEX).expect("failed to build regex") } } fn find_raw_urls( @@ -53,17 +53,17 @@ impl<'a, 'tcx> UrlImprovementsLinter<'a, 'tcx> { } } -pub fn check_url_improvements(krate: Crate, cx: &DocContext<'_>) -> Crate { +pub fn check_non_autolinks(krate: Crate, cx: &DocContext<'_>) -> Crate { if !UnstableFeatures::from_environment().is_nightly_build() { krate } else { - let mut coll = UrlImprovementsLinter::new(cx); + let mut coll = NonAutolinksLinter::new(cx); coll.fold_crate(krate) } } -impl<'a, 'tcx> DocFolder for UrlImprovementsLinter<'a, 'tcx> { +impl<'a, 'tcx> DocFolder for NonAutolinksLinter<'a, 'tcx> { fn fold_item(&mut self, item: Item) -> Option { let hir_id = match self.cx.as_local_hir_id(item.def_id) { Some(hir_id) => hir_id, @@ -78,7 +78,7 @@ impl<'a, 'tcx> DocFolder for UrlImprovementsLinter<'a, 'tcx> { let sp = super::source_span_for_markdown_range(cx, &dox, &range, &item.attrs) .or_else(|| span_of_attrs(&item.attrs)) .unwrap_or(item.source.span()); - cx.tcx.struct_span_lint_hir(lint::builtin::URL_IMPROVEMENTS, hir_id, sp, |lint| { + cx.tcx.struct_span_lint_hir(lint::builtin::NON_AUTOLINKS, hir_id, sp, |lint| { lint.build(msg) .span_suggestion( sp, @@ -103,7 +103,8 @@ impl<'a, 'tcx> DocFolder for UrlImprovementsLinter<'a, 'tcx> { Event::End(Tag::Link(_, url, _)) => { // NOTE: links cannot be nested, so we don't need to // check `kind` - if url.as_ref() == title && !ignore && self.regex.matches(url) { + if url.as_ref() == title && !ignore && self.regex.is_match(&url) + { report_diag( self.cx, "unneeded long form for URL", diff --git a/src/test/rustdoc-ui/url-improvements.rs b/src/test/rustdoc-ui/url-improvements.rs index b7b1c26cd6deb..8531583d38a65 100644 --- a/src/test/rustdoc-ui/url-improvements.rs +++ b/src/test/rustdoc-ui/url-improvements.rs @@ -1,11 +1,11 @@ -#![deny(url_improvements)] +#![deny(non_autolinks)] -/// [http://a.com](http://a.com) +/// [http://aa.com](http://aa.com) //~^ ERROR unneeded long form for URL -/// [http://b.com] +/// [http://bb.com] //~^ ERROR unneeded long form for URL /// -/// [http://b.com]: http://b.com +/// [http://bb.com]: http://bb.com /// /// [http://c.com][http://c.com] pub fn a() {} @@ -59,7 +59,7 @@ pub fn c() {} /// [should_not.lint](should_not.lint) pub fn everything_is_fine_here() {} -#[allow(url_improvements)] +#[allow(non_autolinks)] pub mod foo { /// https://somewhere.com/a?hello=12&bye=11#xyz pub fn bar() {} diff --git a/src/test/rustdoc-ui/url-improvements.stderr b/src/test/rustdoc-ui/url-improvements.stderr index e8ed2331dd84c..70ad4b06a515d 100644 --- a/src/test/rustdoc-ui/url-improvements.stderr +++ b/src/test/rustdoc-ui/url-improvements.stderr @@ -1,20 +1,20 @@ error: unneeded long form for URL --> $DIR/url-improvements.rs:3:5 | -LL | /// [http://a.com](http://a.com) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `` +LL | /// [http://aa.com](http://aa.com) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `` | note: the lint level is defined here --> $DIR/url-improvements.rs:1:9 | -LL | #![deny(url_improvements)] - | ^^^^^^^^^^^^^^^^ +LL | #![deny(non_autolinks)] + | ^^^^^^^^^^^^^ error: unneeded long form for URL --> $DIR/url-improvements.rs:5:5 | -LL | /// [http://b.com] - | ^^^^^^^^^^^^^^ help: use an automatic link instead: `` +LL | /// [http://bb.com] + | ^^^^^^^^^^^^^^^ help: use an automatic link instead: `` error: this URL is not a hyperlink --> $DIR/url-improvements.rs:13:5 From 16ed8501ef35f0008fefd7f51746a10a7e7505ac Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 5 Nov 2020 10:23:39 +0100 Subject: [PATCH 25/33] Fix more URLs --- compiler/rustc_lint_defs/src/lib.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_lint_defs/src/lib.rs b/compiler/rustc_lint_defs/src/lib.rs index 25a7bfcabb728..af9926400ca44 100644 --- a/compiler/rustc_lint_defs/src/lib.rs +++ b/compiler/rustc_lint_defs/src/lib.rs @@ -99,13 +99,13 @@ pub struct Lint { /// The name is written with underscores, e.g., "unused_imports". /// On the command line, underscores become dashes. /// - /// See https://rustc-dev-guide.rust-lang.org/diagnostics.html#lint-naming + /// See /// for naming guidelines. pub name: &'static str, /// Default level for the lint. /// - /// See https://rustc-dev-guide.rust-lang.org/diagnostics.html#diagnostic-levels + /// See /// for guidelines on choosing a default level. pub default_level: Level, @@ -330,8 +330,8 @@ impl LintBuffer { /// Declares a static item of type `&'static Lint`. /// -/// See https://rustc-dev-guide.rust-lang.org/diagnostics.html for documentation -/// and guidelines on writing lints. +/// See for +/// documentation and guidelines on writing lints. /// /// The macro call should start with a doc comment explaining the lint /// which will be embedded in the rustc user documentation book. It should From 54a0a98347f739ee3b9cad8760e237fa6cd8db54 Mon Sep 17 00:00:00 2001 From: Pietro Albini Date: Thu, 22 Oct 2020 12:06:12 +0200 Subject: [PATCH 26/33] ci: gate on aarch64-gnu passing tests --- .github/workflows/ci.yml | 115 ++--------------------------------- src/ci/github-actions/ci.yml | 20 +----- 2 files changed, 8 insertions(+), 127 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 91241d2b214f9..90296ec32eeda 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -154,6 +154,11 @@ jobs: strategy: matrix: include: + - name: aarch64-gnu + os: + - self-hosted + - ARM64 + - linux - name: arm-android os: ubuntu-latest-xl env: {} @@ -509,116 +514,6 @@ jobs: AWS_ACCESS_KEY_ID: "${{ env.ARTIFACTS_AWS_ACCESS_KEY_ID }}" AWS_SECRET_ACCESS_KEY: "${{ secrets[format('AWS_SECRET_ACCESS_KEY_{0}', env.ARTIFACTS_AWS_ACCESS_KEY_ID)] }}" if: "success() && !env.SKIP_JOB && (github.event_name == 'push' || env.DEPLOY == '1' || env.DEPLOY_ALT == '1')" - auto-fallible: - name: auto-fallible - env: - CI_JOB_NAME: "${{ matrix.name }}" - SCCACHE_BUCKET: rust-lang-gha-caches - DEPLOY_BUCKET: rust-lang-gha - TOOLSTATE_REPO: "https://github.com/pietroalbini/rust-toolstate" - TOOLSTATE_ISSUES_API_URL: "https://api.github.com/repos/pietroalbini/rust-toolstate/issues" - TOOLSTATE_PUBLISH: 1 - CACHES_AWS_ACCESS_KEY_ID: AKIA46X5W6CZOMUQATD5 - ARTIFACTS_AWS_ACCESS_KEY_ID: AKIA46X5W6CZH5AYXDVF - CACHE_DOMAIN: ci-caches-gha.rust-lang.org - if: "github.event_name == 'push' && github.ref == 'refs/heads/auto' && github.repository == 'rust-lang-ci/rust'" - strategy: - fail-fast: false - matrix: - include: - - name: aarch64-gnu - os: - - self-hosted - - ARM64 - - linux - timeout-minutes: 600 - runs-on: "${{ matrix.os }}" - steps: - - name: disable git crlf conversion - run: git config --global core.autocrlf false - - name: checkout the source code - uses: actions/checkout@v2 - with: - fetch-depth: 2 - - name: configure the PR in which the error message will be posted - run: "echo \"[CI_PR_NUMBER=$num]\"" - env: - num: "${{ github.event.number }}" - if: "success() && !env.SKIP_JOBS && github.event_name == 'pull_request'" - - name: add extra environment variables - run: src/ci/scripts/setup-environment.sh - env: - EXTRA_VARIABLES: "${{ toJson(matrix.env) }}" - if: success() && !env.SKIP_JOB - - name: decide whether to skip this job - run: src/ci/scripts/should-skip-this.sh - if: success() && !env.SKIP_JOB - - name: configure GitHub Actions to kill the build when outdated - uses: rust-lang/simpleinfra/github-actions/cancel-outdated-builds@master - with: - github_token: "${{ secrets.github_token }}" - if: "success() && !env.SKIP_JOB && github.ref != 'refs/heads/try'" - - name: collect CPU statistics - run: src/ci/scripts/collect-cpu-stats.sh - if: success() && !env.SKIP_JOB - - name: show the current environment - run: src/ci/scripts/dump-environment.sh - if: success() && !env.SKIP_JOB - - name: install awscli - run: src/ci/scripts/install-awscli.sh - if: success() && !env.SKIP_JOB - - name: install sccache - run: src/ci/scripts/install-sccache.sh - if: success() && !env.SKIP_JOB - - name: select Xcode - run: src/ci/scripts/select-xcode.sh - if: success() && !env.SKIP_JOB - - name: install clang - run: src/ci/scripts/install-clang.sh - if: success() && !env.SKIP_JOB - - name: install WIX - run: src/ci/scripts/install-wix.sh - if: success() && !env.SKIP_JOB - - name: ensure the build happens on a partition with enough space - run: src/ci/scripts/symlink-build-dir.sh - if: success() && !env.SKIP_JOB - - name: disable git crlf conversion - run: src/ci/scripts/disable-git-crlf-conversion.sh - if: success() && !env.SKIP_JOB - - name: install MSYS2 - run: src/ci/scripts/install-msys2.sh - if: success() && !env.SKIP_JOB - - name: install MinGW - run: src/ci/scripts/install-mingw.sh - if: success() && !env.SKIP_JOB - - name: install ninja - run: src/ci/scripts/install-ninja.sh - if: success() && !env.SKIP_JOB - - name: enable ipv6 on Docker - run: src/ci/scripts/enable-docker-ipv6.sh - if: success() && !env.SKIP_JOB - - name: disable git crlf conversion - run: src/ci/scripts/disable-git-crlf-conversion.sh - if: success() && !env.SKIP_JOB - - name: checkout submodules - run: src/ci/scripts/checkout-submodules.sh - if: success() && !env.SKIP_JOB - - name: ensure line endings are correct - run: src/ci/scripts/verify-line-endings.sh - if: success() && !env.SKIP_JOB - - name: run the build - run: src/ci/scripts/run-build-from-ci.sh - env: - AWS_ACCESS_KEY_ID: "${{ env.CACHES_AWS_ACCESS_KEY_ID }}" - AWS_SECRET_ACCESS_KEY: "${{ secrets[format('AWS_SECRET_ACCESS_KEY_{0}', env.CACHES_AWS_ACCESS_KEY_ID)] }}" - TOOLSTATE_REPO_ACCESS_TOKEN: "${{ secrets.TOOLSTATE_REPO_ACCESS_TOKEN }}" - if: success() && !env.SKIP_JOB - - name: upload artifacts to S3 - run: src/ci/scripts/upload-artifacts.sh - env: - AWS_ACCESS_KEY_ID: "${{ env.ARTIFACTS_AWS_ACCESS_KEY_ID }}" - AWS_SECRET_ACCESS_KEY: "${{ secrets[format('AWS_SECRET_ACCESS_KEY_{0}', env.ARTIFACTS_AWS_ACCESS_KEY_ID)] }}" - if: "success() && !env.SKIP_JOB && (github.event_name == 'push' || env.DEPLOY == '1' || env.DEPLOY_ALT == '1')" try: name: try env: diff --git a/src/ci/github-actions/ci.yml b/src/ci/github-actions/ci.yml index 0df191f8f7404..1e28b5a253655 100644 --- a/src/ci/github-actions/ci.yml +++ b/src/ci/github-actions/ci.yml @@ -301,6 +301,9 @@ jobs: # Linux/Docker builders # ############################# + - name: aarch64-gnu + <<: *job-aarch64-linux + - name: arm-android <<: *job-linux-xl @@ -653,23 +656,6 @@ jobs: SCRIPT: python x.py dist <<: *job-windows-xl - auto-fallible: - <<: *base-ci-job - name: auto-fallible - env: - <<: [*shared-ci-variables, *dummy-variables] - if: github.event_name == 'push' && github.ref == 'refs/heads/auto' && github.repository == 'rust-lang-ci/rust' - strategy: - fail-fast: false - matrix: - include: - ############################# - # Linux/Docker builders # - ############################# - - - name: aarch64-gnu - <<: *job-aarch64-linux - try: <<: *base-ci-job name: try From 1274faed1a1379bb1521ae9884bc8ef420971636 Mon Sep 17 00:00:00 2001 From: Pietro Albini Date: Thu, 22 Oct 2020 12:23:18 +0200 Subject: [PATCH 27/33] doc/rustc: promote aarch64-unknown-linux-gnu to tier 1 This also adds a note about missing stack probes support, per the discussion on RFC 2959. --- src/doc/rustc/src/platform-support.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md index 85c6f91f08582..8005a5f3563bf 100644 --- a/src/doc/rustc/src/platform-support.md +++ b/src/doc/rustc/src/platform-support.md @@ -34,6 +34,7 @@ Specifically they will each satisfy the following requirements: target | std | host | notes -------|-----|------|------- +`aarch64-unknown-linux-gnu` | ✓ | ✓ | ARM64 Linux (kernel 4.2, glibc 2.17+) [^missing-stack-probes] `i686-pc-windows-gnu` | ✓ | ✓ | 32-bit MinGW (Windows 7+) `i686-pc-windows-msvc` | ✓ | ✓ | 32-bit MSVC (Windows 7+) `i686-unknown-linux-gnu` | ✓ | ✓ | 32-bit Linux (kernel 2.6.32+, glibc 2.11+) @@ -42,6 +43,12 @@ target | std | host | notes `x86_64-pc-windows-msvc` | ✓ | ✓ | 64-bit MSVC (Windows 7+) `x86_64-unknown-linux-gnu` | ✓ | ✓ | 64-bit Linux (kernel 2.6.32+, glibc 2.11+) +[^missing-stack-probes]: Stack probes support is missing on + `aarch64-unknown-linux-gnu`, but it's planned to be implemented in the near + future. The implementation is tracked on [issue #77071][77071]. + +[77071]: https://github.com/rust-lang/rust/issues/77071 + ## Tier 2 Tier 2 platforms can be thought of as "guaranteed to build". Automated tests @@ -62,7 +69,6 @@ target | std | host | notes `aarch64-fuchsia` | ✓ | | ARM64 Fuchsia `aarch64-linux-android` | ✓ | | ARM64 Android `aarch64-pc-windows-msvc` | ✓ | ✓ | ARM64 Windows MSVC -`aarch64-unknown-linux-gnu` | ✓ | ✓ | ARM64 Linux (kernel 4.2, glibc 2.17) `aarch64-unknown-linux-musl` | ✓ | ✓ | ARM64 Linux with MUSL `aarch64-unknown-none` | * | | Bare ARM64, hardfloat `aarch64-unknown-none-softfloat` | * | | Bare ARM64, softfloat From 874cbb88e0379a0e7bab5b9db99e2a4c495534fb Mon Sep 17 00:00:00 2001 From: Pietro Albini Date: Thu, 22 Oct 2020 12:31:11 +0200 Subject: [PATCH 28/33] ci: build docs for aarch64-unknown-linux-gnu --- src/ci/docker/host-x86_64/dist-aarch64-linux/Dockerfile | 3 +-- src/tools/build-manifest/src/main.rs | 1 + 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ci/docker/host-x86_64/dist-aarch64-linux/Dockerfile b/src/ci/docker/host-x86_64/dist-aarch64-linux/Dockerfile index df65f9df44127..95c54ca1abc06 100644 --- a/src/ci/docker/host-x86_64/dist-aarch64-linux/Dockerfile +++ b/src/ci/docker/host-x86_64/dist-aarch64-linux/Dockerfile @@ -35,6 +35,5 @@ ENV HOSTS=aarch64-unknown-linux-gnu ENV RUST_CONFIGURE_ARGS \ --enable-full-tools \ --enable-profiler \ - --enable-sanitizers \ - --disable-docs + --enable-sanitizers ENV SCRIPT python3 ../x.py dist --host $HOSTS --target $HOSTS diff --git a/src/tools/build-manifest/src/main.rs b/src/tools/build-manifest/src/main.rs index 9a8f2404e4a1a..687354dc6aee2 100644 --- a/src/tools/build-manifest/src/main.rs +++ b/src/tools/build-manifest/src/main.rs @@ -155,6 +155,7 @@ static TARGETS: &[&str] = &[ ]; static DOCS_TARGETS: &[&str] = &[ + "aarch64-unknown-linux-gnu", "i686-apple-darwin", "i686-pc-windows-gnu", "i686-pc-windows-msvc", From eed0cebea3d16d82f5517e17ab498b340001fe01 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Mon, 19 Oct 2020 14:20:14 -0400 Subject: [PATCH 29/33] Recognize `private_intra_doc_links` as a lint Previously, trying to allow this would give another error! ``` warning: unknown lint: `private_intra_doc_links` --> private.rs:1:10 | 1 | #![allow(private_intra_doc_links)] | ^^^^^^^^^^^^^^^^^^^^^^^ help: did you mean: `broken_intra_doc_links` | = note: `#[warn(unknown_lints)]` on by default warning: public documentation for `DocMe` links to private item `DontDocMe` --> private.rs:2:11 | 2 | /// docs [DontDocMe] | ^^^^^^^^^ this item is private | = note: `#[warn(private_intra_doc_links)]` on by default = note: this link will resolve properly if you pass `--document-private-items` ``` --- compiler/rustc_lint_defs/src/builtin.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index a1b7c13e4c0f0..7176a66cdc1bd 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -2790,6 +2790,7 @@ declare_lint_pass! { UNSTABLE_NAME_COLLISIONS, IRREFUTABLE_LET_PATTERNS, BROKEN_INTRA_DOC_LINKS, + PRIVATE_INTRA_DOC_LINKS, INVALID_CODEBLOCK_ATTRIBUTES, MISSING_CRATE_LEVEL_DOCS, MISSING_DOC_CODE_EXAMPLES, From 47b21b84f3ed88cff31fccc78a57a66241a26496 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Thu, 5 Nov 2020 13:11:50 -0500 Subject: [PATCH 30/33] Add PRIVATE_INTRA_DOC_LINKS to rustdoc special-casing This is really starting to get out of hand. Rustdoc should instead allow all lints in the rustdoc lint group. --- src/librustdoc/core.rs | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 45a84c4fb30d3..285a3bf8204bb 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -322,7 +322,8 @@ pub fn run_core( let cpath = Some(input.clone()); let input = Input::File(input); - let intra_link_resolution_failure_name = lint::builtin::BROKEN_INTRA_DOC_LINKS.name; + let broken_intra_doc_links = lint::builtin::BROKEN_INTRA_DOC_LINKS.name; + let private_intra_doc_links = lint::builtin::PRIVATE_INTRA_DOC_LINKS.name; let missing_docs = rustc_lint::builtin::MISSING_DOCS.name; let missing_doc_example = rustc_lint::builtin::MISSING_DOC_CODE_EXAMPLES.name; let private_doc_tests = rustc_lint::builtin::PRIVATE_DOC_TESTS.name; @@ -335,7 +336,8 @@ pub fn run_core( // In addition to those specific lints, we also need to allow those given through // command line, otherwise they'll get ignored and we don't want that. let lints_to_show = vec![ - intra_link_resolution_failure_name.to_owned(), + broken_intra_doc_links.to_owned(), + private_intra_doc_links.to_owned(), missing_docs.to_owned(), missing_doc_example.to_owned(), private_doc_tests.to_owned(), @@ -347,9 +349,8 @@ pub fn run_core( ]; let (lint_opts, lint_caps) = init_lints(lints_to_show, lint_opts, |lint| { - if lint.name == intra_link_resolution_failure_name - || lint.name == invalid_codeblock_attributes_name - { + // FIXME: why is this necessary? + if lint.name == broken_intra_doc_links || lint.name == invalid_codeblock_attributes_name { None } else { Some((lint.name_lower(), lint::Allow)) From 99200f760bf588435ca53477bb1eaff34770db0b Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 5 Nov 2020 14:33:23 +0100 Subject: [PATCH 31/33] Fix even more URLs --- compiler/rustc_codegen_cranelift/src/discriminant.rs | 2 +- compiler/rustc_middle/src/mir/coverage.rs | 6 +++--- compiler/rustc_middle/src/mir/mono.rs | 2 +- compiler/rustc_middle/src/ty/context.rs | 2 +- compiler/rustc_mir/src/borrow_check/region_infer/mod.rs | 2 +- compiler/rustc_mir/src/transform/dest_prop.rs | 2 +- compiler/rustc_mir_build/src/thir/pattern/_match.rs | 4 ++-- compiler/rustc_parse/src/lexer/mod.rs | 2 +- compiler/rustc_privacy/src/lib.rs | 2 +- .../rustc_trait_selection/src/traits/object_safety.rs | 2 +- library/core/src/future/mod.rs | 2 +- library/panic_unwind/src/dwarf/eh.rs | 8 ++++---- library/panic_unwind/src/gcc.rs | 6 +++--- src/bootstrap/toolstate.rs | 4 ++-- src/build_helper/lib.rs | 2 +- src/librustdoc/core.rs | 2 +- 16 files changed, 25 insertions(+), 25 deletions(-) diff --git a/compiler/rustc_codegen_cranelift/src/discriminant.rs b/compiler/rustc_codegen_cranelift/src/discriminant.rs index 6c9fb8e051b3c..1e8e86add1a59 100644 --- a/compiler/rustc_codegen_cranelift/src/discriminant.rs +++ b/compiler/rustc_codegen_cranelift/src/discriminant.rs @@ -1,6 +1,6 @@ //! Handling of enum discriminants //! -//! Adapted from https://github.com/rust-lang/rust/blob/d760df5aea483aae041c9a241e7acacf48f75035/src/librustc_codegen_ssa/mir/place.rs +//! Adapted from use rustc_target::abi::{Int, TagEncoding, Variants}; diff --git a/compiler/rustc_middle/src/mir/coverage.rs b/compiler/rustc_middle/src/mir/coverage.rs index 0421eabc2dc05..22c36b928781b 100644 --- a/compiler/rustc_middle/src/mir/coverage.rs +++ b/compiler/rustc_middle/src/mir/coverage.rs @@ -17,9 +17,9 @@ rustc_index::newtype_index! { impl ExpressionOperandId { /// An expression operand for a "zero counter", as described in the following references: /// - /// * https://github.com/rust-lang/llvm-project/blob/llvmorg-8.0.0/llvm/docs/CoverageMappingFormat.rst#counter - /// * https://github.com/rust-lang/llvm-project/blob/llvmorg-8.0.0/llvm/docs/CoverageMappingFormat.rst#tag - /// * https://github.com/rust-lang/llvm-project/blob/llvmorg-8.0.0/llvm/docs/CoverageMappingFormat.rst#counter-expressions + /// * + /// * + /// * /// /// This operand can be used to count two or more separate code regions with a single counter, /// if they run sequentially with no branches, by injecting the `Counter` in a `BasicBlock` for diff --git a/compiler/rustc_middle/src/mir/mono.rs b/compiler/rustc_middle/src/mir/mono.rs index 79e2c5aac2385..1e70f7605045e 100644 --- a/compiler/rustc_middle/src/mir/mono.rs +++ b/compiler/rustc_middle/src/mir/mono.rs @@ -228,7 +228,7 @@ pub struct CodegenUnit<'tcx> { /// Specifies the linkage type for a `MonoItem`. /// -/// See https://llvm.org/docs/LangRef.html#linkage-types for more details about these variants. +/// See for more details about these variants. #[derive(Copy, Clone, PartialEq, Debug, TyEncodable, TyDecodable, HashStable)] pub enum Linkage { External, diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 216451f268f4e..1c6937e685c65 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -368,7 +368,7 @@ pub struct TypeckResults<'tcx> { /// leads to a `vec![&&Option, &Option]`. Empty vectors are not stored. /// /// See: - /// https://github.com/rust-lang/rfcs/blob/master/text/2005-match-ergonomics.md#definitions + /// pat_adjustments: ItemLocalMap>>, /// Borrows diff --git a/compiler/rustc_mir/src/borrow_check/region_infer/mod.rs b/compiler/rustc_mir/src/borrow_check/region_infer/mod.rs index 47726632727d0..ac8ab71a1dc96 100644 --- a/compiler/rustc_mir/src/borrow_check/region_infer/mod.rs +++ b/compiler/rustc_mir/src/borrow_check/region_infer/mod.rs @@ -1364,7 +1364,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { /// terms that the "longer free region" `'a` outlived the "shorter free region" `'b`. /// /// More details can be found in this blog post by Niko: - /// http://smallcultfollowing.com/babysteps/blog/2019/01/17/polonius-and-region-errors/ + /// /// /// In the canonical example /// diff --git a/compiler/rustc_mir/src/transform/dest_prop.rs b/compiler/rustc_mir/src/transform/dest_prop.rs index 410f462ed469f..46de5dba6e0ed 100644 --- a/compiler/rustc_mir/src/transform/dest_prop.rs +++ b/compiler/rustc_mir/src/transform/dest_prop.rs @@ -8,7 +8,7 @@ //! inside a single block to shuffle a value around unnecessarily. //! //! LLVM by itself is not good enough at eliminating these redundant copies (eg. see -//! https://github.com/rust-lang/rust/issues/32966), so this leaves some performance on the table +//! ), so this leaves some performance on the table //! that we can regain by implementing an optimization for removing these assign statements in rustc //! itself. When this optimization runs fast enough, it can also speed up the constant evaluation //! and code generation phases of rustc due to the reduced number of statements and locals. diff --git a/compiler/rustc_mir_build/src/thir/pattern/_match.rs b/compiler/rustc_mir_build/src/thir/pattern/_match.rs index 9e096f9ad6847..bc85d45d86773 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/_match.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/_match.rs @@ -8,7 +8,7 @@ //! (b) each pattern is necessary (usefulness) //! //! The algorithm implemented here is a modified version of the one described in: -//! http://moscova.inria.fr/~maranget/papers/warn/index.html +//! //! However, to save future implementors from reading the original paper, we //! summarise the algorithm here to hopefully save time and be a little clearer //! (without being so rigorous). @@ -2040,7 +2040,7 @@ impl<'tcx> MissingConstructors<'tcx> { } } -/// Algorithm from http://moscova.inria.fr/~maranget/papers/warn/index.html. +/// Algorithm from . /// The algorithm from the paper has been modified to correctly handle empty /// types. The changes are: /// (0) We don't exit early if the pattern matrix has zero rows. We just diff --git a/compiler/rustc_parse/src/lexer/mod.rs b/compiler/rustc_parse/src/lexer/mod.rs index 32b124970cf7c..0dfacd78908ba 100644 --- a/compiler/rustc_parse/src/lexer/mod.rs +++ b/compiler/rustc_parse/src/lexer/mod.rs @@ -511,7 +511,7 @@ impl<'a> StringReader<'a> { } /// Note: It was decided to not add a test case, because it would be to big. - /// https://github.com/rust-lang/rust/pull/50296#issuecomment-392135180 + /// fn report_too_many_hashes(&self, start: BytePos, found: usize) -> ! { self.fatal_span_( start, diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs index 4c0941120a6fc..75d75433f1bf1 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -38,7 +38,7 @@ use std::{cmp, fmt, mem}; /// Implemented to visit all `DefId`s in a type. /// Visiting `DefId`s is useful because visibilities and reachabilities are attached to them. /// The idea is to visit "all components of a type", as documented in -/// https://github.com/rust-lang/rfcs/blob/master/text/2145-type-privacy.md#how-to-determine-visibility-of-a-type. +/// . /// The default type visitor (`TypeVisitor`) does most of the job, but it has some shortcomings. /// First, it doesn't have overridable `fn visit_trait_ref`, so we have to catch trait `DefId`s /// manually. Second, it doesn't visit some type components like signatures of fn types, or traits diff --git a/compiler/rustc_trait_selection/src/traits/object_safety.rs b/compiler/rustc_trait_selection/src/traits/object_safety.rs index 50efbbbe0fd76..32e0991733bd9 100644 --- a/compiler/rustc_trait_selection/src/traits/object_safety.rs +++ b/compiler/rustc_trait_selection/src/traits/object_safety.rs @@ -621,7 +621,7 @@ fn object_ty_for_trait<'tcx>( /// /// In practice, we cannot use `dyn Trait` explicitly in the obligation because it would result /// in a new check that `Trait` is object safe, creating a cycle (until object_safe_for_dispatch -/// is stabilized, see tracking issue https://github.com/rust-lang/rust/issues/43561). +/// is stabilized, see tracking issue ). /// Instead, we fudge a little by introducing a new type parameter `U` such that /// `Self: Unsize` and `U: Trait + ?Sized`, and use `U` in place of `dyn Trait`. /// Written as a chalk-style query: diff --git a/library/core/src/future/mod.rs b/library/core/src/future/mod.rs index fa5655ca35f41..cdde094147012 100644 --- a/library/core/src/future/mod.rs +++ b/library/core/src/future/mod.rs @@ -32,7 +32,7 @@ pub use poll_fn::{poll_fn, PollFn}; /// This type is needed because: /// /// a) Generators cannot implement `for<'a, 'b> Generator<&'a mut Context<'b>>`, so we need to pass -/// a raw pointer (see https://github.com/rust-lang/rust/issues/68923). +/// a raw pointer (see ). /// b) Raw pointers and `NonNull` aren't `Send` or `Sync`, so that would make every single future /// non-Send/Sync as well, and we don't want that. /// diff --git a/library/panic_unwind/src/dwarf/eh.rs b/library/panic_unwind/src/dwarf/eh.rs index 8ce4dcd2acd9c..6dbf7c11b4c4e 100644 --- a/library/panic_unwind/src/dwarf/eh.rs +++ b/library/panic_unwind/src/dwarf/eh.rs @@ -1,9 +1,9 @@ //! Parsing of GCC-style Language-Specific Data Area (LSDA) //! For details see: -//! http://refspecs.linuxfoundation.org/LSB_3.0.0/LSB-PDA/LSB-PDA/ehframechpt.html -//! http://mentorembedded.github.io/cxx-abi/exceptions.pdf -//! http://www.airs.com/blog/archives/460 -//! http://www.airs.com/blog/archives/464 +//! * +//! * +//! * +//! * //! //! A reference implementation may be found in the GCC source tree //! (`/libgcc/unwind-c.c` as of this writing). diff --git a/library/panic_unwind/src/gcc.rs b/library/panic_unwind/src/gcc.rs index 6b88bab8277ee..14f49bbf48337 100644 --- a/library/panic_unwind/src/gcc.rs +++ b/library/panic_unwind/src/gcc.rs @@ -4,9 +4,9 @@ //! "Exception Handling in LLVM" (llvm.org/docs/ExceptionHandling.html) and //! documents linked from it. //! These are also good reads: -//! https://itanium-cxx-abi.github.io/cxx-abi/abi-eh.html -//! http://monoinfinito.wordpress.com/series/exception-handling-in-c/ -//! http://www.airs.com/blog/index.php?s=exception+frames +//! * +//! * +//! * //! //! ## A brief summary //! diff --git a/src/bootstrap/toolstate.rs b/src/bootstrap/toolstate.rs index 8740393288c48..205524ad84fb7 100644 --- a/src/bootstrap/toolstate.rs +++ b/src/bootstrap/toolstate.rs @@ -152,7 +152,7 @@ impl Step for ToolStateCheck { /// error if there are any. /// /// This also handles publishing the results to the `history` directory of - /// the toolstate repo https://github.com/rust-lang-nursery/rust-toolstate + /// the toolstate repo /// if the env var `TOOLSTATE_PUBLISH` is set. Note that there is a /// *separate* step of updating the `latest.json` file and creating GitHub /// issues and comments in `src/ci/publish_toolstate.sh`, which is only @@ -162,7 +162,7 @@ impl Step for ToolStateCheck { /// The rules for failure are: /// * If the PR modifies a tool, the status must be test-pass. /// NOTE: There is intent to change this, see - /// https://github.com/rust-lang/rust/issues/65000. + /// . /// * All "stable" tools must be test-pass on the stable or beta branches. /// * During beta promotion week, a PR is not allowed to "regress" a /// stable tool. That is, the status is not allowed to get worse diff --git a/src/build_helper/lib.rs b/src/build_helper/lib.rs index e30da8d56e10f..80f804174ed08 100644 --- a/src/build_helper/lib.rs +++ b/src/build_helper/lib.rs @@ -32,7 +32,7 @@ macro_rules! t { /// Reads an environment variable and adds it to dependencies. /// Supposed to be used for all variables except those set for build scripts by cargo -/// https://doc.rust-lang.org/cargo/reference/environment-variables.html#environment-variables-cargo-sets-for-build-scripts +/// pub fn tracked_env_var_os + Display>(key: K) -> Option { println!("cargo:rerun-if-env-changed={}", key); env::var_os(key) diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 5cb7a32cf0cbc..5eca54199d6c8 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -665,7 +665,7 @@ fn run_global_ctxt( (krate, ctxt.renderinfo.into_inner(), ctxt.render_options) } -/// Due to https://github.com/rust-lang/rust/pull/73566, +/// Due to , /// the name resolution pass may find errors that are never emitted. /// If typeck is called after this happens, then we'll get an ICE: /// 'Res::Error found but not reported'. To avoid this, emit the errors now. From 3863dee15988d8e2b8b33ff6ba8759342e8dd98f Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Wed, 28 Oct 2020 23:09:41 -0400 Subject: [PATCH 32/33] Infer the default host target from the host toolchain if possible This fixes ongoing issues where x.py will detect the wrong host triple between MSVC and GNU. - Add line to changelog --- src/bootstrap/CHANGELOG.md | 2 ++ src/bootstrap/bootstrap.py | 19 +++++++++++++++++-- src/bootstrap/configure.py | 2 +- 3 files changed, 20 insertions(+), 3 deletions(-) diff --git a/src/bootstrap/CHANGELOG.md b/src/bootstrap/CHANGELOG.md index 7bb4e504275d8..a103c9fb0b78c 100644 --- a/src/bootstrap/CHANGELOG.md +++ b/src/bootstrap/CHANGELOG.md @@ -8,6 +8,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - `x.py check` needs opt-in to check tests (--all-targets) [#77473](https://github.com/rust-lang/rust/pull/77473) - The default bootstrap profiles are now located at `bootstrap/defaults/config.$PROFILE.toml` (previously they were located at `bootstrap/defaults/config.toml.$PROFILE`) [#77558](https://github.com/rust-lang/rust/pull/77558) +- If you have Rust already installed, `x.py` will now infer the host target + from the default rust toolchain. [#78513](https://github.com/rust-lang/rust/pull/78513) ## [Version 2] - 2020-09-25 diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py index 87e1536381841..54d0a23dec58d 100644 --- a/src/bootstrap/bootstrap.py +++ b/src/bootstrap/bootstrap.py @@ -187,8 +187,23 @@ def format_build_time(duration): return str(datetime.timedelta(seconds=int(duration))) -def default_build_triple(): +def default_build_triple(verbose): """Build triple as in LLVM""" + # If the user already has a host build triple with an existing `rustc` + # install, use their preference. This fixes most issues with Windows builds + # being detected as GNU instead of MSVC. + try: + version = subprocess.check_output(["rustc", "--version", "--verbose"]) + host = next(x for x in version.split('\n') if x.startswith("host: ")) + triple = host.split("host: ")[1] + if verbose: + print("detected default triple {}".format(triple)) + return triple + except Exception as e: + if verbose: + print("rustup not detected: {}".format(e)) + print("falling back to auto-detect") + default_encoding = sys.getdefaultencoding() required = sys.platform != 'win32' ostype = require(["uname", "-s"], exit=required) @@ -831,7 +846,7 @@ def build_triple(self): config = self.get_toml('build') if config: return config - return default_build_triple() + return default_build_triple(self.verbose) def check_submodule(self, module, slow_submodules): if not slow_submodules: diff --git a/src/bootstrap/configure.py b/src/bootstrap/configure.py index e156952d56f3d..322e9d6923295 100755 --- a/src/bootstrap/configure.py +++ b/src/bootstrap/configure.py @@ -266,7 +266,7 @@ def err(msg): def build(): if 'build' in known_args: return known_args['build'][-1][1] - return bootstrap.default_build_triple() + return bootstrap.default_build_triple(verbose=False) def set(key, value): From 8d2fa72fc8064e7800e9d2a6512fa7eb302e8d8d Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Mon, 26 Oct 2020 21:18:28 -0400 Subject: [PATCH 33/33] Get `--fix` working for everything except rustdoc Here's the error for rustdoc: ``` Checking rustdoc artifacts (x86_64-unknown-linux-gnu -> x86_64-unknown-linux-gnu) error: no library targets found in package `rustdoc-tool` ``` --- src/bootstrap/builder.rs | 7 +++---- src/bootstrap/check.rs | 17 ++++++++++++++--- 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index 532949e47a17a..011b053f89809 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -851,8 +851,8 @@ impl<'a> Builder<'a> { } rustflags.env("RUSTFLAGS_BOOTSTRAP"); if cmd == "clippy" { - // clippy overwrites any sysroot we pass on the command line. - // Tell it to use the appropriate sysroot instead. + // clippy overwrites sysroot if we pass it to cargo. + // Pass it directly to clippy instead. // NOTE: this can't be fixed in clippy because we explicitly don't set `RUSTC`, // so it has no way of knowing the sysroot. rustflags.arg("--sysroot"); @@ -867,8 +867,7 @@ impl<'a> Builder<'a> { // Explicitly does *not* set `--cfg=bootstrap`, since we're using a nightly clippy. let host_version = Command::new("rustc").arg("--version").output().map_err(|_| ()); let output = host_version.and_then(|output| { - if output.status.success() - { + if output.status.success() { Ok(output) } else { Err(()) diff --git a/src/bootstrap/check.rs b/src/bootstrap/check.rs index b88dca0a9ed34..2e3cfc98c8cf2 100644 --- a/src/bootstrap/check.rs +++ b/src/bootstrap/check.rs @@ -16,12 +16,23 @@ pub struct Std { /// Returns args for the subcommand itself (not for cargo) fn args(builder: &Builder<'_>) -> Vec { + fn strings<'a>(arr: &'a [&str]) -> impl Iterator + 'a { + arr.iter().copied().map(String::from) + } + if let Subcommand::Clippy { fix, .. } = builder.config.cmd { - let mut args = vec!["--".to_owned(), "--cap-lints".to_owned(), "warn".to_owned()]; + let mut args = vec![]; if fix { - args.insert(0, "--fix".to_owned()); - args.insert(0, "-Zunstable-options".to_owned()); + #[rustfmt::skip] + args.extend(strings(&[ + "--fix", "-Zunstable-options", + // FIXME: currently, `--fix` gives an error while checking tests for libtest, + // possibly because libtest is not yet built in the sysroot. + // As a workaround, avoid checking tests and benches when passed --fix. + "--lib", "--bins", "--examples", + ])); } + args.extend(strings(&["--", "--cap-lints", "warn"])); args } else { vec![]