}
}
-impl Box<Any> {
+impl Box<dyn Any> {
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
/// Attempt to downcast the box to a concrete type.
/// 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 {
}
}
-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.
/// 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))
})
}
}
#[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 {
#[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 {
#[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) => {
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());
#[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");
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);
}
}
- 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());
}
}
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
}
}
-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.
/// 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);
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) };
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");
}
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), "()");
}
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());
}
}
-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
///
/// 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);
/// }
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) };
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");
}
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), "()");
}
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());
/// 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`.
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 {
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());
#[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(),
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 _);
//! 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",
#[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()))
}
//! 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
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
[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 _,
#[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,
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;
}
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()
}
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};
// 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()
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> {
// 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>,
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
/// 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>,
/// 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`.
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(),
}
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
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 {
});
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>>
//!
//! 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/")]
"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)]
DUPLICATE_MACRO_EXPORTS,
INTRA_DOC_LINK_RESOLUTION_FAILURE,
WHERE_CLAUSES_OBJECT_SAFETY,
+ PROC_MACRO_DERIVE_RESOLUTION_FALLBACK,
)
}
}
BareTraitObject(Span, /* is_global */ bool),
AbsPathWithModule(Span),
DuplicatedMacroExports(ast::Ident, Span, Span),
+ ProcMacroDeriveResolutionFallback(Span),
}
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");
+ }
}
}
}
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>) {
pub struct UnsafetyViolation {
pub source_info: SourceInfo,
pub description: InternedString,
+ pub details: InternedString,
pub kind: UnsafetyViolationKind,
}
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) {
pub fn modify(
sess: &ParseSess,
- resolver: &mut Resolver,
+ resolver: &mut dyn Resolver,
krate: Crate,
crate_name: String,
handler: &rustc_errors::Handler,
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
&self,
ty: &AllocatorTy,
args: &mut Vec<Arg>,
- ident: &mut FnMut() -> Ident,
+ ident: &mut dyn FnMut() -> Ident,
) -> P<Expr> {
match *ty {
AllocatorTy::Layout => {
// 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;
},
Archive {
archive: ArchiveRO,
- skip: Box<FnMut(&str) -> bool>,
+ skip: Box<dyn FnMut(&str) -> bool>,
},
}
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)
}
}
-fn link_args(cmd: &mut Linker,
+fn link_args(cmd: &mut dyn Linker,
sess: &Session,
crate_type: config::CrateType,
tmpdir: &Path,
// 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| {
// 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,
// 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,
// (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,
}
// 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));
// 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) {
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 => {
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 {
info: self,
hinted_static: false,
is_ld: false,
- }) as Box<Linker>
+ }) as Box<dyn Linker>
}
LinkerFlavor::Lld(LldFlavor::Ld) |
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>
}
}
}
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> {
// 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);
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,
// 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>,
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;
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>,
// 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,
}
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
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, ()>>,
}
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);
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(),
//
// 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;
#![feature(custom_attribute)]
#![feature(fs_read_write)]
#![allow(unused_attributes)]
+#![deny(bare_trait_objects)]
#![feature(libc)]
#![feature(quote)]
#![feature(range_contains)]
impl !Sync for LlvmCodegenBackend {}
impl LlvmCodegenBackend {
- pub fn new() -> Box<CodegenBackend> {
+ pub fn new() -> Box<dyn CodegenBackend> {
box LlvmCodegenBackend(())
}
}
target_features(sess)
}
- fn metadata_loader(&self) -> Box<MetadataLoader + Sync> {
+ fn metadata_loader(&self) -> Box<dyn MetadataLoader + Sync> {
box metadata::LlvmMetadataLoader
}
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,
/// 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()
}
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,
}
impl MetadataOnlyCodegenBackend {
- pub fn new() -> Box<CodegenBackend> {
+ pub fn new() -> Box<dyn CodegenBackend> {
box MetadataOnlyCodegenBackend(())
}
}
}
}
- fn metadata_loader(&self) -> Box<MetadataLoader + Sync> {
+ fn metadata_loader(&self) -> Box<dyn MetadataLoader + Sync> {
box NoLlvmMetadataLoader
}
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);
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;
#![feature(box_syntax)]
#![feature(custom_attribute)]
#![allow(unused_attributes)]
+#![deny(bare_trait_objects)]
#![feature(quote)]
#![feature(rustc_diagnostic_macros)]
//!
//! 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/")]
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>",)
}
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 {
}
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 {
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();
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]
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();
}
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();
}
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]
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]
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();
}
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();
}
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();
}
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();
}
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;
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
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
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 {
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.
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
}
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
}
}
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
// 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/")]
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 {
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);
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()));
// 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") {
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")
}
}
}
}
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);
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)
}], &[]);
}
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() {
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")
}
}
}
}
&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 =
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)
}], &[]);
}
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,
}], &[]);
}
} = 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()[..]);
}
}
}
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};
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(
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) => {}
}
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()));
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
- };
+ 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);
+ }
+
+ // 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);
+ }
+ }
}
- module = parent;
- module_expansion = parent_expansion;
}
- None
+ (None, false)
}
fn resolve_ident_in_module(&mut self,
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 {
}
}
// 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;
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 {
(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()) {
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));
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};
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))
}
// 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 {
///
/// [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
/// 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
// 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);
}
}
-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.
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,
}
- 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 {
/// 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);
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!()
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),
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]) {
(
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;
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)
}
}
/// 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 {
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)
}
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()
///
/// 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 })
}
/// 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 })
}
}
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)]
/// `#[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,
},
/// 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).
/// 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.
/// 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,
}
}
- 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,
}
}
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>>,
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,
}
}
- 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),
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)
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)
}
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)
}
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)
}
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)
}
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)
}
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)
}
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);
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)
}
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)
}
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)
}
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)
/// 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);
/* 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);
/* __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 {
/// 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);
}
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("::");
/// 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),
// 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)
}
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)
cx: &'cx mut ExtCtxt,
sp: Span,
input: TokenStream)
- -> Box<MacResult+'cx> {
+ -> Box<dyn MacResult+'cx> {
if !self.valid {
return DummyResult::any(sp);
}
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));
}
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,
}
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 {
//!
//! 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/",
// 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();
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);
}
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,
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,
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);
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);
}
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 {
// 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,
}
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,
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),
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();
}
}
}
/// 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.
#[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.
}
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)
})
}
})
}
- 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 {
- assert_ne!(self, Mark::root());
- HygieneData::with(|data| data.marks[self.0 as usize].transparency)
- }
-
#[inline]
- pub fn set_transparency(self, transparency: Transparency) {
+ pub fn set_default_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)
}
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),
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
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),
});
data.syntax_contexts.push(SyntaxContextData {
outer_mark: mark,
+ transparency: Transparency::SemiTransparent,
prev_ctxt: SyntaxContext::empty(),
opaque: SyntaxContext::empty(),
opaque_and_semitransparent: SyntaxContext::empty(),
})
}
- /// 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
//
// 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,
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,
}
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,
})
}
- 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
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)]
#[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 &&
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)]
fn main() {
test::free();
- //~^ ERROR call to unsafe function requires unsafe function or block
+ //~^ ERROR call to unsafe function is unsafe
}
+++ /dev/null
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <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.
-
-#![feature(core_intrinsics)]
-
-use std::intrinsics::{init};
-
-// Test that the `forget` and `init` intrinsics are really unsafe
-pub fn main() {
- let stuff = init::<isize>(); //~ ERROR call to unsafe function requires unsafe
-}
--- /dev/null
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <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.
+
+#![feature(core_intrinsics)]
+
+use std::intrinsics::{init};
+
+// Test that the `init` intrinsic is really unsafe
+pub fn main() {
+ let stuff = init::<isize>(); //~ ERROR call to unsafe function is unsafe
+}
+++ /dev/null
-// Copyright 2017 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.
-
-#[repr(packed)]
-pub struct Good {
- data: &'static u32,
- data2: [&'static u32; 2],
- aligned: [u8; 32],
-}
-
-#[repr(packed)]
-pub struct JustArray {
- array: [u32]
-}
-
-#[deny(safe_packed_borrows)]
-fn main() {
- let good = Good {
- data: &0,
- data2: [&0, &0],
- aligned: [0; 32]
- };
-
- unsafe {
- let _ = &good.data; // ok
- let _ = &good.data2[0]; // ok
- }
-
- let _ = &good.data; //~ ERROR borrow of packed field requires unsafe
- //~| hard error
- let _ = &good.data2[0]; //~ ERROR borrow of packed field requires unsafe
- //~| hard error
- let _ = &*good.data; // ok, behind a pointer
- let _ = &good.aligned; // ok, has align 1
- let _ = &good.aligned[2]; // ok, has align 1
-}
&'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()));
fn main() {
return;
*(1 as *mut u32) = 42;
- //~^ ERROR dereference of raw pointer requires unsafe
+ //~^ ERROR dereference of raw pointer is unsafe
}
fn main() {
let _ = || {
*(1 as *mut u32) = 42;
- //~^ ERROR dereference of raw pointer requires unsafe
+ //~^ ERROR dereference of raw pointer is unsafe
yield;
};
}
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() {}
}
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
}
}
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
}
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>() {
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
}
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;
}
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
}
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() {
fn main() {
let x = f;
- x(); //~ ERROR call to unsafe function requires unsafe function or block
+ x(); //~ ERROR call to unsafe function is unsafe
}
// 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
}
+++ /dev/null
-// Copyright 2017 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.
-
-// ignore-pretty pretty-printing is unhygienic
-
-#![feature(decl_macro)]
-
-macro m($t:ty, $e:expr) {
- mod foo {
- #[allow(unused)]
- struct S;
- pub(super) fn f(_: $t) {}
- }
- foo::f($e);
-}
-
-fn main() {
- struct S;
- m!(S, S);
-}
--- /dev/null
+// 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()
+}
--- /dev/null
+// 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() {}
--- /dev/null
+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`.
-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
--- /dev/null
+// Copyright 2017 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.
+
+// ignore-pretty pretty-printing is unhygienic
+
+#![feature(decl_macro)]
+
+macro m($t:ty, $e:expr) {
+ mod foo {
+ #[allow(unused)]
+ struct S;
+ pub(super) fn f(_: $t) {}
+ }
+ foo::f($e);
+}
+
+fn main() {
+ struct S;
+ m!(S, S); //~ ERROR cannot find type `S` in this scope
+}
--- /dev/null
+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`.
#![feature(decl_macro, rustc_attrs)]
+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
+ }
+}
+
#[rustc_transparent_macro]
-macro genmod() {
- mod m {
- type A = S; //~ ERROR cannot find type `S` in this scope
+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
}
}
-struct S;
+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
+ }
+}}
-genmod!();
+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!();
+}
-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_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!();
- | ---------- in this macro invocation
+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`.
}
}
}
+ 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
+ }
}
}
}
|
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: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:64:17
+ --> $DIR/globs.rs:75:17
|
LL | n!(f);
| ------ in this macro invocation
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`.
--- /dev/null
+// Copyright 2017 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.
+
+#[repr(packed)]
+pub struct Good {
+ data: &'static u32,
+ data2: [&'static u32; 2],
+ aligned: [u8; 32],
+}
+
+#[repr(packed)]
+pub struct JustArray {
+ array: [u32]
+}
+
+#[deny(safe_packed_borrows)]
+fn main() {
+ let good = Good {
+ data: &0,
+ data2: [&0, &0],
+ aligned: [0; 32]
+ };
+
+ unsafe {
+ let _ = &good.data; // ok
+ let _ = &good.data2[0]; // ok
+ }
+
+ let _ = &good.data; //~ ERROR borrow of packed field is unsafe
+ //~| hard error
+ 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
+ let _ = &good.aligned[2]; // ok, has align 1
+}
--- /dev/null
+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
+
-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
|
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
-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
-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