Auto merge of #52268 - Mark-Simulacrum:rollup, r=Mark-Simulacrum
Rollup of 14 pull requests Successful merges: - #51614 (Correct suggestion for println) - #51952 ( hygiene: Decouple transparencies from expansion IDs) - #52193 (step_by: leave time of item skip unspecified) - #52207 (improve error message shown for unsafe operations) - #52223 (Deny bare trait objects in in src/liballoc) - #52224 (Deny bare trait objects in in src/libsyntax) - #52239 (Remove sync::Once::call_once 'static bound) - #52247 (Deny bare trait objects in in src/librustc) - #52248 (Deny bare trait objects in in src/librustc_allocator) - #52252 (Deny bare trait objects in in src/librustc_codegen_llvm) - #52253 (Deny bare trait objects in in src/librustc_data_structures) - #52254 (Deny bare trait objects in in src/librustc_metadata) - #52261 (Deny bare trait objects in in src/libpanic_unwind) - #52265 (Deny bare trait objects in in src/librustc_codegen_utils) Failed merges: r? @ghost
This commit is contained in:
commit
704af2d7e1
@ -446,7 +446,7 @@ impl From<Box<str>> for Box<[u8]> {
|
||||
}
|
||||
}
|
||||
|
||||
impl Box<Any> {
|
||||
impl Box<dyn Any> {
|
||||
#[inline]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
/// Attempt to downcast the box to a concrete type.
|
||||
@ -468,10 +468,10 @@ impl Box<Any> {
|
||||
/// print_if_string(Box::new(0i8));
|
||||
/// }
|
||||
/// ```
|
||||
pub fn downcast<T: Any>(self) -> Result<Box<T>, Box<Any>> {
|
||||
pub fn downcast<T: Any>(self) -> Result<Box<T>, Box<dyn Any>> {
|
||||
if self.is::<T>() {
|
||||
unsafe {
|
||||
let raw: *mut Any = Box::into_raw(self);
|
||||
let raw: *mut dyn Any = Box::into_raw(self);
|
||||
Ok(Box::from_raw(raw as *mut T))
|
||||
}
|
||||
} else {
|
||||
@ -480,7 +480,7 @@ impl Box<Any> {
|
||||
}
|
||||
}
|
||||
|
||||
impl Box<Any + Send> {
|
||||
impl Box<dyn Any + Send> {
|
||||
#[inline]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
/// Attempt to downcast the box to a concrete type.
|
||||
@ -502,10 +502,10 @@ impl Box<Any + Send> {
|
||||
/// print_if_string(Box::new(0i8));
|
||||
/// }
|
||||
/// ```
|
||||
pub fn downcast<T: Any>(self) -> Result<Box<T>, Box<Any + Send>> {
|
||||
<Box<Any>>::downcast(self).map_err(|s| unsafe {
|
||||
pub fn downcast<T: Any>(self) -> Result<Box<T>, Box<dyn Any + Send>> {
|
||||
<Box<dyn Any>>::downcast(self).map_err(|s| unsafe {
|
||||
// reapply the Send marker
|
||||
Box::from_raw(Box::into_raw(s) as *mut (Any + Send))
|
||||
Box::from_raw(Box::into_raw(s) as *mut (dyn Any + Send))
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -643,7 +643,7 @@ impl<A, F> FnBox<A> for F
|
||||
|
||||
#[unstable(feature = "fnbox",
|
||||
reason = "will be deprecated if and when `Box<FnOnce>` becomes usable", issue = "28796")]
|
||||
impl<'a, A, R> FnOnce<A> for Box<FnBox<A, Output = R> + 'a> {
|
||||
impl<'a, A, R> FnOnce<A> for Box<dyn FnBox<A, Output = R> + 'a> {
|
||||
type Output = R;
|
||||
|
||||
extern "rust-call" fn call_once(self, args: A) -> R {
|
||||
@ -653,7 +653,7 @@ impl<'a, A, R> FnOnce<A> for Box<FnBox<A, Output = R> + 'a> {
|
||||
|
||||
#[unstable(feature = "fnbox",
|
||||
reason = "will be deprecated if and when `Box<FnOnce>` becomes usable", issue = "28796")]
|
||||
impl<'a, A, R> FnOnce<A> for Box<FnBox<A, Output = R> + Send + 'a> {
|
||||
impl<'a, A, R> FnOnce<A> for Box<dyn FnBox<A, Output = R> + Send + 'a> {
|
||||
type Output = R;
|
||||
|
||||
extern "rust-call" fn call_once(self, args: A) -> R {
|
||||
|
@ -31,8 +31,8 @@ struct Test;
|
||||
|
||||
#[test]
|
||||
fn any_move() {
|
||||
let a = Box::new(8) as Box<Any>;
|
||||
let b = Box::new(Test) as Box<Any>;
|
||||
let a = Box::new(8) as Box<dyn Any>;
|
||||
let b = Box::new(Test) as Box<dyn Any>;
|
||||
|
||||
match a.downcast::<i32>() {
|
||||
Ok(a) => {
|
||||
@ -47,8 +47,8 @@ fn any_move() {
|
||||
Err(..) => panic!(),
|
||||
}
|
||||
|
||||
let a = Box::new(8) as Box<Any>;
|
||||
let b = Box::new(Test) as Box<Any>;
|
||||
let a = Box::new(8) as Box<dyn Any>;
|
||||
let b = Box::new(Test) as Box<dyn Any>;
|
||||
|
||||
assert!(a.downcast::<Box<Test>>().is_err());
|
||||
assert!(b.downcast::<Box<i32>>().is_err());
|
||||
@ -56,8 +56,8 @@ fn any_move() {
|
||||
|
||||
#[test]
|
||||
fn test_show() {
|
||||
let a = Box::new(8) as Box<Any>;
|
||||
let b = Box::new(Test) as Box<Any>;
|
||||
let a = Box::new(8) as Box<dyn Any>;
|
||||
let b = Box::new(Test) as Box<dyn Any>;
|
||||
let a_str = format!("{:?}", a);
|
||||
let b_str = format!("{:?}", b);
|
||||
assert_eq!(a_str, "Any");
|
||||
@ -65,8 +65,8 @@ fn test_show() {
|
||||
|
||||
static EIGHT: usize = 8;
|
||||
static TEST: Test = Test;
|
||||
let a = &EIGHT as &Any;
|
||||
let b = &TEST as &Any;
|
||||
let a = &EIGHT as &dyn Any;
|
||||
let b = &TEST as &dyn Any;
|
||||
let s = format!("{:?}", a);
|
||||
assert_eq!(s, "Any");
|
||||
let s = format!("{:?}", b);
|
||||
@ -110,12 +110,12 @@ fn raw_trait() {
|
||||
}
|
||||
}
|
||||
|
||||
let x: Box<Foo> = Box::new(Bar(17));
|
||||
let x: Box<dyn Foo> = Box::new(Bar(17));
|
||||
let p = Box::into_raw(x);
|
||||
unsafe {
|
||||
assert_eq!(17, (*p).get());
|
||||
(*p).set(19);
|
||||
let y: Box<Foo> = Box::from_raw(p);
|
||||
let y: Box<dyn Foo> = Box::from_raw(p);
|
||||
assert_eq!(19, y.get());
|
||||
}
|
||||
}
|
||||
|
@ -72,6 +72,7 @@
|
||||
test(no_crate_inject, attr(allow(unused_variables), deny(warnings))))]
|
||||
#![no_std]
|
||||
#![needs_allocator]
|
||||
#![deny(bare_trait_objects)]
|
||||
#![deny(missing_debug_implementations)]
|
||||
|
||||
#![cfg_attr(test, allow(deprecated))] // rand
|
||||
|
@ -618,7 +618,7 @@ impl<T: Clone> Rc<T> {
|
||||
}
|
||||
}
|
||||
|
||||
impl Rc<Any> {
|
||||
impl Rc<dyn Any> {
|
||||
#[inline]
|
||||
#[stable(feature = "rc_downcast", since = "1.29.0")]
|
||||
/// Attempt to downcast the `Rc<Any>` to a concrete type.
|
||||
@ -641,7 +641,7 @@ impl Rc<Any> {
|
||||
/// print_if_string(Rc::new(0i8));
|
||||
/// }
|
||||
/// ```
|
||||
pub fn downcast<T: Any>(self) -> Result<Rc<T>, Rc<Any>> {
|
||||
pub fn downcast<T: Any>(self) -> Result<Rc<T>, Rc<dyn Any>> {
|
||||
if (*self).is::<T>() {
|
||||
let ptr = self.ptr.cast::<RcBox<T>>();
|
||||
forget(self);
|
||||
@ -1554,7 +1554,7 @@ mod tests {
|
||||
assert_eq!(unsafe { &*ptr }, "foo");
|
||||
assert_eq!(rc, rc2);
|
||||
|
||||
let rc: Rc<Display> = Rc::new(123);
|
||||
let rc: Rc<dyn Display> = Rc::new(123);
|
||||
|
||||
let ptr = Rc::into_raw(rc.clone());
|
||||
let rc2 = unsafe { Rc::from_raw(ptr) };
|
||||
@ -1755,8 +1755,8 @@ mod tests {
|
||||
use std::fmt::Display;
|
||||
use std::string::ToString;
|
||||
|
||||
let b: Box<Display> = box 123;
|
||||
let r: Rc<Display> = Rc::from(b);
|
||||
let b: Box<dyn Display> = box 123;
|
||||
let r: Rc<dyn Display> = Rc::from(b);
|
||||
|
||||
assert_eq!(r.to_string(), "123");
|
||||
}
|
||||
@ -1765,8 +1765,8 @@ mod tests {
|
||||
fn test_from_box_trait_zero_sized() {
|
||||
use std::fmt::Debug;
|
||||
|
||||
let b: Box<Debug> = box ();
|
||||
let r: Rc<Debug> = Rc::from(b);
|
||||
let b: Box<dyn Debug> = box ();
|
||||
let r: Rc<dyn Debug> = Rc::from(b);
|
||||
|
||||
assert_eq!(format!("{:?}", r), "()");
|
||||
}
|
||||
@ -1783,8 +1783,8 @@ mod tests {
|
||||
fn test_downcast() {
|
||||
use std::any::Any;
|
||||
|
||||
let r1: Rc<Any> = Rc::new(i32::max_value());
|
||||
let r2: Rc<Any> = Rc::new("abc");
|
||||
let r1: Rc<dyn Any> = Rc::new(i32::max_value());
|
||||
let r2: Rc<dyn Any> = Rc::new("abc");
|
||||
|
||||
assert!(r1.clone().downcast::<u32>().is_err());
|
||||
|
||||
|
@ -978,10 +978,10 @@ unsafe impl<#[may_dangle] T: ?Sized> Drop for Arc<T> {
|
||||
}
|
||||
}
|
||||
|
||||
impl Arc<Any + Send + Sync> {
|
||||
impl Arc<dyn Any + Send + Sync> {
|
||||
#[inline]
|
||||
#[stable(feature = "rc_downcast", since = "1.29.0")]
|
||||
/// Attempt to downcast the `Arc<Any + Send + Sync>` to a concrete type.
|
||||
/// Attempt to downcast the `Arc<dyn Any + Send + Sync>` to a concrete type.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
@ -989,7 +989,7 @@ impl Arc<Any + Send + Sync> {
|
||||
/// use std::any::Any;
|
||||
/// use std::sync::Arc;
|
||||
///
|
||||
/// fn print_if_string(value: Arc<Any + Send + Sync>) {
|
||||
/// fn print_if_string(value: Arc<dyn Any + Send + Sync>) {
|
||||
/// if let Ok(string) = value.downcast::<String>() {
|
||||
/// println!("String ({}): {}", string.len(), string);
|
||||
/// }
|
||||
@ -1574,7 +1574,7 @@ mod tests {
|
||||
assert_eq!(unsafe { &*ptr }, "foo");
|
||||
assert_eq!(arc, arc2);
|
||||
|
||||
let arc: Arc<Display> = Arc::new(123);
|
||||
let arc: Arc<dyn Display> = Arc::new(123);
|
||||
|
||||
let ptr = Arc::into_raw(arc.clone());
|
||||
let arc2 = unsafe { Arc::from_raw(ptr) };
|
||||
@ -1879,8 +1879,8 @@ mod tests {
|
||||
use std::fmt::Display;
|
||||
use std::string::ToString;
|
||||
|
||||
let b: Box<Display> = box 123;
|
||||
let r: Arc<Display> = Arc::from(b);
|
||||
let b: Box<dyn Display> = box 123;
|
||||
let r: Arc<dyn Display> = Arc::from(b);
|
||||
|
||||
assert_eq!(r.to_string(), "123");
|
||||
}
|
||||
@ -1889,8 +1889,8 @@ mod tests {
|
||||
fn test_from_box_trait_zero_sized() {
|
||||
use std::fmt::Debug;
|
||||
|
||||
let b: Box<Debug> = box ();
|
||||
let r: Arc<Debug> = Arc::from(b);
|
||||
let b: Box<dyn Debug> = box ();
|
||||
let r: Arc<dyn Debug> = Arc::from(b);
|
||||
|
||||
assert_eq!(format!("{:?}", r), "()");
|
||||
}
|
||||
@ -1907,8 +1907,8 @@ mod tests {
|
||||
fn test_downcast() {
|
||||
use std::any::Any;
|
||||
|
||||
let r1: Arc<Any + Send + Sync> = Arc::new(i32::max_value());
|
||||
let r2: Arc<Any + Send + Sync> = Arc::new("abc");
|
||||
let r1: Arc<dyn Any + Send + Sync> = Arc::new(i32::max_value());
|
||||
let r2: Arc<dyn Any + Send + Sync> = Arc::new("abc");
|
||||
|
||||
assert!(r1.clone().downcast::<u32>().is_err());
|
||||
|
||||
|
@ -271,9 +271,30 @@ pub trait Iterator {
|
||||
/// Creates an iterator starting at the same point, but stepping by
|
||||
/// the given amount at each iteration.
|
||||
///
|
||||
/// Note that it will always return the first element of the iterator,
|
||||
/// Note 1: The first element of the iterator will always be returned,
|
||||
/// regardless of the step given.
|
||||
///
|
||||
/// Note 2: The time at which ignored elements are pulled is not fixed.
|
||||
/// `StepBy` behaves like the sequence `next(), nth(step-1), nth(step-1), …`,
|
||||
/// but is also free to behave like the sequence
|
||||
/// `advance_n_and_return_first(step), advance_n_and_return_first(step), …`
|
||||
/// Which way is used may change for some iterators for performance reasons.
|
||||
/// The second way will advance the iterator earlier and may consume more items.
|
||||
///
|
||||
/// `advance_n_and_return_first` is the equivalent of:
|
||||
/// ```
|
||||
/// fn advance_n_and_return_first<I>(iter: &mut I, total_step: usize) -> Option<I::Item>
|
||||
/// where
|
||||
/// I: Iterator,
|
||||
/// {
|
||||
/// let next = iter.next();
|
||||
/// if total_step > 1 {
|
||||
/// iter.nth(total_step-2);
|
||||
/// }
|
||||
/// next
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// The method will panic if the given step is `0`.
|
||||
|
@ -48,8 +48,8 @@ pub const DW_EH_PE_indirect: u8 = 0x80;
|
||||
pub struct EHContext<'a> {
|
||||
pub ip: usize, // Current instruction pointer
|
||||
pub func_start: usize, // Address of the current function
|
||||
pub get_text_start: &'a Fn() -> usize, // Get address of the code section
|
||||
pub get_data_start: &'a Fn() -> usize, // Get address of the data section
|
||||
pub get_text_start: &'a dyn Fn() -> usize, // Get address of the code section
|
||||
pub get_data_start: &'a dyn Fn() -> usize, // Get address of the data section
|
||||
}
|
||||
|
||||
pub enum EHAction {
|
||||
|
@ -29,20 +29,20 @@ pub fn payload() -> *mut u8 {
|
||||
ptr::null_mut()
|
||||
}
|
||||
|
||||
pub unsafe fn cleanup(ptr: *mut u8) -> Box<Any + Send> {
|
||||
pub unsafe fn cleanup(ptr: *mut u8) -> Box<dyn Any + Send> {
|
||||
assert!(!ptr.is_null());
|
||||
let ex = ptr::read(ptr as *mut _);
|
||||
__cxa_free_exception(ptr as *mut _);
|
||||
ex
|
||||
}
|
||||
|
||||
pub unsafe fn panic(data: Box<Any + Send>) -> u32 {
|
||||
pub unsafe fn panic(data: Box<dyn Any + Send>) -> u32 {
|
||||
let sz = mem::size_of_val(&data);
|
||||
let exception = __cxa_allocate_exception(sz);
|
||||
if exception == ptr::null_mut() {
|
||||
return uw::_URC_FATAL_PHASE1_ERROR as u32;
|
||||
}
|
||||
let exception = exception as *mut Box<Any + Send>;
|
||||
let exception = exception as *mut Box<dyn Any + Send>;
|
||||
ptr::write(exception, data);
|
||||
__cxa_throw(exception as *mut _, ptr::null_mut(), ptr::null_mut());
|
||||
|
||||
|
@ -67,10 +67,10 @@ use dwarf::eh::{self, EHContext, EHAction};
|
||||
#[repr(C)]
|
||||
struct Exception {
|
||||
_uwe: uw::_Unwind_Exception,
|
||||
cause: Option<Box<Any + Send>>,
|
||||
cause: Option<Box<dyn Any + Send>>,
|
||||
}
|
||||
|
||||
pub unsafe fn panic(data: Box<Any + Send>) -> u32 {
|
||||
pub unsafe fn panic(data: Box<dyn Any + Send>) -> u32 {
|
||||
let exception = Box::new(Exception {
|
||||
_uwe: uw::_Unwind_Exception {
|
||||
exception_class: rust_exception_class(),
|
||||
@ -94,7 +94,7 @@ pub fn payload() -> *mut u8 {
|
||||
ptr::null_mut()
|
||||
}
|
||||
|
||||
pub unsafe fn cleanup(ptr: *mut u8) -> Box<Any + Send> {
|
||||
pub unsafe fn cleanup(ptr: *mut u8) -> Box<dyn Any + Send> {
|
||||
let my_ep = ptr as *mut Exception;
|
||||
let cause = (*my_ep).cause.take();
|
||||
uw::_Unwind_DeleteException(ptr as *mut _);
|
||||
|
@ -22,6 +22,7 @@
|
||||
//! More documentation about each implementation can be found in the respective
|
||||
//! module.
|
||||
|
||||
#![deny(bare_trait_objects)]
|
||||
#![no_std]
|
||||
#![unstable(feature = "panic_unwind", issue = "32837")]
|
||||
#![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
|
||||
@ -117,6 +118,6 @@ pub unsafe extern "C" fn __rust_maybe_catch_panic(f: fn(*mut u8),
|
||||
#[no_mangle]
|
||||
#[unwind(allowed)]
|
||||
pub unsafe extern "C" fn __rust_start_panic(payload: usize) -> u32 {
|
||||
let payload = payload as *mut &mut BoxMeUp;
|
||||
let payload = payload as *mut &mut dyn BoxMeUp;
|
||||
imp::panic(Box::from_raw((*payload).box_me_up()))
|
||||
}
|
||||
|
@ -43,7 +43,7 @@
|
||||
//! throwing. Note that throwing an exception into Rust is undefined behavior
|
||||
//! anyway, so this should be fine.
|
||||
//! * We've got some data to transmit across the unwinding boundary,
|
||||
//! specifically a `Box<Any + Send>`. Like with Dwarf exceptions
|
||||
//! specifically a `Box<dyn Any + Send>`. Like with Dwarf exceptions
|
||||
//! these two pointers are stored as a payload in the exception itself. On
|
||||
//! MSVC, however, there's no need for an extra heap allocation because the
|
||||
//! call stack is preserved while filter functions are being executed. This
|
||||
@ -243,7 +243,7 @@ static mut TYPE_DESCRIPTOR2: _TypeDescriptor = _TypeDescriptor {
|
||||
name: imp::NAME2,
|
||||
};
|
||||
|
||||
pub unsafe fn panic(data: Box<Any + Send>) -> u32 {
|
||||
pub unsafe fn panic(data: Box<dyn Any + Send>) -> u32 {
|
||||
use core::intrinsics::atomic_store;
|
||||
|
||||
// _CxxThrowException executes entirely on this stack frame, so there's no
|
||||
@ -297,7 +297,7 @@ pub fn payload() -> [u64; 2] {
|
||||
[0; 2]
|
||||
}
|
||||
|
||||
pub unsafe fn cleanup(payload: [u64; 2]) -> Box<Any + Send> {
|
||||
pub unsafe fn cleanup(payload: [u64; 2]) -> Box<dyn Any + Send> {
|
||||
mem::transmute(raw::TraitObject {
|
||||
data: payload[0] as *mut _,
|
||||
vtable: payload[1] as *mut _,
|
||||
|
@ -37,10 +37,10 @@ const RUST_PANIC: c::DWORD = ETYPE | (1 << 24) | MAGIC;
|
||||
|
||||
#[repr(C)]
|
||||
struct PanicData {
|
||||
data: Box<Any + Send>,
|
||||
data: Box<dyn Any + Send>,
|
||||
}
|
||||
|
||||
pub unsafe fn panic(data: Box<Any + Send>) -> u32 {
|
||||
pub unsafe fn panic(data: Box<dyn Any + Send>) -> u32 {
|
||||
let panic_ctx = Box::new(PanicData { data: data });
|
||||
let params = [Box::into_raw(panic_ctx) as c::ULONG_PTR];
|
||||
c::RaiseException(RUST_PANIC,
|
||||
@ -54,7 +54,7 @@ pub fn payload() -> *mut u8 {
|
||||
ptr::null_mut()
|
||||
}
|
||||
|
||||
pub unsafe fn cleanup(ptr: *mut u8) -> Box<Any + Send> {
|
||||
pub unsafe fn cleanup(ptr: *mut u8) -> Box<dyn Any + Send> {
|
||||
let panic_ctx = Box::from_raw(ptr as *mut PanicData);
|
||||
return panic_ctx.data;
|
||||
}
|
||||
|
@ -20,10 +20,10 @@ pub fn payload() -> *mut u8 {
|
||||
0 as *mut u8
|
||||
}
|
||||
|
||||
pub unsafe fn cleanup(_ptr: *mut u8) -> Box<Any + Send> {
|
||||
pub unsafe fn cleanup(_ptr: *mut u8) -> Box<dyn Any + Send> {
|
||||
intrinsics::abort()
|
||||
}
|
||||
|
||||
pub unsafe fn panic(_data: Box<Any + Send>) -> u32 {
|
||||
pub unsafe fn panic(_data: Box<dyn Any + Send>) -> u32 {
|
||||
intrinsics::abort()
|
||||
}
|
||||
|
@ -1351,7 +1351,7 @@ pub mod __internal {
|
||||
use syntax::parse::token::{self, Token};
|
||||
use syntax::tokenstream;
|
||||
use syntax_pos::{BytePos, Loc, DUMMY_SP};
|
||||
use syntax_pos::hygiene::{Mark, SyntaxContext, Transparency};
|
||||
use syntax_pos::hygiene::{SyntaxContext, Transparency};
|
||||
|
||||
use super::{TokenStream, LexError, Span};
|
||||
|
||||
@ -1436,20 +1436,15 @@ pub mod __internal {
|
||||
|
||||
// No way to determine def location for a proc macro right now, so use call location.
|
||||
let location = cx.current_expansion.mark.expn_info().unwrap().call_site;
|
||||
// Opaque mark was already created by expansion, now create its transparent twin.
|
||||
// We can't use the call-site span literally here, even if it appears to provide
|
||||
// correct name resolution, because it has all the `ExpnInfo` wrong, so the edition
|
||||
// checks, lint macro checks, macro backtraces will all break.
|
||||
let opaque_mark = cx.current_expansion.mark;
|
||||
let transparent_mark = Mark::fresh_cloned(opaque_mark);
|
||||
transparent_mark.set_transparency(Transparency::Transparent);
|
||||
|
||||
let to_span = |mark| Span(location.with_ctxt(SyntaxContext::empty().apply_mark(mark)));
|
||||
let to_span = |transparency| Span(location.with_ctxt(
|
||||
SyntaxContext::empty().apply_mark_with_transparency(cx.current_expansion.mark,
|
||||
transparency))
|
||||
);
|
||||
p.set(ProcMacroSess {
|
||||
parse_sess: cx.parse_sess,
|
||||
data: ProcMacroData {
|
||||
def_site: to_span(opaque_mark),
|
||||
call_site: to_span(transparent_mark),
|
||||
def_site: to_span(Transparency::Opaque),
|
||||
call_site: to_span(Transparency::Transparent),
|
||||
},
|
||||
});
|
||||
f()
|
||||
|
@ -129,6 +129,16 @@ pub enum Namespace {
|
||||
MacroNS,
|
||||
}
|
||||
|
||||
impl Namespace {
|
||||
pub fn descr(self) -> &'static str {
|
||||
match self {
|
||||
TypeNS => "type",
|
||||
ValueNS => "value",
|
||||
MacroNS => "macro",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Just a helper ‒ separate structure for each namespace.
|
||||
#[derive(Copy, Clone, Default, Debug)]
|
||||
pub struct PerNS<T> {
|
||||
|
@ -82,9 +82,9 @@ pub struct LoweringContext<'a> {
|
||||
// Use to assign ids to hir nodes that do not directly correspond to an ast node
|
||||
sess: &'a Session,
|
||||
|
||||
cstore: &'a CrateStore,
|
||||
cstore: &'a dyn CrateStore,
|
||||
|
||||
resolver: &'a mut Resolver,
|
||||
resolver: &'a mut dyn Resolver,
|
||||
|
||||
/// The items being lowered are collected here.
|
||||
items: BTreeMap<NodeId, hir::Item>,
|
||||
@ -199,10 +199,10 @@ impl<'a> ImplTraitContext<'a> {
|
||||
|
||||
pub fn lower_crate(
|
||||
sess: &Session,
|
||||
cstore: &CrateStore,
|
||||
cstore: &dyn CrateStore,
|
||||
dep_graph: &DepGraph,
|
||||
krate: &Crate,
|
||||
resolver: &mut Resolver,
|
||||
resolver: &mut dyn Resolver,
|
||||
) -> hir::Crate {
|
||||
// We're constructing the HIR here; we don't care what we will
|
||||
// read, since we haven't even constructed the *input* to
|
||||
|
@ -153,6 +153,7 @@ impl Decodable for DefPathTable {
|
||||
/// The definition table containing node definitions.
|
||||
/// It holds the DefPathTable for local DefIds/DefPaths and it also stores a
|
||||
/// mapping from NodeIds to local DefIds.
|
||||
#[derive(Clone)]
|
||||
pub struct Definitions {
|
||||
table: DefPathTable,
|
||||
node_to_def_index: NodeMap<DefIndex>,
|
||||
@ -161,34 +162,12 @@ pub struct Definitions {
|
||||
/// If `Mark` is an ID of some macro expansion,
|
||||
/// then `DefId` is the normal module (`mod`) in which the expanded macro was defined.
|
||||
parent_modules_of_macro_defs: FxHashMap<Mark, DefId>,
|
||||
/// Item with a given `DefIndex` was defined during opaque macro expansion with ID `Mark`.
|
||||
/// It can actually be defined during transparent macro expansions inside that opaque expansion,
|
||||
/// but transparent expansions are ignored here.
|
||||
opaque_expansions_that_defined: FxHashMap<DefIndex, Mark>,
|
||||
/// Item with a given `DefIndex` was defined during macro expansion with ID `Mark`.
|
||||
expansions_that_defined: FxHashMap<DefIndex, Mark>,
|
||||
next_disambiguator: FxHashMap<(DefIndex, DefPathData), u32>,
|
||||
def_index_to_span: FxHashMap<DefIndex, Span>,
|
||||
}
|
||||
|
||||
// Unfortunately we have to provide a manual impl of Clone because of the
|
||||
// fixed-sized array field.
|
||||
impl Clone for Definitions {
|
||||
fn clone(&self) -> Self {
|
||||
Definitions {
|
||||
table: self.table.clone(),
|
||||
node_to_def_index: self.node_to_def_index.clone(),
|
||||
def_index_to_node: [
|
||||
self.def_index_to_node[0].clone(),
|
||||
self.def_index_to_node[1].clone(),
|
||||
],
|
||||
node_to_hir_id: self.node_to_hir_id.clone(),
|
||||
parent_modules_of_macro_defs: self.parent_modules_of_macro_defs.clone(),
|
||||
opaque_expansions_that_defined: self.opaque_expansions_that_defined.clone(),
|
||||
next_disambiguator: self.next_disambiguator.clone(),
|
||||
def_index_to_span: self.def_index_to_span.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A unique identifier that we can use to lookup a definition
|
||||
/// precisely. It combines the index of the definition's parent (if
|
||||
/// any) with a `DisambiguatedDefPathData`.
|
||||
@ -409,7 +388,7 @@ impl Definitions {
|
||||
def_index_to_node: [vec![], vec![]],
|
||||
node_to_hir_id: IndexVec::new(),
|
||||
parent_modules_of_macro_defs: FxHashMap(),
|
||||
opaque_expansions_that_defined: FxHashMap(),
|
||||
expansions_that_defined: FxHashMap(),
|
||||
next_disambiguator: FxHashMap(),
|
||||
def_index_to_span: FxHashMap(),
|
||||
}
|
||||
@ -584,9 +563,8 @@ impl Definitions {
|
||||
self.node_to_def_index.insert(node_id, index);
|
||||
}
|
||||
|
||||
let expansion = expansion.modern();
|
||||
if expansion != Mark::root() {
|
||||
self.opaque_expansions_that_defined.insert(index, expansion);
|
||||
self.expansions_that_defined.insert(index, expansion);
|
||||
}
|
||||
|
||||
// The span is added if it isn't dummy
|
||||
@ -606,8 +584,8 @@ impl Definitions {
|
||||
self.node_to_hir_id = mapping;
|
||||
}
|
||||
|
||||
pub fn opaque_expansion_that_defined(&self, index: DefIndex) -> Mark {
|
||||
self.opaque_expansions_that_defined.get(&index).cloned().unwrap_or(Mark::root())
|
||||
pub fn expansion_that_defined(&self, index: DefIndex) -> Mark {
|
||||
self.expansions_that_defined.get(&index).cloned().unwrap_or(Mark::root())
|
||||
}
|
||||
|
||||
pub fn parent_module_of_macro_def(&self, mark: Mark) -> DefId {
|
||||
|
@ -32,7 +32,7 @@ impl_stable_hash_for!(struct mir::LocalDecl<'tcx> {
|
||||
});
|
||||
impl_stable_hash_for!(struct mir::UpvarDecl { debug_name, var_hir_id, by_ref, mutability });
|
||||
impl_stable_hash_for!(struct mir::BasicBlockData<'tcx> { statements, terminator, is_cleanup });
|
||||
impl_stable_hash_for!(struct mir::UnsafetyViolation { source_info, description, kind });
|
||||
impl_stable_hash_for!(struct mir::UnsafetyViolation { source_info, description, details, kind });
|
||||
impl_stable_hash_for!(struct mir::UnsafetyCheckResult { violations, unsafe_blocks });
|
||||
|
||||
impl<'a> HashStable<StableHashingContext<'a>>
|
||||
|
@ -36,6 +36,8 @@
|
||||
//!
|
||||
//! This API is completely unstable and subject to change.
|
||||
|
||||
#![deny(bare_trait_objects)]
|
||||
|
||||
#![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
|
||||
html_favicon_url = "https://doc.rust-lang.org/favicon.ico",
|
||||
html_root_url = "https://doc.rust-lang.org/nightly/")]
|
||||
|
@ -316,6 +316,12 @@ declare_lint! {
|
||||
"checks the object safety of where clauses"
|
||||
}
|
||||
|
||||
declare_lint! {
|
||||
pub PROC_MACRO_DERIVE_RESOLUTION_FALLBACK,
|
||||
Warn,
|
||||
"detects proc macro derives using inaccessible names from parent modules"
|
||||
}
|
||||
|
||||
/// Does nothing as a lint pass, but registers some `Lint`s
|
||||
/// which are used by other parts of the compiler.
|
||||
#[derive(Copy, Clone)]
|
||||
@ -372,6 +378,7 @@ impl LintPass for HardwiredLints {
|
||||
DUPLICATE_MACRO_EXPORTS,
|
||||
INTRA_DOC_LINK_RESOLUTION_FAILURE,
|
||||
WHERE_CLAUSES_OBJECT_SAFETY,
|
||||
PROC_MACRO_DERIVE_RESOLUTION_FALLBACK,
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -384,6 +391,7 @@ pub enum BuiltinLintDiagnostics {
|
||||
BareTraitObject(Span, /* is_global */ bool),
|
||||
AbsPathWithModule(Span),
|
||||
DuplicatedMacroExports(ast::Ident, Span, Span),
|
||||
ProcMacroDeriveResolutionFallback(Span),
|
||||
}
|
||||
|
||||
impl BuiltinLintDiagnostics {
|
||||
@ -420,6 +428,10 @@ impl BuiltinLintDiagnostics {
|
||||
db.span_label(later_span, format!("`{}` already exported", ident));
|
||||
db.span_note(earlier_span, "previous macro export is now shadowed");
|
||||
}
|
||||
BuiltinLintDiagnostics::ProcMacroDeriveResolutionFallback(span) => {
|
||||
db.span_label(span, "names from parent modules are not \
|
||||
accessible without an explicit import");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -257,7 +257,7 @@ pub trait CrateStore {
|
||||
fn metadata_encoding_version(&self) -> &[u8];
|
||||
}
|
||||
|
||||
pub type CrateStoreDyn = CrateStore + sync::Sync;
|
||||
pub type CrateStoreDyn = dyn CrateStore + sync::Sync;
|
||||
|
||||
// FIXME: find a better place for this?
|
||||
pub fn validate_crate_name(sess: Option<&Session>, s: &str, sp: Option<Span>) {
|
||||
|
@ -2377,6 +2377,7 @@ pub enum UnsafetyViolationKind {
|
||||
pub struct UnsafetyViolation {
|
||||
pub source_info: SourceInfo,
|
||||
pub description: InternedString,
|
||||
pub details: InternedString,
|
||||
pub kind: UnsafetyViolationKind,
|
||||
}
|
||||
|
||||
|
@ -2724,7 +2724,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
||||
pub fn adjust_ident(self, mut ident: Ident, scope: DefId, block: NodeId) -> (Ident, DefId) {
|
||||
ident = ident.modern();
|
||||
let target_expansion = match scope.krate {
|
||||
LOCAL_CRATE => self.hir.definitions().opaque_expansion_that_defined(scope.index),
|
||||
LOCAL_CRATE => self.hir.definitions().expansion_that_defined(scope.index),
|
||||
_ => Mark::root(),
|
||||
};
|
||||
let scope = match ident.span.adjust(target_expansion) {
|
||||
|
@ -37,7 +37,7 @@ use {AllocatorMethod, AllocatorTy, ALLOCATOR_METHODS};
|
||||
|
||||
pub fn modify(
|
||||
sess: &ParseSess,
|
||||
resolver: &mut Resolver,
|
||||
resolver: &mut dyn Resolver,
|
||||
krate: Crate,
|
||||
crate_name: String,
|
||||
handler: &rustc_errors::Handler,
|
||||
@ -56,7 +56,7 @@ struct ExpandAllocatorDirectives<'a> {
|
||||
found: bool,
|
||||
handler: &'a rustc_errors::Handler,
|
||||
sess: &'a ParseSess,
|
||||
resolver: &'a mut Resolver,
|
||||
resolver: &'a mut dyn Resolver,
|
||||
crate_name: Option<String>,
|
||||
|
||||
// For now, we disallow `global_allocator` in submodules because hygiene is hard. Keep track of
|
||||
@ -256,7 +256,7 @@ impl<'a> AllocFnFactory<'a> {
|
||||
&self,
|
||||
ty: &AllocatorTy,
|
||||
args: &mut Vec<Arg>,
|
||||
ident: &mut FnMut() -> Ident,
|
||||
ident: &mut dyn FnMut() -> Ident,
|
||||
) -> P<Expr> {
|
||||
match *ty {
|
||||
AllocatorTy::Layout => {
|
||||
|
@ -8,6 +8,7 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#![deny(bare_trait_objects)]
|
||||
#![feature(rustc_private)]
|
||||
|
||||
#[macro_use] extern crate log;
|
||||
|
@ -48,7 +48,7 @@ enum Addition {
|
||||
},
|
||||
Archive {
|
||||
archive: ArchiveRO,
|
||||
skip: Box<FnMut(&str) -> bool>,
|
||||
skip: Box<dyn FnMut(&str) -> bool>,
|
||||
},
|
||||
}
|
||||
|
||||
|
@ -251,7 +251,7 @@ fn filename_for_metadata(sess: &Session, crate_name: &str, outputs: &OutputFilen
|
||||
|
||||
pub(crate) fn each_linked_rlib(sess: &Session,
|
||||
info: &CrateInfo,
|
||||
f: &mut FnMut(CrateNum, &Path)) -> Result<(), String> {
|
||||
f: &mut dyn FnMut(CrateNum, &Path)) -> Result<(), String> {
|
||||
let crates = info.used_crates_static.iter();
|
||||
let fmts = sess.dependency_formats.borrow();
|
||||
let fmts = fmts.get(&config::CrateTypeExecutable)
|
||||
@ -984,7 +984,7 @@ fn exec_linker(sess: &Session, cmd: &mut Command, out_filename: &Path, tmpdir: &
|
||||
}
|
||||
}
|
||||
|
||||
fn link_args(cmd: &mut Linker,
|
||||
fn link_args(cmd: &mut dyn Linker,
|
||||
sess: &Session,
|
||||
crate_type: config::CrateType,
|
||||
tmpdir: &Path,
|
||||
@ -1195,7 +1195,7 @@ fn link_args(cmd: &mut Linker,
|
||||
// Also note that the native libraries linked here are only the ones located
|
||||
// in the current crate. Upstream crates with native library dependencies
|
||||
// may have their native library pulled in above.
|
||||
fn add_local_native_libraries(cmd: &mut Linker,
|
||||
fn add_local_native_libraries(cmd: &mut dyn Linker,
|
||||
sess: &Session,
|
||||
codegen_results: &CodegenResults) {
|
||||
sess.target_filesearch(PathKind::All).for_each_lib_search_path(|path, k| {
|
||||
@ -1226,7 +1226,7 @@ fn add_local_native_libraries(cmd: &mut Linker,
|
||||
// Rust crates are not considered at all when creating an rlib output. All
|
||||
// dependencies will be linked when producing the final output (instead of
|
||||
// the intermediate rlib version)
|
||||
fn add_upstream_rust_crates(cmd: &mut Linker,
|
||||
fn add_upstream_rust_crates(cmd: &mut dyn Linker,
|
||||
sess: &Session,
|
||||
codegen_results: &CodegenResults,
|
||||
crate_type: config::CrateType,
|
||||
@ -1350,7 +1350,7 @@ fn add_upstream_rust_crates(cmd: &mut Linker,
|
||||
// it's packed in a .rlib, it contains stuff that are not objects that will
|
||||
// make the linker error. So we must remove those bits from the .rlib before
|
||||
// linking it.
|
||||
fn link_sanitizer_runtime(cmd: &mut Linker,
|
||||
fn link_sanitizer_runtime(cmd: &mut dyn Linker,
|
||||
sess: &Session,
|
||||
codegen_results: &CodegenResults,
|
||||
tmpdir: &Path,
|
||||
@ -1419,7 +1419,7 @@ fn add_upstream_rust_crates(cmd: &mut Linker,
|
||||
// (aka we're making an executable), we can just pass the rlib blindly to
|
||||
// the linker (fast) because it's fine if it's not actually included as
|
||||
// we're at the end of the dependency chain.
|
||||
fn add_static_crate(cmd: &mut Linker,
|
||||
fn add_static_crate(cmd: &mut dyn Linker,
|
||||
sess: &Session,
|
||||
codegen_results: &CodegenResults,
|
||||
tmpdir: &Path,
|
||||
@ -1524,7 +1524,7 @@ fn add_upstream_rust_crates(cmd: &mut Linker,
|
||||
}
|
||||
|
||||
// Same thing as above, but for dynamic crates instead of static crates.
|
||||
fn add_dynamic_crate(cmd: &mut Linker, sess: &Session, cratepath: &Path) {
|
||||
fn add_dynamic_crate(cmd: &mut dyn Linker, sess: &Session, cratepath: &Path) {
|
||||
// If we're performing LTO, then it should have been previously required
|
||||
// that all upstream rust dependencies were available in an rlib format.
|
||||
assert!(!is_full_lto_enabled(sess));
|
||||
@ -1559,7 +1559,7 @@ fn add_upstream_rust_crates(cmd: &mut Linker,
|
||||
// generic function calls a native function, then the generic function must
|
||||
// be instantiated in the target crate, meaning that the native symbol must
|
||||
// also be resolved in the target crate.
|
||||
fn add_upstream_native_libraries(cmd: &mut Linker,
|
||||
fn add_upstream_native_libraries(cmd: &mut dyn Linker,
|
||||
sess: &Session,
|
||||
codegen_results: &CodegenResults,
|
||||
crate_type: config::CrateType) {
|
||||
|
@ -44,7 +44,7 @@ impl LinkerInfo {
|
||||
|
||||
pub fn to_linker<'a>(&'a self,
|
||||
cmd: Command,
|
||||
sess: &'a Session) -> Box<Linker+'a> {
|
||||
sess: &'a Session) -> Box<dyn Linker+'a> {
|
||||
match sess.linker_flavor() {
|
||||
LinkerFlavor::Lld(LldFlavor::Link) |
|
||||
LinkerFlavor::Msvc => {
|
||||
@ -52,14 +52,14 @@ impl LinkerInfo {
|
||||
cmd,
|
||||
sess,
|
||||
info: self
|
||||
}) as Box<Linker>
|
||||
}) as Box<dyn Linker>
|
||||
}
|
||||
LinkerFlavor::Em => {
|
||||
Box::new(EmLinker {
|
||||
cmd,
|
||||
sess,
|
||||
info: self
|
||||
}) as Box<Linker>
|
||||
}) as Box<dyn Linker>
|
||||
}
|
||||
LinkerFlavor::Gcc => {
|
||||
Box::new(GccLinker {
|
||||
@ -68,7 +68,7 @@ impl LinkerInfo {
|
||||
info: self,
|
||||
hinted_static: false,
|
||||
is_ld: false,
|
||||
}) as Box<Linker>
|
||||
}) as Box<dyn Linker>
|
||||
}
|
||||
|
||||
LinkerFlavor::Lld(LldFlavor::Ld) |
|
||||
@ -80,14 +80,14 @@ impl LinkerInfo {
|
||||
info: self,
|
||||
hinted_static: false,
|
||||
is_ld: true,
|
||||
}) as Box<Linker>
|
||||
}) as Box<dyn Linker>
|
||||
}
|
||||
|
||||
LinkerFlavor::Lld(LldFlavor::Wasm) => {
|
||||
Box::new(WasmLd {
|
||||
cmd,
|
||||
sess,
|
||||
}) as Box<Linker>
|
||||
}) as Box<dyn Linker>
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ pub struct RPathConfig<'a> {
|
||||
pub is_like_osx: bool,
|
||||
pub has_rpath: bool,
|
||||
pub linker_is_gnu: bool,
|
||||
pub get_install_prefix_lib_path: &'a mut FnMut() -> PathBuf,
|
||||
pub get_install_prefix_lib_path: &'a mut dyn FnMut() -> PathBuf,
|
||||
}
|
||||
|
||||
pub fn get_rpath_flags(config: &mut RPathConfig) -> Vec<String> {
|
||||
|
@ -140,7 +140,7 @@ pub fn create_target_machine(sess: &Session, find_features: bool) -> TargetMachi
|
||||
// that `is_pie_binary` is false. When we discover LLVM target features
|
||||
// `sess.crate_types` is uninitialized so we cannot access it.
|
||||
pub fn target_machine_factory(sess: &Session, find_features: bool)
|
||||
-> Arc<Fn() -> Result<TargetMachineRef, String> + Send + Sync>
|
||||
-> Arc<dyn Fn() -> Result<TargetMachineRef, String> + Send + Sync>
|
||||
{
|
||||
let reloc_model = get_reloc_model(sess);
|
||||
|
||||
@ -343,7 +343,7 @@ pub struct CodegenContext {
|
||||
regular_module_config: Arc<ModuleConfig>,
|
||||
metadata_module_config: Arc<ModuleConfig>,
|
||||
allocator_module_config: Arc<ModuleConfig>,
|
||||
pub tm_factory: Arc<Fn() -> Result<TargetMachineRef, String> + Send + Sync>,
|
||||
pub tm_factory: Arc<dyn Fn() -> Result<TargetMachineRef, String> + Send + Sync>,
|
||||
pub msvc_imps_needed: bool,
|
||||
pub target_pointer_width: String,
|
||||
debuginfo: config::DebugInfoLevel,
|
||||
@ -362,7 +362,7 @@ pub struct CodegenContext {
|
||||
// compiling incrementally
|
||||
pub incr_comp_session_dir: Option<PathBuf>,
|
||||
// Channel back to the main control thread to send messages to
|
||||
coordinator_send: Sender<Box<Any + Send>>,
|
||||
coordinator_send: Sender<Box<dyn Any + Send>>,
|
||||
// A reference to the TimeGraph so we can register timings. None means that
|
||||
// measuring is disabled.
|
||||
time_graph: Option<TimeGraph>,
|
||||
@ -884,7 +884,7 @@ pub fn start_async_codegen(tcx: TyCtxt,
|
||||
time_graph: Option<TimeGraph>,
|
||||
link: LinkMeta,
|
||||
metadata: EncodedMetadata,
|
||||
coordinator_receive: Receiver<Box<Any + Send>>,
|
||||
coordinator_receive: Receiver<Box<dyn Any + Send>>,
|
||||
total_cgus: usize)
|
||||
-> OngoingCodegen {
|
||||
let sess = tcx.sess;
|
||||
@ -1412,7 +1412,7 @@ fn start_executing_work(tcx: TyCtxt,
|
||||
crate_info: &CrateInfo,
|
||||
shared_emitter: SharedEmitter,
|
||||
codegen_worker_send: Sender<Message>,
|
||||
coordinator_receive: Receiver<Box<Any + Send>>,
|
||||
coordinator_receive: Receiver<Box<dyn Any + Send>>,
|
||||
total_cgus: usize,
|
||||
jobserver: Client,
|
||||
time_graph: Option<TimeGraph>,
|
||||
@ -1976,7 +1976,7 @@ fn spawn_work(cgcx: CodegenContext, work: WorkItem) {
|
||||
// Set up a destructor which will fire off a message that we're done as
|
||||
// we exit.
|
||||
struct Bomb {
|
||||
coordinator_send: Sender<Box<Any + Send>>,
|
||||
coordinator_send: Sender<Box<dyn Any + Send>>,
|
||||
result: Option<WorkItemResult>,
|
||||
worker_id: usize,
|
||||
}
|
||||
@ -2056,7 +2056,7 @@ pub unsafe fn with_llvm_pmb(llmod: ModuleRef,
|
||||
config: &ModuleConfig,
|
||||
opt_level: llvm::CodeGenOptLevel,
|
||||
prepare_for_thin_lto: bool,
|
||||
f: &mut FnMut(llvm::PassManagerBuilderRef)) {
|
||||
f: &mut dyn FnMut(llvm::PassManagerBuilderRef)) {
|
||||
use std::ptr;
|
||||
|
||||
// Create the PassManagerBuilder for LLVM. We configure it with
|
||||
@ -2243,7 +2243,7 @@ pub struct OngoingCodegen {
|
||||
linker_info: LinkerInfo,
|
||||
crate_info: CrateInfo,
|
||||
time_graph: Option<TimeGraph>,
|
||||
coordinator_send: Sender<Box<Any + Send>>,
|
||||
coordinator_send: Sender<Box<dyn Any + Send>>,
|
||||
codegen_worker_receive: Receiver<Message>,
|
||||
shared_emitter_main: SharedEmitterMain,
|
||||
future: thread::JoinHandle<Result<CompiledModules, ()>>,
|
||||
|
@ -717,7 +717,7 @@ pub fn iter_globals(llmod: llvm::ModuleRef) -> ValueIter {
|
||||
}
|
||||
|
||||
pub fn codegen_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
rx: mpsc::Receiver<Box<Any + Send>>)
|
||||
rx: mpsc::Receiver<Box<dyn Any + Send>>)
|
||||
-> OngoingCodegen {
|
||||
|
||||
check_for_rustc_errors_attr(tcx);
|
||||
|
@ -916,7 +916,7 @@ fn gen_fn<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
|
||||
name: &str,
|
||||
inputs: Vec<Ty<'tcx>>,
|
||||
output: Ty<'tcx>,
|
||||
codegen: &mut for<'b> FnMut(Builder<'b, 'tcx>))
|
||||
codegen: &mut dyn for<'b> FnMut(Builder<'b, 'tcx>))
|
||||
-> ValueRef {
|
||||
let rust_fn_ty = cx.tcx.mk_fn_ptr(ty::Binder::bind(cx.tcx.mk_fn_sig(
|
||||
inputs.into_iter(),
|
||||
@ -936,7 +936,7 @@ fn gen_fn<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
|
||||
//
|
||||
// This function is only generated once and is then cached.
|
||||
fn get_rust_try_fn<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
|
||||
codegen: &mut for<'b> FnMut(Builder<'b, 'tcx>))
|
||||
codegen: &mut dyn for<'b> FnMut(Builder<'b, 'tcx>))
|
||||
-> ValueRef {
|
||||
if let Some(llfn) = cx.rust_try_fn.get() {
|
||||
return llfn;
|
||||
|
@ -23,6 +23,7 @@
|
||||
#![feature(custom_attribute)]
|
||||
#![feature(fs_read_write)]
|
||||
#![allow(unused_attributes)]
|
||||
#![deny(bare_trait_objects)]
|
||||
#![feature(libc)]
|
||||
#![feature(quote)]
|
||||
#![feature(range_contains)]
|
||||
@ -125,7 +126,7 @@ impl !Send for LlvmCodegenBackend {} // Llvm is on a per-thread basis
|
||||
impl !Sync for LlvmCodegenBackend {}
|
||||
|
||||
impl LlvmCodegenBackend {
|
||||
pub fn new() -> Box<CodegenBackend> {
|
||||
pub fn new() -> Box<dyn CodegenBackend> {
|
||||
box LlvmCodegenBackend(())
|
||||
}
|
||||
}
|
||||
@ -178,7 +179,7 @@ impl CodegenBackend for LlvmCodegenBackend {
|
||||
target_features(sess)
|
||||
}
|
||||
|
||||
fn metadata_loader(&self) -> Box<MetadataLoader + Sync> {
|
||||
fn metadata_loader(&self) -> Box<dyn MetadataLoader + Sync> {
|
||||
box metadata::LlvmMetadataLoader
|
||||
}
|
||||
|
||||
@ -198,14 +199,14 @@ impl CodegenBackend for LlvmCodegenBackend {
|
||||
fn codegen_crate<'a, 'tcx>(
|
||||
&self,
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
rx: mpsc::Receiver<Box<Any + Send>>
|
||||
) -> Box<Any> {
|
||||
rx: mpsc::Receiver<Box<dyn Any + Send>>
|
||||
) -> Box<dyn Any> {
|
||||
box base::codegen_crate(tcx, rx)
|
||||
}
|
||||
|
||||
fn join_codegen_and_link(
|
||||
&self,
|
||||
ongoing_codegen: Box<Any>,
|
||||
ongoing_codegen: Box<dyn Any>,
|
||||
sess: &Session,
|
||||
dep_graph: &DepGraph,
|
||||
outputs: &OutputFilenames,
|
||||
@ -247,7 +248,7 @@ impl CodegenBackend for LlvmCodegenBackend {
|
||||
|
||||
/// This is the entrypoint for a hot plugged rustc_codegen_llvm
|
||||
#[no_mangle]
|
||||
pub fn __rustc_codegen_backend() -> Box<CodegenBackend> {
|
||||
pub fn __rustc_codegen_backend() -> Box<dyn CodegenBackend> {
|
||||
LlvmCodegenBackend::new()
|
||||
}
|
||||
|
||||
|
@ -56,23 +56,23 @@ pub trait CodegenBackend {
|
||||
fn print_version(&self) {}
|
||||
fn diagnostics(&self) -> &[(&'static str, &'static str)] { &[] }
|
||||
|
||||
fn metadata_loader(&self) -> Box<MetadataLoader + Sync>;
|
||||
fn metadata_loader(&self) -> Box<dyn MetadataLoader + Sync>;
|
||||
fn provide(&self, _providers: &mut Providers);
|
||||
fn provide_extern(&self, _providers: &mut Providers);
|
||||
fn codegen_crate<'a, 'tcx>(
|
||||
&self,
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
rx: mpsc::Receiver<Box<Any + Send>>
|
||||
) -> Box<Any>;
|
||||
rx: mpsc::Receiver<Box<dyn Any + Send>>
|
||||
) -> Box<dyn Any>;
|
||||
|
||||
/// This is called on the returned `Box<Any>` from `codegen_backend`
|
||||
/// This is called on the returned `Box<dyn Any>` from `codegen_backend`
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics when the passed `Box<Any>` was not returned by `codegen_backend`.
|
||||
/// Panics when the passed `Box<dyn Any>` was not returned by `codegen_backend`.
|
||||
fn join_codegen_and_link(
|
||||
&self,
|
||||
ongoing_codegen: Box<Any>,
|
||||
ongoing_codegen: Box<dyn Any>,
|
||||
sess: &Session,
|
||||
dep_graph: &DepGraph,
|
||||
outputs: &OutputFilenames,
|
||||
@ -105,7 +105,7 @@ pub struct OngoingCodegen {
|
||||
}
|
||||
|
||||
impl MetadataOnlyCodegenBackend {
|
||||
pub fn new() -> Box<CodegenBackend> {
|
||||
pub fn new() -> Box<dyn CodegenBackend> {
|
||||
box MetadataOnlyCodegenBackend(())
|
||||
}
|
||||
}
|
||||
@ -125,7 +125,7 @@ impl CodegenBackend for MetadataOnlyCodegenBackend {
|
||||
}
|
||||
}
|
||||
|
||||
fn metadata_loader(&self) -> Box<MetadataLoader + Sync> {
|
||||
fn metadata_loader(&self) -> Box<dyn MetadataLoader + Sync> {
|
||||
box NoLlvmMetadataLoader
|
||||
}
|
||||
|
||||
@ -145,8 +145,8 @@ impl CodegenBackend for MetadataOnlyCodegenBackend {
|
||||
fn codegen_crate<'a, 'tcx>(
|
||||
&self,
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
_rx: mpsc::Receiver<Box<Any + Send>>
|
||||
) -> Box<Any> {
|
||||
_rx: mpsc::Receiver<Box<dyn Any + Send>>
|
||||
) -> Box<dyn Any> {
|
||||
use rustc_mir::monomorphize::item::MonoItem;
|
||||
|
||||
::check_for_rustc_errors_attr(tcx);
|
||||
@ -193,13 +193,13 @@ impl CodegenBackend for MetadataOnlyCodegenBackend {
|
||||
|
||||
fn join_codegen_and_link(
|
||||
&self,
|
||||
ongoing_codegen: Box<Any>,
|
||||
ongoing_codegen: Box<dyn Any>,
|
||||
sess: &Session,
|
||||
_dep_graph: &DepGraph,
|
||||
outputs: &OutputFilenames,
|
||||
) -> Result<(), CompileIncomplete> {
|
||||
let ongoing_codegen = ongoing_codegen.downcast::<OngoingCodegen>()
|
||||
.expect("Expected MetadataOnlyCodegenBackend's OngoingCodegen, found Box<Any>");
|
||||
.expect("Expected MetadataOnlyCodegenBackend's OngoingCodegen, found Box<dyn Any>");
|
||||
for &crate_type in sess.opts.crate_types.iter() {
|
||||
if crate_type != CrateType::CrateTypeRlib && crate_type != CrateType::CrateTypeDylib {
|
||||
continue;
|
||||
|
@ -20,6 +20,7 @@
|
||||
#![feature(box_syntax)]
|
||||
#![feature(custom_attribute)]
|
||||
#![allow(unused_attributes)]
|
||||
#![deny(bare_trait_objects)]
|
||||
#![feature(quote)]
|
||||
#![feature(rustc_diagnostic_macros)]
|
||||
|
||||
|
@ -16,6 +16,8 @@
|
||||
//!
|
||||
//! This API is completely unstable and subject to change.
|
||||
|
||||
#![deny(bare_trait_objects)]
|
||||
|
||||
#![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
|
||||
html_favicon_url = "https://www.rust-lang.org/favicon.ico",
|
||||
html_root_url = "https://doc.rust-lang.org/nightly/")]
|
||||
|
@ -1046,7 +1046,7 @@ unsafe impl<O, T: ?Sized> Send for OwningRefMut<O, T>
|
||||
unsafe impl<O, T: ?Sized> Sync for OwningRefMut<O, T>
|
||||
where O: Sync, for<'a> (&'a mut T): Sync {}
|
||||
|
||||
impl Debug for Erased {
|
||||
impl Debug for dyn Erased {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "<Erased>",)
|
||||
}
|
||||
@ -1166,35 +1166,35 @@ pub type MutexGuardRefMut<'a, T, U = T> = OwningRefMut<MutexGuard<'a, T>, U>;
|
||||
pub type RwLockWriteGuardRefMut<'a, T, U = T> = OwningRef<RwLockWriteGuard<'a, T>, U>;
|
||||
|
||||
unsafe impl<'a, T: 'a> IntoErased<'a> for Box<T> {
|
||||
type Erased = Box<Erased + 'a>;
|
||||
type Erased = Box<dyn Erased + 'a>;
|
||||
fn into_erased(self) -> Self::Erased {
|
||||
self
|
||||
}
|
||||
}
|
||||
unsafe impl<'a, T: 'a> IntoErased<'a> for Rc<T> {
|
||||
type Erased = Rc<Erased + 'a>;
|
||||
type Erased = Rc<dyn Erased + 'a>;
|
||||
fn into_erased(self) -> Self::Erased {
|
||||
self
|
||||
}
|
||||
}
|
||||
unsafe impl<'a, T: 'a> IntoErased<'a> for Arc<T> {
|
||||
type Erased = Arc<Erased + 'a>;
|
||||
type Erased = Arc<dyn Erased + 'a>;
|
||||
fn into_erased(self) -> Self::Erased {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl<'a, T: Send + 'a> IntoErasedSend<'a> for Box<T> {
|
||||
type Erased = Box<Erased + Send + 'a>;
|
||||
type Erased = Box<dyn Erased + Send + 'a>;
|
||||
fn into_erased_send(self) -> Self::Erased {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl<'a, T: Send + 'a> IntoErasedSendSync<'a> for Box<T> {
|
||||
type Erased = Box<Erased + Sync + Send + 'a>;
|
||||
type Erased = Box<dyn Erased + Sync + Send + 'a>;
|
||||
fn into_erased_send_sync(self) -> Self::Erased {
|
||||
let result: Box<Erased + Send + 'a> = self;
|
||||
let result: Box<dyn Erased + Send + 'a> = self;
|
||||
// This is safe since Erased can always implement Sync
|
||||
// Only the destructor is available and it takes &mut self
|
||||
unsafe {
|
||||
@ -1204,21 +1204,21 @@ unsafe impl<'a, T: Send + 'a> IntoErasedSendSync<'a> for Box<T> {
|
||||
}
|
||||
|
||||
unsafe impl<'a, T: Send + Sync + 'a> IntoErasedSendSync<'a> for Arc<T> {
|
||||
type Erased = Arc<Erased + Send + Sync + 'a>;
|
||||
type Erased = Arc<dyn Erased + Send + Sync + 'a>;
|
||||
fn into_erased_send_sync(self) -> Self::Erased {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
/// Typedef of a owning reference that uses an erased `Box` as the owner.
|
||||
pub type ErasedBoxRef<U> = OwningRef<Box<Erased>, U>;
|
||||
pub type ErasedBoxRef<U> = OwningRef<Box<dyn Erased>, U>;
|
||||
/// Typedef of a owning reference that uses an erased `Rc` as the owner.
|
||||
pub type ErasedRcRef<U> = OwningRef<Rc<Erased>, U>;
|
||||
pub type ErasedRcRef<U> = OwningRef<Rc<dyn Erased>, U>;
|
||||
/// Typedef of a owning reference that uses an erased `Arc` as the owner.
|
||||
pub type ErasedArcRef<U> = OwningRef<Arc<Erased>, U>;
|
||||
pub type ErasedArcRef<U> = OwningRef<Arc<dyn Erased>, U>;
|
||||
|
||||
/// Typedef of a mutable owning reference that uses an erased `Box` as the owner.
|
||||
pub type ErasedBoxRefMut<U> = OwningRefMut<Box<Erased>, U>;
|
||||
pub type ErasedBoxRefMut<U> = OwningRefMut<Box<dyn Erased>, U>;
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
@ -1443,8 +1443,8 @@ mod tests {
|
||||
let c: OwningRef<Rc<Vec<u8>>, [u8]> = unsafe {a.map_owner(Rc::new)};
|
||||
let d: OwningRef<Rc<Box<[u8]>>, [u8]> = unsafe {b.map_owner(Rc::new)};
|
||||
|
||||
let e: OwningRef<Rc<Erased>, [u8]> = c.erase_owner();
|
||||
let f: OwningRef<Rc<Erased>, [u8]> = d.erase_owner();
|
||||
let e: OwningRef<Rc<dyn Erased>, [u8]> = c.erase_owner();
|
||||
let f: OwningRef<Rc<dyn Erased>, [u8]> = d.erase_owner();
|
||||
|
||||
let _g = e.clone();
|
||||
let _h = f.clone();
|
||||
@ -1460,8 +1460,8 @@ mod tests {
|
||||
let c: OwningRef<Box<Vec<u8>>, [u8]> = a.map_owner_box();
|
||||
let d: OwningRef<Box<Box<[u8]>>, [u8]> = b.map_owner_box();
|
||||
|
||||
let _e: OwningRef<Box<Erased>, [u8]> = c.erase_owner();
|
||||
let _f: OwningRef<Box<Erased>, [u8]> = d.erase_owner();
|
||||
let _e: OwningRef<Box<dyn Erased>, [u8]> = c.erase_owner();
|
||||
let _f: OwningRef<Box<dyn Erased>, [u8]> = d.erase_owner();
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -1469,7 +1469,7 @@ mod tests {
|
||||
use std::any::Any;
|
||||
|
||||
let x = Box::new(123_i32);
|
||||
let y: Box<Any> = x;
|
||||
let y: Box<dyn Any> = x;
|
||||
|
||||
OwningRef::new(y).try_map(|x| x.downcast_ref::<i32>().ok_or(())).is_ok();
|
||||
}
|
||||
@ -1479,7 +1479,7 @@ mod tests {
|
||||
use std::any::Any;
|
||||
|
||||
let x = Box::new(123_i32);
|
||||
let y: Box<Any> = x;
|
||||
let y: Box<dyn Any> = x;
|
||||
|
||||
OwningRef::new(y).try_map(|x| x.downcast_ref::<i32>().ok_or(())).is_err();
|
||||
}
|
||||
@ -1843,8 +1843,8 @@ mod tests {
|
||||
let c: OwningRefMut<Box<Vec<u8>>, [u8]> = unsafe {a.map_owner(Box::new)};
|
||||
let d: OwningRefMut<Box<Box<[u8]>>, [u8]> = unsafe {b.map_owner(Box::new)};
|
||||
|
||||
let _e: OwningRefMut<Box<Erased>, [u8]> = c.erase_owner();
|
||||
let _f: OwningRefMut<Box<Erased>, [u8]> = d.erase_owner();
|
||||
let _e: OwningRefMut<Box<dyn Erased>, [u8]> = c.erase_owner();
|
||||
let _f: OwningRefMut<Box<dyn Erased>, [u8]> = d.erase_owner();
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -1857,8 +1857,8 @@ mod tests {
|
||||
let c: OwningRefMut<Box<Vec<u8>>, [u8]> = a.map_owner_box();
|
||||
let d: OwningRefMut<Box<Box<[u8]>>, [u8]> = b.map_owner_box();
|
||||
|
||||
let _e: OwningRefMut<Box<Erased>, [u8]> = c.erase_owner();
|
||||
let _f: OwningRefMut<Box<Erased>, [u8]> = d.erase_owner();
|
||||
let _e: OwningRefMut<Box<dyn Erased>, [u8]> = c.erase_owner();
|
||||
let _f: OwningRefMut<Box<dyn Erased>, [u8]> = d.erase_owner();
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -1866,7 +1866,7 @@ mod tests {
|
||||
use std::any::Any;
|
||||
|
||||
let x = Box::new(123_i32);
|
||||
let y: Box<Any> = x;
|
||||
let y: Box<dyn Any> = x;
|
||||
|
||||
OwningRefMut::new(y).try_map_mut(|x| x.downcast_mut::<i32>().ok_or(())).is_ok();
|
||||
}
|
||||
@ -1876,7 +1876,7 @@ mod tests {
|
||||
use std::any::Any;
|
||||
|
||||
let x = Box::new(123_i32);
|
||||
let y: Box<Any> = x;
|
||||
let y: Box<dyn Any> = x;
|
||||
|
||||
OwningRefMut::new(y).try_map_mut(|x| x.downcast_mut::<i32>().ok_or(())).is_err();
|
||||
}
|
||||
@ -1886,7 +1886,7 @@ mod tests {
|
||||
use std::any::Any;
|
||||
|
||||
let x = Box::new(123_i32);
|
||||
let y: Box<Any> = x;
|
||||
let y: Box<dyn Any> = x;
|
||||
|
||||
OwningRefMut::new(y).try_map(|x| x.downcast_ref::<i32>().ok_or(())).is_ok();
|
||||
}
|
||||
@ -1896,7 +1896,7 @@ mod tests {
|
||||
use std::any::Any;
|
||||
|
||||
let x = Box::new(123_i32);
|
||||
let y: Box<Any> = x;
|
||||
let y: Box<dyn Any> = x;
|
||||
|
||||
OwningRefMut::new(y).try_map(|x| x.downcast_ref::<i32>().ok_or(())).is_err();
|
||||
}
|
||||
|
@ -88,7 +88,7 @@ cfg_if! {
|
||||
t.into_iter()
|
||||
}
|
||||
|
||||
pub type MetadataRef = OwningRef<Box<Erased>, [u8]>;
|
||||
pub type MetadataRef = OwningRef<Box<dyn Erased>, [u8]>;
|
||||
|
||||
pub use std::rc::Rc as Lrc;
|
||||
pub use std::rc::Weak as Weak;
|
||||
@ -268,7 +268,7 @@ cfg_if! {
|
||||
t.into_par_iter()
|
||||
}
|
||||
|
||||
pub type MetadataRef = OwningRef<Box<Erased + Send + Sync>, [u8]>;
|
||||
pub type MetadataRef = OwningRef<Box<dyn Erased + Send + Sync>, [u8]>;
|
||||
|
||||
/// This makes locks panic if they are already held.
|
||||
/// It is only useful when you are running in a single thread
|
||||
|
@ -293,6 +293,11 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) {
|
||||
reference: "issue #50589 <https://github.com/rust-lang/rust/issues/50589>",
|
||||
edition: None,
|
||||
},
|
||||
FutureIncompatibleInfo {
|
||||
id: LintId::of(PROC_MACRO_DERIVE_RESOLUTION_FALLBACK),
|
||||
reference: "issue #50504 <https://github.com/rust-lang/rust/issues/50504>",
|
||||
edition: None,
|
||||
},
|
||||
]);
|
||||
|
||||
// Register renamed and removed lints
|
||||
|
@ -536,7 +536,7 @@ impl<'a> CrateLoader<'a> {
|
||||
Ok(f) => f,
|
||||
Err(err) => self.sess.span_fatal(span, &err),
|
||||
};
|
||||
mem::transmute::<*mut u8, fn(&mut Registry)>(sym)
|
||||
mem::transmute::<*mut u8, fn(&mut dyn Registry)>(sym)
|
||||
};
|
||||
|
||||
struct MyRegistrar {
|
||||
@ -1019,7 +1019,7 @@ impl<'a> CrateLoader<'a> {
|
||||
fn inject_dependency_if(&self,
|
||||
krate: CrateNum,
|
||||
what: &str,
|
||||
needs_dep: &Fn(&cstore::CrateMetadata) -> bool) {
|
||||
needs_dep: &dyn Fn(&cstore::CrateMetadata) -> bool) {
|
||||
// don't perform this validation if the session has errors, as one of
|
||||
// those errors may indicate a circular dependency which could cause
|
||||
// this to stack overflow.
|
||||
|
@ -90,11 +90,11 @@ pub struct CStore {
|
||||
metas: RwLock<IndexVec<CrateNum, Option<Lrc<CrateMetadata>>>>,
|
||||
/// Map from NodeId's of local extern crate statements to crate numbers
|
||||
extern_mod_crate_map: Lock<NodeMap<CrateNum>>,
|
||||
pub metadata_loader: Box<MetadataLoader + Sync>,
|
||||
pub metadata_loader: Box<dyn MetadataLoader + Sync>,
|
||||
}
|
||||
|
||||
impl CStore {
|
||||
pub fn new(metadata_loader: Box<MetadataLoader + Sync>) -> CStore {
|
||||
pub fn new(metadata_loader: Box<dyn MetadataLoader + Sync>) -> CStore {
|
||||
CStore {
|
||||
// We add an empty entry for LOCAL_CRATE (which maps to zero) in
|
||||
// order to make array indices in `metas` match with the
|
||||
|
@ -413,11 +413,11 @@ pub fn provide<'tcx>(providers: &mut Providers<'tcx>) {
|
||||
}
|
||||
|
||||
impl CrateStore for cstore::CStore {
|
||||
fn crate_data_as_rc_any(&self, krate: CrateNum) -> Lrc<Any> {
|
||||
fn crate_data_as_rc_any(&self, krate: CrateNum) -> Lrc<dyn Any> {
|
||||
self.get_crate_data(krate)
|
||||
}
|
||||
|
||||
fn metadata_loader(&self) -> &MetadataLoader {
|
||||
fn metadata_loader(&self) -> &dyn MetadataLoader {
|
||||
&*self.metadata_loader
|
||||
}
|
||||
|
||||
|
@ -391,7 +391,7 @@ impl<'a, 'tcx> MetadataBlob {
|
||||
}
|
||||
|
||||
pub fn list_crate_metadata(&self,
|
||||
out: &mut io::Write) -> io::Result<()> {
|
||||
out: &mut dyn io::Write) -> io::Result<()> {
|
||||
write!(out, "=External Dependencies=\n")?;
|
||||
let root = self.get_root();
|
||||
for (i, dep) in root.crate_deps
|
||||
|
@ -8,6 +8,8 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#![deny(bare_trait_objects)]
|
||||
|
||||
#![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
|
||||
html_favicon_url = "https://doc.rust-lang.org/favicon.ico",
|
||||
html_root_url = "https://doc.rust-lang.org/nightly/")]
|
||||
|
@ -273,7 +273,7 @@ pub struct Context<'a> {
|
||||
pub rejected_via_filename: Vec<CrateMismatch>,
|
||||
pub should_match_name: bool,
|
||||
pub is_proc_macro: Option<bool>,
|
||||
pub metadata_loader: &'a MetadataLoader,
|
||||
pub metadata_loader: &'a dyn MetadataLoader,
|
||||
}
|
||||
|
||||
pub struct CratePaths {
|
||||
@ -842,7 +842,7 @@ impl<'a> Context<'a> {
|
||||
fn get_metadata_section(target: &Target,
|
||||
flavor: CrateFlavor,
|
||||
filename: &Path,
|
||||
loader: &MetadataLoader)
|
||||
loader: &dyn MetadataLoader)
|
||||
-> Result<MetadataBlob, String> {
|
||||
let start = Instant::now();
|
||||
let ret = get_metadata_section_imp(target, flavor, filename, loader);
|
||||
@ -855,7 +855,7 @@ fn get_metadata_section(target: &Target,
|
||||
fn get_metadata_section_imp(target: &Target,
|
||||
flavor: CrateFlavor,
|
||||
filename: &Path,
|
||||
loader: &MetadataLoader)
|
||||
loader: &dyn MetadataLoader)
|
||||
-> Result<MetadataBlob, String> {
|
||||
if !filename.exists() {
|
||||
return Err(format!("no such file: '{}'", filename.display()));
|
||||
@ -904,8 +904,8 @@ fn get_metadata_section_imp(target: &Target,
|
||||
// A diagnostic function for dumping crate metadata to an output stream
|
||||
pub fn list_file_metadata(target: &Target,
|
||||
path: &Path,
|
||||
loader: &MetadataLoader,
|
||||
out: &mut io::Write)
|
||||
loader: &dyn MetadataLoader,
|
||||
out: &mut dyn io::Write)
|
||||
-> io::Result<()> {
|
||||
let filename = path.file_name().unwrap().to_str().unwrap();
|
||||
let flavor = if filename.ends_with(".rlib") {
|
||||
|
@ -85,7 +85,9 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> {
|
||||
let func_ty = func.ty(self.mir, self.tcx);
|
||||
let sig = func_ty.fn_sig(self.tcx);
|
||||
if let hir::Unsafety::Unsafe = sig.unsafety() {
|
||||
self.require_unsafe("call to unsafe function")
|
||||
self.require_unsafe("call to unsafe function",
|
||||
"consult the function's documentation for information on how to avoid \
|
||||
undefined behavior")
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -112,7 +114,8 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> {
|
||||
}
|
||||
|
||||
StatementKind::InlineAsm { .. } => {
|
||||
self.require_unsafe("use of inline assembly")
|
||||
self.require_unsafe("use of inline assembly",
|
||||
"inline assembly is entirely unchecked and can cause undefined behavior")
|
||||
},
|
||||
}
|
||||
self.super_statement(block, statement, location);
|
||||
@ -151,6 +154,11 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> {
|
||||
self.register_violations(&[UnsafetyViolation {
|
||||
source_info,
|
||||
description: Symbol::intern("borrow of packed field").as_interned_str(),
|
||||
details:
|
||||
Symbol::intern("fields of packed structs might be misaligned: \
|
||||
dereferencing a misaligned pointer or even just creating a \
|
||||
misaligned reference is undefined behavior")
|
||||
.as_interned_str(),
|
||||
kind: UnsafetyViolationKind::BorrowPacked(lint_root)
|
||||
}], &[]);
|
||||
}
|
||||
@ -172,7 +180,10 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> {
|
||||
let base_ty = base.ty(self.mir, self.tcx).to_ty(self.tcx);
|
||||
match base_ty.sty {
|
||||
ty::TyRawPtr(..) => {
|
||||
self.require_unsafe("dereference of raw pointer")
|
||||
self.require_unsafe("dereference of raw pointer",
|
||||
"raw pointers may be NULL, dangling or unaligned; they can violate \
|
||||
aliasing rules and cause data races: all of these are undefined \
|
||||
behavior")
|
||||
}
|
||||
ty::TyAdt(adt, _) => {
|
||||
if adt.is_union() {
|
||||
@ -190,12 +201,17 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> {
|
||||
if elem_ty.moves_by_default(self.tcx, self.param_env,
|
||||
self.source_info.span) {
|
||||
self.require_unsafe(
|
||||
"assignment to non-`Copy` union field")
|
||||
"assignment to non-`Copy` union field",
|
||||
"the previous content of the field will be dropped, which \
|
||||
causes undefined behavior if the field was not properly \
|
||||
initialized")
|
||||
} else {
|
||||
// write to non-move union, safe
|
||||
}
|
||||
} else {
|
||||
self.require_unsafe("access to union field")
|
||||
self.require_unsafe("access to union field",
|
||||
"the field may not be properly initialized: using \
|
||||
uninitialized data will cause undefined behavior")
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -208,7 +224,9 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> {
|
||||
}
|
||||
&Place::Static(box Static { def_id, ty: _ }) => {
|
||||
if self.tcx.is_static(def_id) == Some(hir::Mutability::MutMutable) {
|
||||
self.require_unsafe("use of mutable static");
|
||||
self.require_unsafe("use of mutable static",
|
||||
"mutable statics can be mutated by multiple threads: aliasing violations \
|
||||
or data races will cause undefined behavior");
|
||||
} else if self.tcx.is_foreign_item(def_id) {
|
||||
let source_info = self.source_info;
|
||||
let lint_root =
|
||||
@ -216,6 +234,11 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> {
|
||||
self.register_violations(&[UnsafetyViolation {
|
||||
source_info,
|
||||
description: Symbol::intern("use of extern static").as_interned_str(),
|
||||
details:
|
||||
Symbol::intern("extern statics are not controlled by the Rust type \
|
||||
system: invalid data, aliasing violations or data \
|
||||
races will cause undefined behavior")
|
||||
.as_interned_str(),
|
||||
kind: UnsafetyViolationKind::ExternStatic(lint_root)
|
||||
}], &[]);
|
||||
}
|
||||
@ -227,12 +250,14 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> {
|
||||
|
||||
impl<'a, 'tcx> UnsafetyChecker<'a, 'tcx> {
|
||||
fn require_unsafe(&mut self,
|
||||
description: &'static str)
|
||||
description: &'static str,
|
||||
details: &'static str)
|
||||
{
|
||||
let source_info = self.source_info;
|
||||
self.register_violations(&[UnsafetyViolation {
|
||||
source_info,
|
||||
description: Symbol::intern(description).as_interned_str(),
|
||||
details: Symbol::intern(details).as_interned_str(),
|
||||
kind: UnsafetyViolationKind::General,
|
||||
}], &[]);
|
||||
}
|
||||
@ -437,33 +462,36 @@ pub fn check_unsafety<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) {
|
||||
} = tcx.unsafety_check_result(def_id);
|
||||
|
||||
for &UnsafetyViolation {
|
||||
source_info, description, kind
|
||||
source_info, description, details, kind
|
||||
} in violations.iter() {
|
||||
// Report an error.
|
||||
match kind {
|
||||
UnsafetyViolationKind::General => {
|
||||
struct_span_err!(
|
||||
tcx.sess, source_info.span, E0133,
|
||||
"{} requires unsafe function or block", description)
|
||||
"{} is unsafe and requires unsafe function or block", description)
|
||||
.span_label(source_info.span, &description.as_str()[..])
|
||||
.note(&details.as_str()[..])
|
||||
.emit();
|
||||
}
|
||||
UnsafetyViolationKind::ExternStatic(lint_node_id) => {
|
||||
tcx.lint_node(SAFE_EXTERN_STATICS,
|
||||
tcx.lint_node_note(SAFE_EXTERN_STATICS,
|
||||
lint_node_id,
|
||||
source_info.span,
|
||||
&format!("{} requires unsafe function or \
|
||||
block (error E0133)", &description.as_str()[..]));
|
||||
&format!("{} is unsafe and requires unsafe function or block \
|
||||
(error E0133)", &description.as_str()[..]),
|
||||
&details.as_str()[..]);
|
||||
}
|
||||
UnsafetyViolationKind::BorrowPacked(lint_node_id) => {
|
||||
if let Some(impl_def_id) = builtin_derive_def_id(tcx, def_id) {
|
||||
tcx.unsafe_derive_on_repr_packed(impl_def_id);
|
||||
} else {
|
||||
tcx.lint_node(SAFE_PACKED_BORROWS,
|
||||
tcx.lint_node_note(SAFE_PACKED_BORROWS,
|
||||
lint_node_id,
|
||||
source_info.span,
|
||||
&format!("{} requires unsafe function or \
|
||||
block (error E0133)", &description.as_str()[..]));
|
||||
&format!("{} is unsafe and requires unsafe function or block \
|
||||
(error E0133)", &description.as_str()[..]),
|
||||
&details.as_str()[..]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -55,7 +55,7 @@ use syntax::util::lev_distance::find_best_match_for_name;
|
||||
|
||||
use syntax::visit::{self, FnKind, Visitor};
|
||||
use syntax::attr;
|
||||
use syntax::ast::{Arm, IsAsync, BindingMode, Block, Crate, Expr, ExprKind};
|
||||
use syntax::ast::{CRATE_NODE_ID, Arm, IsAsync, BindingMode, Block, Crate, Expr, ExprKind};
|
||||
use syntax::ast::{FnDecl, ForeignItem, ForeignItemKind, GenericParamKind, Generics};
|
||||
use syntax::ast::{Item, ItemKind, ImplItem, ImplItemKind};
|
||||
use syntax::ast::{Label, Local, Mutability, Pat, PatKind, Path};
|
||||
@ -1891,7 +1891,12 @@ impl<'a> Resolver<'a> {
|
||||
|
||||
ident.span = ident.span.modern();
|
||||
loop {
|
||||
module = unwrap_or!(self.hygienic_lexical_parent(module, &mut ident.span), break);
|
||||
let (opt_module, poisoned) = if record_used {
|
||||
self.hygienic_lexical_parent_with_compatibility_fallback(module, &mut ident.span)
|
||||
} else {
|
||||
(self.hygienic_lexical_parent(module, &mut ident.span), false)
|
||||
};
|
||||
module = unwrap_or!(opt_module, break);
|
||||
let orig_current_module = self.current_module;
|
||||
self.current_module = module; // Lexical resolutions can never be a privacy error.
|
||||
let result = self.resolve_ident_in_module_unadjusted(
|
||||
@ -1900,7 +1905,19 @@ impl<'a> Resolver<'a> {
|
||||
self.current_module = orig_current_module;
|
||||
|
||||
match result {
|
||||
Ok(binding) => return Some(LexicalScopeBinding::Item(binding)),
|
||||
Ok(binding) => {
|
||||
if poisoned {
|
||||
self.session.buffer_lint_with_diagnostic(
|
||||
lint::builtin::PROC_MACRO_DERIVE_RESOLUTION_FALLBACK,
|
||||
CRATE_NODE_ID, ident.span,
|
||||
&format!("cannot find {} `{}` in this scope", ns.descr(), ident),
|
||||
lint::builtin::BuiltinLintDiagnostics::
|
||||
ProcMacroDeriveResolutionFallback(ident.span),
|
||||
);
|
||||
}
|
||||
return Some(LexicalScopeBinding::Item(binding))
|
||||
}
|
||||
_ if poisoned => break,
|
||||
Err(Undetermined) => return None,
|
||||
Err(Determined) => {}
|
||||
}
|
||||
@ -1935,7 +1952,7 @@ impl<'a> Resolver<'a> {
|
||||
None
|
||||
}
|
||||
|
||||
fn hygienic_lexical_parent(&mut self, mut module: Module<'a>, span: &mut Span)
|
||||
fn hygienic_lexical_parent(&mut self, module: Module<'a>, span: &mut Span)
|
||||
-> Option<Module<'a>> {
|
||||
if !module.expansion.is_descendant_of(span.ctxt().outer()) {
|
||||
return Some(self.macro_def_scope(span.remove_mark()));
|
||||
@ -1945,22 +1962,41 @@ impl<'a> Resolver<'a> {
|
||||
return Some(module.parent.unwrap());
|
||||
}
|
||||
|
||||
let mut module_expansion = module.expansion.modern(); // for backward compatibility
|
||||
while let Some(parent) = module.parent {
|
||||
let parent_expansion = parent.expansion.modern();
|
||||
if module_expansion.is_descendant_of(parent_expansion) &&
|
||||
parent_expansion != module_expansion {
|
||||
return if parent_expansion.is_descendant_of(span.ctxt().outer()) {
|
||||
Some(parent)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
}
|
||||
module = parent;
|
||||
module_expansion = parent_expansion;
|
||||
None
|
||||
}
|
||||
|
||||
fn hygienic_lexical_parent_with_compatibility_fallback(
|
||||
&mut self, module: Module<'a>, span: &mut Span) -> (Option<Module<'a>>, /* poisoned */ bool
|
||||
) {
|
||||
if let module @ Some(..) = self.hygienic_lexical_parent(module, span) {
|
||||
return (module, false);
|
||||
}
|
||||
|
||||
None
|
||||
// We need to support the next case under a deprecation warning
|
||||
// ```
|
||||
// struct MyStruct;
|
||||
// ---- begin: this comes from a proc macro derive
|
||||
// mod implementation_details {
|
||||
// // Note that `MyStruct` is not in scope here.
|
||||
// impl SomeTrait for MyStruct { ... }
|
||||
// }
|
||||
// ---- end
|
||||
// ```
|
||||
// So we have to fall back to the module's parent during lexical resolution in this case.
|
||||
if let Some(parent) = module.parent {
|
||||
// Inner module is inside the macro, parent module is outside of the macro.
|
||||
if module.expansion != parent.expansion &&
|
||||
module.expansion.is_descendant_of(parent.expansion) {
|
||||
// The macro is a proc macro derive
|
||||
if module.expansion.looks_like_proc_macro_derive() {
|
||||
if parent.expansion.is_descendant_of(span.ctxt().outer()) {
|
||||
return (module.parent, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
(None, false)
|
||||
}
|
||||
|
||||
fn resolve_ident_in_module(&mut self,
|
||||
@ -1996,8 +2032,8 @@ impl<'a> Resolver<'a> {
|
||||
let mut iter = ctxt.marks().into_iter().rev().peekable();
|
||||
let mut result = None;
|
||||
// Find the last modern mark from the end if it exists.
|
||||
while let Some(&mark) = iter.peek() {
|
||||
if mark.transparency() == Transparency::Opaque {
|
||||
while let Some(&(mark, transparency)) = iter.peek() {
|
||||
if transparency == Transparency::Opaque {
|
||||
result = Some(mark);
|
||||
iter.next();
|
||||
} else {
|
||||
@ -2005,8 +2041,8 @@ impl<'a> Resolver<'a> {
|
||||
}
|
||||
}
|
||||
// Then find the last legacy mark from the end if it exists.
|
||||
for mark in iter {
|
||||
if mark.transparency() == Transparency::SemiTransparent {
|
||||
for (mark, transparency) in iter {
|
||||
if transparency == Transparency::SemiTransparent {
|
||||
result = Some(mark);
|
||||
} else {
|
||||
break;
|
||||
@ -4037,8 +4073,9 @@ impl<'a> Resolver<'a> {
|
||||
let mut search_module = self.current_module;
|
||||
loop {
|
||||
self.get_traits_in_module_containing_item(ident, ns, search_module, &mut found_traits);
|
||||
search_module =
|
||||
unwrap_or!(self.hygienic_lexical_parent(search_module, &mut ident.span), break);
|
||||
search_module = unwrap_or!(
|
||||
self.hygienic_lexical_parent(search_module, &mut ident.span), break
|
||||
);
|
||||
}
|
||||
|
||||
if let Some(prelude) = self.prelude {
|
||||
@ -4406,12 +4443,6 @@ impl<'a> Resolver<'a> {
|
||||
(TypeNS, _) => "type",
|
||||
};
|
||||
|
||||
let namespace = match ns {
|
||||
ValueNS => "value",
|
||||
MacroNS => "macro",
|
||||
TypeNS => "type",
|
||||
};
|
||||
|
||||
let msg = format!("the name `{}` is defined multiple times", name);
|
||||
|
||||
let mut err = match (old_binding.is_extern_crate(), new_binding.is_extern_crate()) {
|
||||
@ -4429,7 +4460,7 @@ impl<'a> Resolver<'a> {
|
||||
|
||||
err.note(&format!("`{}` must be defined only once in the {} namespace of this {}",
|
||||
name,
|
||||
namespace,
|
||||
ns.descr(),
|
||||
container));
|
||||
|
||||
err.span_label(span, format!("`{}` re{} here", name, new_participle));
|
||||
|
@ -24,7 +24,7 @@ use syntax::errors::DiagnosticBuilder;
|
||||
use syntax::ext::base::{self, Annotatable, Determinacy, MultiModifier, MultiDecorator};
|
||||
use syntax::ext::base::{MacroKind, SyntaxExtension, Resolver as SyntaxResolver};
|
||||
use syntax::ext::expand::{self, AstFragment, AstFragmentKind, Invocation, InvocationKind};
|
||||
use syntax::ext::hygiene::{self, Mark, Transparency};
|
||||
use syntax::ext::hygiene::{self, Mark};
|
||||
use syntax::ext::placeholders::placeholder;
|
||||
use syntax::ext::tt::macro_rules;
|
||||
use syntax::feature_gate::{self, emit_feature_err, GateIssue};
|
||||
@ -331,13 +331,8 @@ impl<'a> base::Resolver for Resolver<'a> {
|
||||
|
||||
self.unused_macros.remove(&def_id);
|
||||
let ext = self.get_macro(def);
|
||||
if ext.is_modern() {
|
||||
let transparency =
|
||||
if ext.is_transparent() { Transparency::Transparent } else { Transparency::Opaque };
|
||||
invoc.expansion_data.mark.set_transparency(transparency);
|
||||
} else if def_id.krate == BUILTIN_MACROS_CRATE {
|
||||
invoc.expansion_data.mark.set_is_builtin(true);
|
||||
}
|
||||
invoc.expansion_data.mark.set_default_transparency(ext.default_transparency());
|
||||
invoc.expansion_data.mark.set_is_builtin(def_id.krate == BUILTIN_MACROS_CRATE);
|
||||
Ok(Some(ext))
|
||||
}
|
||||
|
||||
|
@ -149,9 +149,9 @@ struct Waiter {
|
||||
|
||||
// Helper struct used to clean up after a closure call with a `Drop`
|
||||
// implementation to also run on panic.
|
||||
struct Finish {
|
||||
struct Finish<'a> {
|
||||
panicked: bool,
|
||||
me: &'static Once,
|
||||
me: &'a Once,
|
||||
}
|
||||
|
||||
impl Once {
|
||||
@ -218,7 +218,7 @@ impl Once {
|
||||
///
|
||||
/// [poison]: struct.Mutex.html#poisoning
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub fn call_once<F>(&'static self, f: F) where F: FnOnce() {
|
||||
pub fn call_once<F>(&self, f: F) where F: FnOnce() {
|
||||
// Fast path, just see if we've completed initialization.
|
||||
if self.state.load(Ordering::SeqCst) == COMPLETE {
|
||||
return
|
||||
@ -275,7 +275,7 @@ impl Once {
|
||||
/// INIT.call_once(|| {});
|
||||
/// ```
|
||||
#[unstable(feature = "once_poison", issue = "33577")]
|
||||
pub fn call_once_force<F>(&'static self, f: F) where F: FnOnce(&OnceState) {
|
||||
pub fn call_once_force<F>(&self, f: F) where F: FnOnce(&OnceState) {
|
||||
// same as above, just with a different parameter to `call_inner`.
|
||||
if self.state.load(Ordering::SeqCst) == COMPLETE {
|
||||
return
|
||||
@ -299,7 +299,7 @@ impl Once {
|
||||
// currently no way to take an `FnOnce` and call it via virtual dispatch
|
||||
// without some allocation overhead.
|
||||
#[cold]
|
||||
fn call_inner(&'static self,
|
||||
fn call_inner(&self,
|
||||
ignore_poisoning: bool,
|
||||
init: &mut FnMut(bool)) {
|
||||
let mut state = self.state.load(Ordering::SeqCst);
|
||||
@ -390,7 +390,7 @@ impl fmt::Debug for Once {
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for Finish {
|
||||
impl<'a> Drop for Finish<'a> {
|
||||
fn drop(&mut self) {
|
||||
// Swap out our state with however we finished. We should only ever see
|
||||
// an old state which was RUNNING.
|
||||
|
@ -131,7 +131,7 @@ pub(super) struct CodeMapFiles {
|
||||
|
||||
pub struct CodeMap {
|
||||
pub(super) files: Lock<CodeMapFiles>,
|
||||
file_loader: Box<FileLoader + Sync + Send>,
|
||||
file_loader: Box<dyn FileLoader + Sync + Send>,
|
||||
// This is used to apply the file path remapping as specified via
|
||||
// --remap-path-prefix to all FileMaps allocated within this CodeMap.
|
||||
path_mapping: FilePathMapping,
|
||||
@ -162,7 +162,7 @@ impl CodeMap {
|
||||
|
||||
}
|
||||
|
||||
pub fn with_file_loader(file_loader: Box<FileLoader + Sync + Send>,
|
||||
pub fn with_file_loader(file_loader: Box<dyn FileLoader + Sync + Send>,
|
||||
path_mapping: FilePathMapping)
|
||||
-> CodeMap {
|
||||
CodeMap {
|
||||
|
@ -73,7 +73,7 @@ fn get_metadata_path(directory: PathBuf, name: &str) -> PathBuf {
|
||||
/// For our current purposes the prefix is the target architecture and the name is a crate name.
|
||||
/// If an error occurs steps will be taken to ensure that no file is created.
|
||||
pub fn output_metadata(ecx: &ExtCtxt, prefix: &str, name: &str, err_map: &ErrorMap)
|
||||
-> Result<(), Box<Error>>
|
||||
-> Result<(), Box<dyn Error>>
|
||||
{
|
||||
// Create the directory to place the file in.
|
||||
let metadata_dir = get_metadata_dir(prefix);
|
||||
|
@ -42,7 +42,7 @@ pub type ErrorMap = BTreeMap<Name, ErrorInfo>;
|
||||
pub fn expand_diagnostic_used<'cx>(ecx: &'cx mut ExtCtxt,
|
||||
span: Span,
|
||||
token_tree: &[TokenTree])
|
||||
-> Box<MacResult+'cx> {
|
||||
-> Box<dyn MacResult+'cx> {
|
||||
let code = match (token_tree.len(), token_tree.get(0)) {
|
||||
(1, Some(&TokenTree::Token(_, token::Ident(code, _)))) => code,
|
||||
_ => unreachable!()
|
||||
@ -75,7 +75,7 @@ pub fn expand_diagnostic_used<'cx>(ecx: &'cx mut ExtCtxt,
|
||||
pub fn expand_register_diagnostic<'cx>(ecx: &'cx mut ExtCtxt,
|
||||
span: Span,
|
||||
token_tree: &[TokenTree])
|
||||
-> Box<MacResult+'cx> {
|
||||
-> Box<dyn MacResult+'cx> {
|
||||
let (code, description) = match (
|
||||
token_tree.len(),
|
||||
token_tree.get(0),
|
||||
@ -145,7 +145,7 @@ pub fn expand_register_diagnostic<'cx>(ecx: &'cx mut ExtCtxt,
|
||||
pub fn expand_build_diagnostic_array<'cx>(ecx: &'cx mut ExtCtxt,
|
||||
span: Span,
|
||||
token_tree: &[TokenTree])
|
||||
-> Box<MacResult+'cx> {
|
||||
-> Box<dyn MacResult+'cx> {
|
||||
assert_eq!(token_tree.len(), 3);
|
||||
let (crate_name, name) = match (&token_tree[0], &token_tree[2]) {
|
||||
(
|
||||
|
@ -17,7 +17,7 @@ use syntax_pos::{Span, MultiSpan, DUMMY_SP};
|
||||
use edition::Edition;
|
||||
use errors::{DiagnosticBuilder, DiagnosticId};
|
||||
use ext::expand::{self, AstFragment, Invocation};
|
||||
use ext::hygiene::{self, Mark, SyntaxContext};
|
||||
use ext::hygiene::{self, Mark, SyntaxContext, Transparency};
|
||||
use fold::{self, Folder};
|
||||
use parse::{self, parser, DirectoryOwnership};
|
||||
use parse::token;
|
||||
@ -153,18 +153,18 @@ pub trait MultiItemDecorator {
|
||||
sp: Span,
|
||||
meta_item: &ast::MetaItem,
|
||||
item: &Annotatable,
|
||||
push: &mut FnMut(Annotatable));
|
||||
push: &mut dyn FnMut(Annotatable));
|
||||
}
|
||||
|
||||
impl<F> MultiItemDecorator for F
|
||||
where F : Fn(&mut ExtCtxt, Span, &ast::MetaItem, &Annotatable, &mut FnMut(Annotatable))
|
||||
where F : Fn(&mut ExtCtxt, Span, &ast::MetaItem, &Annotatable, &mut dyn FnMut(Annotatable))
|
||||
{
|
||||
fn expand(&self,
|
||||
ecx: &mut ExtCtxt,
|
||||
sp: Span,
|
||||
meta_item: &ast::MetaItem,
|
||||
item: &Annotatable,
|
||||
push: &mut FnMut(Annotatable)) {
|
||||
push: &mut dyn FnMut(Annotatable)) {
|
||||
(*self)(ecx, sp, meta_item, item, push)
|
||||
}
|
||||
}
|
||||
@ -247,18 +247,19 @@ impl<F> AttrProcMacro for F
|
||||
/// Represents a thing that maps token trees to Macro Results
|
||||
pub trait TTMacroExpander {
|
||||
fn expand<'cx>(&self, ecx: &'cx mut ExtCtxt, span: Span, input: TokenStream)
|
||||
-> Box<MacResult+'cx>;
|
||||
-> Box<dyn MacResult+'cx>;
|
||||
}
|
||||
|
||||
pub type MacroExpanderFn =
|
||||
for<'cx> fn(&'cx mut ExtCtxt, Span, &[tokenstream::TokenTree])
|
||||
-> Box<MacResult+'cx>;
|
||||
-> Box<dyn MacResult+'cx>;
|
||||
|
||||
impl<F> TTMacroExpander for F
|
||||
where F: for<'cx> Fn(&'cx mut ExtCtxt, Span, &[tokenstream::TokenTree]) -> Box<MacResult+'cx>
|
||||
where F: for<'cx> Fn(&'cx mut ExtCtxt, Span, &[tokenstream::TokenTree])
|
||||
-> Box<dyn MacResult+'cx>
|
||||
{
|
||||
fn expand<'cx>(&self, ecx: &'cx mut ExtCtxt, span: Span, input: TokenStream)
|
||||
-> Box<MacResult+'cx> {
|
||||
-> Box<dyn MacResult+'cx> {
|
||||
struct AvoidInterpolatedIdents;
|
||||
|
||||
impl Folder for AvoidInterpolatedIdents {
|
||||
@ -289,23 +290,23 @@ pub trait IdentMacroExpander {
|
||||
sp: Span,
|
||||
ident: ast::Ident,
|
||||
token_tree: Vec<tokenstream::TokenTree>)
|
||||
-> Box<MacResult+'cx>;
|
||||
-> Box<dyn MacResult+'cx>;
|
||||
}
|
||||
|
||||
pub type IdentMacroExpanderFn =
|
||||
for<'cx> fn(&'cx mut ExtCtxt, Span, ast::Ident, Vec<tokenstream::TokenTree>)
|
||||
-> Box<MacResult+'cx>;
|
||||
-> Box<dyn MacResult+'cx>;
|
||||
|
||||
impl<F> IdentMacroExpander for F
|
||||
where F : for<'cx> Fn(&'cx mut ExtCtxt, Span, ast::Ident,
|
||||
Vec<tokenstream::TokenTree>) -> Box<MacResult+'cx>
|
||||
Vec<tokenstream::TokenTree>) -> Box<dyn MacResult+'cx>
|
||||
{
|
||||
fn expand<'cx>(&self,
|
||||
cx: &'cx mut ExtCtxt,
|
||||
sp: Span,
|
||||
ident: ast::Ident,
|
||||
token_tree: Vec<tokenstream::TokenTree>)
|
||||
-> Box<MacResult+'cx>
|
||||
-> Box<dyn MacResult+'cx>
|
||||
{
|
||||
(*self)(cx, sp, ident, token_tree)
|
||||
}
|
||||
@ -378,7 +379,7 @@ macro_rules! make_MacEager {
|
||||
|
||||
impl MacEager {
|
||||
$(
|
||||
pub fn $fld(v: $t) -> Box<MacResult> {
|
||||
pub fn $fld(v: $t) -> Box<dyn MacResult> {
|
||||
Box::new(MacEager {
|
||||
$fld: Some(v),
|
||||
..Default::default()
|
||||
@ -462,7 +463,7 @@ impl DummyResult {
|
||||
///
|
||||
/// Use this as a return value after hitting any errors and
|
||||
/// calling `span_err`.
|
||||
pub fn any(sp: Span) -> Box<MacResult+'static> {
|
||||
pub fn any(sp: Span) -> Box<dyn MacResult+'static> {
|
||||
Box::new(DummyResult { expr_only: false, span: sp })
|
||||
}
|
||||
|
||||
@ -471,7 +472,7 @@ impl DummyResult {
|
||||
/// Use this for macros that must expand to an expression, so even
|
||||
/// if an error is encountered internally, the user will receive
|
||||
/// an error that they also used it in the wrong place.
|
||||
pub fn expr(sp: Span) -> Box<MacResult+'static> {
|
||||
pub fn expr(sp: Span) -> Box<dyn MacResult+'static> {
|
||||
Box::new(DummyResult { expr_only: true, span: sp })
|
||||
}
|
||||
|
||||
@ -559,7 +560,7 @@ impl MacResult for DummyResult {
|
||||
}
|
||||
|
||||
pub type BuiltinDeriveFn =
|
||||
for<'cx> fn(&'cx mut ExtCtxt, Span, &MetaItem, &Annotatable, &mut FnMut(Annotatable));
|
||||
for<'cx> fn(&'cx mut ExtCtxt, Span, &MetaItem, &Annotatable, &mut dyn FnMut(Annotatable));
|
||||
|
||||
/// Represents different kinds of macro invocations that can be resolved.
|
||||
#[derive(Clone, Copy, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
||||
@ -590,15 +591,15 @@ pub enum SyntaxExtension {
|
||||
/// `#[derive(...)]` is a `MultiItemDecorator`.
|
||||
///
|
||||
/// Prefer ProcMacro or MultiModifier since they are more flexible.
|
||||
MultiDecorator(Box<MultiItemDecorator + sync::Sync + sync::Send>),
|
||||
MultiDecorator(Box<dyn MultiItemDecorator + sync::Sync + sync::Send>),
|
||||
|
||||
/// A syntax extension that is attached to an item and modifies it
|
||||
/// in-place. Also allows decoration, i.e., creating new items.
|
||||
MultiModifier(Box<MultiItemModifier + sync::Sync + sync::Send>),
|
||||
MultiModifier(Box<dyn MultiItemModifier + sync::Sync + sync::Send>),
|
||||
|
||||
/// A function-like procedural macro. TokenStream -> TokenStream.
|
||||
ProcMacro {
|
||||
expander: Box<ProcMacro + sync::Sync + sync::Send>,
|
||||
expander: Box<dyn ProcMacro + sync::Sync + sync::Send>,
|
||||
allow_internal_unstable: bool,
|
||||
edition: Edition,
|
||||
},
|
||||
@ -607,13 +608,13 @@ pub enum SyntaxExtension {
|
||||
/// The first TokenSteam is the attribute, the second is the annotated item.
|
||||
/// Allows modification of the input items and adding new items, similar to
|
||||
/// MultiModifier, but uses TokenStreams, rather than AST nodes.
|
||||
AttrProcMacro(Box<AttrProcMacro + sync::Sync + sync::Send>, Edition),
|
||||
AttrProcMacro(Box<dyn AttrProcMacro + sync::Sync + sync::Send>, Edition),
|
||||
|
||||
/// A normal, function-like syntax extension.
|
||||
///
|
||||
/// `bytes!` is a `NormalTT`.
|
||||
NormalTT {
|
||||
expander: Box<TTMacroExpander + sync::Sync + sync::Send>,
|
||||
expander: Box<dyn TTMacroExpander + sync::Sync + sync::Send>,
|
||||
def_info: Option<(ast::NodeId, Span)>,
|
||||
/// Whether the contents of the macro can
|
||||
/// directly use `#[unstable]` things (true == yes).
|
||||
@ -633,13 +634,13 @@ pub enum SyntaxExtension {
|
||||
/// A function-like syntax extension that has an extra ident before
|
||||
/// the block.
|
||||
///
|
||||
IdentTT(Box<IdentMacroExpander + sync::Sync + sync::Send>, Option<Span>, bool),
|
||||
IdentTT(Box<dyn IdentMacroExpander + sync::Sync + sync::Send>, Option<Span>, bool),
|
||||
|
||||
/// An attribute-like procedural macro. TokenStream -> TokenStream.
|
||||
/// The input is the annotated item.
|
||||
/// Allows generating code to implement a Trait for a given struct
|
||||
/// or enum item.
|
||||
ProcMacroDerive(Box<MultiItemModifier + sync::Sync + sync::Send>,
|
||||
ProcMacroDerive(Box<dyn MultiItemModifier + sync::Sync + sync::Send>,
|
||||
Vec<Symbol> /* inert attribute names */, Edition),
|
||||
|
||||
/// An attribute-like procedural macro that derives a builtin trait.
|
||||
@ -647,7 +648,7 @@ pub enum SyntaxExtension {
|
||||
|
||||
/// A declarative macro, e.g. `macro m() {}`.
|
||||
DeclMacro {
|
||||
expander: Box<TTMacroExpander + sync::Sync + sync::Send>,
|
||||
expander: Box<dyn TTMacroExpander + sync::Sync + sync::Send>,
|
||||
def_info: Option<(ast::NodeId, Span)>,
|
||||
is_transparent: bool,
|
||||
edition: Edition,
|
||||
@ -673,20 +674,14 @@ impl SyntaxExtension {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_modern(&self) -> bool {
|
||||
pub fn default_transparency(&self) -> Transparency {
|
||||
match *self {
|
||||
SyntaxExtension::DeclMacro { .. } |
|
||||
SyntaxExtension::ProcMacro { .. } |
|
||||
SyntaxExtension::AttrProcMacro(..) |
|
||||
SyntaxExtension::ProcMacroDerive(..) => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_transparent(&self) -> bool {
|
||||
match *self {
|
||||
SyntaxExtension::DeclMacro { is_transparent, .. } => is_transparent,
|
||||
_ => false,
|
||||
SyntaxExtension::ProcMacroDerive(..) |
|
||||
SyntaxExtension::DeclMacro { is_transparent: false, .. } => Transparency::Opaque,
|
||||
SyntaxExtension::DeclMacro { is_transparent: true, .. } => Transparency::Transparent,
|
||||
_ => Transparency::SemiTransparent,
|
||||
}
|
||||
}
|
||||
|
||||
@ -784,7 +779,7 @@ pub struct ExtCtxt<'a> {
|
||||
pub parse_sess: &'a parse::ParseSess,
|
||||
pub ecfg: expand::ExpansionConfig<'a>,
|
||||
pub root_path: PathBuf,
|
||||
pub resolver: &'a mut Resolver,
|
||||
pub resolver: &'a mut dyn Resolver,
|
||||
pub resolve_err_count: usize,
|
||||
pub current_expansion: ExpansionData,
|
||||
pub expansions: HashMap<Span, Vec<String>>,
|
||||
@ -793,7 +788,7 @@ pub struct ExtCtxt<'a> {
|
||||
impl<'a> ExtCtxt<'a> {
|
||||
pub fn new(parse_sess: &'a parse::ParseSess,
|
||||
ecfg: expand::ExpansionConfig<'a>,
|
||||
resolver: &'a mut Resolver)
|
||||
resolver: &'a mut dyn Resolver)
|
||||
-> ExtCtxt<'a> {
|
||||
ExtCtxt {
|
||||
parse_sess,
|
||||
|
@ -71,7 +71,7 @@ macro_rules! ast_fragments {
|
||||
}
|
||||
}
|
||||
|
||||
fn make_from<'a>(self, result: Box<MacResult + 'a>) -> Option<AstFragment> {
|
||||
fn make_from<'a>(self, result: Box<dyn MacResult + 'a>) -> Option<AstFragment> {
|
||||
match self {
|
||||
AstFragmentKind::OptExpr =>
|
||||
result.make_expr().map(Some).map(AstFragment::OptExpr),
|
||||
|
@ -452,7 +452,7 @@ pub fn parse_path_panic(parser: &mut Parser, mode: PathStyle) -> ast::Path {
|
||||
pub fn expand_quote_tokens<'cx>(cx: &'cx mut ExtCtxt,
|
||||
sp: Span,
|
||||
tts: &[TokenTree])
|
||||
-> Box<base::MacResult+'cx> {
|
||||
-> Box<dyn base::MacResult+'cx> {
|
||||
let (cx_expr, expr) = expand_tts(cx, sp, tts);
|
||||
let expanded = expand_wrapper(cx, sp, cx_expr, expr, &[&["syntax", "ext", "quote", "rt"]]);
|
||||
base::MacEager::expr(expanded)
|
||||
@ -461,7 +461,7 @@ pub fn expand_quote_tokens<'cx>(cx: &'cx mut ExtCtxt,
|
||||
pub fn expand_quote_expr<'cx>(cx: &'cx mut ExtCtxt,
|
||||
sp: Span,
|
||||
tts: &[TokenTree])
|
||||
-> Box<base::MacResult+'cx> {
|
||||
-> Box<dyn base::MacResult+'cx> {
|
||||
let expanded = expand_parse_call(cx, sp, "parse_expr_panic", vec![], tts);
|
||||
base::MacEager::expr(expanded)
|
||||
}
|
||||
@ -469,7 +469,7 @@ pub fn expand_quote_expr<'cx>(cx: &'cx mut ExtCtxt,
|
||||
pub fn expand_quote_item<'cx>(cx: &'cx mut ExtCtxt,
|
||||
sp: Span,
|
||||
tts: &[TokenTree])
|
||||
-> Box<base::MacResult+'cx> {
|
||||
-> Box<dyn base::MacResult+'cx> {
|
||||
let expanded = expand_parse_call(cx, sp, "parse_item_panic", vec![], tts);
|
||||
base::MacEager::expr(expanded)
|
||||
}
|
||||
@ -477,7 +477,7 @@ pub fn expand_quote_item<'cx>(cx: &'cx mut ExtCtxt,
|
||||
pub fn expand_quote_pat<'cx>(cx: &'cx mut ExtCtxt,
|
||||
sp: Span,
|
||||
tts: &[TokenTree])
|
||||
-> Box<base::MacResult+'cx> {
|
||||
-> Box<dyn base::MacResult+'cx> {
|
||||
let expanded = expand_parse_call(cx, sp, "parse_pat_panic", vec![], tts);
|
||||
base::MacEager::expr(expanded)
|
||||
}
|
||||
@ -485,7 +485,7 @@ pub fn expand_quote_pat<'cx>(cx: &'cx mut ExtCtxt,
|
||||
pub fn expand_quote_arm(cx: &mut ExtCtxt,
|
||||
sp: Span,
|
||||
tts: &[TokenTree])
|
||||
-> Box<base::MacResult+'static> {
|
||||
-> Box<dyn base::MacResult+'static> {
|
||||
let expanded = expand_parse_call(cx, sp, "parse_arm_panic", vec![], tts);
|
||||
base::MacEager::expr(expanded)
|
||||
}
|
||||
@ -493,7 +493,7 @@ pub fn expand_quote_arm(cx: &mut ExtCtxt,
|
||||
pub fn expand_quote_ty(cx: &mut ExtCtxt,
|
||||
sp: Span,
|
||||
tts: &[TokenTree])
|
||||
-> Box<base::MacResult+'static> {
|
||||
-> Box<dyn base::MacResult+'static> {
|
||||
let expanded = expand_parse_call(cx, sp, "parse_ty_panic", vec![], tts);
|
||||
base::MacEager::expr(expanded)
|
||||
}
|
||||
@ -501,7 +501,7 @@ pub fn expand_quote_ty(cx: &mut ExtCtxt,
|
||||
pub fn expand_quote_stmt(cx: &mut ExtCtxt,
|
||||
sp: Span,
|
||||
tts: &[TokenTree])
|
||||
-> Box<base::MacResult+'static> {
|
||||
-> Box<dyn base::MacResult+'static> {
|
||||
let expanded = expand_parse_call(cx, sp, "parse_stmt_panic", vec![], tts);
|
||||
base::MacEager::expr(expanded)
|
||||
}
|
||||
@ -509,7 +509,7 @@ pub fn expand_quote_stmt(cx: &mut ExtCtxt,
|
||||
pub fn expand_quote_attr(cx: &mut ExtCtxt,
|
||||
sp: Span,
|
||||
tts: &[TokenTree])
|
||||
-> Box<base::MacResult+'static> {
|
||||
-> Box<dyn base::MacResult+'static> {
|
||||
let expanded = expand_parse_call(cx, sp, "parse_attribute_panic",
|
||||
vec![cx.expr_bool(sp, true)], tts);
|
||||
|
||||
@ -519,7 +519,7 @@ pub fn expand_quote_attr(cx: &mut ExtCtxt,
|
||||
pub fn expand_quote_arg(cx: &mut ExtCtxt,
|
||||
sp: Span,
|
||||
tts: &[TokenTree])
|
||||
-> Box<base::MacResult+'static> {
|
||||
-> Box<dyn base::MacResult+'static> {
|
||||
let expanded = expand_parse_call(cx, sp, "parse_arg_panic", vec![], tts);
|
||||
base::MacEager::expr(expanded)
|
||||
}
|
||||
@ -527,7 +527,7 @@ pub fn expand_quote_arg(cx: &mut ExtCtxt,
|
||||
pub fn expand_quote_block(cx: &mut ExtCtxt,
|
||||
sp: Span,
|
||||
tts: &[TokenTree])
|
||||
-> Box<base::MacResult+'static> {
|
||||
-> Box<dyn base::MacResult+'static> {
|
||||
let expanded = expand_parse_call(cx, sp, "parse_block_panic", vec![], tts);
|
||||
base::MacEager::expr(expanded)
|
||||
}
|
||||
@ -535,7 +535,7 @@ pub fn expand_quote_block(cx: &mut ExtCtxt,
|
||||
pub fn expand_quote_meta_item(cx: &mut ExtCtxt,
|
||||
sp: Span,
|
||||
tts: &[TokenTree])
|
||||
-> Box<base::MacResult+'static> {
|
||||
-> Box<dyn base::MacResult+'static> {
|
||||
let expanded = expand_parse_call(cx, sp, "parse_meta_item_panic", vec![], tts);
|
||||
base::MacEager::expr(expanded)
|
||||
}
|
||||
@ -543,7 +543,7 @@ pub fn expand_quote_meta_item(cx: &mut ExtCtxt,
|
||||
pub fn expand_quote_path(cx: &mut ExtCtxt,
|
||||
sp: Span,
|
||||
tts: &[TokenTree])
|
||||
-> Box<base::MacResult+'static> {
|
||||
-> Box<dyn base::MacResult+'static> {
|
||||
let mode = mk_parser_path(cx, sp, &["PathStyle", "Type"]);
|
||||
let expanded = expand_parse_call(cx, sp, "parse_path_panic", vec![mode], tts);
|
||||
base::MacEager::expr(expanded)
|
||||
|
@ -32,7 +32,7 @@ use rustc_data_structures::sync::Lrc;
|
||||
|
||||
/// line!(): expands to the current line number
|
||||
pub fn expand_line(cx: &mut ExtCtxt, sp: Span, tts: &[tokenstream::TokenTree])
|
||||
-> Box<base::MacResult+'static> {
|
||||
-> Box<dyn base::MacResult+'static> {
|
||||
base::check_zero_tts(cx, sp, tts, "line!");
|
||||
|
||||
let topmost = cx.expansion_cause().unwrap_or(sp);
|
||||
@ -43,7 +43,7 @@ pub fn expand_line(cx: &mut ExtCtxt, sp: Span, tts: &[tokenstream::TokenTree])
|
||||
|
||||
/* column!(): expands to the current column number */
|
||||
pub fn expand_column(cx: &mut ExtCtxt, sp: Span, tts: &[tokenstream::TokenTree])
|
||||
-> Box<base::MacResult+'static> {
|
||||
-> Box<dyn base::MacResult+'static> {
|
||||
base::check_zero_tts(cx, sp, tts, "column!");
|
||||
|
||||
let topmost = cx.expansion_cause().unwrap_or(sp);
|
||||
@ -54,7 +54,7 @@ pub fn expand_column(cx: &mut ExtCtxt, sp: Span, tts: &[tokenstream::TokenTree])
|
||||
|
||||
/* __rust_unstable_column!(): expands to the current column number */
|
||||
pub fn expand_column_gated(cx: &mut ExtCtxt, sp: Span, tts: &[tokenstream::TokenTree])
|
||||
-> Box<base::MacResult+'static> {
|
||||
-> Box<dyn base::MacResult+'static> {
|
||||
if sp.allows_unstable() {
|
||||
expand_column(cx, sp, tts)
|
||||
} else {
|
||||
@ -66,7 +66,7 @@ pub fn expand_column_gated(cx: &mut ExtCtxt, sp: Span, tts: &[tokenstream::Token
|
||||
/// The filemap (`loc.file`) contains a bunch more information we could spit
|
||||
/// out if we wanted.
|
||||
pub fn expand_file(cx: &mut ExtCtxt, sp: Span, tts: &[tokenstream::TokenTree])
|
||||
-> Box<base::MacResult+'static> {
|
||||
-> Box<dyn base::MacResult+'static> {
|
||||
base::check_zero_tts(cx, sp, tts, "file!");
|
||||
|
||||
let topmost = cx.expansion_cause().unwrap_or(sp);
|
||||
@ -75,13 +75,13 @@ pub fn expand_file(cx: &mut ExtCtxt, sp: Span, tts: &[tokenstream::TokenTree])
|
||||
}
|
||||
|
||||
pub fn expand_stringify(cx: &mut ExtCtxt, sp: Span, tts: &[tokenstream::TokenTree])
|
||||
-> Box<base::MacResult+'static> {
|
||||
-> Box<dyn base::MacResult+'static> {
|
||||
let s = pprust::tts_to_string(tts);
|
||||
base::MacEager::expr(cx.expr_str(sp, Symbol::intern(&s)))
|
||||
}
|
||||
|
||||
pub fn expand_mod(cx: &mut ExtCtxt, sp: Span, tts: &[tokenstream::TokenTree])
|
||||
-> Box<base::MacResult+'static> {
|
||||
-> Box<dyn base::MacResult+'static> {
|
||||
base::check_zero_tts(cx, sp, tts, "module_path!");
|
||||
let mod_path = &cx.current_expansion.module.mod_path;
|
||||
let string = mod_path.iter().map(|x| x.to_string()).collect::<Vec<String>>().join("::");
|
||||
@ -93,7 +93,7 @@ pub fn expand_mod(cx: &mut ExtCtxt, sp: Span, tts: &[tokenstream::TokenTree])
|
||||
/// This is generally a bad idea because it's going to behave
|
||||
/// unhygienically.
|
||||
pub fn expand_include<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[tokenstream::TokenTree])
|
||||
-> Box<base::MacResult+'cx> {
|
||||
-> Box<dyn base::MacResult+'cx> {
|
||||
let file = match get_single_str_from_tts(cx, sp, tts, "include!") {
|
||||
Some(f) => f,
|
||||
None => return DummyResult::expr(sp),
|
||||
@ -131,7 +131,7 @@ pub fn expand_include<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[tokenstream::T
|
||||
|
||||
// include_str! : read the given file, insert it as a literal string expr
|
||||
pub fn expand_include_str(cx: &mut ExtCtxt, sp: Span, tts: &[tokenstream::TokenTree])
|
||||
-> Box<base::MacResult+'static> {
|
||||
-> Box<dyn base::MacResult+'static> {
|
||||
let file = match get_single_str_from_tts(cx, sp, tts, "include_str!") {
|
||||
Some(f) => f,
|
||||
None => return DummyResult::expr(sp)
|
||||
@ -168,7 +168,7 @@ pub fn expand_include_str(cx: &mut ExtCtxt, sp: Span, tts: &[tokenstream::TokenT
|
||||
}
|
||||
|
||||
pub fn expand_include_bytes(cx: &mut ExtCtxt, sp: Span, tts: &[tokenstream::TokenTree])
|
||||
-> Box<base::MacResult+'static> {
|
||||
-> Box<dyn base::MacResult+'static> {
|
||||
let file = match get_single_str_from_tts(cx, sp, tts, "include_bytes!") {
|
||||
Some(f) => f,
|
||||
None => return DummyResult::expr(sp)
|
||||
|
@ -73,7 +73,7 @@ impl TTMacroExpander for MacroRulesMacroExpander {
|
||||
cx: &'cx mut ExtCtxt,
|
||||
sp: Span,
|
||||
input: TokenStream)
|
||||
-> Box<MacResult+'cx> {
|
||||
-> Box<dyn MacResult+'cx> {
|
||||
if !self.valid {
|
||||
return DummyResult::any(sp);
|
||||
}
|
||||
@ -99,7 +99,7 @@ fn generic_extension<'cx>(cx: &'cx mut ExtCtxt,
|
||||
arg: TokenStream,
|
||||
lhses: &[quoted::TokenTree],
|
||||
rhses: &[quoted::TokenTree])
|
||||
-> Box<MacResult+'cx> {
|
||||
-> Box<dyn MacResult+'cx> {
|
||||
if cx.trace_macros() {
|
||||
trace_macros_note(cx, sp, format!("expanding `{}! {{ {} }}`", name, arg));
|
||||
}
|
||||
|
@ -34,9 +34,9 @@ use std::sync::{Arc, Mutex};
|
||||
use rustc_serialize::json::{as_json, as_pretty_json};
|
||||
|
||||
pub struct JsonEmitter {
|
||||
dst: Box<Write + Send>,
|
||||
dst: Box<dyn Write + Send>,
|
||||
registry: Option<Registry>,
|
||||
cm: Lrc<CodeMapper + sync::Send + sync::Sync>,
|
||||
cm: Lrc<dyn CodeMapper + sync::Send + sync::Sync>,
|
||||
pretty: bool,
|
||||
ui_testing: bool,
|
||||
}
|
||||
@ -60,7 +60,7 @@ impl JsonEmitter {
|
||||
pretty)
|
||||
}
|
||||
|
||||
pub fn new(dst: Box<Write + Send>,
|
||||
pub fn new(dst: Box<dyn Write + Send>,
|
||||
registry: Option<Registry>,
|
||||
code_map: Lrc<CodeMap>,
|
||||
pretty: bool) -> JsonEmitter {
|
||||
|
@ -14,6 +14,8 @@
|
||||
//!
|
||||
//! This API is completely unstable and subject to change.
|
||||
|
||||
#![deny(bare_trait_objects)]
|
||||
|
||||
#![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
|
||||
html_favicon_url = "https://doc.rust-lang.org/favicon.ico",
|
||||
html_root_url = "https://doc.rust-lang.org/nightly/",
|
||||
|
@ -357,7 +357,7 @@ pub struct Literal {
|
||||
|
||||
// it appears this function is called only from pprust... that's
|
||||
// probably not a good thing.
|
||||
pub fn gather_comments_and_literals(sess: &ParseSess, path: FileName, srdr: &mut Read)
|
||||
pub fn gather_comments_and_literals(sess: &ParseSess, path: FileName, srdr: &mut dyn Read)
|
||||
-> (Vec<Comment>, Vec<Literal>) {
|
||||
let mut src = Vec::new();
|
||||
srdr.read_to_end(&mut src).unwrap();
|
||||
|
@ -241,7 +241,7 @@ pub struct PrintStackElem {
|
||||
|
||||
const SIZE_INFINITY: isize = 0xffff;
|
||||
|
||||
pub fn mk_printer<'a>(out: Box<io::Write+'a>, linewidth: usize) -> Printer<'a> {
|
||||
pub fn mk_printer<'a>(out: Box<dyn io::Write+'a>, linewidth: usize) -> Printer<'a> {
|
||||
// Yes 55, it makes the ring buffers big enough to never fall behind.
|
||||
let n: usize = 55 * linewidth;
|
||||
debug!("mk_printer {}", linewidth);
|
||||
@ -264,7 +264,7 @@ pub fn mk_printer<'a>(out: Box<io::Write+'a>, linewidth: usize) -> Printer<'a> {
|
||||
}
|
||||
|
||||
pub struct Printer<'a> {
|
||||
out: Box<io::Write+'a>,
|
||||
out: Box<dyn io::Write+'a>,
|
||||
buf_max_len: usize,
|
||||
/// Width of lines we're constrained to
|
||||
margin: isize,
|
||||
|
@ -62,10 +62,10 @@ pub struct State<'a> {
|
||||
literals: Peekable<vec::IntoIter<comments::Literal>>,
|
||||
cur_cmnt: usize,
|
||||
boxes: Vec<pp::Breaks>,
|
||||
ann: &'a (PpAnn+'a),
|
||||
ann: &'a (dyn PpAnn+'a),
|
||||
}
|
||||
|
||||
fn rust_printer<'a>(writer: Box<Write+'a>, ann: &'a PpAnn) -> State<'a> {
|
||||
fn rust_printer<'a>(writer: Box<dyn Write+'a>, ann: &'a dyn PpAnn) -> State<'a> {
|
||||
State {
|
||||
s: pp::mk_printer(writer, DEFAULT_COLUMNS),
|
||||
cm: None,
|
||||
@ -88,9 +88,9 @@ pub fn print_crate<'a>(cm: &'a CodeMap,
|
||||
sess: &ParseSess,
|
||||
krate: &ast::Crate,
|
||||
filename: FileName,
|
||||
input: &mut Read,
|
||||
out: Box<Write+'a>,
|
||||
ann: &'a PpAnn,
|
||||
input: &mut dyn Read,
|
||||
out: Box<dyn Write+'a>,
|
||||
ann: &'a dyn PpAnn,
|
||||
is_expanded: bool) -> io::Result<()> {
|
||||
let mut s = State::new_from_input(cm, sess, filename, input, out, ann, is_expanded);
|
||||
|
||||
@ -121,9 +121,9 @@ impl<'a> State<'a> {
|
||||
pub fn new_from_input(cm: &'a CodeMap,
|
||||
sess: &ParseSess,
|
||||
filename: FileName,
|
||||
input: &mut Read,
|
||||
out: Box<Write+'a>,
|
||||
ann: &'a PpAnn,
|
||||
input: &mut dyn Read,
|
||||
out: Box<dyn Write+'a>,
|
||||
ann: &'a dyn PpAnn,
|
||||
is_expanded: bool) -> State<'a> {
|
||||
let (cmnts, lits) = comments::gather_comments_and_literals(sess, filename, input);
|
||||
|
||||
@ -139,8 +139,8 @@ impl<'a> State<'a> {
|
||||
}
|
||||
|
||||
pub fn new(cm: &'a CodeMap,
|
||||
out: Box<Write+'a>,
|
||||
ann: &'a PpAnn,
|
||||
out: Box<dyn Write+'a>,
|
||||
ann: &'a dyn PpAnn,
|
||||
comments: Option<Vec<comments::Comment>>,
|
||||
literals: Option<Vec<comments::Literal>>) -> State<'a> {
|
||||
State {
|
||||
|
@ -72,7 +72,7 @@ struct TestCtxt<'a> {
|
||||
// Traverse the crate, collecting all the test functions, eliding any
|
||||
// existing main functions, and synthesizing a main test harness
|
||||
pub fn modify_for_testing(sess: &ParseSess,
|
||||
resolver: &mut Resolver,
|
||||
resolver: &mut dyn Resolver,
|
||||
should_test: bool,
|
||||
krate: ast::Crate,
|
||||
span_diagnostic: &errors::Handler,
|
||||
@ -278,7 +278,7 @@ fn mk_reexport_mod(cx: &mut TestCtxt,
|
||||
}
|
||||
|
||||
fn generate_test_harness(sess: &ParseSess,
|
||||
resolver: &mut Resolver,
|
||||
resolver: &mut dyn Resolver,
|
||||
reexport_test_harness_main: Option<Symbol>,
|
||||
krate: ast::Crate,
|
||||
sd: &errors::Handler,
|
||||
|
@ -12,15 +12,16 @@ use syntax::ast;
|
||||
use syntax::ext::base;
|
||||
use syntax::ext::build::AstBuilder;
|
||||
use syntax::symbol::Symbol;
|
||||
use syntax_pos;
|
||||
use syntax::tokenstream;
|
||||
use syntax_pos;
|
||||
|
||||
use std::string::String;
|
||||
|
||||
pub fn expand_syntax_ext(cx: &mut base::ExtCtxt,
|
||||
sp: syntax_pos::Span,
|
||||
tts: &[tokenstream::TokenTree])
|
||||
-> Box<base::MacResult + 'static> {
|
||||
pub fn expand_syntax_ext(
|
||||
cx: &mut base::ExtCtxt,
|
||||
sp: syntax_pos::Span,
|
||||
tts: &[tokenstream::TokenTree],
|
||||
) -> Box<base::MacResult + 'static> {
|
||||
let es = match base::get_exprs_from_tts(cx, sp, tts) {
|
||||
Some(e) => e,
|
||||
None => return base::DummyResult::expr(sp),
|
||||
@ -28,32 +29,36 @@ pub fn expand_syntax_ext(cx: &mut base::ExtCtxt,
|
||||
let mut accumulator = String::new();
|
||||
for e in es {
|
||||
match e.node {
|
||||
ast::ExprKind::Lit(ref lit) => {
|
||||
match lit.node {
|
||||
ast::LitKind::Str(ref s, _) |
|
||||
ast::LitKind::Float(ref s, _) |
|
||||
ast::LitKind::FloatUnsuffixed(ref s) => {
|
||||
accumulator.push_str(&s.as_str());
|
||||
}
|
||||
ast::LitKind::Char(c) => {
|
||||
accumulator.push(c);
|
||||
}
|
||||
ast::LitKind::Int(i, ast::LitIntType::Unsigned(_)) |
|
||||
ast::LitKind::Int(i, ast::LitIntType::Signed(_)) |
|
||||
ast::LitKind::Int(i, ast::LitIntType::Unsuffixed) => {
|
||||
accumulator.push_str(&format!("{}", i));
|
||||
}
|
||||
ast::LitKind::Bool(b) => {
|
||||
accumulator.push_str(&format!("{}", b));
|
||||
}
|
||||
ast::LitKind::Byte(..) |
|
||||
ast::LitKind::ByteStr(..) => {
|
||||
cx.span_err(e.span, "cannot concatenate a byte string literal");
|
||||
}
|
||||
ast::ExprKind::Lit(ref lit) => match lit.node {
|
||||
ast::LitKind::Str(ref s, _)
|
||||
| ast::LitKind::Float(ref s, _)
|
||||
| ast::LitKind::FloatUnsuffixed(ref s) => {
|
||||
accumulator.push_str(&s.as_str());
|
||||
}
|
||||
}
|
||||
ast::LitKind::Char(c) => {
|
||||
accumulator.push(c);
|
||||
}
|
||||
ast::LitKind::Int(i, ast::LitIntType::Unsigned(_))
|
||||
| ast::LitKind::Int(i, ast::LitIntType::Signed(_))
|
||||
| ast::LitKind::Int(i, ast::LitIntType::Unsuffixed) => {
|
||||
accumulator.push_str(&format!("{}", i));
|
||||
}
|
||||
ast::LitKind::Bool(b) => {
|
||||
accumulator.push_str(&format!("{}", b));
|
||||
}
|
||||
ast::LitKind::Byte(..) | ast::LitKind::ByteStr(..) => {
|
||||
cx.span_err(e.span, "cannot concatenate a byte string literal");
|
||||
}
|
||||
},
|
||||
_ => {
|
||||
cx.span_err(e.span, "expected a literal");
|
||||
let mut err = cx.struct_span_err(e.span, "expected a literal");
|
||||
let snippet = cx.codemap().span_to_snippet(e.span).unwrap();
|
||||
err.span_suggestion(
|
||||
e.span,
|
||||
"you might be missing a string literal to format with",
|
||||
format!("\"{{}}\", {}", snippet),
|
||||
);
|
||||
err.emit();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -27,16 +27,17 @@ use std::fmt;
|
||||
|
||||
/// A SyntaxContext represents a chain of macro expansions (represented by marks).
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Default, PartialOrd, Ord, Hash)]
|
||||
pub struct SyntaxContext(pub(super) u32);
|
||||
pub struct SyntaxContext(u32);
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub struct SyntaxContextData {
|
||||
pub outer_mark: Mark,
|
||||
pub prev_ctxt: SyntaxContext,
|
||||
struct SyntaxContextData {
|
||||
outer_mark: Mark,
|
||||
transparency: Transparency,
|
||||
prev_ctxt: SyntaxContext,
|
||||
// This context, but with all transparent and semi-transparent marks filtered away.
|
||||
pub opaque: SyntaxContext,
|
||||
opaque: SyntaxContext,
|
||||
// This context, but with all transparent marks filtered away.
|
||||
pub opaque_and_semitransparent: SyntaxContext,
|
||||
opaque_and_semitransparent: SyntaxContext,
|
||||
}
|
||||
|
||||
/// A mark is a unique id associated with a macro expansion.
|
||||
@ -46,14 +47,14 @@ pub struct Mark(u32);
|
||||
#[derive(Clone, Debug)]
|
||||
struct MarkData {
|
||||
parent: Mark,
|
||||
transparency: Transparency,
|
||||
default_transparency: Transparency,
|
||||
is_builtin: bool,
|
||||
expn_info: Option<ExpnInfo>,
|
||||
}
|
||||
|
||||
/// A property of a macro expansion that determines how identifiers
|
||||
/// produced by that expansion are resolved.
|
||||
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Debug)]
|
||||
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Hash, Debug)]
|
||||
pub enum Transparency {
|
||||
/// Identifier produced by a transparent expansion is always resolved at call-site.
|
||||
/// Call-site spans in procedural macros, hygiene opt-out in `macro` should use this.
|
||||
@ -71,26 +72,16 @@ pub enum Transparency {
|
||||
}
|
||||
|
||||
impl Mark {
|
||||
fn fresh_with_data(mark_data: MarkData, data: &mut HygieneData) -> Self {
|
||||
data.marks.push(mark_data);
|
||||
Mark(data.marks.len() as u32 - 1)
|
||||
}
|
||||
|
||||
pub fn fresh(parent: Mark) -> Self {
|
||||
HygieneData::with(|data| {
|
||||
Mark::fresh_with_data(MarkData {
|
||||
data.marks.push(MarkData {
|
||||
parent,
|
||||
// By default expansions behave like `macro_rules`.
|
||||
transparency: Transparency::SemiTransparent,
|
||||
default_transparency: Transparency::SemiTransparent,
|
||||
is_builtin: false,
|
||||
expn_info: None,
|
||||
}, data)
|
||||
})
|
||||
}
|
||||
|
||||
pub fn fresh_cloned(clone_from: Mark) -> Self {
|
||||
HygieneData::with(|data| {
|
||||
Mark::fresh_with_data(data.marks[clone_from.0 as usize].clone(), data)
|
||||
});
|
||||
Mark(data.marks.len() as u32 - 1)
|
||||
})
|
||||
}
|
||||
|
||||
@ -127,34 +118,21 @@ impl Mark {
|
||||
})
|
||||
}
|
||||
|
||||
pub fn modern(mut self) -> Mark {
|
||||
HygieneData::with(|data| {
|
||||
while data.marks[self.0 as usize].transparency != Transparency::Opaque {
|
||||
self = data.marks[self.0 as usize].parent;
|
||||
}
|
||||
self
|
||||
})
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn transparency(self) -> Transparency {
|
||||
pub fn set_default_transparency(self, transparency: Transparency) {
|
||||
assert_ne!(self, Mark::root());
|
||||
HygieneData::with(|data| data.marks[self.0 as usize].transparency)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_transparency(self, transparency: Transparency) {
|
||||
assert_ne!(self, Mark::root());
|
||||
HygieneData::with(|data| data.marks[self.0 as usize].transparency = transparency)
|
||||
HygieneData::with(|data| data.marks[self.0 as usize].default_transparency = transparency)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_builtin(self) -> bool {
|
||||
assert_ne!(self, Mark::root());
|
||||
HygieneData::with(|data| data.marks[self.0 as usize].is_builtin)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_is_builtin(self, is_builtin: bool) {
|
||||
assert_ne!(self, Mark::root());
|
||||
HygieneData::with(|data| data.marks[self.0 as usize].is_builtin = is_builtin)
|
||||
}
|
||||
|
||||
@ -195,29 +173,48 @@ impl Mark {
|
||||
b
|
||||
})
|
||||
}
|
||||
|
||||
// Used for enabling some compatibility fallback in resolve.
|
||||
#[inline]
|
||||
pub fn looks_like_proc_macro_derive(self) -> bool {
|
||||
HygieneData::with(|data| {
|
||||
let mark_data = &data.marks[self.0 as usize];
|
||||
if mark_data.default_transparency == Transparency::Opaque {
|
||||
if let Some(expn_info) = &mark_data.expn_info {
|
||||
if let ExpnFormat::MacroAttribute(name) = expn_info.format {
|
||||
if name.as_str().starts_with("derive(") {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
false
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct HygieneData {
|
||||
crate struct HygieneData {
|
||||
marks: Vec<MarkData>,
|
||||
syntax_contexts: Vec<SyntaxContextData>,
|
||||
markings: HashMap<(SyntaxContext, Mark), SyntaxContext>,
|
||||
markings: HashMap<(SyntaxContext, Mark, Transparency), SyntaxContext>,
|
||||
default_edition: Edition,
|
||||
}
|
||||
|
||||
impl HygieneData {
|
||||
pub fn new() -> Self {
|
||||
crate fn new() -> Self {
|
||||
HygieneData {
|
||||
marks: vec![MarkData {
|
||||
parent: Mark::root(),
|
||||
// If the root is opaque, then loops searching for an opaque mark
|
||||
// will automatically stop after reaching it.
|
||||
transparency: Transparency::Opaque,
|
||||
default_transparency: Transparency::Opaque,
|
||||
is_builtin: true,
|
||||
expn_info: None,
|
||||
}],
|
||||
syntax_contexts: vec![SyntaxContextData {
|
||||
outer_mark: Mark::root(),
|
||||
transparency: Transparency::Opaque,
|
||||
prev_ctxt: SyntaxContext(0),
|
||||
opaque: SyntaxContext(0),
|
||||
opaque_and_semitransparent: SyntaxContext(0),
|
||||
@ -249,6 +246,14 @@ impl SyntaxContext {
|
||||
SyntaxContext(0)
|
||||
}
|
||||
|
||||
crate fn as_u32(self) -> u32 {
|
||||
self.0
|
||||
}
|
||||
|
||||
crate fn from_u32(raw: u32) -> SyntaxContext {
|
||||
SyntaxContext(raw)
|
||||
}
|
||||
|
||||
// Allocate a new SyntaxContext with the given ExpnInfo. This is used when
|
||||
// deserializing Spans from the incr. comp. cache.
|
||||
// FIXME(mw): This method does not restore MarkData::parent or
|
||||
@ -259,7 +264,7 @@ impl SyntaxContext {
|
||||
HygieneData::with(|data| {
|
||||
data.marks.push(MarkData {
|
||||
parent: Mark::root(),
|
||||
transparency: Transparency::SemiTransparent,
|
||||
default_transparency: Transparency::SemiTransparent,
|
||||
is_builtin: false,
|
||||
expn_info: Some(expansion_info),
|
||||
});
|
||||
@ -268,6 +273,7 @@ impl SyntaxContext {
|
||||
|
||||
data.syntax_contexts.push(SyntaxContextData {
|
||||
outer_mark: mark,
|
||||
transparency: Transparency::SemiTransparent,
|
||||
prev_ctxt: SyntaxContext::empty(),
|
||||
opaque: SyntaxContext::empty(),
|
||||
opaque_and_semitransparent: SyntaxContext::empty(),
|
||||
@ -276,22 +282,32 @@ impl SyntaxContext {
|
||||
})
|
||||
}
|
||||
|
||||
/// Extend a syntax context with a given mark
|
||||
/// Extend a syntax context with a given mark and default transparency for that mark.
|
||||
pub fn apply_mark(self, mark: Mark) -> SyntaxContext {
|
||||
if mark.transparency() == Transparency::Opaque {
|
||||
return self.apply_mark_internal(mark);
|
||||
assert_ne!(mark, Mark::root());
|
||||
self.apply_mark_with_transparency(
|
||||
mark, HygieneData::with(|data| data.marks[mark.0 as usize].default_transparency)
|
||||
)
|
||||
}
|
||||
|
||||
/// Extend a syntax context with a given mark and transparency
|
||||
pub fn apply_mark_with_transparency(self, mark: Mark, transparency: Transparency)
|
||||
-> SyntaxContext {
|
||||
assert_ne!(mark, Mark::root());
|
||||
if transparency == Transparency::Opaque {
|
||||
return self.apply_mark_internal(mark, transparency);
|
||||
}
|
||||
|
||||
let call_site_ctxt =
|
||||
mark.expn_info().map_or(SyntaxContext::empty(), |info| info.call_site.ctxt());
|
||||
let call_site_ctxt = if mark.transparency() == Transparency::SemiTransparent {
|
||||
let call_site_ctxt = if transparency == Transparency::SemiTransparent {
|
||||
call_site_ctxt.modern()
|
||||
} else {
|
||||
call_site_ctxt.modern_and_legacy()
|
||||
};
|
||||
|
||||
if call_site_ctxt == SyntaxContext::empty() {
|
||||
return self.apply_mark_internal(mark);
|
||||
return self.apply_mark_internal(mark, transparency);
|
||||
}
|
||||
|
||||
// Otherwise, `mark` is a macros 1.0 definition and the call site is in a
|
||||
@ -304,27 +320,26 @@ impl SyntaxContext {
|
||||
//
|
||||
// See the example at `test/run-pass/hygiene/legacy_interaction.rs`.
|
||||
let mut ctxt = call_site_ctxt;
|
||||
for mark in self.marks() {
|
||||
ctxt = ctxt.apply_mark_internal(mark);
|
||||
for (mark, transparency) in self.marks() {
|
||||
ctxt = ctxt.apply_mark_internal(mark, transparency);
|
||||
}
|
||||
ctxt.apply_mark_internal(mark)
|
||||
ctxt.apply_mark_internal(mark, transparency)
|
||||
}
|
||||
|
||||
fn apply_mark_internal(self, mark: Mark) -> SyntaxContext {
|
||||
fn apply_mark_internal(self, mark: Mark, transparency: Transparency) -> SyntaxContext {
|
||||
HygieneData::with(|data| {
|
||||
let syntax_contexts = &mut data.syntax_contexts;
|
||||
let transparency = data.marks[mark.0 as usize].transparency;
|
||||
|
||||
let mut opaque = syntax_contexts[self.0 as usize].opaque;
|
||||
let mut opaque_and_semitransparent =
|
||||
syntax_contexts[self.0 as usize].opaque_and_semitransparent;
|
||||
|
||||
if transparency >= Transparency::Opaque {
|
||||
let prev_ctxt = opaque;
|
||||
opaque = *data.markings.entry((prev_ctxt, mark)).or_insert_with(|| {
|
||||
opaque = *data.markings.entry((prev_ctxt, mark, transparency)).or_insert_with(|| {
|
||||
let new_opaque = SyntaxContext(syntax_contexts.len() as u32);
|
||||
syntax_contexts.push(SyntaxContextData {
|
||||
outer_mark: mark,
|
||||
transparency,
|
||||
prev_ctxt,
|
||||
opaque: new_opaque,
|
||||
opaque_and_semitransparent: new_opaque,
|
||||
@ -336,11 +351,12 @@ impl SyntaxContext {
|
||||
if transparency >= Transparency::SemiTransparent {
|
||||
let prev_ctxt = opaque_and_semitransparent;
|
||||
opaque_and_semitransparent =
|
||||
*data.markings.entry((prev_ctxt, mark)).or_insert_with(|| {
|
||||
*data.markings.entry((prev_ctxt, mark, transparency)).or_insert_with(|| {
|
||||
let new_opaque_and_semitransparent =
|
||||
SyntaxContext(syntax_contexts.len() as u32);
|
||||
syntax_contexts.push(SyntaxContextData {
|
||||
outer_mark: mark,
|
||||
transparency,
|
||||
prev_ctxt,
|
||||
opaque,
|
||||
opaque_and_semitransparent: new_opaque_and_semitransparent,
|
||||
@ -350,11 +366,12 @@ impl SyntaxContext {
|
||||
}
|
||||
|
||||
let prev_ctxt = self;
|
||||
*data.markings.entry((prev_ctxt, mark)).or_insert_with(|| {
|
||||
*data.markings.entry((prev_ctxt, mark, transparency)).or_insert_with(|| {
|
||||
let new_opaque_and_semitransparent_and_transparent =
|
||||
SyntaxContext(syntax_contexts.len() as u32);
|
||||
syntax_contexts.push(SyntaxContextData {
|
||||
outer_mark: mark,
|
||||
transparency,
|
||||
prev_ctxt,
|
||||
opaque,
|
||||
opaque_and_semitransparent,
|
||||
@ -388,12 +405,13 @@ impl SyntaxContext {
|
||||
})
|
||||
}
|
||||
|
||||
pub fn marks(mut self) -> Vec<Mark> {
|
||||
pub fn marks(mut self) -> Vec<(Mark, Transparency)> {
|
||||
HygieneData::with(|data| {
|
||||
let mut marks = Vec::new();
|
||||
while self != SyntaxContext::empty() {
|
||||
marks.push(data.syntax_contexts[self.0 as usize].outer_mark);
|
||||
self = data.syntax_contexts[self.0 as usize].prev_ctxt;
|
||||
let ctxt_data = &data.syntax_contexts[self.0 as usize];
|
||||
marks.push((ctxt_data.outer_mark, ctxt_data.transparency));
|
||||
self = ctxt_data.prev_ctxt;
|
||||
}
|
||||
marks.reverse();
|
||||
marks
|
||||
|
@ -19,10 +19,10 @@
|
||||
html_root_url = "https://doc.rust-lang.org/nightly/")]
|
||||
|
||||
#![feature(const_fn)]
|
||||
#![feature(crate_visibility_modifier)]
|
||||
#![feature(custom_attribute)]
|
||||
#![feature(non_exhaustive)]
|
||||
#![feature(optin_builtin_traits)]
|
||||
#![allow(unused_attributes)]
|
||||
#![feature(specialization)]
|
||||
#![feature(stdsimd)]
|
||||
|
||||
|
@ -100,7 +100,7 @@ const INTERNED_INDEX_OFFSET: u32 = 1;
|
||||
|
||||
#[inline]
|
||||
fn encode(sd: &SpanData) -> Span {
|
||||
let (base, len, ctxt) = (sd.lo.0, sd.hi.0 - sd.lo.0, sd.ctxt.0);
|
||||
let (base, len, ctxt) = (sd.lo.0, sd.hi.0 - sd.lo.0, sd.ctxt.as_u32());
|
||||
|
||||
let val = if (base >> INLINE_SIZES[BASE_INDEX]) == 0 &&
|
||||
(len >> INLINE_SIZES[LEN_INDEX]) == 0 &&
|
||||
@ -132,7 +132,7 @@ fn decode(span: Span) -> SpanData {
|
||||
let index = extract(INTERNED_INDEX_OFFSET, INTERNED_INDEX_SIZE);
|
||||
return with_span_interner(|interner| *interner.get(index));
|
||||
};
|
||||
SpanData { lo: BytePos(base), hi: BytePos(base + len), ctxt: SyntaxContext(ctxt) }
|
||||
SpanData { lo: BytePos(base), hi: BytePos(base + len), ctxt: SyntaxContext::from_u32(ctxt) }
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
|
@ -17,5 +17,5 @@ mod test {
|
||||
|
||||
fn main() {
|
||||
test::free();
|
||||
//~^ ERROR call to unsafe function requires unsafe function or block
|
||||
//~^ ERROR call to unsafe function is unsafe
|
||||
}
|
||||
|
@ -12,7 +12,7 @@
|
||||
|
||||
use std::intrinsics::{init};
|
||||
|
||||
// Test that the `forget` and `init` intrinsics are really unsafe
|
||||
// Test that the `init` intrinsic is really unsafe
|
||||
pub fn main() {
|
||||
let stuff = init::<isize>(); //~ ERROR call to unsafe function requires unsafe
|
||||
let stuff = init::<isize>(); //~ ERROR call to unsafe function is unsafe
|
||||
}
|
@ -27,12 +27,12 @@ fn __getit() -> std::option::Option<
|
||||
&'static std::cell::UnsafeCell<
|
||||
std::option::Option<Foo>>>
|
||||
{
|
||||
__KEY.get() //~ ERROR call to unsafe function requires unsafe
|
||||
__KEY.get() //~ ERROR call to unsafe function is unsafe
|
||||
}
|
||||
|
||||
static FOO: std::thread::LocalKey<Foo> =
|
||||
std::thread::LocalKey::new(__getit, Default::default);
|
||||
//~^ ERROR call to unsafe function requires unsafe
|
||||
//~^ ERROR call to unsafe function is unsafe
|
||||
|
||||
fn main() {
|
||||
FOO.with(|foo| println!("{}", foo.borrow()));
|
||||
|
@ -11,5 +11,5 @@
|
||||
fn main() {
|
||||
return;
|
||||
*(1 as *mut u32) = 42;
|
||||
//~^ ERROR dereference of raw pointer requires unsafe
|
||||
//~^ ERROR dereference of raw pointer is unsafe
|
||||
}
|
||||
|
@ -13,7 +13,7 @@
|
||||
fn main() {
|
||||
let _ = || {
|
||||
*(1 as *mut u32) = 42;
|
||||
//~^ ERROR dereference of raw pointer requires unsafe
|
||||
//~^ ERROR dereference of raw pointer is unsafe
|
||||
yield;
|
||||
};
|
||||
}
|
||||
|
@ -19,13 +19,13 @@ fn union_field() {
|
||||
union Union { unit: (), void: Void }
|
||||
let u = Union { unit: () };
|
||||
match u.void {}
|
||||
//~^ ERROR access to union field requires unsafe function or block
|
||||
//~^ ERROR access to union field is unsafe
|
||||
}
|
||||
|
||||
fn raw_ptr_deref() {
|
||||
let ptr = std::ptr::null::<Void>();
|
||||
match *ptr {}
|
||||
//~^ ERROR dereference of raw pointer requires unsafe function or block
|
||||
//~^ ERROR dereference of raw pointer is unsafe
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
@ -18,8 +18,8 @@ extern {
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let b = B; //~ ERROR use of mutable static requires unsafe function or block
|
||||
let rb = &B; //~ ERROR use of mutable static requires unsafe function or block
|
||||
let xb = XB; //~ ERROR use of mutable static requires unsafe function or block
|
||||
let xrb = &XB; //~ ERROR use of mutable static requires unsafe function or block
|
||||
let b = B; //~ ERROR use of mutable static is unsafe
|
||||
let rb = &B; //~ ERROR use of mutable static is unsafe
|
||||
let xb = XB; //~ ERROR use of mutable static is unsafe
|
||||
let xrb = &XB; //~ ERROR use of mutable static is unsafe
|
||||
}
|
||||
|
@ -20,12 +20,12 @@ extern {
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let a = A; //~ ERROR use of extern static requires unsafe function or block
|
||||
let a = A; //~ ERROR use of extern static is unsafe
|
||||
//~^ WARN this was previously accepted by the compiler
|
||||
let ra = &A; //~ ERROR use of extern static requires unsafe function or block
|
||||
let ra = &A; //~ ERROR use of extern static is unsafe
|
||||
//~^ WARN this was previously accepted by the compiler
|
||||
let xa = XA; //~ ERROR use of extern static requires unsafe function or block
|
||||
let xa = XA; //~ ERROR use of extern static is unsafe
|
||||
//~^ WARN this was previously accepted by the compiler
|
||||
let xra = &XA; //~ ERROR use of extern static requires unsafe function or block
|
||||
let xra = &XA; //~ ERROR use of extern static is unsafe
|
||||
//~^ WARN this was previously accepted by the compiler
|
||||
}
|
||||
|
@ -28,7 +28,7 @@ union U4<T: Copy> {
|
||||
|
||||
fn generic_noncopy<T: Default>() {
|
||||
let mut u3 = U3 { a: T::default() };
|
||||
u3.a = T::default(); //~ ERROR assignment to non-`Copy` union field requires unsafe
|
||||
u3.a = T::default(); //~ ERROR assignment to non-`Copy` union field is unsafe
|
||||
}
|
||||
|
||||
fn generic_copy<T: Copy + Default>() {
|
||||
@ -40,16 +40,16 @@ fn generic_copy<T: Copy + Default>() {
|
||||
|
||||
fn main() {
|
||||
let mut u1 = U1 { a: 10 }; // OK
|
||||
let a = u1.a; //~ ERROR access to union field requires unsafe
|
||||
let a = u1.a; //~ ERROR access to union field is unsafe
|
||||
u1.a = 11; // OK
|
||||
let U1 { a } = u1; //~ ERROR access to union field requires unsafe
|
||||
if let U1 { a: 12 } = u1 {} //~ ERROR access to union field requires unsafe
|
||||
let U1 { a } = u1; //~ ERROR access to union field is unsafe
|
||||
if let U1 { a: 12 } = u1 {} //~ ERROR access to union field is unsafe
|
||||
// let U1 { .. } = u1; // OK
|
||||
|
||||
let mut u2 = U2 { a: String::from("old") }; // OK
|
||||
u2.a = String::from("new"); //~ ERROR assignment to non-`Copy` union field requires unsafe
|
||||
u2.a = String::from("new"); //~ ERROR assignment to non-`Copy` union field is unsafe
|
||||
let mut u3 = U3 { a: 0 }; // OK
|
||||
u3.a = 1; // OK
|
||||
let mut u3 = U3 { a: String::from("old") }; // OK
|
||||
u3.a = String::from("new"); //~ ERROR assignment to non-`Copy` union field requires unsafe
|
||||
u3.a = String::from("new"); //~ ERROR assignment to non-`Copy` union field is unsafe
|
||||
}
|
||||
|
@ -11,7 +11,7 @@
|
||||
|
||||
|
||||
fn f(p: *mut u8) {
|
||||
*p = 0; //~ ERROR dereference of raw pointer requires unsafe function or block
|
||||
*p = 0; //~ ERROR dereference of raw pointer is unsafe
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -12,5 +12,5 @@
|
||||
unsafe fn f() { return; }
|
||||
|
||||
fn main() {
|
||||
f(); //~ ERROR call to unsafe function requires unsafe function or block
|
||||
f(); //~ ERROR call to unsafe function is unsafe
|
||||
}
|
||||
|
@ -10,7 +10,7 @@
|
||||
|
||||
|
||||
fn f(p: *const u8) -> u8 {
|
||||
return *p; //~ ERROR dereference of raw pointer requires unsafe function or block
|
||||
return *p; //~ ERROR dereference of raw pointer is unsafe
|
||||
}
|
||||
|
||||
fn main() {
|
||||
|
@ -13,5 +13,5 @@ unsafe fn f() { return; }
|
||||
|
||||
fn main() {
|
||||
let x = f;
|
||||
x(); //~ ERROR call to unsafe function requires unsafe function or block
|
||||
x(); //~ ERROR call to unsafe function is unsafe
|
||||
}
|
||||
|
@ -16,5 +16,5 @@ use std::intrinsics;
|
||||
// as unsafe.
|
||||
fn main() {
|
||||
intrinsics::move_val_init(1 as *mut u32, 1);
|
||||
//~^ ERROR dereference of raw pointer requires unsafe function or block
|
||||
//~^ ERROR dereference of raw pointer is unsafe
|
||||
}
|
||||
|
54
src/test/ui-fulldeps/proc-macro/auxiliary/generate-mod.rs
Normal file
54
src/test/ui-fulldeps/proc-macro/auxiliary/generate-mod.rs
Normal file
@ -0,0 +1,54 @@
|
||||
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// run-pass
|
||||
// no-prefer-dynamic
|
||||
|
||||
#![feature(proc_macro)]
|
||||
#![crate_type = "proc-macro"]
|
||||
|
||||
extern crate proc_macro;
|
||||
use proc_macro::*;
|
||||
|
||||
#[proc_macro]
|
||||
pub fn check(_: TokenStream) -> TokenStream {
|
||||
"
|
||||
type Alias = FromOutside; // OK
|
||||
struct Outer;
|
||||
mod inner {
|
||||
type Alias = FromOutside; // `FromOutside` shouldn't be available from here
|
||||
type Inner = Outer; // `Outer` shouldn't be available from here
|
||||
}
|
||||
".parse().unwrap()
|
||||
}
|
||||
|
||||
#[proc_macro_attribute]
|
||||
pub fn check_attr(_: TokenStream, _: TokenStream) -> TokenStream {
|
||||
"
|
||||
type AliasAttr = FromOutside; // OK
|
||||
struct OuterAttr;
|
||||
mod inner_attr {
|
||||
type Alias = FromOutside; // `FromOutside` shouldn't be available from here
|
||||
type Inner = OuterAttr; // `OuterAttr` shouldn't be available from here
|
||||
}
|
||||
".parse().unwrap()
|
||||
}
|
||||
|
||||
#[proc_macro_derive(CheckDerive)]
|
||||
pub fn check_derive(_: TokenStream) -> TokenStream {
|
||||
"
|
||||
type AliasDerive = FromOutside; // OK
|
||||
struct OuterDerive;
|
||||
mod inner_derive {
|
||||
type Alias = FromOutside; // `FromOutside` shouldn't be available from here
|
||||
type Inner = OuterDerive; // `OuterDerive` shouldn't be available from here
|
||||
}
|
||||
".parse().unwrap()
|
||||
}
|
34
src/test/ui-fulldeps/proc-macro/generate-mod.rs
Normal file
34
src/test/ui-fulldeps/proc-macro/generate-mod.rs
Normal file
@ -0,0 +1,34 @@
|
||||
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// Modules generated by transparent proc macros still acts as barriers for names (issue #50504).
|
||||
|
||||
// aux-build:generate-mod.rs
|
||||
|
||||
#![feature(proc_macro, proc_macro_gen, proc_macro_path_invoc)]
|
||||
|
||||
extern crate generate_mod;
|
||||
|
||||
struct FromOutside;
|
||||
|
||||
generate_mod::check!(); //~ ERROR cannot find type `FromOutside` in this scope
|
||||
//~| ERROR cannot find type `Outer` in this scope
|
||||
|
||||
#[generate_mod::check_attr] //~ ERROR cannot find type `FromOutside` in this scope
|
||||
//~| ERROR cannot find type `OuterAttr` in this scope
|
||||
struct S;
|
||||
|
||||
#[derive(generate_mod::CheckDerive)] //~ WARN cannot find type `FromOutside` in this scope
|
||||
//~| WARN cannot find type `OuterDerive` in this scope
|
||||
//~| WARN this was previously accepted
|
||||
//~| WARN this was previously accepted
|
||||
struct Z;
|
||||
|
||||
fn main() {}
|
46
src/test/ui-fulldeps/proc-macro/generate-mod.stderr
Normal file
46
src/test/ui-fulldeps/proc-macro/generate-mod.stderr
Normal file
@ -0,0 +1,46 @@
|
||||
error[E0412]: cannot find type `FromOutside` in this scope
|
||||
--> $DIR/generate-mod.rs:21:1
|
||||
|
|
||||
LL | generate_mod::check!(); //~ ERROR cannot find type `FromOutside` in this scope
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^ not found in this scope
|
||||
|
||||
error[E0412]: cannot find type `Outer` in this scope
|
||||
--> $DIR/generate-mod.rs:21:1
|
||||
|
|
||||
LL | generate_mod::check!(); //~ ERROR cannot find type `FromOutside` in this scope
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^ not found in this scope
|
||||
|
||||
error[E0412]: cannot find type `FromOutside` in this scope
|
||||
--> $DIR/generate-mod.rs:24:1
|
||||
|
|
||||
LL | #[generate_mod::check_attr] //~ ERROR cannot find type `FromOutside` in this scope
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ not found in this scope
|
||||
|
||||
error[E0412]: cannot find type `OuterAttr` in this scope
|
||||
--> $DIR/generate-mod.rs:24:1
|
||||
|
|
||||
LL | #[generate_mod::check_attr] //~ ERROR cannot find type `FromOutside` in this scope
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ not found in this scope
|
||||
|
||||
warning: cannot find type `FromOutside` in this scope
|
||||
--> $DIR/generate-mod.rs:28:10
|
||||
|
|
||||
LL | #[derive(generate_mod::CheckDerive)] //~ WARN cannot find type `FromOutside` in this scope
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^ names from parent modules are not accessible without an explicit import
|
||||
|
|
||||
= note: #[warn(proc_macro_derive_resolution_fallback)] on by default
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #50504 <https://github.com/rust-lang/rust/issues/50504>
|
||||
|
||||
warning: cannot find type `OuterDerive` in this scope
|
||||
--> $DIR/generate-mod.rs:28:10
|
||||
|
|
||||
LL | #[derive(generate_mod::CheckDerive)] //~ WARN cannot find type `FromOutside` in this scope
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^ names from parent modules are not accessible without an explicit import
|
||||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #50504 <https://github.com/rust-lang/rust/issues/50504>
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0412`.
|
@ -1,8 +1,10 @@
|
||||
error[E0133]: call to unsafe function requires unsafe function or block
|
||||
error[E0133]: call to unsafe function is unsafe and requires unsafe function or block
|
||||
--> $DIR/E0133.rs:14:5
|
||||
|
|
||||
LL | f();
|
||||
| ^^^ call to unsafe function
|
||||
|
|
||||
= note: consult the function's documentation for information on how to avoid undefined behavior
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -23,5 +23,5 @@ macro m($t:ty, $e:expr) {
|
||||
|
||||
fn main() {
|
||||
struct S;
|
||||
m!(S, S);
|
||||
m!(S, S); //~ ERROR cannot find type `S` in this scope
|
||||
}
|
9
src/test/ui/hygiene/arguments.stderr
Normal file
9
src/test/ui/hygiene/arguments.stderr
Normal file
@ -0,0 +1,9 @@
|
||||
error[E0412]: cannot find type `S` in this scope
|
||||
--> $DIR/arguments.rs:26:8
|
||||
|
|
||||
LL | m!(S, S); //~ ERROR cannot find type `S` in this scope
|
||||
| ^ not found in this scope
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0412`.
|
@ -12,13 +12,46 @@
|
||||
|
||||
#![feature(decl_macro, rustc_attrs)]
|
||||
|
||||
#[rustc_transparent_macro]
|
||||
macro genmod() {
|
||||
mod m {
|
||||
type A = S; //~ ERROR cannot find type `S` in this scope
|
||||
macro genmod($FromOutside: ident, $Outer: ident) {
|
||||
type A = $FromOutside;
|
||||
struct $Outer;
|
||||
mod inner {
|
||||
type A = $FromOutside; // `FromOutside` shouldn't be available from here
|
||||
type Inner = $Outer; // `Outer` shouldn't be available from here
|
||||
}
|
||||
}
|
||||
|
||||
struct S;
|
||||
#[rustc_transparent_macro]
|
||||
macro genmod_transparent() {
|
||||
type A = FromOutside;
|
||||
struct Outer;
|
||||
mod inner {
|
||||
type A = FromOutside; //~ ERROR cannot find type `FromOutside` in this scope
|
||||
type Inner = Outer; //~ ERROR cannot find type `Outer` in this scope
|
||||
}
|
||||
}
|
||||
|
||||
genmod!();
|
||||
macro_rules! genmod_legacy { () => {
|
||||
type A = FromOutside;
|
||||
struct Outer;
|
||||
mod inner {
|
||||
type A = FromOutside; //~ ERROR cannot find type `FromOutside` in this scope
|
||||
type Inner = Outer; //~ ERROR cannot find type `Outer` in this scope
|
||||
}
|
||||
}}
|
||||
|
||||
fn check() {
|
||||
struct FromOutside;
|
||||
genmod!(FromOutside, Outer); //~ ERROR cannot find type `FromOutside` in this scope
|
||||
//~| ERROR cannot find type `Outer` in this scope
|
||||
}
|
||||
|
||||
fn check_transparent() {
|
||||
struct FromOutside;
|
||||
genmod_transparent!();
|
||||
}
|
||||
|
||||
fn check_legacy() {
|
||||
struct FromOutside;
|
||||
genmod_legacy!();
|
||||
}
|
||||
|
@ -1,17 +1,56 @@
|
||||
error[E0412]: cannot find type `S` in this scope
|
||||
--> $DIR/generate-mod.rs:18:18
|
||||
error[E0412]: cannot find type `FromOutside` in this scope
|
||||
--> $DIR/generate-mod.rs:45:13
|
||||
|
|
||||
LL | type A = S; //~ ERROR cannot find type `S` in this scope
|
||||
| ^ did you mean `A`?
|
||||
LL | genmod!(FromOutside, Outer); //~ ERROR cannot find type `FromOutside` in this scope
|
||||
| ^^^^^^^^^^^ not found in this scope
|
||||
|
||||
error[E0412]: cannot find type `Outer` in this scope
|
||||
--> $DIR/generate-mod.rs:45:26
|
||||
|
|
||||
LL | genmod!(FromOutside, Outer); //~ ERROR cannot find type `FromOutside` in this scope
|
||||
| ^^^^^ not found in this scope
|
||||
|
||||
error[E0412]: cannot find type `FromOutside` in this scope
|
||||
--> $DIR/generate-mod.rs:29:18
|
||||
|
|
||||
LL | type A = FromOutside; //~ ERROR cannot find type `FromOutside` in this scope
|
||||
| ^^^^^^^^^^^ not found in this scope
|
||||
...
|
||||
LL | genmod!();
|
||||
| ---------- in this macro invocation
|
||||
LL | genmod_transparent!();
|
||||
| ---------------------- in this macro invocation
|
||||
|
||||
error[E0412]: cannot find type `Outer` in this scope
|
||||
--> $DIR/generate-mod.rs:30:22
|
||||
|
|
||||
LL | type Inner = Outer; //~ ERROR cannot find type `Outer` in this scope
|
||||
| ^^^^^ not found in this scope
|
||||
...
|
||||
LL | genmod_transparent!();
|
||||
| ---------------------- in this macro invocation
|
||||
|
||||
error[E0412]: cannot find type `FromOutside` in this scope
|
||||
--> $DIR/generate-mod.rs:38:18
|
||||
|
|
||||
LL | type A = FromOutside; //~ ERROR cannot find type `FromOutside` in this scope
|
||||
| ^^^^^^^^^^^ not found in this scope
|
||||
...
|
||||
LL | genmod_legacy!();
|
||||
| ----------------- in this macro invocation
|
||||
|
||||
error[E0412]: cannot find type `Outer` in this scope
|
||||
--> $DIR/generate-mod.rs:39:22
|
||||
|
|
||||
LL | type Inner = Outer; //~ ERROR cannot find type `Outer` in this scope
|
||||
| ^^^^^ not found in this scope
|
||||
...
|
||||
LL | genmod_legacy!();
|
||||
| ----------------- in this macro invocation
|
||||
|
||||
error[E0601]: `main` function not found in crate `generate_mod`
|
||||
|
|
||||
= note: consider adding a `main` function to `$DIR/generate-mod.rs`
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
error: aborting due to 7 previous errors
|
||||
|
||||
Some errors occurred: E0412, E0601.
|
||||
For more information about an error, try `rustc --explain E0412`.
|
||||
|
@ -57,12 +57,26 @@ macro n($i:ident) {
|
||||
}
|
||||
}
|
||||
}
|
||||
macro n_with_super($j:ident) {
|
||||
mod test {
|
||||
use super::*;
|
||||
fn g() {
|
||||
let _: u32 = $i();
|
||||
let _: () = f();
|
||||
super::$j();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
n!(f);
|
||||
n!(f); //~ ERROR cannot find function `f` in this scope
|
||||
n_with_super!(f);
|
||||
mod test2 {
|
||||
super::n! {
|
||||
f //~ ERROR cannot find function `f` in this scope
|
||||
}
|
||||
super::n_with_super! {
|
||||
f
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -30,13 +30,23 @@ LL | use bar::g;
|
||||
|
|
||||
LL | use foo::test2::test::g;
|
||||
|
|
||||
LL | use foo::test::g;
|
||||
LL | use foo::test2::test::g;
|
||||
|
|
||||
LL | use foo::test::g;
|
||||
|
|
||||
and 2 other candidates
|
||||
|
||||
error[E0425]: cannot find function `f` in this scope
|
||||
--> $DIR/globs.rs:64:17
|
||||
--> $DIR/globs.rs:71:12
|
||||
|
|
||||
LL | n!(f);
|
||||
| ------ in this macro invocation
|
||||
...
|
||||
LL | n!(f); //~ ERROR cannot find function `f` in this scope
|
||||
| ^ not found in this scope
|
||||
|
||||
error[E0425]: cannot find function `f` in this scope
|
||||
--> $DIR/globs.rs:75:17
|
||||
|
|
||||
LL | n!(f);
|
||||
| ------ in this macro invocation
|
||||
@ -44,6 +54,6 @@ LL | n!(f);
|
||||
LL | f //~ ERROR cannot find function `f` in this scope
|
||||
| ^ not found in this scope
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0425`.
|
||||
|
@ -33,9 +33,9 @@ fn main() {
|
||||
let _ = &good.data2[0]; // ok
|
||||
}
|
||||
|
||||
let _ = &good.data; //~ ERROR borrow of packed field requires unsafe
|
||||
let _ = &good.data; //~ ERROR borrow of packed field is unsafe
|
||||
//~| hard error
|
||||
let _ = &good.data2[0]; //~ ERROR borrow of packed field requires unsafe
|
||||
let _ = &good.data2[0]; //~ ERROR borrow of packed field is unsafe
|
||||
//~| hard error
|
||||
let _ = &*good.data; // ok, behind a pointer
|
||||
let _ = &good.aligned; // ok, has align 1
|
27
src/test/ui/issue-27060.stderr
Normal file
27
src/test/ui/issue-27060.stderr
Normal file
@ -0,0 +1,27 @@
|
||||
error: borrow of packed field is unsafe and requires unsafe function or block (error E0133)
|
||||
--> $DIR/issue-27060.rs:36:13
|
||||
|
|
||||
LL | let _ = &good.data; //~ ERROR borrow of packed field is unsafe
|
||||
| ^^^^^^^^^^
|
||||
|
|
||||
note: lint level defined here
|
||||
--> $DIR/issue-27060.rs:23:8
|
||||
|
|
||||
LL | #[deny(safe_packed_borrows)]
|
||||
| ^^^^^^^^^^^^^^^^^^^
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #46043 <https://github.com/rust-lang/rust/issues/46043>
|
||||
= note: fields of packed structs might be misaligned: dereferencing a misaligned pointer or even just creating a misaligned reference is undefined behavior
|
||||
|
||||
error: borrow of packed field is unsafe and requires unsafe function or block (error E0133)
|
||||
--> $DIR/issue-27060.rs:38:13
|
||||
|
|
||||
LL | let _ = &good.data2[0]; //~ ERROR borrow of packed field is unsafe
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #46043 <https://github.com/rust-lang/rust/issues/46043>
|
||||
= note: fields of packed structs might be misaligned: dereferencing a misaligned pointer or even just creating a misaligned reference is undefined behavior
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
@ -1,8 +1,10 @@
|
||||
error[E0133]: call to unsafe function requires unsafe function or block
|
||||
error[E0133]: call to unsafe function is unsafe and requires unsafe function or block
|
||||
--> $DIR/issue-28776.rs:14:5
|
||||
|
|
||||
LL | (&ptr::write)(1 as *mut _, 42);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ call to unsafe function
|
||||
|
|
||||
= note: consult the function's documentation for information on how to avoid undefined behavior
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -3,6 +3,10 @@ error: expected a literal
|
||||
|
|
||||
LL | println!(3 + 4); //~ ERROR expected a literal
|
||||
| ^^^^^
|
||||
help: you might be missing a string literal to format with
|
||||
|
|
||||
LL | println!("{}", 3 + 4); //~ ERROR expected a literal
|
||||
| ^^^^^^^^^^^
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -1,8 +1,10 @@
|
||||
error[E0133]: dereference of raw pointer requires unsafe function or block
|
||||
error[E0133]: dereference of raw pointer is unsafe and requires unsafe function or block
|
||||
--> $DIR/trait-safety-fn-body.rs:21:9
|
||||
|
|
||||
LL | *self += 1;
|
||||
| ^^^^^^^^^^ dereference of raw pointer
|
||||
|
|
||||
= note: raw pointers may be NULL, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -1,8 +1,10 @@
|
||||
error[E0133]: call to unsafe function requires unsafe function or block
|
||||
error[E0133]: call to unsafe function is unsafe and requires unsafe function or block
|
||||
--> $DIR/unsafe-const-fn.rs:19:18
|
||||
|
|
||||
LL | const VAL: u32 = dummy(0xFFFF);
|
||||
| ^^^^^^^^^^^^^ call to unsafe function
|
||||
|
|
||||
= note: consult the function's documentation for information on how to avoid undefined behavior
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user