diff --git a/src/libcore/future.rs b/src/libcore/future.rs index a8c8f69411ea6..153cd6c0724d6 100644 --- a/src/libcore/future.rs +++ b/src/libcore/future.rs @@ -45,18 +45,18 @@ pub trait Future { /// /// This function returns: /// - /// - `Poll::Pending` if the future is not ready yet - /// - `Poll::Ready(val)` with the result `val` of this future if it finished - /// successfully. + /// - [`Poll::Pending`] if the future is not ready yet + /// - [`Poll::Ready(val)`] with the result `val` of this future if it + /// finished successfully. /// /// Once a future has finished, clients should not `poll` it again. /// /// When a future is not ready yet, `poll` returns - /// [`Poll::Pending`](::task::Poll). The future will *also* register the + /// `Poll::Pending`. The future will *also* register the /// interest of the current task in the value being produced. For example, /// if the future represents the availability of data on a socket, then the /// task is recorded so that when data arrives, it is woken up (via - /// [`cx.waker()`](::task::Context::waker)). Once a task has been woken up, + /// [`cx.waker()`]). Once a task has been woken up, /// it should attempt to `poll` the future again, which may or may not /// produce a final value. /// @@ -90,6 +90,10 @@ pub trait Future { /// then any future calls to `poll` may panic, block forever, or otherwise /// cause bad behavior. The `Future` trait itself provides no guarantees /// about the behavior of `poll` after a future has completed. + /// + /// [`Poll::Pending`]: ../task/enum.Poll.html#variant.Pending + /// [`Poll::Ready(val)`]: ../task/enum.Poll.html#variant.Ready + /// [`cx.waker()`]: ../task/struct.Context.html#method.waker fn poll(self: PinMut, cx: &mut task::Context) -> Poll; } diff --git a/src/liblibc b/src/liblibc index a7e78a78e17c8..7cac8d0c9db3e 160000 --- a/src/liblibc +++ b/src/liblibc @@ -1 +1 @@ -Subproject commit a7e78a78e17c8776d7780008ccb3ce541ec64ae9 +Subproject commit 7cac8d0c9db3eff1d8c0d0e21f4a27bedb3c0ad5 diff --git a/src/libproc_macro/diagnostic.rs b/src/libproc_macro/diagnostic.rs index c39aec896e6b4..a82e3dcb0600c 100644 --- a/src/libproc_macro/diagnostic.rs +++ b/src/libproc_macro/diagnostic.rs @@ -97,7 +97,7 @@ impl Diagnostic { /// Emit the diagnostic. #[unstable(feature = "proc_macro", issue = "38356")] pub fn emit(self) { - ::__internal::with_sess(move |(sess, _)| { + ::__internal::with_sess(move |sess, _| { let handler = &sess.span_diagnostic; let level = __internal::level_to_internal_level(self.level); let mut diag = rustc::DiagnosticBuilder::new(handler, level, &*self.message); diff --git a/src/libproc_macro/lib.rs b/src/libproc_macro/lib.rs index befc1ba064aa2..fb5cbf473a387 100644 --- a/src/libproc_macro/lib.rs +++ b/src/libproc_macro/lib.rs @@ -58,8 +58,7 @@ use syntax::parse::{self, token}; use syntax::symbol::{keywords, Symbol}; use syntax::tokenstream; use syntax::parse::lexer::{self, comments}; -use syntax_pos::{FileMap, Pos, SyntaxContext, FileName}; -use syntax_pos::hygiene::Mark; +use syntax_pos::{FileMap, Pos, FileName}; /// The main type provided by this crate, representing an abstract stream of /// tokens, or, more specifically, a sequence of token trees. @@ -109,6 +108,7 @@ impl TokenStream { /// Attempts to break the string into tokens and parse those tokens into a token stream. /// May fail for a number of reasons, for example, if the string contains unbalanced delimiters /// or characters not existing in the language. +/// All tokens in the parsed stream get `Span::call_site()` spans. /// /// NOTE: Some errors may cause panics instead of returning `LexError`. We reserve the right to /// change these errors into `LexError`s later. @@ -117,17 +117,10 @@ impl FromStr for TokenStream { type Err = LexError; fn from_str(src: &str) -> Result { - __internal::with_sess(|(sess, mark)| { - let src = src.to_string(); - let name = FileName::ProcMacroSourceCode; - let expn_info = mark.expn_info().unwrap(); - let call_site = expn_info.call_site; - // notify the expansion info that it is unhygienic - let mark = Mark::fresh(mark); - mark.set_expn_info(expn_info); - let span = call_site.with_ctxt(SyntaxContext::empty().apply_mark(mark)); - let stream = parse::parse_stream_from_source_str(name, src, sess, Some(span)); - Ok(__internal::token_stream_wrap(stream)) + __internal::with_sess(|sess, data| { + Ok(__internal::token_stream_wrap(parse::parse_stream_from_source_str( + FileName::ProcMacroSourceCode, src.to_string(), sess, Some(data.call_site.0) + ))) }) } } @@ -184,8 +177,6 @@ impl iter::FromIterator for TokenStream { #[unstable(feature = "proc_macro", issue = "38356")] pub mod token_stream { use syntax::tokenstream; - use syntax_pos::DUMMY_SP; - use {TokenTree, TokenStream, Delimiter}; /// An iterator over `TokenStream`'s `TokenTree`s. @@ -214,7 +205,7 @@ pub mod token_stream { // need to flattened during iteration over stream's token trees. // Eventually this needs to be removed in favor of keeping original token trees // and not doing the roundtrip through AST. - if tree.span().0 == DUMMY_SP { + if tree.span().0.is_dummy() { if let TokenTree::Group(ref group) = tree { if group.delimiter() == Delimiter::None { self.cursor.insert(group.stream.clone().0); @@ -284,10 +275,7 @@ impl Span { /// A span that resolves at the macro definition site. #[unstable(feature = "proc_macro", issue = "38356")] pub fn def_site() -> Span { - ::__internal::with_sess(|(_, mark)| { - let call_site = mark.expn_info().unwrap().call_site; - Span(call_site.with_ctxt(SyntaxContext::empty().apply_mark(mark))) - }) + ::__internal::with_sess(|_, data| data.def_site) } /// The span of the invocation of the current procedural macro. @@ -296,7 +284,7 @@ impl Span { /// at the macro call site will be able to refer to them as well. #[unstable(feature = "proc_macro", issue = "38356")] pub fn call_site() -> Span { - ::__internal::with_sess(|(_, mark)| Span(mark.expn_info().unwrap().call_site)) + ::__internal::with_sess(|_, data| data.call_site) } /// The original source file into which this span points. @@ -1243,7 +1231,7 @@ impl TokenTree { } Interpolated(_) => { - __internal::with_sess(|(sess, _)| { + __internal::with_sess(|sess, _| { let tts = token.interpolated_to_tokenstream(sess, span); tt!(Group::new(Delimiter::None, TokenStream(tts))) }) @@ -1354,20 +1342,21 @@ pub mod __internal { pub use quote::{LiteralKind, SpannedSymbol, Quoter, unquote}; use std::cell::Cell; + use std::ptr; use syntax::ast; use syntax::ext::base::ExtCtxt; - use syntax::ext::hygiene::Mark; use syntax::ptr::P; use syntax::parse::{self, ParseSess}; use syntax::parse::token::{self, Token}; use syntax::tokenstream; use syntax_pos::{BytePos, Loc, DUMMY_SP}; + use syntax_pos::hygiene::{Mark, SyntaxContext, Transparency}; - use super::{TokenStream, LexError}; + use super::{TokenStream, LexError, Span}; pub fn lookup_char_pos(pos: BytePos) -> Loc { - with_sess(|(sess, _)| sess.codemap().lookup_char_pos(pos)) + with_sess(|sess, _| sess.codemap().lookup_char_pos(pos)) } pub fn new_token_stream(item: P) -> TokenStream { @@ -1380,7 +1369,7 @@ pub mod __internal { } pub fn token_stream_parse_items(stream: TokenStream) -> Result>, LexError> { - with_sess(move |(sess, _)| { + with_sess(move |sess, _| { let mut parser = parse::stream_to_parser(sess, stream.0); let mut items = Vec::new(); @@ -1411,16 +1400,30 @@ pub mod __internal { expand: fn(TokenStream) -> TokenStream); } + #[derive(Clone, Copy)] + pub struct ProcMacroData { + pub def_site: Span, + pub call_site: Span, + } + + #[derive(Clone, Copy)] + struct ProcMacroSess { + parse_sess: *const ParseSess, + data: ProcMacroData, + } + // Emulate scoped_thread_local!() here essentially thread_local! { - static CURRENT_SESS: Cell<(*const ParseSess, Mark)> = - Cell::new((0 as *const _, Mark::root())); + static CURRENT_SESS: Cell = Cell::new(ProcMacroSess { + parse_sess: ptr::null(), + data: ProcMacroData { def_site: Span(DUMMY_SP), call_site: Span(DUMMY_SP) }, + }); } pub fn set_sess(cx: &ExtCtxt, f: F) -> R where F: FnOnce() -> R { - struct Reset { prev: (*const ParseSess, Mark) } + struct Reset { prev: ProcMacroSess } impl Drop for Reset { fn drop(&mut self) { @@ -1430,24 +1433,42 @@ pub mod __internal { CURRENT_SESS.with(|p| { let _reset = Reset { prev: p.get() }; - p.set((cx.parse_sess, cx.current_expansion.mark)); + + // 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))); + p.set(ProcMacroSess { + parse_sess: cx.parse_sess, + data: ProcMacroData { + def_site: to_span(opaque_mark), + call_site: to_span(transparent_mark), + }, + }); f() }) } pub fn in_sess() -> bool { - let p = CURRENT_SESS.with(|p| p.get()); - !p.0.is_null() + !CURRENT_SESS.with(|sess| sess.get()).parse_sess.is_null() } pub fn with_sess(f: F) -> R - where F: FnOnce((&ParseSess, Mark)) -> R + where F: FnOnce(&ParseSess, &ProcMacroData) -> R { - let p = CURRENT_SESS.with(|p| p.get()); - assert!(!p.0.is_null(), "proc_macro::__internal::with_sess() called \ - before set_parse_sess()!"); - f(unsafe { (&*p.0, p.1) }) + let sess = CURRENT_SESS.with(|sess| sess.get()); + if sess.parse_sess.is_null() { + panic!("procedural macro API is used outside of a procedural macro"); + } + f(unsafe { &*sess.parse_sess }, &sess.data) } } diff --git a/src/librustc/hir/map/definitions.rs b/src/librustc/hir/map/definitions.rs index b2365e22cc66f..e262c951e391d 100644 --- a/src/librustc/hir/map/definitions.rs +++ b/src/librustc/hir/map/definitions.rs @@ -486,12 +486,7 @@ impl Definitions { #[inline] pub fn opt_span(&self, def_id: DefId) -> Option { if def_id.krate == LOCAL_CRATE { - let span = self.def_index_to_span.get(&def_id.index).cloned().unwrap_or(DUMMY_SP); - if span != DUMMY_SP { - Some(span) - } else { - None - } + self.def_index_to_span.get(&def_id.index).cloned() } else { None } @@ -588,8 +583,8 @@ impl Definitions { self.opaque_expansions_that_defined.insert(index, expansion); } - // The span is added if it isn't DUMMY_SP - if span != DUMMY_SP { + // The span is added if it isn't dummy + if !span.is_dummy() { self.def_index_to_span.insert(index, span); } diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs index b7071970a04b9..dbf99cf30e56b 100644 --- a/src/librustc/hir/map/mod.rs +++ b/src/librustc/hir/map/mod.rs @@ -25,7 +25,7 @@ use rustc_target::spec::abi::Abi; use syntax::ast::{self, Name, NodeId, CRATE_NODE_ID}; use syntax::codemap::Spanned; use syntax::ext::base::MacroKind; -use syntax_pos::Span; +use syntax_pos::{Span, DUMMY_SP}; use hir::*; use hir::print::Nested; @@ -664,6 +664,33 @@ impl<'hir> Map<'hir> { self.as_local_node_id(id).map(|id| self.get(id)) // read recorded by `get` } + pub fn get_generics(&self, id: DefId) -> Option<&'hir Generics> { + self.get_if_local(id).and_then(|node| { + match node { + NodeImplItem(ref impl_item) => Some(&impl_item.generics), + NodeTraitItem(ref trait_item) => Some(&trait_item.generics), + NodeItem(ref item) => { + match item.node { + ItemFn(_, _, ref generics, _) | + ItemTy(_, ref generics) | + ItemEnum(_, ref generics) | + ItemStruct(_, ref generics) | + ItemUnion(_, ref generics) | + ItemTrait(_, _, ref generics, ..) | + ItemTraitAlias(ref generics, _) | + ItemImpl(_, _, _, ref generics, ..) => Some(generics), + _ => None, + } + } + _ => None, + } + }) + } + + pub fn get_generics_span(&self, id: DefId) -> Option { + self.get_generics(id).map(|generics| generics.span).filter(|sp| *sp != DUMMY_SP) + } + /// Retrieve the Node corresponding to `id`, returning None if /// cannot be found. pub fn find(&self, id: NodeId) -> Option> { diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs index 5416474721045..d8bf5fe9b6ddf 100644 --- a/src/librustc/hir/mod.rs +++ b/src/librustc/hir/mod.rs @@ -31,7 +31,7 @@ use hir::def_id::{DefId, DefIndex, LocalDefId, CRATE_DEF_INDEX}; use util::nodemap::{NodeMap, FxHashSet}; use mir::mono::Linkage; -use syntax_pos::{Span, DUMMY_SP}; +use syntax_pos::{Span, DUMMY_SP, symbol::InternedString}; use syntax::codemap::{self, Spanned}; use rustc_target::spec::abi::Abi; use syntax::ast::{self, CrateSugar, Ident, Name, NodeId, DUMMY_NODE_ID, AsmDialect}; @@ -547,6 +547,15 @@ impl Generics { own_counts } + + pub fn get_named(&self, name: &InternedString) -> Option<&GenericParam> { + for param in &self.params { + if *name == param.name.ident().as_interned_str() { + return Some(param); + } + } + None + } } /// Synthetic Type Parameters are converted to an other form during lowering, this allows diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs index 482af9c005f32..afc83771fe1c7 100644 --- a/src/librustc/infer/error_reporting/mod.rs +++ b/src/librustc/infer/error_reporting/mod.rs @@ -189,6 +189,8 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { self, region: ty::Region<'tcx>, ) -> (String, Option) { + let cm = self.sess.codemap(); + let scope = region.free_region_binding_scope(self); let node = self.hir.as_local_node_id(scope).unwrap_or(DUMMY_NODE_ID); let unknown; @@ -219,10 +221,26 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { } }; let (prefix, span) = match *region { - ty::ReEarlyBound(ref br) => ( - format!("the lifetime {} as defined on", br.name), - self.sess.codemap().def_span(self.hir.span(node)), - ), + ty::ReEarlyBound(ref br) => { + let mut sp = cm.def_span(self.hir.span(node)); + if let Some(param) = self.hir.get_generics(scope).and_then(|generics| { + generics.get_named(&br.name) + }) { + sp = param.span; + } + (format!("the lifetime {} as defined on", br.name), sp) + } + ty::ReFree(ty::FreeRegion { + bound_region: ty::BoundRegion::BrNamed(_, ref name), .. + }) => { + let mut sp = cm.def_span(self.hir.span(node)); + if let Some(param) = self.hir.get_generics(scope).and_then(|generics| { + generics.get_named(&name) + }) { + sp = param.span; + } + (format!("the lifetime {} as defined on", name), sp) + } ty::ReFree(ref fr) => match fr.bound_region { ty::BrAnon(idx) => ( format!("the anonymous lifetime #{} defined on", idx + 1), @@ -234,7 +252,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { ), _ => ( format!("the lifetime {} as defined on", fr.bound_region), - self.sess.codemap().def_span(self.hir.span(node)), + cm.def_span(self.hir.span(node)), ), }, _ => bug!(), diff --git a/src/librustc/middle/stability.rs b/src/librustc/middle/stability.rs index a289a2c21ce7f..9bf5c4d72b70c 100644 --- a/src/librustc/middle/stability.rs +++ b/src/librustc/middle/stability.rs @@ -20,7 +20,7 @@ use ty::{self, TyCtxt}; use middle::privacy::AccessLevels; use session::DiagnosticMessageId; use syntax::symbol::Symbol; -use syntax_pos::{Span, MultiSpan, DUMMY_SP}; +use syntax_pos::{Span, MultiSpan}; use syntax::ast; use syntax::ast::{NodeId, Attribute}; use syntax::feature_gate::{GateIssue, emit_feature_err, find_lang_feature_accepted_version}; @@ -687,7 +687,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { let msp: MultiSpan = span.into(); let cm = &self.sess.parse_sess.codemap(); let span_key = msp.primary_span().and_then(|sp: Span| - if sp != DUMMY_SP { + if !sp.is_dummy() { let file = cm.lookup_char_pos(sp.lo()).file; if file.name.is_macros() { None @@ -725,7 +725,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Checker<'a, 'tcx> { match item.node { hir::ItemExternCrate(_) => { // compiler-generated `extern crate` items have a dummy span. - if item.span == DUMMY_SP { return } + if item.span.is_dummy() { return } let def_id = self.tcx.hir.local_def_id(item.id); let cnum = match self.tcx.extern_mod_stmt_cnum(def_id) { diff --git a/src/librustc/middle/weak_lang_items.rs b/src/librustc/middle/weak_lang_items.rs index 1d147eef054f3..180e75df1a66e 100644 --- a/src/librustc/middle/weak_lang_items.rs +++ b/src/librustc/middle/weak_lang_items.rs @@ -112,9 +112,13 @@ fn verify<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, if missing.contains(&lang_items::$item) && !whitelisted(tcx, lang_items::$item) && items.$name().is_none() { - tcx.sess.err(&format!("language item required, but not found: `{}`", - stringify!($name))); - + if lang_items::$item == lang_items::PanicImplLangItem { + tcx.sess.err(&format!("`#[panic_implementation]` function required, \ + but not found")); + } else { + tcx.sess.err(&format!("language item required, but not found: `{}`", + stringify!($name))); + } } )* } diff --git a/src/librustc/ty/query/plumbing.rs b/src/librustc/ty/query/plumbing.rs index e17c6fba74c6e..d783b9574efb2 100644 --- a/src/librustc/ty/query/plumbing.rs +++ b/src/librustc/ty/query/plumbing.rs @@ -708,7 +708,7 @@ macro_rules! define_queries { // FIXME(eddyb) Get more valid Span's on queries. pub fn default_span(&self, tcx: TyCtxt<'_, $tcx, '_>, span: Span) -> Span { - if span != DUMMY_SP { + if !span.is_dummy() { return span; } // The def_span query is used to calculate default_span, diff --git a/src/librustc_codegen_llvm/consts.rs b/src/librustc_codegen_llvm/consts.rs index afa81465ea2d1..199c40bb704ea 100644 --- a/src/librustc_codegen_llvm/consts.rs +++ b/src/librustc_codegen_llvm/consts.rs @@ -250,7 +250,7 @@ pub fn codegen_static<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, unsafe { let g = get_static(cx, def_id); - let v = match ::mir::codegen_static_initializer(cx, def_id) { + let (v, alloc) = match ::mir::codegen_static_initializer(cx, def_id) { Ok(v) => v, // Error has already been reported Err(_) => return, @@ -309,6 +309,44 @@ pub fn codegen_static<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, if attr::contains_name(attrs, "thread_local") { llvm::set_thread_local_mode(g, cx.tls_model); + + // Do not allow LLVM to change the alignment of a TLS on macOS. + // + // By default a global's alignment can be freely increased. + // This allows LLVM to generate more performant instructions + // e.g. using load-aligned into a SIMD register. + // + // However, on macOS 10.10 or below, the dynamic linker does not + // respect any alignment given on the TLS (radar 24221680). + // This will violate the alignment assumption, and causing segfault at runtime. + // + // This bug is very easy to trigger. In `println!` and `panic!`, + // the `LOCAL_STDOUT`/`LOCAL_STDERR` handles are stored in a TLS, + // which the values would be `mem::replace`d on initialization. + // The implementation of `mem::replace` will use SIMD + // whenever the size is 32 bytes or higher. LLVM notices SIMD is used + // and tries to align `LOCAL_STDOUT`/`LOCAL_STDERR` to a 32-byte boundary, + // which macOS's dyld disregarded and causing crashes + // (see issues #51794, #51758, #50867, #48866 and #44056). + // + // To workaround the bug, we trick LLVM into not increasing + // the global's alignment by explicitly assigning a section to it + // (equivalent to automatically generating a `#[link_section]` attribute). + // See the comment in the `GlobalValue::canIncreaseAlignment()` function + // of `lib/IR/Globals.cpp` for why this works. + // + // When the alignment is not increased, the optimized `mem::replace` + // will use load-unaligned instructions instead, and thus avoiding the crash. + // + // We could remove this hack whenever we decide to drop macOS 10.10 support. + if cx.tcx.sess.target.target.options.is_like_osx { + let sect_name = if alloc.bytes.iter().all(|b| *b == 0) { + CStr::from_bytes_with_nul_unchecked(b"__DATA,__thread_bss\0") + } else { + CStr::from_bytes_with_nul_unchecked(b"__DATA,__thread_data\0") + }; + llvm::LLVMSetSection(g, sect_name.as_ptr()); + } } base::set_link_section(cx, g, attrs); diff --git a/src/librustc_codegen_llvm/debuginfo/metadata.rs b/src/librustc_codegen_llvm/debuginfo/metadata.rs index 1eec57c9c877c..6d727f7b048c6 100644 --- a/src/librustc_codegen_llvm/debuginfo/metadata.rs +++ b/src/librustc_codegen_llvm/debuginfo/metadata.rs @@ -1662,7 +1662,7 @@ pub fn create_global_var_metadata(cx: &CodegenCx, let var_scope = get_namespace_for_item(cx, def_id); let span = tcx.def_span(def_id); - let (file_metadata, line_number) = if span != syntax_pos::DUMMY_SP { + let (file_metadata, line_number) = if !span.is_dummy() { let loc = span_start(cx, span); (file_metadata(cx, &loc.file.name, LOCAL_CRATE), loc.line as c_uint) } else { diff --git a/src/librustc_codegen_llvm/debuginfo/mod.rs b/src/librustc_codegen_llvm/debuginfo/mod.rs index 803966145f773..068dd9821ac97 100644 --- a/src/librustc_codegen_llvm/debuginfo/mod.rs +++ b/src/librustc_codegen_llvm/debuginfo/mod.rs @@ -219,7 +219,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, let span = mir.span; // This can be the case for functions inlined from another crate - if span == syntax_pos::DUMMY_SP { + if span.is_dummy() { // FIXME(simulacrum): Probably can't happen; remove. return FunctionDebugContext::FunctionWithoutDebugInfo; } diff --git a/src/librustc_codegen_llvm/mir/constant.rs b/src/librustc_codegen_llvm/mir/constant.rs index bbe0e34b48f26..d7939bd2ab224 100644 --- a/src/librustc_codegen_llvm/mir/constant.rs +++ b/src/librustc_codegen_llvm/mir/constant.rs @@ -118,7 +118,7 @@ pub fn const_alloc_to_llvm(cx: &CodegenCx, alloc: &Allocation) -> ValueRef { pub fn codegen_static_initializer<'a, 'tcx>( cx: &CodegenCx<'a, 'tcx>, def_id: DefId) - -> Result>> + -> Result<(ValueRef, &'tcx Allocation), Lrc>> { let instance = ty::Instance::mono(cx.tcx, def_id); let cid = GlobalId { @@ -132,7 +132,7 @@ pub fn codegen_static_initializer<'a, 'tcx>( ConstValue::ByRef(alloc, n) if n.bytes() == 0 => alloc, _ => bug!("static const eval returned {:#?}", static_), }; - Ok(const_alloc_to_llvm(cx, alloc)) + Ok((const_alloc_to_llvm(cx, alloc), alloc)) } impl<'a, 'tcx> FunctionCx<'a, 'tcx> { diff --git a/src/librustc_errors/emitter.rs b/src/librustc_errors/emitter.rs index 92e72fe91d3e8..e79a3a87738ec 100644 --- a/src/librustc_errors/emitter.rs +++ b/src/librustc_errors/emitter.rs @@ -10,7 +10,7 @@ use self::Destination::*; -use syntax_pos::{DUMMY_SP, FileMap, Span, MultiSpan}; +use syntax_pos::{FileMap, Span, MultiSpan}; use {Level, CodeSuggestion, DiagnosticBuilder, SubDiagnostic, CodeMapperDyn, DiagnosticId}; use snippet::{Annotation, AnnotationType, Line, MultilineAnnotation, StyledString, Style}; @@ -216,7 +216,7 @@ impl EmitterWriter { if let Some(ref cm) = self.cm { for span_label in msp.span_labels() { - if span_label.span == DUMMY_SP { + if span_label.span.is_dummy() { continue; } @@ -730,7 +730,7 @@ impl EmitterWriter { let mut max = 0; if let Some(ref cm) = self.cm { for primary_span in msp.primary_spans() { - if primary_span != &DUMMY_SP { + if !primary_span.is_dummy() { let hi = cm.lookup_char_pos(primary_span.hi()); if hi.line > max { max = hi.line; @@ -739,7 +739,7 @@ impl EmitterWriter { } if !self.short_message { for span_label in msp.span_labels() { - if span_label.span != DUMMY_SP { + if !span_label.span.is_dummy() { let hi = cm.lookup_char_pos(span_label.span.hi()); if hi.line > max { max = hi.line; @@ -778,7 +778,7 @@ impl EmitterWriter { // First, find all the spans in <*macros> and point instead at their use site for sp in span.primary_spans() { - if *sp == DUMMY_SP { + if sp.is_dummy() { continue; } let call_sp = cm.call_span_if_macro(*sp); @@ -790,7 +790,7 @@ impl EmitterWriter { // Only show macro locations that are local // and display them like a span_note if let Some(def_site) = trace.def_site_span { - if def_site == DUMMY_SP { + if def_site.is_dummy() { continue; } if always_backtrace { @@ -830,7 +830,7 @@ impl EmitterWriter { span.push_span_label(label_span, label_text); } for sp_label in span.span_labels() { - if sp_label.span == DUMMY_SP { + if sp_label.span.is_dummy() { continue; } if cm.span_to_filename(sp_label.span.clone()).is_macros() && @@ -1003,7 +1003,7 @@ impl EmitterWriter { // Make sure our primary file comes first let (primary_lo, cm) = if let (Some(cm), Some(ref primary_span)) = (self.cm.as_ref(), msp.primary_span().as_ref()) { - if primary_span != &&DUMMY_SP { + if !primary_span.is_dummy() { (cm.lookup_char_pos(primary_span.lo()), cm) } else { emit_to_destination(&buffer.render(), level, &mut self.dst, self.short_message)?; diff --git a/src/librustc_metadata/creader.rs b/src/librustc_metadata/creader.rs index 1a13335a0e49d..cdeee92cb073f 100644 --- a/src/librustc_metadata/creader.rs +++ b/src/librustc_metadata/creader.rs @@ -569,9 +569,11 @@ impl<'a> CrateLoader<'a> { fn register_bang_proc_macro(&mut self, name: &str, expand: fn(TokenStream) -> TokenStream) { - let expand = SyntaxExtension::ProcMacro( - Box::new(BangProcMacro { inner: expand }), false, self.edition - ); + let expand = SyntaxExtension::ProcMacro { + expander: Box::new(BangProcMacro { inner: expand }), + allow_internal_unstable: false, + edition: self.edition, + }; self.extensions.push((Symbol::intern(name), Lrc::new(expand))); } } diff --git a/src/librustc_metadata/cstore_impl.rs b/src/librustc_metadata/cstore_impl.rs index d0e4e54e63d67..23da82f5a4514 100644 --- a/src/librustc_metadata/cstore_impl.rs +++ b/src/librustc_metadata/cstore_impl.rs @@ -518,8 +518,11 @@ impl CrateStore for cstore::CStore { return LoadedMacro::ProcMacro(proc_macros[id.index.to_proc_macro_index()].1.clone()); } else if data.name == "proc_macro" && self.get_crate_data(id.krate).item_name(id.index) == "quote" { - let ext = SyntaxExtension::ProcMacro(Box::new(::proc_macro::__internal::Quoter), - true, data.root.edition); + let ext = SyntaxExtension::ProcMacro { + expander: Box::new(::proc_macro::__internal::Quoter), + allow_internal_unstable: true, + edition: data.root.edition, + }; return LoadedMacro::ProcMacro(Lrc::new(ext)); } diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs index d8a224d3badd8..9329407527258 100644 --- a/src/librustc_metadata/encoder.rs +++ b/src/librustc_metadata/encoder.rs @@ -41,7 +41,7 @@ use std::u32; use syntax::ast::{self, CRATE_NODE_ID}; use syntax::attr; use syntax::symbol::keywords; -use syntax_pos::{self, hygiene, FileName, FileMap, Span, DUMMY_SP}; +use syntax_pos::{self, hygiene, FileName, FileMap, Span}; use rustc::hir::{self, PatKind}; use rustc::hir::itemlikevisit::ItemLikeVisitor; @@ -147,7 +147,7 @@ impl<'a, 'tcx> SpecializedEncoder for EncodeContext<'a, 'tcx> { impl<'a, 'tcx> SpecializedEncoder for EncodeContext<'a, 'tcx> { fn specialized_encode(&mut self, span: &Span) -> Result<(), Self::Error> { - if *span == DUMMY_SP { + if span.is_dummy() { return TAG_INVALID_SPAN.encode(self) } diff --git a/src/librustc_mir/borrow_check/nll/type_check/mod.rs b/src/librustc_mir/borrow_check/nll/type_check/mod.rs index 2da2b10edb803..9b6e3e0cab6ba 100644 --- a/src/librustc_mir/borrow_check/nll/type_check/mod.rs +++ b/src/librustc_mir/borrow_check/nll/type_check/mod.rs @@ -190,7 +190,7 @@ struct TypeVerifier<'a, 'b: 'a, 'gcx: 'b + 'tcx, 'tcx: 'b> { impl<'a, 'b, 'gcx, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'gcx, 'tcx> { fn visit_span(&mut self, span: &Span) { - if *span != DUMMY_SP { + if !span.is_dummy() { self.last_span = *span; } } @@ -1601,7 +1601,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> { statement_index: 0, }; for stmt in &block_data.statements { - if stmt.source_info.span != DUMMY_SP { + if !stmt.source_info.span.is_dummy() { self.last_span = stmt.source_info.span; } self.check_stmt(mir, stmt, location); diff --git a/src/librustc_passes/ast_validation.rs b/src/librustc_passes/ast_validation.rs index 25187032fb473..00b71accbf5a0 100644 --- a/src/librustc_passes/ast_validation.rs +++ b/src/librustc_passes/ast_validation.rs @@ -172,12 +172,27 @@ impl<'a> Visitor<'a> for AstValidator<'a> { ExprKind::InlineAsm(..) if !self.session.target.target.options.allow_asm => { span_err!(self.session, expr.span, E0472, "asm! is unsupported on this target"); } - ExprKind::ObsoleteInPlace(..) => { - self.err_handler() - .struct_span_err(expr.span, "emplacement syntax is obsolete (for now, anyway)") - .note("for more information, see \ - ") - .emit(); + ExprKind::ObsoleteInPlace(ref place, ref val) => { + let mut err = self.err_handler().struct_span_err( + expr.span, + "emplacement syntax is obsolete (for now, anyway)", + ); + err.note( + "for more information, see \ + " + ); + match val.node { + ExprKind::Lit(ref v) if v.node.is_numeric() => { + err.span_suggestion( + place.span.between(val.span), + "if you meant to write a comparison against a negative value, add a \ + space in between `<` and `-`", + "< -".to_string(), + ); + } + _ => {} + } + err.emit(); } _ => {} } diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs index af7678aa06f7e..a770f07840470 100644 --- a/src/librustc_resolve/build_reduced_graph.rs +++ b/src/librustc_resolve/build_reduced_graph.rs @@ -156,7 +156,7 @@ impl<'a> Resolver<'a> { // Disallow `use $crate;` if source.name == keywords::DollarCrate.name() && path.segments.len() == 1 { - let crate_root = self.resolve_crate_root(source.span.ctxt(), true); + let crate_root = self.resolve_crate_root(source); let crate_name = match crate_root.kind { ModuleKind::Def(_, name) => name, ModuleKind::Block(..) => unreachable!(), diff --git a/src/librustc_resolve/check_unused.rs b/src/librustc_resolve/check_unused.rs index 590ce168d5d0f..0c4b9a546cbd1 100644 --- a/src/librustc_resolve/check_unused.rs +++ b/src/librustc_resolve/check_unused.rs @@ -86,7 +86,7 @@ impl<'a, 'b> Visitor<'a> for UnusedImportCheckVisitor<'a, 'b> { // because this means that they were generated in some fashion by the // compiler and we don't need to consider them. if let ast::ItemKind::Use(..) = item.node { - if item.vis.node == ast::VisibilityKind::Public || item.span.source_equal(&DUMMY_SP) { + if item.vis.node == ast::VisibilityKind::Public || item.span.is_dummy() { return; } } @@ -129,7 +129,7 @@ pub fn check_crate(resolver: &mut Resolver, krate: &ast::Crate) { match directive.subclass { _ if directive.used.get() || directive.vis.get() == ty::Visibility::Public || - directive.span.source_equal(&DUMMY_SP) => {} + directive.span.is_dummy() => {} ImportDirectiveSubclass::ExternCrate(_) => { resolver.maybe_unused_extern_crates.push((directive.id, directive.span)); } diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 464356eb5d242..8a32ec6978c4d 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -1850,6 +1850,8 @@ impl<'a> Resolver<'a> { } else { ident.span.modern() } + } else { + ident = ident.modern_and_legacy(); } // Walk backwards up the ribs in scope. @@ -1981,12 +1983,36 @@ impl<'a> Resolver<'a> { result } - fn resolve_crate_root(&mut self, mut ctxt: SyntaxContext, legacy: bool) -> Module<'a> { - let mark = if legacy { + fn resolve_crate_root(&mut self, ident: Ident) -> Module<'a> { + let mut ctxt = ident.span.ctxt(); + let mark = if ident.name == keywords::DollarCrate.name() { // When resolving `$crate` from a `macro_rules!` invoked in a `macro`, // we don't want to pretend that the `macro_rules!` definition is in the `macro` // as described in `SyntaxContext::apply_mark`, so we ignore prepended modern marks. - ctxt.marks().into_iter().find(|&mark| mark.transparency() != Transparency::Opaque) + // FIXME: This is only a guess and it doesn't work correctly for `macro_rules!` + // definitions actually produced by `macro` and `macro` definitions produced by + // `macro_rules!`, but at least such configurations are not stable yet. + ctxt = ctxt.modern_and_legacy(); + 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 { + result = Some(mark); + iter.next(); + } else { + break; + } + } + // Then find the last legacy mark from the end if it exists. + for mark in iter { + if mark.transparency() == Transparency::SemiTransparent { + result = Some(mark); + } else { + break; + } + } + result } else { ctxt = ctxt.modern(); ctxt.adjust(Mark::root()) @@ -2627,6 +2653,7 @@ impl<'a> Resolver<'a> { // must not add it if it's in the bindings map // because that breaks the assumptions later // passes make about or-patterns.) + let ident = ident.modern_and_legacy(); let mut def = Def::Local(pat_id); match bindings.get(&ident).cloned() { Some(id) if id == outer_pat_id => { @@ -2857,7 +2884,7 @@ impl<'a> Resolver<'a> { .map(|suggestion| import_candidate_to_paths(&suggestion)).collect::>(); enum_candidates.sort(); for (sp, variant_path, enum_path) in enum_candidates { - if sp == DUMMY_SP { + if sp.is_dummy() { let msg = format!("there is an enum variant `{}`, \ try using `{}`?", variant_path, @@ -3345,14 +3372,11 @@ impl<'a> Resolver<'a> { if ns == TypeNS { if (i == 0 && name == keywords::CrateRoot.name()) || (i == 0 && name == keywords::Crate.name()) || + (i == 0 && name == keywords::DollarCrate.name()) || (i == 1 && name == keywords::Crate.name() && path[0].name == keywords::CrateRoot.name()) { - // `::a::b` or `::crate::a::b` - module = Some(self.resolve_crate_root(ident.span.ctxt(), false)); - continue - } else if i == 0 && name == keywords::DollarCrate.name() { - // `$crate::a::b` - module = Some(self.resolve_crate_root(ident.span.ctxt(), true)); + // `::a::b`, `crate::a::b`, `::crate::a::b` or `$crate::a::b` + module = Some(self.resolve_crate_root(ident)); continue } else if i == 1 && !ident.is_path_segment_keyword() { let prev_name = path[0].name; @@ -3784,7 +3808,8 @@ impl<'a> Resolver<'a> { self.unused_labels.insert(id, label.ident.span); let def = Def::Label(id); self.with_label_rib(|this| { - this.label_ribs.last_mut().unwrap().bindings.insert(label.ident, def); + let ident = label.ident.modern_and_legacy(); + this.label_ribs.last_mut().unwrap().bindings.insert(ident, def); f(this); }); } else { @@ -3815,7 +3840,10 @@ impl<'a> Resolver<'a> { } ExprKind::Break(Some(label), _) | ExprKind::Continue(Some(label)) => { - match self.search_label(label.ident, |rib, id| rib.bindings.get(&id).cloned()) { + let def = self.search_label(label.ident, |rib, ident| { + rib.bindings.get(&ident.modern_and_legacy()).cloned() + }); + match def { None => { // Search again for close matches... // Picks the first label that is "close enough", which is not necessarily @@ -4280,7 +4308,7 @@ impl<'a> Resolver<'a> { let mut err = struct_span_err!(self.session, span, E0659, "`{}` is ambiguous", name); err.span_note(b1.span, &msg1); match b2.def() { - Def::Macro(..) if b2.span == DUMMY_SP => + Def::Macro(..) if b2.span.is_dummy() => err.note(&format!("`{}` is also a builtin macro", name)), _ => err.span_note(b2.span, &msg2), }; @@ -4393,14 +4421,14 @@ impl<'a> Resolver<'a> { container)); err.span_label(span, format!("`{}` re{} here", name, new_participle)); - if old_binding.span != DUMMY_SP { + if !old_binding.span.is_dummy() { err.span_label(self.session.codemap().def_span(old_binding.span), format!("previous {} of the {} `{}` here", old_noun, old_kind, name)); } // See https://github.com/rust-lang/rust/issues/32354 if old_binding.is_import() || new_binding.is_import() { - let binding = if new_binding.is_import() && new_binding.span != DUMMY_SP { + let binding = if new_binding.is_import() && !new_binding.span.is_dummy() { new_binding } else { old_binding diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs index c9d00f80b0ba3..0523765ea1897 100644 --- a/src/librustc_resolve/macros.rs +++ b/src/librustc_resolve/macros.rs @@ -155,10 +155,9 @@ impl<'a> base::Resolver for Resolver<'a> { } }); - let ident = path.segments[0].ident; - if ident.name == keywords::DollarCrate.name() { + if path.segments[0].ident.name == keywords::DollarCrate.name() { + let module = self.0.resolve_crate_root(path.segments[0].ident); path.segments[0].ident.name = keywords::CrateRoot.name(); - let module = self.0.resolve_crate_root(ident.span.ctxt(), true); if !module.is_local() { let span = path.segments[0].ident.span; path.segments.insert(1, match module.kind { @@ -333,7 +332,9 @@ impl<'a> base::Resolver for Resolver<'a> { self.unused_macros.remove(&def_id); let ext = self.get_macro(def); if ext.is_modern() { - invoc.expansion_data.mark.set_transparency(Transparency::Opaque); + 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); } @@ -351,8 +352,8 @@ impl<'a> base::Resolver for Resolver<'a> { fn check_unused_macros(&self) { for did in self.unused_macros.iter() { let id_span = match *self.macro_map[did] { - SyntaxExtension::NormalTT { def_info, .. } => def_info, - SyntaxExtension::DeclMacro(.., osp, _) => osp, + SyntaxExtension::NormalTT { def_info, .. } | + SyntaxExtension::DeclMacro { def_info, .. } => def_info, _ => None, }; if let Some((id, span)) = id_span { @@ -849,8 +850,6 @@ impl<'a> Resolver<'a> { /// Error if `ext` is a Macros 1.1 procedural macro being imported by `#[macro_use]` fn err_if_macro_use_proc_macro(&mut self, name: Name, use_span: Span, binding: &NameBinding<'a>) { - use self::SyntaxExtension::*; - let krate = binding.def().def_id().krate; // Plugin-based syntax extensions are exempt from this check @@ -860,15 +859,16 @@ impl<'a> Resolver<'a> { match *ext { // If `ext` is a procedural macro, check if we've already warned about it - AttrProcMacro(..) | ProcMacro(..) => + SyntaxExtension::AttrProcMacro(..) | SyntaxExtension::ProcMacro { .. } => if !self.warned_proc_macros.insert(name) { return; }, _ => return, } let warn_msg = match *ext { - AttrProcMacro(..) => "attribute procedural macros cannot be \ - imported with `#[macro_use]`", - ProcMacro(..) => "procedural macros cannot be imported with `#[macro_use]`", + SyntaxExtension::AttrProcMacro(..) => + "attribute procedural macros cannot be imported with `#[macro_use]`", + SyntaxExtension::ProcMacro { .. } => + "procedural macros cannot be imported with `#[macro_use]`", _ => return, }; diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs index 8ac5e248dade4..0ee17ebc48704 100644 --- a/src/librustc_resolve/resolve_imports.rs +++ b/src/librustc_resolve/resolve_imports.rs @@ -698,7 +698,7 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> { "crate root imports need to be explicitly named: \ `use crate as name;`".to_string())); } else { - Some(self.resolve_crate_root(source.span.ctxt().modern(), false)) + Some(self.resolve_crate_root(source)) } } else if is_extern && !source.is_path_segment_keyword() { let crate_id = diff --git a/src/librustc_save_analysis/lib.rs b/src/librustc_save_analysis/lib.rs index 89d30fd666a88..c07db44b36ccf 100644 --- a/src/librustc_save_analysis/lib.rs +++ b/src/librustc_save_analysis/lib.rs @@ -1157,7 +1157,7 @@ fn escape(s: String) -> String { // Helper function to determine if a span came from a // macro expansion or syntax extension. fn generated_code(span: Span) -> bool { - span.ctxt() != NO_EXPANSION || span == DUMMY_SP + span.ctxt() != NO_EXPANSION || span.is_dummy() } // DefId::index is a newtype and so the JSON serialisation is ugly. Therefore diff --git a/src/librustc_typeck/check/compare_method.rs b/src/librustc_typeck/check/compare_method.rs index 04c11d30d2679..4c903b6fe5851 100644 --- a/src/librustc_typeck/check/compare_method.rs +++ b/src/librustc_typeck/check/compare_method.rs @@ -356,7 +356,6 @@ fn check_region_bounds_on_impl_method<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, impl_generics: &ty::Generics, trait_to_skol_substs: &Substs<'tcx>) -> Result<(), ErrorReported> { - let span = tcx.sess.codemap().def_span(span); let trait_params = trait_generics.own_counts().lifetimes; let impl_params = impl_generics.own_counts().lifetimes; @@ -378,16 +377,20 @@ fn check_region_bounds_on_impl_method<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, // are zero. Since I don't quite know how to phrase things at // the moment, give a kind of vague error message. if trait_params != impl_params { - let mut err = struct_span_err!(tcx.sess, - span, - E0195, - "lifetime parameters or bounds on method `{}` do not match \ - the trait declaration", - impl_m.ident); + let def_span = tcx.sess.codemap().def_span(span); + let span = tcx.hir.get_generics_span(impl_m.def_id).unwrap_or(def_span); + let mut err = struct_span_err!( + tcx.sess, + span, + E0195, + "lifetime parameters or bounds on method `{}` do not match the trait declaration", + impl_m.ident, + ); err.span_label(span, "lifetimes do not match method in trait"); if let Some(sp) = tcx.hir.span_if_local(trait_m.def_id) { - err.span_label(tcx.sess.codemap().def_span(sp), - "lifetimes in impl do not match this method in trait"); + let def_sp = tcx.sess.codemap().def_span(sp); + let sp = tcx.hir.get_generics_span(trait_m.def_id).unwrap_or(def_sp); + err.span_label(sp, "lifetimes in impl do not match this method in trait"); } err.emit(); return Err(ErrorReported); diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs index 35d237d94de82..68c71f4ce90e9 100644 --- a/src/librustc_typeck/check/method/suggest.rs +++ b/src/librustc_typeck/check/method/suggest.rs @@ -245,12 +245,11 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { "f32" }; match expr.node { - hir::ExprLit(_) => { // numeric literal - let snippet = tcx.sess.codemap().span_to_snippet(expr.span) + hir::ExprLit(ref lit) => { // numeric literal + let snippet = tcx.sess.codemap().span_to_snippet(lit.span) .unwrap_or("".to_string()); - // FIXME: use the literal for missing snippet - err.span_suggestion(expr.span, + err.span_suggestion(lit.span, &format!("you must specify a concrete type for \ this numeric value, like `{}`", concrete_type), diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs index be42549df74a3..a9b4f7f3021f1 100644 --- a/src/librustc_typeck/check/wfcheck.rs +++ b/src/librustc_typeck/check/wfcheck.rs @@ -118,10 +118,10 @@ pub fn check_item_well_formed<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: Def check_item_fn(tcx, item); } hir::ItemStatic(..) => { - check_item_type(tcx, item); + check_item_type(tcx, item.id, None); } hir::ItemConst(..) => { - check_item_type(tcx, item); + check_item_type(tcx, item.id, None); } hir::ItemStruct(ref struct_def, ref ast_generics) => { check_type_defn(tcx, item, false, |fcx| { @@ -147,6 +147,17 @@ pub fn check_item_well_formed<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: Def hir::ItemTrait(..) => { check_trait(tcx, item); } + hir::ItemForeignMod(ref foreign_mod) => { + for foreign_item in foreign_mod.items.iter() { + match foreign_item.node { + hir::ForeignItemStatic(..) => { + check_item_type(tcx, foreign_item.id, + Some(ObligationCauseCode::SizedReturnType)); + }, + _ => {} + } + } + } _ => {} } } @@ -215,9 +226,9 @@ fn check_associated_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, }) } -fn for_item<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'gcx>, item: &hir::Item) +fn for_item<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'gcx>, id: ast::NodeId) -> CheckWfFcxBuilder<'a, 'gcx, 'tcx> { - for_id(tcx, item.id, item.span) + for_id(tcx, id, tcx.hir.span(id)) } fn for_id<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'gcx>, id: ast::NodeId, span: Span) @@ -236,7 +247,7 @@ fn check_type_defn<'a, 'tcx, F>(tcx: TyCtxt<'a, 'tcx, 'tcx>, item: &hir::Item, all_sized: bool, mut lookup_fields: F) where F: for<'fcx, 'gcx, 'tcx2> FnMut(&FnCtxt<'fcx, 'gcx, 'tcx2>) -> Vec> { - for_item(tcx, item).with_fcx(|fcx, fcx_tcx| { + for_item(tcx, item.id).with_fcx(|fcx, fcx_tcx| { let variants = lookup_fields(fcx); let def_id = fcx.tcx.hir.local_def_id(item.id); let packed = fcx.tcx.adt_def(def_id).repr.packed(); @@ -290,14 +301,14 @@ fn check_type_defn<'a, 'tcx, F>(tcx: TyCtxt<'a, 'tcx, 'tcx>, fn check_trait<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, item: &hir::Item) { let trait_def_id = tcx.hir.local_def_id(item.id); - for_item(tcx, item).with_fcx(|fcx, _| { + for_item(tcx, item.id).with_fcx(|fcx, _| { check_where_clauses(tcx, fcx, item.span, trait_def_id); vec![] }); } fn check_item_fn<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, item: &hir::Item) { - for_item(tcx, item).with_fcx(|fcx, tcx| { + for_item(tcx, item.id).with_fcx(|fcx, tcx| { let def_id = fcx.tcx.hir.local_def_id(item.id); let sig = fcx.tcx.fn_sig(def_id); let sig = fcx.normalize_associated_types_in(item.span, &sig); @@ -309,15 +320,24 @@ fn check_item_fn<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, item: &hir::Item) { } fn check_item_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, - item: &hir::Item) + id: ast::NodeId, + size_check: Option>) { - debug!("check_item_type: {:?}", item); + debug!("check_item_type: {:?}", tcx.hir.get(id)); - for_item(tcx, item).with_fcx(|fcx, _this| { - let ty = fcx.tcx.type_of(fcx.tcx.hir.local_def_id(item.id)); - let item_ty = fcx.normalize_associated_types_in(item.span, &ty); + for_item(tcx, id).with_fcx(|fcx, _this| { + let span = tcx.hir.span(id); + let ty = fcx.tcx.type_of(fcx.tcx.hir.local_def_id(id)); + let item_ty = fcx.normalize_associated_types_in(span, &ty); - fcx.register_wf_obligation(item_ty, item.span, ObligationCauseCode::MiscObligation); + fcx.register_wf_obligation(item_ty, span, ObligationCauseCode::MiscObligation); + + match size_check { + None => {} + Some(code) => { + fcx.require_type_is_sized(item_ty, span, code); + } + } vec![] // no implied bounds in a const etc }); @@ -330,7 +350,7 @@ fn check_impl<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, { debug!("check_impl: {:?}", item); - for_item(tcx, item).with_fcx(|fcx, tcx| { + for_item(tcx, item.id).with_fcx(|fcx, tcx| { let item_def_id = fcx.tcx.hir.local_def_id(item.id); match *ast_trait_ref { diff --git a/src/librustc_typeck/check_unused.rs b/src/librustc_typeck/check_unused.rs index 41adde0d4a188..ae5ca5441adf6 100644 --- a/src/librustc_typeck/check_unused.rs +++ b/src/librustc_typeck/check_unused.rs @@ -12,7 +12,7 @@ use lint; use rustc::ty::TyCtxt; use syntax::ast; -use syntax_pos::{Span, DUMMY_SP}; +use syntax_pos::Span; use rustc::hir::def_id::{DefId, LOCAL_CRATE}; use rustc::hir::itemlikevisit::ItemLikeVisitor; @@ -39,7 +39,7 @@ pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) { impl<'a, 'tcx, 'v> ItemLikeVisitor<'v> for CheckVisitor<'a, 'tcx> { fn visit_item(&mut self, item: &hir::Item) { - if item.vis == hir::Public || item.span == DUMMY_SP { + if item.vis == hir::Public || item.span.is_dummy() { return; } if let hir::ItemUse(ref path, _) = item.node { diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 8cdffcd558d75..65babbffffef1 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1219,7 +1219,7 @@ fn macro_resolve(cx: &DocContext, path_str: &str) -> Option { let res = resolver .resolve_macro_to_def_inner(mark, &path, MacroKind::Bang, false); if let Ok(def) = res { - if let SyntaxExtension::DeclMacro(..) = *resolver.get_macro(def) { + if let SyntaxExtension::DeclMacro { .. } = *resolver.get_macro(def) { Some(def) } else { None @@ -3464,7 +3464,7 @@ impl Span { impl Clean for syntax_pos::Span { fn clean(&self, cx: &DocContext) -> Span { - if *self == DUMMY_SP { + if self.is_dummy() { return Span::empty(); } diff --git a/src/libstd/alloc.rs b/src/libstd/alloc.rs index f28e91e19b73c..f6cecbea11f8d 100644 --- a/src/libstd/alloc.rs +++ b/src/libstd/alloc.rs @@ -61,7 +61,7 @@ //! ```rust,ignore (demonstrates crates.io usage) //! extern crate jemallocator; //! -//! use jemallacator::Jemalloc; +//! use jemallocator::Jemalloc; //! //! #[global_allocator] //! static GLOBAL: Jemalloc = Jemalloc; diff --git a/src/libstd/error.rs b/src/libstd/error.rs index 3160485375f6d..1958915602f83 100644 --- a/src/libstd/error.rs +++ b/src/libstd/error.rs @@ -49,6 +49,7 @@ use string; /// /// [`Result`]: ../result/enum.Result.html /// [`Display`]: ../fmt/trait.Display.html +/// [`Debug`]: ../fmt/trait.Debug.html /// [`cause`]: trait.Error.html#method.cause #[stable(feature = "rust1", since = "1.0.0")] pub trait Error: Debug + Display { diff --git a/src/libstd/ffi/os_str.rs b/src/libstd/ffi/os_str.rs index 0a3148029d053..4ada6a77a8eec 100644 --- a/src/libstd/ffi/os_str.rs +++ b/src/libstd/ffi/os_str.rs @@ -417,6 +417,20 @@ impl PartialEq for str { } } +#[stable(feature = "os_str_str_ref_eq", since = "1.28.0")] +impl<'a> PartialEq<&'a str> for OsString { + fn eq(&self, other: &&'a str) -> bool { + **self == **other + } +} + +#[stable(feature = "os_str_str_ref_eq", since = "1.28.0")] +impl<'a> PartialEq for &'a str { + fn eq(&self, other: &OsString) -> bool { + **other == **self + } +} + #[stable(feature = "rust1", since = "1.0.0")] impl Eq for OsString {} diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 53465c071f33a..07e22b02c55bb 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -1298,6 +1298,16 @@ impl LitKind { } } + /// Returns true if this is a numeric literal. + pub fn is_numeric(&self) -> bool { + match *self { + LitKind::Int(..) | + LitKind::Float(..) | + LitKind::FloatUnsuffixed(..) => true, + _ => false, + } + } + /// Returns true if this literal has no suffix. Note: this will return true /// for literals with prefixes such as raw strings and byte strings. pub fn is_unsuffixed(&self) -> bool { diff --git a/src/libsyntax/codemap.rs b/src/libsyntax/codemap.rs index 1d5429bdf8f7d..ea6b39504e81d 100644 --- a/src/libsyntax/codemap.rs +++ b/src/libsyntax/codemap.rs @@ -443,7 +443,7 @@ impl CodeMap { } pub fn span_to_string(&self, sp: Span) -> String { - if self.files.borrow().file_maps.is_empty() && sp.source_equal(&DUMMY_SP) { + if self.files.borrow().file_maps.is_empty() && sp.is_dummy() { return "no-location".to_string(); } diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index 9afce74f53cc4..e2424de4d1449 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -597,11 +597,11 @@ pub enum SyntaxExtension { MultiModifier(Box), /// A function-like procedural macro. TokenStream -> TokenStream. - ProcMacro( - /* expander: */ Box, - /* allow_internal_unstable: */ bool, - /* edition: */ Edition, - ), + ProcMacro { + expander: Box, + allow_internal_unstable: bool, + edition: Edition, + }, /// An attribute-like procedural macro. TokenStream, TokenStream -> TokenStream. /// The first TokenSteam is the attribute, the second is the annotated item. @@ -646,19 +646,22 @@ pub enum SyntaxExtension { BuiltinDerive(BuiltinDeriveFn), /// A declarative macro, e.g. `macro m() {}`. - /// - /// The second element is the definition site span. - DeclMacro(Box, Option<(ast::NodeId, Span)>, Edition), + DeclMacro { + expander: Box, + def_info: Option<(ast::NodeId, Span)>, + is_transparent: bool, + edition: Edition, + } } impl SyntaxExtension { /// Return which kind of macro calls this syntax extension. pub fn kind(&self) -> MacroKind { match *self { - SyntaxExtension::DeclMacro(..) | + SyntaxExtension::DeclMacro { .. } | SyntaxExtension::NormalTT { .. } | SyntaxExtension::IdentTT(..) | - SyntaxExtension::ProcMacro(..) => + SyntaxExtension::ProcMacro { .. } => MacroKind::Bang, SyntaxExtension::MultiDecorator(..) | SyntaxExtension::MultiModifier(..) | @@ -672,19 +675,26 @@ impl SyntaxExtension { pub fn is_modern(&self) -> bool { match *self { - SyntaxExtension::DeclMacro(..) | - SyntaxExtension::ProcMacro(..) | + 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, + } + } + pub fn edition(&self) -> Edition { match *self { SyntaxExtension::NormalTT { edition, .. } | - SyntaxExtension::DeclMacro(.., edition) | - SyntaxExtension::ProcMacro(.., edition) | + SyntaxExtension::DeclMacro { edition, .. } | + SyntaxExtension::ProcMacro { edition, .. } | SyntaxExtension::AttrProcMacro(.., edition) | SyntaxExtension::ProcMacroDerive(.., edition) => edition, // Unstable legacy stuff diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 9cd410d424394..f29bff20f3dd6 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -738,13 +738,13 @@ impl<'a, 'b> MacroExpander<'a, 'b> { }; let opt_expanded = match *ext { - DeclMacro(ref expand, def_span, edition) => { - if let Err(dummy_span) = validate_and_set_expn_info(self, def_span.map(|(_, s)| s), + DeclMacro { ref expander, def_info, edition, .. } => { + if let Err(dummy_span) = validate_and_set_expn_info(self, def_info.map(|(_, s)| s), false, false, false, None, edition) { dummy_span } else { - kind.make_from(expand.expand(self.cx, span, mac.node.stream())) + kind.make_from(expander.expand(self.cx, span, mac.node.stream())) } } @@ -804,7 +804,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { kind.dummy(span) } - ProcMacro(ref expandfun, allow_internal_unstable, edition) => { + SyntaxExtension::ProcMacro { ref expander, allow_internal_unstable, edition } => { if ident.name != keywords::Invalid.name() { let msg = format!("macro {}! expects no ident argument, given '{}'", path, ident); @@ -826,7 +826,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { edition, }); - let tok_result = expandfun.expand(self.cx, span, mac.node.stream()); + let tok_result = expander.expand(self.cx, span, mac.node.stream()); let result = self.parse_ast_fragment(tok_result, kind, path, span); self.gate_proc_macro_expansion(span, &result); result @@ -1297,7 +1297,7 @@ impl<'a, 'b> Folder for InvocationCollector<'a, 'b> { // Detect if this is an inline module (`mod m { ... }` as opposed to `mod m;`). // In the non-inline case, `inner` is never the dummy span (c.f. `parse_item_mod`). // Thus, if `inner` is the dummy span, we know the module is inline. - let inline_module = item.span.contains(inner) || inner == DUMMY_SP; + let inline_module = item.span.contains(inner) || inner.is_dummy(); if inline_module { if let Some(path) = attr::first_attr_value_str_by_name(&item.attrs, "path") { diff --git a/src/libsyntax/ext/tt/macro_rules.rs b/src/libsyntax/ext/tt/macro_rules.rs index 3b3892729d93c..70fc9dada428e 100644 --- a/src/libsyntax/ext/tt/macro_rules.rs +++ b/src/libsyntax/ext/tt/macro_rules.rs @@ -312,7 +312,14 @@ pub fn compile(sess: &ParseSess, features: &Features, def: &ast::Item, edition: edition, } } else { - SyntaxExtension::DeclMacro(expander, Some((def.id, def.span)), edition) + let is_transparent = attr::contains_name(&def.attrs, "rustc_transparent_macro"); + + SyntaxExtension::DeclMacro { + expander, + def_info: Some((def.id, def.span)), + is_transparent, + edition, + } } } diff --git a/src/libsyntax/ext/tt/quoted.rs b/src/libsyntax/ext/tt/quoted.rs index 01b971976a763..82b0fae3e9c68 100644 --- a/src/libsyntax/ext/tt/quoted.rs +++ b/src/libsyntax/ext/tt/quoted.rs @@ -14,7 +14,7 @@ use feature_gate::{self, emit_feature_err, Features, GateIssue}; use parse::{token, ParseSess}; use print::pprust; use symbol::keywords; -use syntax_pos::{BytePos, Span, DUMMY_SP}; +use syntax_pos::{BytePos, Span}; use tokenstream; use std::iter::Peekable; @@ -41,8 +41,8 @@ impl Delimited { /// Return a `self::TokenTree` with a `Span` corresponding to the opening delimiter. pub fn open_tt(&self, span: Span) -> TokenTree { - let open_span = if span == DUMMY_SP { - DUMMY_SP + let open_span = if span.is_dummy() { + span } else { span.with_lo(span.lo() + BytePos(self.delim.len() as u32)) }; @@ -51,8 +51,8 @@ impl Delimited { /// Return a `self::TokenTree` with a `Span` corresponding to the closing delimiter. pub fn close_tt(&self, span: Span) -> TokenTree { - let close_span = if span == DUMMY_SP { - DUMMY_SP + let close_span = if span.is_dummy() { + span } else { span.with_lo(span.hi() - BytePos(self.delim.len() as u32)) }; diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs index cce8da1dcbd53..c443f24078031 100644 --- a/src/libsyntax/parse/mod.rs +++ b/src/libsyntax/parse/mod.rs @@ -13,7 +13,7 @@ use rustc_data_structures::sync::{Lrc, Lock}; use ast::{self, CrateConfig}; use codemap::{CodeMap, FilePathMapping}; -use syntax_pos::{self, Span, FileMap, NO_EXPANSION, FileName}; +use syntax_pos::{Span, FileMap, FileName}; use errors::{Handler, ColorConfig, DiagnosticBuilder}; use feature_gate::UnstableFeatures; use parse::parser::Parser; @@ -188,8 +188,8 @@ fn filemap_to_parser(sess: & ParseSess, filemap: Lrc) -> Parser { let end_pos = filemap.end_pos; let mut parser = stream_to_parser(sess, filemap_to_stream(sess, filemap, None)); - if parser.token == token::Eof && parser.span == syntax_pos::DUMMY_SP { - parser.span = Span::new(end_pos, end_pos, NO_EXPANSION); + if parser.token == token::Eof && parser.span.is_dummy() { + parser.span = Span::new(end_pos, end_pos, parser.span.ctxt()); } parser diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index faf2cf64e1d9f..96053f988fa26 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -43,7 +43,7 @@ use ast::{BinOpKind, UnOp}; use ast::{RangeEnd, RangeSyntax}; use {ast, attr}; use codemap::{self, CodeMap, Spanned, respan}; -use syntax_pos::{self, Span, MultiSpan, BytePos, FileName, DUMMY_SP, edition::Edition}; +use syntax_pos::{self, Span, MultiSpan, BytePos, FileName, edition::Edition}; use errors::{self, Applicability, DiagnosticBuilder}; use parse::{self, SeqSep, classify, token}; use parse::lexer::TokenAndSpan; @@ -567,7 +567,7 @@ impl<'a> Parser<'a> { if let Some(directory) = directory { parser.directory = directory; - } else if !parser.span.source_equal(&DUMMY_SP) { + } else if !parser.span.is_dummy() { if let FileName::Real(mut path) = sess.codemap().span_to_unmapped_path(parser.span) { path.pop(); parser.directory.path = Cow::from(path); @@ -584,7 +584,7 @@ impl<'a> Parser<'a> { } else { self.token_cursor.next() }; - if next.sp == syntax_pos::DUMMY_SP { + if next.sp.is_dummy() { // Tweak the location for better diagnostics, but keep syntactic context intact. next.sp = self.prev_span.with_ctxt(next.sp.ctxt()); } @@ -6137,7 +6137,7 @@ impl<'a> Parser<'a> { return Err(err); } - let hi = if self.span == syntax_pos::DUMMY_SP { + let hi = if self.span.is_dummy() { inner_lo } else { self.prev_span @@ -6368,7 +6368,7 @@ impl<'a> Parser<'a> { } let mut err = self.diagnostic().struct_span_err(id_sp, "cannot declare a new module at this location"); - if id_sp != syntax_pos::DUMMY_SP { + if !id_sp.is_dummy() { let src_path = self.sess.codemap().span_to_filename(id_sp); if let FileName::Real(src_path) = src_path { if let Some(stem) = src_path.file_stem() { diff --git a/src/libsyntax/tokenstream.rs b/src/libsyntax/tokenstream.rs index 455cc4391dd3b..8736fcf9729a6 100644 --- a/src/libsyntax/tokenstream.rs +++ b/src/libsyntax/tokenstream.rs @@ -57,8 +57,8 @@ impl Delimited { /// Returns the opening delimiter as a token tree. pub fn open_tt(&self, span: Span) -> TokenTree { - let open_span = if span == DUMMY_SP { - DUMMY_SP + let open_span = if span.is_dummy() { + span } else { span.with_hi(span.lo() + BytePos(self.delim.len() as u32)) }; @@ -67,8 +67,8 @@ impl Delimited { /// Returns the closing delimiter as a token tree. pub fn close_tt(&self, span: Span) -> TokenTree { - let close_span = if span == DUMMY_SP { - DUMMY_SP + let close_span = if span.is_dummy() { + span } else { span.with_lo(span.hi() - BytePos(self.delim.len() as u32)) }; diff --git a/src/libsyntax_pos/hygiene.rs b/src/libsyntax_pos/hygiene.rs index 99d8b1b172d24..33d02d0b10a7b 100644 --- a/src/libsyntax_pos/hygiene.rs +++ b/src/libsyntax_pos/hygiene.rs @@ -33,14 +33,17 @@ pub struct SyntaxContext(pub(super) u32); pub struct SyntaxContextData { pub outer_mark: Mark, pub prev_ctxt: SyntaxContext, - pub modern: SyntaxContext, + // This context, but with all transparent and semi-transparent marks filtered away. + pub opaque: SyntaxContext, + // This context, but with all transparent marks filtered away. + pub opaque_and_semitransparent: SyntaxContext, } /// A mark is a unique id associated with a macro expansion. #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable)] pub struct Mark(u32); -#[derive(Debug)] +#[derive(Clone, Debug)] struct MarkData { parent: Mark, transparency: Transparency, @@ -50,11 +53,10 @@ struct MarkData { /// A property of a macro expansion that determines how identifiers /// produced by that expansion are resolved. -#[derive(Copy, Clone, PartialEq, Eq, Debug)] +#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, 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. - /// (Not used yet.) Transparent, /// Identifier produced by a semi-transparent expansion may be resolved /// either at call-site or at definition-site. @@ -69,16 +71,26 @@ pub enum Transparency { } impl Mark { + fn fresh_with_data(mark_data: MarkData, data: &mut HygieneData) -> Self { + data.marks.push(mark_data); + Mark(data.marks.len() as u32 - 1) + } + pub fn fresh(parent: Mark) -> Self { HygieneData::with(|data| { - data.marks.push(MarkData { + Mark::fresh_with_data(MarkData { parent, // By default expansions behave like `macro_rules`. transparency: Transparency::SemiTransparent, is_builtin: false, expn_info: None, - }); - Mark(data.marks.len() as u32 - 1) + }, 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) }) } @@ -207,7 +219,8 @@ impl HygieneData { syntax_contexts: vec![SyntaxContextData { outer_mark: Mark::root(), prev_ctxt: SyntaxContext(0), - modern: SyntaxContext(0), + opaque: SyntaxContext(0), + opaque_and_semitransparent: SyntaxContext(0), }], markings: HashMap::new(), default_edition: Edition::Edition2015, @@ -239,7 +252,7 @@ impl SyntaxContext { // 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 - // SyntaxContextData::prev_ctxt or SyntaxContextData::modern. These things + // SyntaxContextData::prev_ctxt or SyntaxContextData::opaque. These things // don't seem to be used after HIR lowering, so everything should be fine // as long as incremental compilation does not kick in before that. pub fn allocate_directly(expansion_info: ExpnInfo) -> Self { @@ -256,7 +269,8 @@ impl SyntaxContext { data.syntax_contexts.push(SyntaxContextData { outer_mark: mark, prev_ctxt: SyntaxContext::empty(), - modern: SyntaxContext::empty(), + opaque: SyntaxContext::empty(), + opaque_and_semitransparent: SyntaxContext::empty(), }); SyntaxContext(data.syntax_contexts.len() as u32 - 1) }) @@ -269,7 +283,13 @@ impl SyntaxContext { } let call_site_ctxt = - mark.expn_info().map_or(SyntaxContext::empty(), |info| info.call_site.ctxt()).modern(); + mark.expn_info().map_or(SyntaxContext::empty(), |info| info.call_site.ctxt()); + let call_site_ctxt = if mark.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); } @@ -293,26 +313,53 @@ impl SyntaxContext { fn apply_mark_internal(self, mark: Mark) -> SyntaxContext { HygieneData::with(|data| { let syntax_contexts = &mut data.syntax_contexts; - let mut modern = syntax_contexts[self.0 as usize].modern; - if data.marks[mark.0 as usize].transparency == Transparency::Opaque { - modern = *data.markings.entry((modern, mark)).or_insert_with(|| { - let len = syntax_contexts.len() as u32; + 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(|| { + let new_opaque = SyntaxContext(syntax_contexts.len() as u32); + syntax_contexts.push(SyntaxContextData { + outer_mark: mark, + prev_ctxt, + opaque: new_opaque, + opaque_and_semitransparent: new_opaque, + }); + new_opaque + }); + } + + if transparency >= Transparency::SemiTransparent { + let prev_ctxt = opaque_and_semitransparent; + opaque_and_semitransparent = + *data.markings.entry((prev_ctxt, mark)).or_insert_with(|| { + let new_opaque_and_semitransparent = + SyntaxContext(syntax_contexts.len() as u32); syntax_contexts.push(SyntaxContextData { outer_mark: mark, - prev_ctxt: modern, - modern: SyntaxContext(len), + prev_ctxt, + opaque, + opaque_and_semitransparent: new_opaque_and_semitransparent, }); - SyntaxContext(len) + new_opaque_and_semitransparent }); } - *data.markings.entry((self, mark)).or_insert_with(|| { + let prev_ctxt = self; + *data.markings.entry((prev_ctxt, mark)).or_insert_with(|| { + let new_opaque_and_semitransparent_and_transparent = + SyntaxContext(syntax_contexts.len() as u32); syntax_contexts.push(SyntaxContextData { outer_mark: mark, - prev_ctxt: self, - modern, + prev_ctxt, + opaque, + opaque_and_semitransparent, }); - SyntaxContext(syntax_contexts.len() as u32 - 1) + new_opaque_and_semitransparent_and_transparent }) }) } @@ -452,7 +499,12 @@ impl SyntaxContext { #[inline] pub fn modern(self) -> SyntaxContext { - HygieneData::with(|data| data.syntax_contexts[self.0 as usize].modern) + HygieneData::with(|data| data.syntax_contexts[self.0 as usize].opaque) + } + + #[inline] + pub fn modern_and_legacy(self) -> SyntaxContext { + HygieneData::with(|data| data.syntax_contexts[self.0 as usize].opaque_and_semitransparent) } #[inline] diff --git a/src/libsyntax_pos/lib.rs b/src/libsyntax_pos/lib.rs index 55dec31511c37..491ce720f36c5 100644 --- a/src/libsyntax_pos/lib.rs +++ b/src/libsyntax_pos/lib.rs @@ -248,6 +248,13 @@ impl Span { self.data().with_ctxt(ctxt) } + /// Returns `true` if this is a dummy span with any hygienic context. + #[inline] + pub fn is_dummy(self) -> bool { + let span = self.data(); + span.lo.0 == 0 && span.hi.0 == 0 + } + /// Returns a new span representing an empty span at the beginning of this span #[inline] pub fn shrink_to_lo(self) -> Span { @@ -263,7 +270,7 @@ impl Span { /// Returns `self` if `self` is not the dummy span, and `other` otherwise. pub fn substitute_dummy(self, other: Span) -> Span { - if self.source_equal(&DUMMY_SP) { other } else { self } + if self.is_dummy() { other } else { self } } /// Return true if `self` fully encloses `other`. @@ -491,6 +498,12 @@ impl Span { let span = self.data(); span.with_ctxt(span.ctxt.modern()) } + + #[inline] + pub fn modern_and_legacy(self) -> Span { + let span = self.data(); + span.with_ctxt(span.ctxt.modern_and_legacy()) + } } #[derive(Clone, Debug)] diff --git a/src/libsyntax_pos/symbol.rs b/src/libsyntax_pos/symbol.rs index bb64dad12085d..9a0c92f679366 100644 --- a/src/libsyntax_pos/symbol.rs +++ b/src/libsyntax_pos/symbol.rs @@ -68,6 +68,15 @@ impl Ident { Ident::new(self.name, self.span.modern()) } + /// "Normalize" ident for use in comparisons using "local variable hygiene". + /// Identifiers with same string value become same if they came from the same non-transparent + /// macro (e.g. `macro` or `macro_rules!` items) and stay different if they came from different + /// non-transparent macros. + /// Technically, this operation strips all transparent marks from ident's syntactic context. + pub fn modern_and_legacy(self) -> Ident { + Ident::new(self.name, self.span.modern_and_legacy()) + } + pub fn gensym(self) -> Ident { Ident::new(self.name.gensymed(), self.span) } diff --git a/src/test/codegen/issue-44056-macos-tls-align.rs b/src/test/codegen/issue-44056-macos-tls-align.rs new file mode 100644 index 0000000000000..362d0a3c1071b --- /dev/null +++ b/src/test/codegen/issue-44056-macos-tls-align.rs @@ -0,0 +1,40 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// ignore-tidy-linelength +// only-macos +// no-system-llvm +// min-llvm-version 6.0 +// compile-flags: -O + +#![crate_type = "rlib"] +#![feature(thread_local)] + +// CHECK: @STATIC_VAR_1 = internal thread_local unnamed_addr global <{ [32 x i8] }> zeroinitializer, section "__DATA,__thread_bss", align 8 +#[no_mangle] +#[allow(private_no_mangle_statics)] +#[thread_local] +static mut STATIC_VAR_1: [u64; 4] = [0; 4]; + +// CHECK: @STATIC_VAR_2 = internal thread_local unnamed_addr global <{ [32 x i8] }> <{{[^>]*}}>, section "__DATA,__thread_data", align 8 +#[no_mangle] +#[allow(private_no_mangle_statics)] +#[thread_local] +static mut STATIC_VAR_2: [u64; 4] = [4; 4]; + +#[no_mangle] +pub unsafe fn f(x: &mut [u64; 4]) { + std::mem::swap(x, &mut STATIC_VAR_1) +} + +#[no_mangle] +pub unsafe fn g(x: &mut [u64; 4]) { + std::mem::swap(x, &mut STATIC_VAR_2) +} diff --git a/src/test/compile-fail-fulldeps/proc-macro/lints_in_proc_macros.rs b/src/test/compile-fail-fulldeps/proc-macro/lints_in_proc_macros.rs index 98e50183097cc..6473b69b4591d 100644 --- a/src/test/compile-fail-fulldeps/proc-macro/lints_in_proc_macros.rs +++ b/src/test/compile-fail-fulldeps/proc-macro/lints_in_proc_macros.rs @@ -23,5 +23,5 @@ fn main() { bang_proc_macro2!(); //~^ ERROR cannot find value `foobar2` in this scope //~^^ did you mean `foobar`? - println!("{}", x); //~ ERROR cannot find value `x` in this scope + println!("{}", x); } diff --git a/src/test/compile-fail/issue-36122.rs b/src/test/compile-fail/issue-36122.rs new file mode 100644 index 0000000000000..ef3f7156d6070 --- /dev/null +++ b/src/test/compile-fail/issue-36122.rs @@ -0,0 +1,22 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// ignore-tidy-linelength + +fn main() { + extern "C" { + static symbol: [usize]; + //~^ ERROR the size for value values of type `[usize]` cannot be known at compilation time [E0277] + } + + unsafe { + println!("{}", symbol[0]); + } +} diff --git a/src/test/compile-fail/panic-implementation-missing.rs b/src/test/compile-fail/panic-implementation-missing.rs new file mode 100644 index 0000000000000..b11081a3e3bbe --- /dev/null +++ b/src/test/compile-fail/panic-implementation-missing.rs @@ -0,0 +1,18 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// error-pattern: `#[panic_implementation]` function required, but not found + +#![feature(lang_items)] +#![no_main] +#![no_std] + +#[lang = "eh_personality"] +fn eh() {} diff --git a/src/test/compile-fail/weak-lang-item.rs b/src/test/compile-fail/weak-lang-item.rs index 7b988c3595f5e..42972c40674b6 100644 --- a/src/test/compile-fail/weak-lang-item.rs +++ b/src/test/compile-fail/weak-lang-item.rs @@ -9,7 +9,7 @@ // except according to those terms. // aux-build:weak-lang-items.rs -// error-pattern: language item required, but not found: `panic_impl` +// error-pattern: `#[panic_implementation]` function required, but not found // error-pattern: language item required, but not found: `eh_personality` // ignore-wasm32-bare compiled with panic=abort, personality not required diff --git a/src/test/run-pass-fulldeps/proc-macro/auxiliary/call-site.rs b/src/test/run-pass-fulldeps/proc-macro/auxiliary/call-site.rs new file mode 100644 index 0000000000000..ab4e082ed74fc --- /dev/null +++ b/src/test/run-pass-fulldeps/proc-macro/auxiliary/call-site.rs @@ -0,0 +1,37 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// no-prefer-dynamic + +#![crate_type = "proc-macro"] +#![feature(proc_macro)] + +extern crate proc_macro; +use proc_macro::*; + +#[proc_macro] +pub fn check(input: TokenStream) -> TokenStream { + // Parsed `x2` can refer to `x2` from `input` + let parsed1: TokenStream = "let x3 = x2;".parse().unwrap(); + // `x3` parsed from one string can refer to `x3` parsed from another string. + let parsed2: TokenStream = "let x4 = x3;".parse().unwrap(); + // Manually assembled `x4` can refer to parsed `x4`. + let manual: Vec = vec![ + Ident::new("let", Span::call_site()).into(), + Ident::new("x5", Span::call_site()).into(), + Punct::new('=', Spacing::Alone).into(), + Ident::new("x4", Span::call_site()).into(), + Punct::new(';', Spacing::Alone).into(), + ]; + input.into_iter().chain(parsed1.into_iter()) + .chain(parsed2.into_iter()) + .chain(manual.into_iter()) + .collect() +} diff --git a/src/test/run-pass-fulldeps/proc-macro/call-site.rs b/src/test/run-pass-fulldeps/proc-macro/call-site.rs new file mode 100644 index 0000000000000..f0d48972894ae --- /dev/null +++ b/src/test/run-pass-fulldeps/proc-macro/call-site.rs @@ -0,0 +1,23 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// aux-build:call-site.rs +// ignore-stage1 + +#![feature(proc_macro, proc_macro_non_items)] + +extern crate call_site; +use call_site::*; + +fn main() { + let x1 = 10; + call_site::check!(let x2 = x1;); + let x6 = x5; +} diff --git a/src/test/run-pass/issue-44056.rs b/src/test/run-pass/issue-44056.rs new file mode 100644 index 0000000000000..dcaa0bf86294a --- /dev/null +++ b/src/test/run-pass/issue-44056.rs @@ -0,0 +1,15 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// only-x86_64 +// no-prefer-dynamic +// compile-flags: -Ctarget-feature=+avx -Clto + +fn main() {} diff --git a/src/test/run-pass/issue-49854.rs b/src/test/run-pass/issue-49854.rs new file mode 100644 index 0000000000000..5bb80b5e2c6a1 --- /dev/null +++ b/src/test/run-pass/issue-49854.rs @@ -0,0 +1,18 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use std::ffi::OsString; + +fn main() { + let os_str = OsString::from("Hello Rust!"); + + assert_eq!(os_str, "Hello Rust!"); + assert_eq!("Hello Rust!", os_str); +} diff --git a/src/test/ui/associated-const-impl-wrong-lifetime.stderr b/src/test/ui/associated-const-impl-wrong-lifetime.stderr index d800f4c727d70..f8375899e3e01 100644 --- a/src/test/ui/associated-const-impl-wrong-lifetime.stderr +++ b/src/test/ui/associated-const-impl-wrong-lifetime.stderr @@ -6,11 +6,11 @@ LL | const NAME: &'a str = "unit"; | = note: expected type `&'static str` found type `&'a str` -note: the lifetime 'a as defined on the impl at 17:1... - --> $DIR/associated-const-impl-wrong-lifetime.rs:17:1 +note: the lifetime 'a as defined on the impl at 17:6... + --> $DIR/associated-const-impl-wrong-lifetime.rs:17:6 | LL | impl<'a> Foo for &'a () { - | ^^^^^^^^^^^^^^^^^^^^^^^ + | ^^ = note: ...does not necessarily outlive the static lifetime error: aborting due to previous error diff --git a/src/test/ui/borrowck/borrowck-escaping-closure-error-2.nll.stderr b/src/test/ui/borrowck/borrowck-escaping-closure-error-2.nll.stderr index 2b5070977a39b..5448049a8017d 100644 --- a/src/test/ui/borrowck/borrowck-escaping-closure-error-2.nll.stderr +++ b/src/test/ui/borrowck/borrowck-escaping-closure-error-2.nll.stderr @@ -7,11 +7,11 @@ LL | //~^ ERROR E0373 LL | } | - borrowed value only lives until here | -note: borrowed value must be valid for the lifetime 'a as defined on the function body at 19:1... - --> $DIR/borrowck-escaping-closure-error-2.rs:19:1 +note: borrowed value must be valid for the lifetime 'a as defined on the function body at 19:8... + --> $DIR/borrowck-escaping-closure-error-2.rs:19:8 | LL | fn foo<'a>(x: &'a i32) -> Box { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^ error: aborting due to previous error diff --git a/src/test/ui/borrowck/regions-bound-missing-bound-in-impl.rs b/src/test/ui/borrowck/regions-bound-missing-bound-in-impl.rs index 617de2c5dfe84..04f90ea9ad3a2 100644 --- a/src/test/ui/borrowck/regions-bound-missing-bound-in-impl.rs +++ b/src/test/ui/borrowck/regions-bound-missing-bound-in-impl.rs @@ -20,6 +20,7 @@ pub trait Foo<'a, 't> { fn no_bound<'b>(self, b: Inv<'b>); fn has_bound<'b:'a>(self, b: Inv<'b>); fn wrong_bound1<'b,'c,'d:'a+'b>(self, b: Inv<'b>, c: Inv<'c>, d: Inv<'d>); + fn wrong_bound2<'b,'c,'d:'a+'b>(self, b: Inv<'b>, c: Inv<'c>, d: Inv<'d>); fn okay_bound<'b,'c,'d:'a+'b+'c>(self, b: Inv<'b>, c: Inv<'c>, d: Inv<'d>); fn another_bound<'x: 'a>(self, x: Inv<'x>, y: Inv<'t>); } @@ -47,6 +48,10 @@ impl<'a, 't> Foo<'a, 't> for &'a isize { // cases. } + fn wrong_bound2(self, b: Inv, c: Inv, d: Inv) { + //~^ ERROR lifetime parameters or bounds on method `wrong_bound2` do not match the trait + } + fn okay_bound<'b,'c,'e:'b+'c>(self, b: Inv<'b>, c: Inv<'c>, e: Inv<'e>) { } diff --git a/src/test/ui/borrowck/regions-bound-missing-bound-in-impl.stderr b/src/test/ui/borrowck/regions-bound-missing-bound-in-impl.stderr index b58dbd1e4d1c9..b139369014e44 100644 --- a/src/test/ui/borrowck/regions-bound-missing-bound-in-impl.stderr +++ b/src/test/ui/borrowck/regions-bound-missing-bound-in-impl.stderr @@ -1,42 +1,51 @@ error[E0195]: lifetime parameters or bounds on method `no_bound` do not match the trait declaration - --> $DIR/regions-bound-missing-bound-in-impl.rs:28:5 + --> $DIR/regions-bound-missing-bound-in-impl.rs:29:16 | LL | fn no_bound<'b>(self, b: Inv<'b>); - | ---------------------------------- lifetimes in impl do not match this method in trait + | ---- lifetimes in impl do not match this method in trait ... LL | fn no_bound<'b:'a>(self, b: Inv<'b>) { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ lifetimes do not match method in trait + | ^^^^^^^ lifetimes do not match method in trait error[E0195]: lifetime parameters or bounds on method `has_bound` do not match the trait declaration - --> $DIR/regions-bound-missing-bound-in-impl.rs:32:5 + --> $DIR/regions-bound-missing-bound-in-impl.rs:33:17 | LL | fn has_bound<'b:'a>(self, b: Inv<'b>); - | -------------------------------------- lifetimes in impl do not match this method in trait + | ------- lifetimes in impl do not match this method in trait ... LL | fn has_bound<'b>(self, b: Inv<'b>) { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ lifetimes do not match method in trait + | ^^^^ lifetimes do not match method in trait error[E0308]: method not compatible with trait - --> $DIR/regions-bound-missing-bound-in-impl.rs:36:5 + --> $DIR/regions-bound-missing-bound-in-impl.rs:37:5 | LL | fn wrong_bound1<'b,'c,'d:'a+'c>(self, b: Inv<'b>, c: Inv<'c>, d: Inv<'d>) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ lifetime mismatch | = note: expected type `fn(&'a isize, Inv<'c>, Inv<'c>, Inv<'d>)` found type `fn(&'a isize, Inv<'_>, Inv<'c>, Inv<'d>)` -note: the lifetime 'c as defined on the method body at 36:5... - --> $DIR/regions-bound-missing-bound-in-impl.rs:36:5 +note: the lifetime 'c as defined on the method body at 37:24... + --> $DIR/regions-bound-missing-bound-in-impl.rs:37:24 | LL | fn wrong_bound1<'b,'c,'d:'a+'c>(self, b: Inv<'b>, c: Inv<'c>, d: Inv<'d>) { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: ...does not necessarily outlive the lifetime 'c as defined on the method body at 36:5 - --> $DIR/regions-bound-missing-bound-in-impl.rs:36:5 + | ^^ +note: ...does not necessarily outlive the lifetime 'c as defined on the method body at 37:24 + --> $DIR/regions-bound-missing-bound-in-impl.rs:37:24 | LL | fn wrong_bound1<'b,'c,'d:'a+'c>(self, b: Inv<'b>, c: Inv<'c>, d: Inv<'d>) { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^ + +error[E0195]: lifetime parameters or bounds on method `wrong_bound2` do not match the trait declaration + --> $DIR/regions-bound-missing-bound-in-impl.rs:51:5 + | +LL | fn wrong_bound2<'b,'c,'d:'a+'b>(self, b: Inv<'b>, c: Inv<'c>, d: Inv<'d>); + | ---------------- lifetimes in impl do not match this method in trait +... +LL | fn wrong_bound2(self, b: Inv, c: Inv, d: Inv) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ lifetimes do not match method in trait error[E0276]: impl has stricter requirements than trait - --> $DIR/regions-bound-missing-bound-in-impl.rs:53:5 + --> $DIR/regions-bound-missing-bound-in-impl.rs:58:5 | LL | fn another_bound<'x: 'a>(self, x: Inv<'x>, y: Inv<'t>); | ------------------------------------------------------- definition of `another_bound` from trait @@ -44,7 +53,7 @@ LL | fn another_bound<'x: 'a>(self, x: Inv<'x>, y: Inv<'t>); LL | fn another_bound<'x: 't>(self, x: Inv<'x>, y: Inv<'t>) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl has extra requirement `'x: 't` -error: aborting due to 4 previous errors +error: aborting due to 5 previous errors Some errors occurred: E0195, E0276, E0308. For more information about an error, try `rustc --explain E0195`. diff --git a/src/test/ui/closure-expected-type/expect-region-supply-region.stderr b/src/test/ui/closure-expected-type/expect-region-supply-region.stderr index 8184616c97ff3..56b43bbd7d34c 100644 --- a/src/test/ui/closure-expected-type/expect-region-supply-region.stderr +++ b/src/test/ui/closure-expected-type/expect-region-supply-region.stderr @@ -38,11 +38,11 @@ LL | | LL | | //~^ ERROR borrowed data cannot be stored outside of its closure LL | | }); | |_____^ -note: ...does not necessarily outlive the lifetime 'x as defined on the function body at 42:1 - --> $DIR/expect-region-supply-region.rs:42:1 +note: ...does not necessarily outlive the lifetime 'x as defined on the function body at 42:30 + --> $DIR/expect-region-supply-region.rs:42:30 | LL | fn expect_bound_supply_named<'x>() { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^ error[E0308]: mismatched types --> $DIR/expect-region-supply-region.rs:47:33 @@ -52,11 +52,11 @@ LL | closure_expecting_bound(|x: &'x u32| { | = note: expected type `&u32` found type `&'x u32` -note: the lifetime 'x as defined on the function body at 42:1... - --> $DIR/expect-region-supply-region.rs:42:1 +note: the lifetime 'x as defined on the function body at 42:30... + --> $DIR/expect-region-supply-region.rs:42:30 | LL | fn expect_bound_supply_named<'x>() { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^ note: ...does not necessarily outlive the anonymous lifetime #2 defined on the body at 47:29 --> $DIR/expect-region-supply-region.rs:47:29 | diff --git a/src/test/ui/error-codes/E0195.stderr b/src/test/ui/error-codes/E0195.stderr index f2cf661830d8a..3860c93a45f49 100644 --- a/src/test/ui/error-codes/E0195.stderr +++ b/src/test/ui/error-codes/E0195.stderr @@ -1,11 +1,11 @@ error[E0195]: lifetime parameters or bounds on method `bar` do not match the trait declaration - --> $DIR/E0195.rs:19:5 + --> $DIR/E0195.rs:19:11 | LL | fn bar<'a,'b:'a>(x: &'a str, y: &'b str); - | ----------------------------------------- lifetimes in impl do not match this method in trait + | ---------- lifetimes in impl do not match this method in trait ... LL | fn bar<'a,'b>(x: &'a str, y: &'b str) { //~ ERROR E0195 - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ lifetimes do not match method in trait + | ^^^^^^^ lifetimes do not match method in trait error: aborting due to previous error diff --git a/src/test/ui/error-codes/E0478.stderr b/src/test/ui/error-codes/E0478.stderr index 44d8151303f72..0e778908058e0 100644 --- a/src/test/ui/error-codes/E0478.stderr +++ b/src/test/ui/error-codes/E0478.stderr @@ -4,16 +4,16 @@ error[E0478]: lifetime bound not satisfied LL | child: Box + 'SnowWhite>, //~ ERROR E0478 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | -note: lifetime parameter instantiated with the lifetime 'SnowWhite as defined on the struct at 13:1 - --> $DIR/E0478.rs:13:1 +note: lifetime parameter instantiated with the lifetime 'SnowWhite as defined on the struct at 13:22 + --> $DIR/E0478.rs:13:22 | LL | struct Prince<'kiss, 'SnowWhite> { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: but lifetime parameter must outlive the lifetime 'kiss as defined on the struct at 13:1 - --> $DIR/E0478.rs:13:1 + | ^^^^^^^^^^ +note: but lifetime parameter must outlive the lifetime 'kiss as defined on the struct at 13:15 + --> $DIR/E0478.rs:13:15 | LL | struct Prince<'kiss, 'SnowWhite> { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^ error: aborting due to previous error diff --git a/src/test/ui/hygiene/auxiliary/intercrate.rs b/src/test/ui/hygiene/auxiliary/intercrate.rs index aa67e5c5f4db7..f917fabbe0c58 100644 --- a/src/test/ui/hygiene/auxiliary/intercrate.rs +++ b/src/test/ui/hygiene/auxiliary/intercrate.rs @@ -19,3 +19,38 @@ pub mod foo { } } } + +pub struct SomeType; + +// `$crate` +pub macro uses_dollar_crate_modern() { + type Alias = $crate::SomeType; +} + +pub macro define_uses_dollar_crate_modern_nested($uses_dollar_crate_modern_nested: ident) { + macro $uses_dollar_crate_modern_nested() { + type AliasCrateModernNested = $crate::SomeType; + } +} + +#[macro_export] +macro_rules! define_uses_dollar_crate_legacy_nested { + () => { + macro_rules! uses_dollar_crate_legacy_nested { + () => { + type AliasLegacyNested = $crate::SomeType; + } + } + } +} + +// `crate` +pub macro uses_crate_modern() { + type AliasCrate = crate::SomeType; +} + +pub macro define_uses_crate_modern_nested($uses_crate_modern_nested: ident) { + macro $uses_crate_modern_nested() { + type AliasCrateModernNested = crate::SomeType; + } +} diff --git a/src/test/ui/hygiene/auxiliary/transparent-basic.rs b/src/test/ui/hygiene/auxiliary/transparent-basic.rs new file mode 100644 index 0000000000000..ba65c5f4da80c --- /dev/null +++ b/src/test/ui/hygiene/auxiliary/transparent-basic.rs @@ -0,0 +1,16 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(decl_macro, rustc_attrs)] + +#[rustc_transparent_macro] +pub macro dollar_crate() { + let s = $crate::S; +} diff --git a/src/test/ui/hygiene/dollar-crate-modern.rs b/src/test/ui/hygiene/dollar-crate-modern.rs new file mode 100644 index 0000000000000..6e536ab142215 --- /dev/null +++ b/src/test/ui/hygiene/dollar-crate-modern.rs @@ -0,0 +1,35 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Make sure `$crate` and `crate` work in for basic cases of nested macros. + +// compile-pass +// aux-build:intercrate.rs + +#![feature(decl_macro, crate_in_paths)] + +extern crate intercrate; + +// `$crate` +intercrate::uses_dollar_crate_modern!(); + +intercrate::define_uses_dollar_crate_modern_nested!(uses_dollar_crate_modern_nested); +uses_dollar_crate_modern_nested!(); + +intercrate::define_uses_dollar_crate_legacy_nested!(); +uses_dollar_crate_legacy_nested!(); + +// `crate` +intercrate::uses_crate_modern!(); + +intercrate::define_uses_crate_modern_nested!(uses_crate_modern_nested); +uses_crate_modern_nested!(); + +fn main() {} diff --git a/src/test/ui/hygiene/generate-mod.rs b/src/test/ui/hygiene/generate-mod.rs new file mode 100644 index 0000000000000..90409857deadc --- /dev/null +++ b/src/test/ui/hygiene/generate-mod.rs @@ -0,0 +1,24 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// This is an equivalent of issue #50504, but for declarative macros. + +#![feature(decl_macro, rustc_attrs)] + +#[rustc_transparent_macro] +macro genmod() { + mod m { + type A = S; //~ ERROR cannot find type `S` in this scope + } +} + +struct S; + +genmod!(); diff --git a/src/test/ui/hygiene/generate-mod.stderr b/src/test/ui/hygiene/generate-mod.stderr new file mode 100644 index 0000000000000..e79f8528c2cd7 --- /dev/null +++ b/src/test/ui/hygiene/generate-mod.stderr @@ -0,0 +1,17 @@ +error[E0412]: cannot find type `S` in this scope + --> $DIR/generate-mod.rs:18:18 + | +LL | type A = S; //~ ERROR cannot find type `S` in this scope + | ^ did you mean `A`? +... +LL | genmod!(); + | ---------- 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 + +Some errors occurred: E0412, E0601. +For more information about an error, try `rustc --explain E0412`. diff --git a/src/test/ui/hygiene/transparent-basic.rs b/src/test/ui/hygiene/transparent-basic.rs new file mode 100644 index 0000000000000..81ece1f11bc6a --- /dev/null +++ b/src/test/ui/hygiene/transparent-basic.rs @@ -0,0 +1,53 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// compile-pass +// aux-build:transparent-basic.rs + +#![feature(decl_macro, rustc_attrs)] + +extern crate transparent_basic; + +#[rustc_transparent_macro] +macro binding() { + let x = 10; +} + +#[rustc_transparent_macro] +macro label() { + break 'label +} + +macro_rules! legacy { + () => { + binding!(); + let y = x; + } +} + +fn legacy_interaction1() { + legacy!(); +} + +struct S; + +fn check_dollar_crate() { + // `$crate::S` inside the macro resolves to `S` from this crate. + transparent_basic::dollar_crate!(); +} + +fn main() { + binding!(); + let y = x; + + 'label: loop { + label!(); + } +} diff --git a/src/test/ui/impl-trait/region-escape-via-bound.stderr b/src/test/ui/impl-trait/region-escape-via-bound.stderr index b673111d21986..92464a2430169 100644 --- a/src/test/ui/impl-trait/region-escape-via-bound.stderr +++ b/src/test/ui/impl-trait/region-escape-via-bound.stderr @@ -4,16 +4,11 @@ error[E0700]: hidden type for `impl Trait` captures lifetime that does not appea LL | fn foo(x: Cell<&'x u32>) -> impl Trait<'y> | ^^^^^^^^^^^^^^ | -note: hidden type `std::cell::Cell<&'x u32>` captures the lifetime 'x as defined on the function body at 26:1 - --> $DIR/region-escape-via-bound.rs:26:1 +note: hidden type `std::cell::Cell<&'x u32>` captures the lifetime 'x as defined on the function body at 28:7 + --> $DIR/region-escape-via-bound.rs:28:7 | -LL | / fn foo(x: Cell<&'x u32>) -> impl Trait<'y> -LL | | //~^ ERROR hidden type for `impl Trait` captures lifetime that does not appear in bounds [E0700] -LL | | where 'x: 'y -LL | | { -LL | | x -LL | | } - | |_^ +LL | where 'x: 'y + | ^^ error: aborting due to previous error diff --git a/src/test/ui/impl-trait/static-return-lifetime-infered.stderr b/src/test/ui/impl-trait/static-return-lifetime-infered.stderr index 2795bb92ed56f..083ad03ff8503 100644 --- a/src/test/ui/impl-trait/static-return-lifetime-infered.stderr +++ b/src/test/ui/impl-trait/static-return-lifetime-infered.stderr @@ -30,12 +30,12 @@ LL | self.x.iter().map(|a| a.0) | | | ...but this borrow... | -note: ...can't outlive the lifetime 'a as defined on the method body at 20:5 - --> $DIR/static-return-lifetime-infered.rs:20:5 +note: ...can't outlive the lifetime 'a as defined on the method body at 20:20 + --> $DIR/static-return-lifetime-infered.rs:20:20 | LL | fn iter_values<'a>(&'a self) -> impl Iterator { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -help: you can add a constraint to the return type to make it last less than `'static` and match the lifetime 'a as defined on the method body at 20:5 + | ^^ +help: you can add a constraint to the return type to make it last less than `'static` and match the lifetime 'a as defined on the method body at 20:20 | LL | fn iter_values<'a>(&'a self) -> impl Iterator + 'a { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/in-band-lifetimes/impl/dyn-trait.stderr b/src/test/ui/in-band-lifetimes/impl/dyn-trait.stderr index 07b86228f6118..3e54ebeb398d6 100644 --- a/src/test/ui/in-band-lifetimes/impl/dyn-trait.stderr +++ b/src/test/ui/in-band-lifetimes/impl/dyn-trait.stderr @@ -4,11 +4,11 @@ error[E0495]: cannot infer an appropriate lifetime due to conflicting requiremen LL | static_val(x); //~ ERROR cannot infer | ^ | -note: first, the lifetime cannot outlive the lifetime 'a as defined on the function body at 31:1... - --> $DIR/dyn-trait.rs:31:1 +note: first, the lifetime cannot outlive the lifetime 'a as defined on the function body at 31:26... + --> $DIR/dyn-trait.rs:31:26 | LL | fn with_dyn_debug_static<'a>(x: Box) { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^ = note: ...so that the expression is assignable: expected std::boxed::Box found std::boxed::Box<(dyn std::fmt::Debug + 'a)> diff --git a/src/test/ui/in-band-lifetimes/mismatched_trait_impl.stderr b/src/test/ui/in-band-lifetimes/mismatched_trait_impl.stderr index 675ae1695b55f..f2c6155fd98f8 100644 --- a/src/test/ui/in-band-lifetimes/mismatched_trait_impl.stderr +++ b/src/test/ui/in-band-lifetimes/mismatched_trait_impl.stderr @@ -11,11 +11,11 @@ LL | / fn foo(&self, x: &u32, y: &'a u32) -> &'a u32 { //~ ERROR cannot infe LL | | x LL | | } | |_____^ -note: ...but the lifetime must also be valid for the lifetime 'a as defined on the method body at 19:5... - --> $DIR/mismatched_trait_impl.rs:19:5 +note: ...but the lifetime must also be valid for the lifetime 'a as defined on the method body at 19:32... + --> $DIR/mismatched_trait_impl.rs:19:32 | LL | fn foo(&self, x: &u32, y: &'a u32) -> &'a u32 { //~ ERROR cannot infer - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^ = note: ...so that the method type is compatible with trait: expected fn(&i32, &'a u32, &u32) -> &'a u32 found fn(&i32, &u32, &u32) -> &u32 diff --git a/src/test/ui/issue-27942.stderr b/src/test/ui/issue-27942.stderr index 879eda0f85640..5e2ecbb05aebc 100644 --- a/src/test/ui/issue-27942.stderr +++ b/src/test/ui/issue-27942.stderr @@ -11,11 +11,11 @@ note: the anonymous lifetime #1 defined on the method body at 15:5... | LL | fn select(&self) -> BufferViewHandle; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: ...does not necessarily outlive the lifetime 'a as defined on the trait at 13:1 - --> $DIR/issue-27942.rs:13:1 +note: ...does not necessarily outlive the lifetime 'a as defined on the trait at 13:18 + --> $DIR/issue-27942.rs:13:18 | LL | pub trait Buffer<'a, R: Resources<'a>> { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^ error[E0308]: mismatched types --> $DIR/issue-27942.rs:15:5 @@ -25,11 +25,11 @@ LL | fn select(&self) -> BufferViewHandle; | = note: expected type `Resources<'_>` found type `Resources<'a>` -note: the lifetime 'a as defined on the trait at 13:1... - --> $DIR/issue-27942.rs:13:1 +note: the lifetime 'a as defined on the trait at 13:18... + --> $DIR/issue-27942.rs:13:18 | LL | pub trait Buffer<'a, R: Resources<'a>> { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^ note: ...does not necessarily outlive the anonymous lifetime #1 defined on the method body at 15:5 --> $DIR/issue-27942.rs:15:5 | diff --git a/src/test/ui/issue-37884.stderr b/src/test/ui/issue-37884.stderr index 73fbb2d320388..f01b623aced42 100644 --- a/src/test/ui/issue-37884.stderr +++ b/src/test/ui/issue-37884.stderr @@ -21,11 +21,11 @@ LL | | { LL | | Some(&mut self.0) LL | | } | |_____^ -note: ...does not necessarily outlive the lifetime 'a as defined on the impl at 13:1 - --> $DIR/issue-37884.rs:13:1 +note: ...does not necessarily outlive the lifetime 'a as defined on the impl at 13:6 + --> $DIR/issue-37884.rs:13:6 | LL | impl<'a, T: 'a> Iterator for RepeatMut<'a, T> { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^ error: aborting due to previous error diff --git a/src/test/ui/issue-4335.nll.stderr b/src/test/ui/issue-4335.nll.stderr index 7f4273bc8c770..8eede34747827 100644 --- a/src/test/ui/issue-4335.nll.stderr +++ b/src/test/ui/issue-4335.nll.stderr @@ -13,11 +13,11 @@ LL | id(Box::new(|| *v)) LL | } | - borrowed value only lives until here | -note: borrowed value must be valid for the lifetime 'r as defined on the function body at 15:1... - --> $DIR/issue-4335.rs:15:1 +note: borrowed value must be valid for the lifetime 'r as defined on the function body at 15:6... + --> $DIR/issue-4335.rs:15:6 | LL | fn f<'r, T>(v: &'r T) -> Box T + 'r> { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^ error: aborting due to 2 previous errors diff --git a/src/test/ui/issue-46472.stderr b/src/test/ui/issue-46472.stderr index 9b55b78b43d57..9e5acf56d26ca 100644 --- a/src/test/ui/issue-46472.stderr +++ b/src/test/ui/issue-46472.stderr @@ -7,11 +7,11 @@ LL | &mut 4 LL | } | - temporary value only lives until here | -note: borrowed value must be valid for the lifetime 'a as defined on the function body at 13:1... - --> $DIR/issue-46472.rs:13:1 +note: borrowed value must be valid for the lifetime 'a as defined on the function body at 13:8... + --> $DIR/issue-46472.rs:13:8 | LL | fn bar<'a>() -> &'a mut u32 { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^ error[E0597]: borrowed value does not live long enough (Mir) --> $DIR/issue-46472.rs:14:10 @@ -22,11 +22,11 @@ LL | &mut 4 LL | } | - temporary value only lives until here | -note: borrowed value must be valid for the lifetime 'a as defined on the function body at 13:1... - --> $DIR/issue-46472.rs:13:1 +note: borrowed value must be valid for the lifetime 'a as defined on the function body at 13:8... + --> $DIR/issue-46472.rs:13:8 | LL | fn bar<'a>() -> &'a mut u32 { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^ error: aborting due to 2 previous errors diff --git a/src/test/ui/issue-51874.rs b/src/test/ui/issue-51874.rs new file mode 100644 index 0000000000000..63425274d4c49 --- /dev/null +++ b/src/test/ui/issue-51874.rs @@ -0,0 +1,13 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +fn main() { + let a = (1.0).pow(1.0); //~ ERROR can't call method `pow` on ambiguous numeric type +} diff --git a/src/test/ui/issue-51874.stderr b/src/test/ui/issue-51874.stderr new file mode 100644 index 0000000000000..8674645357189 --- /dev/null +++ b/src/test/ui/issue-51874.stderr @@ -0,0 +1,13 @@ +error[E0689]: can't call method `pow` on ambiguous numeric type `{float}` + --> $DIR/issue-51874.rs:12:19 + | +LL | let a = (1.0).pow(1.0); //~ ERROR can't call method `pow` on ambiguous numeric type + | ^^^ +help: you must specify a concrete type for this numeric value, like `f32` + | +LL | let a = (1.0_f32).pow(1.0); //~ ERROR can't call method `pow` on ambiguous numeric type + | ^^^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0689`. diff --git a/src/test/ui/nll/borrowed-universal-error-2.stderr b/src/test/ui/nll/borrowed-universal-error-2.stderr index 467b02d207dd2..ea7d819938443 100644 --- a/src/test/ui/nll/borrowed-universal-error-2.stderr +++ b/src/test/ui/nll/borrowed-universal-error-2.stderr @@ -7,11 +7,11 @@ LL | //~^ ERROR `v` does not live long enough [E0597] LL | } | - borrowed value only lives until here | -note: borrowed value must be valid for the lifetime 'a as defined on the function body at 14:1... - --> $DIR/borrowed-universal-error-2.rs:14:1 +note: borrowed value must be valid for the lifetime 'a as defined on the function body at 14:8... + --> $DIR/borrowed-universal-error-2.rs:14:8 | LL | fn foo<'a>(x: &'a (u32,)) -> &'a u32 { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^ error: aborting due to previous error diff --git a/src/test/ui/nll/borrowed-universal-error.stderr b/src/test/ui/nll/borrowed-universal-error.stderr index 94d9bb36fa428..da287980e8c5f 100644 --- a/src/test/ui/nll/borrowed-universal-error.stderr +++ b/src/test/ui/nll/borrowed-universal-error.stderr @@ -7,11 +7,11 @@ LL | //~^ ERROR borrowed value does not live long enough [E0597] LL | } | - temporary value only lives until here | -note: borrowed value must be valid for the lifetime 'a as defined on the function body at 18:1... - --> $DIR/borrowed-universal-error.rs:18:1 +note: borrowed value must be valid for the lifetime 'a as defined on the function body at 18:8... + --> $DIR/borrowed-universal-error.rs:18:8 | LL | fn foo<'a>(x: &'a (u32,)) -> &'a u32 { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^ error: aborting due to previous error diff --git a/src/test/ui/nll/issue-31567.stderr b/src/test/ui/nll/issue-31567.stderr index 579dc7eba8c85..065de6ea600b4 100644 --- a/src/test/ui/nll/issue-31567.stderr +++ b/src/test/ui/nll/issue-31567.stderr @@ -7,11 +7,11 @@ LL | &s_inner.0 LL | } | - borrowed value only lives until here | -note: borrowed value must be valid for the lifetime 'a as defined on the function body at 21:1... - --> $DIR/issue-31567.rs:21:1 +note: borrowed value must be valid for the lifetime 'a as defined on the function body at 21:17... + --> $DIR/issue-31567.rs:21:17 | LL | fn get_dangling<'a>(v: VecWrapper<'a>) -> &'a u32 { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^ error: aborting due to previous error diff --git a/src/test/ui/nll/issue-47470.stderr b/src/test/ui/nll/issue-47470.stderr index f84a68d85b95f..a89e186540a47 100644 --- a/src/test/ui/nll/issue-47470.stderr +++ b/src/test/ui/nll/issue-47470.stderr @@ -6,11 +6,11 @@ LL | &local //~ ERROR `local` does not live long enough LL | } | - borrowed value only lives until here | -note: borrowed value must be valid for the lifetime 'a as defined on the impl at 23:1... - --> $DIR/issue-47470.rs:23:1 +note: borrowed value must be valid for the lifetime 'a as defined on the impl at 23:6... + --> $DIR/issue-47470.rs:23:6 | LL | impl<'a> Bar for Foo<'a> { - | ^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^ error: aborting due to previous error diff --git a/src/test/ui/nll/normalization-bounds-error.stderr b/src/test/ui/nll/normalization-bounds-error.stderr index 970384f9d56ff..3548219361fc7 100644 --- a/src/test/ui/nll/normalization-bounds-error.stderr +++ b/src/test/ui/nll/normalization-bounds-error.stderr @@ -4,16 +4,16 @@ error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'d` d LL | fn visit_seq<'d, 'a: 'd>() -> <&'a () as Visitor<'d>>::Value {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | -note: first, the lifetime cannot outlive the lifetime 'd as defined on the function body at 23:1... - --> $DIR/normalization-bounds-error.rs:23:1 +note: first, the lifetime cannot outlive the lifetime 'd as defined on the function body at 23:14... + --> $DIR/normalization-bounds-error.rs:23:14 | LL | fn visit_seq<'d, 'a: 'd>() -> <&'a () as Visitor<'d>>::Value {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: ...but the lifetime must also be valid for the lifetime 'a as defined on the function body at 23:1... - --> $DIR/normalization-bounds-error.rs:23:1 + | ^^ +note: ...but the lifetime must also be valid for the lifetime 'a as defined on the function body at 23:18... + --> $DIR/normalization-bounds-error.rs:23:18 | LL | fn visit_seq<'d, 'a: 'd>() -> <&'a () as Visitor<'d>>::Value {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^ = note: ...so that the types are compatible: expected Visitor<'d> found Visitor<'_> diff --git a/src/test/ui/nll/trait-associated-constant.stderr b/src/test/ui/nll/trait-associated-constant.stderr index 2c3fd091f9a0d..07972ecced313 100644 --- a/src/test/ui/nll/trait-associated-constant.stderr +++ b/src/test/ui/nll/trait-associated-constant.stderr @@ -6,16 +6,16 @@ LL | const AC: Option<&'c str> = None; | = note: expected type `std::option::Option<&'b str>` found type `std::option::Option<&'c str>` -note: the lifetime 'c as defined on the impl at 30:1... - --> $DIR/trait-associated-constant.rs:30:1 +note: the lifetime 'c as defined on the impl at 30:18... + --> $DIR/trait-associated-constant.rs:30:18 | LL | impl<'a: 'b, 'b, 'c> Anything<'a, 'b> for FailStruct1 { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: ...does not necessarily outlive the lifetime 'b as defined on the impl at 30:1 - --> $DIR/trait-associated-constant.rs:30:1 + | ^^ +note: ...does not necessarily outlive the lifetime 'b as defined on the impl at 30:14 + --> $DIR/trait-associated-constant.rs:30:14 | LL | impl<'a: 'b, 'b, 'c> Anything<'a, 'b> for FailStruct1 { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^ error[E0308]: mismatched types --> $DIR/trait-associated-constant.rs:38:5 @@ -25,16 +25,16 @@ LL | const AC: Option<&'a str> = None; | = note: expected type `std::option::Option<&'b str>` found type `std::option::Option<&'a str>` -note: the lifetime 'a as defined on the impl at 37:1... - --> $DIR/trait-associated-constant.rs:37:1 +note: the lifetime 'a as defined on the impl at 37:6... + --> $DIR/trait-associated-constant.rs:37:6 | LL | impl<'a: 'b, 'b> Anything<'a, 'b> for FailStruct2 { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: ...does not necessarily outlive the lifetime 'b as defined on the impl at 37:1 - --> $DIR/trait-associated-constant.rs:37:1 + | ^^ +note: ...does not necessarily outlive the lifetime 'b as defined on the impl at 37:14 + --> $DIR/trait-associated-constant.rs:37:14 | LL | impl<'a: 'b, 'b> Anything<'a, 'b> for FailStruct2 { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^ error: aborting due to 2 previous errors diff --git a/src/test/ui/region-borrow-params-issue-29793-small.nll.stderr b/src/test/ui/region-borrow-params-issue-29793-small.nll.stderr index 1a53c033baa53..443af08e1cc7c 100644 --- a/src/test/ui/region-borrow-params-issue-29793-small.nll.stderr +++ b/src/test/ui/region-borrow-params-issue-29793-small.nll.stderr @@ -43,11 +43,11 @@ LL | let f = |t: bool| if t { x } else { y }; // (separate errors for `x LL | }; | - borrowed value only lives until here | -note: borrowed value must be valid for the lifetime 'a as defined on the function body at 64:5... - --> $DIR/region-borrow-params-issue-29793-small.rs:64:5 +note: borrowed value must be valid for the lifetime 'a as defined on the function body at 64:10... + --> $DIR/region-borrow-params-issue-29793-small.rs:64:10 | LL | fn g<'a>(x: usize, y:usize) -> Box usize + 'a> { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^ error[E0597]: `y` does not live long enough --> $DIR/region-borrow-params-issue-29793-small.rs:65:17 @@ -58,11 +58,11 @@ LL | let f = |t: bool| if t { x } else { y }; // (separate errors for `x LL | }; | - borrowed value only lives until here | -note: borrowed value must be valid for the lifetime 'a as defined on the function body at 64:5... - --> $DIR/region-borrow-params-issue-29793-small.rs:64:5 +note: borrowed value must be valid for the lifetime 'a as defined on the function body at 64:10... + --> $DIR/region-borrow-params-issue-29793-small.rs:64:10 | LL | fn g<'a>(x: usize, y:usize) -> Box usize + 'a> { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^ error[E0597]: `x` does not live long enough --> $DIR/region-borrow-params-issue-29793-small.rs:76:17 @@ -73,11 +73,11 @@ LL | let f = |t: bool| if t { x } else { y }; // (separate errors for `x LL | }; | - borrowed value only lives until here | -note: borrowed value must be valid for the lifetime 'a as defined on the function body at 75:5... - --> $DIR/region-borrow-params-issue-29793-small.rs:75:5 +note: borrowed value must be valid for the lifetime 'a as defined on the function body at 75:10... + --> $DIR/region-borrow-params-issue-29793-small.rs:75:10 | LL | fn g<'a>(x: usize, y:usize) -> Box usize + 'a> { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^ error[E0597]: `y` does not live long enough --> $DIR/region-borrow-params-issue-29793-small.rs:76:17 @@ -88,11 +88,11 @@ LL | let f = |t: bool| if t { x } else { y }; // (separate errors for `x LL | }; | - borrowed value only lives until here | -note: borrowed value must be valid for the lifetime 'a as defined on the function body at 75:5... - --> $DIR/region-borrow-params-issue-29793-small.rs:75:5 +note: borrowed value must be valid for the lifetime 'a as defined on the function body at 75:10... + --> $DIR/region-borrow-params-issue-29793-small.rs:75:10 | LL | fn g<'a>(x: usize, y:usize) -> Box usize + 'a> { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^ error[E0597]: `x` does not live long enough --> $DIR/region-borrow-params-issue-29793-small.rs:100:21 @@ -103,11 +103,11 @@ LL | let f = |t: bool| if t { x } else { y }; // (separate errors fo LL | } | - borrowed value only lives until here | -note: borrowed value must be valid for the lifetime 'a as defined on the method body at 99:9... - --> $DIR/region-borrow-params-issue-29793-small.rs:99:9 +note: borrowed value must be valid for the lifetime 'a as defined on the method body at 99:14... + --> $DIR/region-borrow-params-issue-29793-small.rs:99:14 | LL | fn g<'a>(&self, x: usize, y:usize) -> Box usize + 'a> { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^ error[E0597]: `y` does not live long enough --> $DIR/region-borrow-params-issue-29793-small.rs:100:21 @@ -118,11 +118,11 @@ LL | let f = |t: bool| if t { x } else { y }; // (separate errors fo LL | } | - borrowed value only lives until here | -note: borrowed value must be valid for the lifetime 'a as defined on the method body at 99:9... - --> $DIR/region-borrow-params-issue-29793-small.rs:99:9 +note: borrowed value must be valid for the lifetime 'a as defined on the method body at 99:14... + --> $DIR/region-borrow-params-issue-29793-small.rs:99:14 | LL | fn g<'a>(&self, x: usize, y:usize) -> Box usize + 'a> { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^ error[E0597]: `x` does not live long enough --> $DIR/region-borrow-params-issue-29793-small.rs:114:21 @@ -133,11 +133,11 @@ LL | let f = |t: bool| if t { x } else { y }; // (separate errors fo LL | } | - borrowed value only lives until here | -note: borrowed value must be valid for the lifetime 'a as defined on the method body at 113:9... - --> $DIR/region-borrow-params-issue-29793-small.rs:113:9 +note: borrowed value must be valid for the lifetime 'a as defined on the method body at 113:14... + --> $DIR/region-borrow-params-issue-29793-small.rs:113:14 | LL | fn g<'a>(&self, x: usize, y:usize) -> Box usize + 'a> { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^ error[E0597]: `y` does not live long enough --> $DIR/region-borrow-params-issue-29793-small.rs:114:21 @@ -148,11 +148,11 @@ LL | let f = |t: bool| if t { x } else { y }; // (separate errors fo LL | } | - borrowed value only lives until here | -note: borrowed value must be valid for the lifetime 'a as defined on the method body at 113:9... - --> $DIR/region-borrow-params-issue-29793-small.rs:113:9 +note: borrowed value must be valid for the lifetime 'a as defined on the method body at 113:14... + --> $DIR/region-borrow-params-issue-29793-small.rs:113:14 | LL | fn g<'a>(&self, x: usize, y:usize) -> Box usize + 'a> { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^ error[E0597]: `x` does not live long enough --> $DIR/region-borrow-params-issue-29793-small.rs:142:21 @@ -163,11 +163,11 @@ LL | let f = |t: bool| if t { x } else { y }; // (separate errors fo LL | } | - borrowed value only lives until here | -note: borrowed value must be valid for the lifetime 'a as defined on the method body at 141:9... - --> $DIR/region-borrow-params-issue-29793-small.rs:141:9 +note: borrowed value must be valid for the lifetime 'a as defined on the method body at 141:14... + --> $DIR/region-borrow-params-issue-29793-small.rs:141:14 | LL | fn g<'a>(&self, x: usize, y:usize) -> Box usize + 'a> { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^ error[E0597]: `y` does not live long enough --> $DIR/region-borrow-params-issue-29793-small.rs:142:21 @@ -178,11 +178,11 @@ LL | let f = |t: bool| if t { x } else { y }; // (separate errors fo LL | } | - borrowed value only lives until here | -note: borrowed value must be valid for the lifetime 'a as defined on the method body at 141:9... - --> $DIR/region-borrow-params-issue-29793-small.rs:141:9 +note: borrowed value must be valid for the lifetime 'a as defined on the method body at 141:14... + --> $DIR/region-borrow-params-issue-29793-small.rs:141:14 | LL | fn g<'a>(&self, x: usize, y:usize) -> Box usize + 'a> { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^ error[E0597]: `x` does not live long enough --> $DIR/region-borrow-params-issue-29793-small.rs:157:21 @@ -193,11 +193,11 @@ LL | let f = |t: bool| if t { x } else { y }; // (separate errors fo LL | } | - borrowed value only lives until here | -note: borrowed value must be valid for the lifetime 'a as defined on the method body at 156:9... - --> $DIR/region-borrow-params-issue-29793-small.rs:156:9 +note: borrowed value must be valid for the lifetime 'a as defined on the method body at 156:14... + --> $DIR/region-borrow-params-issue-29793-small.rs:156:14 | LL | fn g<'a>(&self, x: usize, y:usize) -> Box usize + 'a> { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^ error[E0597]: `y` does not live long enough --> $DIR/region-borrow-params-issue-29793-small.rs:157:21 @@ -208,11 +208,11 @@ LL | let f = |t: bool| if t { x } else { y }; // (separate errors fo LL | } | - borrowed value only lives until here | -note: borrowed value must be valid for the lifetime 'a as defined on the method body at 156:9... - --> $DIR/region-borrow-params-issue-29793-small.rs:156:9 +note: borrowed value must be valid for the lifetime 'a as defined on the method body at 156:14... + --> $DIR/region-borrow-params-issue-29793-small.rs:156:14 | LL | fn g<'a>(&self, x: usize, y:usize) -> Box usize + 'a> { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^ error[E0597]: `x` does not live long enough --> $DIR/region-borrow-params-issue-29793-small.rs:185:21 @@ -223,11 +223,11 @@ LL | let f = |t: bool| if t { x } else { y }; // (separate errors fo LL | } | - borrowed value only lives until here | -note: borrowed value must be valid for the lifetime 'a as defined on the method body at 184:9... - --> $DIR/region-borrow-params-issue-29793-small.rs:184:9 +note: borrowed value must be valid for the lifetime 'a as defined on the method body at 184:14... + --> $DIR/region-borrow-params-issue-29793-small.rs:184:14 | LL | fn g<'a>(&self, x: usize, y:usize) -> Box usize + 'a> { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^ error[E0597]: `y` does not live long enough --> $DIR/region-borrow-params-issue-29793-small.rs:185:21 @@ -238,11 +238,11 @@ LL | let f = |t: bool| if t { x } else { y }; // (separate errors fo LL | } | - borrowed value only lives until here | -note: borrowed value must be valid for the lifetime 'a as defined on the method body at 184:9... - --> $DIR/region-borrow-params-issue-29793-small.rs:184:9 +note: borrowed value must be valid for the lifetime 'a as defined on the method body at 184:14... + --> $DIR/region-borrow-params-issue-29793-small.rs:184:14 | LL | fn g<'a>(&self, x: usize, y:usize) -> Box usize + 'a> { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^ error[E0597]: `x` does not live long enough --> $DIR/region-borrow-params-issue-29793-small.rs:199:21 @@ -253,11 +253,11 @@ LL | let f = |t: bool| if t { x } else { y }; // (separate errors fo LL | } | - borrowed value only lives until here | -note: borrowed value must be valid for the lifetime 'a as defined on the method body at 198:9... - --> $DIR/region-borrow-params-issue-29793-small.rs:198:9 +note: borrowed value must be valid for the lifetime 'a as defined on the method body at 198:14... + --> $DIR/region-borrow-params-issue-29793-small.rs:198:14 | LL | fn g<'a>(&self, x: usize, y:usize) -> Box usize + 'a> { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^ error[E0597]: `y` does not live long enough --> $DIR/region-borrow-params-issue-29793-small.rs:199:21 @@ -268,11 +268,11 @@ LL | let f = |t: bool| if t { x } else { y }; // (separate errors fo LL | } | - borrowed value only lives until here | -note: borrowed value must be valid for the lifetime 'a as defined on the method body at 198:9... - --> $DIR/region-borrow-params-issue-29793-small.rs:198:9 +note: borrowed value must be valid for the lifetime 'a as defined on the method body at 198:14... + --> $DIR/region-borrow-params-issue-29793-small.rs:198:14 | LL | fn g<'a>(&self, x: usize, y:usize) -> Box usize + 'a> { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^ error: aborting due to 20 previous errors diff --git a/src/test/ui/static-lifetime.stderr b/src/test/ui/static-lifetime.stderr index 4fe4e569df954..c38b8a96f9fc2 100644 --- a/src/test/ui/static-lifetime.stderr +++ b/src/test/ui/static-lifetime.stderr @@ -4,11 +4,11 @@ error[E0478]: lifetime bound not satisfied LL | impl<'a, A: Clone> Arbitrary for ::std::borrow::Cow<'a, A> {} //~ ERROR lifetime bound | ^^^^^^^^^ | -note: lifetime parameter instantiated with the lifetime 'a as defined on the impl at 13:1 - --> $DIR/static-lifetime.rs:13:1 +note: lifetime parameter instantiated with the lifetime 'a as defined on the impl at 13:6 + --> $DIR/static-lifetime.rs:13:6 | LL | impl<'a, A: Clone> Arbitrary for ::std::borrow::Cow<'a, A> {} //~ ERROR lifetime bound - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^ = note: but lifetime parameter must outlive the static lifetime error: aborting due to previous error diff --git a/src/test/ui/suggestions/placement-syntax.rs b/src/test/ui/suggestions/placement-syntax.rs new file mode 100644 index 0000000000000..39252597a23e8 --- /dev/null +++ b/src/test/ui/suggestions/placement-syntax.rs @@ -0,0 +1,17 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +fn main() { + let x = -5; + if x<-1 { + //~^ ERROR emplacement syntax is obsolete + println!("ok"); + } +} diff --git a/src/test/ui/suggestions/placement-syntax.stderr b/src/test/ui/suggestions/placement-syntax.stderr new file mode 100644 index 0000000000000..933ba96519c44 --- /dev/null +++ b/src/test/ui/suggestions/placement-syntax.stderr @@ -0,0 +1,14 @@ +error: emplacement syntax is obsolete (for now, anyway) + --> $DIR/placement-syntax.rs:13:8 + | +LL | if x<-1 { + | ^^^^ + | + = note: for more information, see +help: if you meant to write a comparison against a negative value, add a space in between `<` and `-` + | +LL | if x< -1 { + | ^^^ + +error: aborting due to previous error +