Skip to content

Commit 0da7098

Browse files
authoredAug 27, 2019
Rollup merge of #63761 - petrochenkov:procattrs, r=eddyb
Propagate spans and attributes from proc macro definitions Thanks to #63269 we now have spans and attributes from proc macro definitions available in metadata. However, that PR didn't actually put them into use! This PR finishes that work. Attributes `rustc_macro_transparency`, `allow_internal_unstable`, `allow_internal_unsafe`, `local_inner_macros`, `rustc_builtin_macro`, `stable`, `unstable`, `rustc_deprecated`, `deprecated` now have effect when applied to proc macro definition functions. From those attributes only `deprecated` is both stable and supposed to be used in new code. (`#![staged_api]` still cannot be used in proc macro crates for unrelated reasons though.) `Span::def_site` from the proc macro API now returns the correct location of the proc macro definition. Also, I made a mistake in #63269 (comment), loaded proc macros didn't actually use the resolver cache. This PR fixes the caching issue, now proc macros go through the `Resolver::macro_map` cache as well. (Also, the first commit turns `proc_macro::quote` into a regular built-in macro to reduce the number of places where `SyntaxExtension`s need to be manually created.)
2 parents 68597c7 + c476b55 commit 0da7098

21 files changed

+318
-172
lines changed
 

‎src/libproc_macro/lib.rs

+6-4
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,15 @@
1919

2020
#![feature(nll)]
2121
#![feature(staged_api)]
22+
#![feature(allow_internal_unstable)]
2223
#![feature(const_fn)]
24+
#![feature(decl_macro)]
2325
#![feature(extern_types)]
2426
#![feature(in_band_lifetimes)]
2527
#![feature(optin_builtin_traits)]
2628
#![feature(mem_take)]
2729
#![feature(non_exhaustive)]
30+
#![feature(rustc_attrs)]
2831
#![feature(specialization)]
2932

3033
#![recursion_limit="256"]
@@ -222,11 +225,10 @@ pub mod token_stream {
222225
///
223226
/// Unquoting is done with `$`, and works by taking the single next ident as the unquoted term.
224227
/// To quote `$` itself, use `$$`.
225-
///
226-
/// This is a dummy macro, the actual implementation is in `quote::quote`.`
227228
#[unstable(feature = "proc_macro_quote", issue = "54722")]
228-
#[macro_export]
229-
macro_rules! quote { () => {} }
229+
#[allow_internal_unstable(proc_macro_def_site)]
230+
#[cfg_attr(not(bootstrap), rustc_builtin_macro)]
231+
pub macro quote ($($t:tt)*) { /* compiler built-in */ }
230232

231233
#[unstable(feature = "proc_macro_internals", issue = "27812")]
232234
#[doc(hidden)]

‎src/libproc_macro/quote.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -57,9 +57,9 @@ macro_rules! quote {
5757
}
5858

5959
/// Quote a `TokenStream` into a `TokenStream`.
60-
/// This is the actual `quote!()` proc macro.
60+
/// This is the actual implementation of the `quote!()` proc macro.
6161
///
62-
/// It is manually loaded in `CStore::load_macro_untracked`.
62+
/// It is loaded by the compiler in `register_builtin_macros`.
6363
#[unstable(feature = "proc_macro_quote", issue = "54722")]
6464
pub fn quote(stream: TokenStream) -> TokenStream {
6565
if stream.is_empty() {

‎src/librustc_metadata/cstore.rs

+1-6
Original file line numberDiff line numberDiff line change
@@ -95,11 +95,6 @@ pub struct CrateMetadata {
9595
pub raw_proc_macros: Option<&'static [ProcMacro]>,
9696
}
9797

98-
pub struct FullProcMacro {
99-
pub name: ast::Name,
100-
pub ext: Lrc<SyntaxExtension>
101-
}
102-
10398
pub struct CStore {
10499
metas: RwLock<IndexVec<CrateNum, Option<Lrc<CrateMetadata>>>>,
105100
/// Map from NodeId's of local extern crate statements to crate numbers
@@ -109,7 +104,7 @@ pub struct CStore {
109104

110105
pub enum LoadedMacro {
111106
MacroDef(ast::Item),
112-
ProcMacro(Lrc<SyntaxExtension>),
107+
ProcMacro(SyntaxExtension),
113108
}
114109

115110
impl CStore {

‎src/librustc_metadata/cstore_impl.rs

+2-12
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,9 @@ use syntax::ast;
3030
use syntax::attr;
3131
use syntax::source_map;
3232
use syntax::edition::Edition;
33-
use syntax::ext::base::{SyntaxExtension, SyntaxExtensionKind};
34-
use syntax::ext::proc_macro::BangProcMacro;
3533
use syntax::parse::source_file_to_stream;
3634
use syntax::parse::parser::emit_unclosed_delims;
37-
use syntax::symbol::{Symbol, sym};
35+
use syntax::symbol::Symbol;
3836
use syntax_pos::{Span, FileName};
3937
use rustc_data_structures::bit_set::BitSet;
4038

@@ -436,15 +434,7 @@ impl cstore::CStore {
436434
pub fn load_macro_untracked(&self, id: DefId, sess: &Session) -> LoadedMacro {
437435
let data = self.get_crate_data(id.krate);
438436
if data.is_proc_macro_crate() {
439-
return LoadedMacro::ProcMacro(data.get_proc_macro(id.index, sess).ext);
440-
} else if data.name == sym::proc_macro && data.item_name(id.index) == sym::quote {
441-
let client = proc_macro::bridge::client::Client::expand1(proc_macro::quote);
442-
let kind = SyntaxExtensionKind::Bang(Box::new(BangProcMacro { client }));
443-
let ext = SyntaxExtension {
444-
allow_internal_unstable: Some([sym::proc_macro_def_site][..].into()),
445-
..SyntaxExtension::default(kind, data.root.edition)
446-
};
447-
return LoadedMacro::ProcMacro(Lrc::new(ext));
437+
return LoadedMacro::ProcMacro(data.load_proc_macro(id.index, sess));
448438
}
449439

450440
let def = data.get_macro(id.index);

‎src/librustc_metadata/decoder.rs

+17-32
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// Decoding metadata from a single crate's metadata
22

3-
use crate::cstore::{self, CrateMetadata, MetadataBlob, NativeLibrary, ForeignModule, FullProcMacro};
3+
use crate::cstore::{self, CrateMetadata, MetadataBlob, NativeLibrary, ForeignModule};
44
use crate::schema::*;
55

66
use rustc_data_structures::indexed_vec::IndexVec;
@@ -512,27 +512,8 @@ impl<'a, 'tcx> CrateMetadata {
512512
self.entry(index).span.decode((self, sess))
513513
}
514514

515-
516-
pub fn get_proc_macro(&self, id: DefIndex, sess: &Session) -> FullProcMacro {
517-
if sess.opts.debugging_opts.dual_proc_macros {
518-
let host_lib = self.host_lib.as_ref().unwrap();
519-
self.load_proc_macro(
520-
&host_lib.metadata.get_root(),
521-
id,
522-
sess
523-
)
524-
} else {
525-
self.load_proc_macro(&self.root, id, sess)
526-
}
527-
}
528-
529-
fn load_proc_macro(&self, root: &CrateRoot<'_>,
530-
id: DefIndex,
531-
sess: &Session)
532-
-> FullProcMacro {
533-
534-
let raw_macro = self.raw_proc_macro(id);
535-
let (name, kind, helper_attrs) = match *raw_macro {
515+
crate fn load_proc_macro(&self, id: DefIndex, sess: &Session) -> SyntaxExtension {
516+
let (name, kind, helper_attrs) = match *self.raw_proc_macro(id) {
536517
ProcMacro::CustomDerive { trait_name, attributes, client } => {
537518
let helper_attrs =
538519
attributes.iter().cloned().map(Symbol::intern).collect::<Vec<_>>();
@@ -551,17 +532,21 @@ impl<'a, 'tcx> CrateMetadata {
551532
name, SyntaxExtensionKind::Bang(Box::new(BangProcMacro { client })), Vec::new()
552533
)
553534
};
535+
let edition = if sess.opts.debugging_opts.dual_proc_macros {
536+
self.host_lib.as_ref().unwrap().metadata.get_root().edition
537+
} else {
538+
self.root.edition
539+
};
554540

555-
let span = self.get_span(id, sess);
556-
557-
FullProcMacro {
558-
name: Symbol::intern(name),
559-
ext: Lrc::new(SyntaxExtension {
560-
span,
561-
helper_attrs,
562-
..SyntaxExtension::default(kind, root.edition)
563-
})
564-
}
541+
SyntaxExtension::new(
542+
&sess.parse_sess,
543+
kind,
544+
self.get_span(id, sess),
545+
helper_attrs,
546+
edition,
547+
Symbol::intern(name),
548+
&self.get_attributes(&self.entry(id), sess),
549+
)
565550
}
566551

567552
pub fn get_trait_def(&self, item_id: DefIndex, sess: &Session) -> ty::TraitDef {

‎src/librustc_resolve/build_reduced_graph.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -150,12 +150,12 @@ impl<'a> Resolver<'a> {
150150
return Some(ext.clone());
151151
}
152152

153-
let macro_def = match self.cstore.load_macro_untracked(def_id, &self.session) {
154-
LoadedMacro::MacroDef(macro_def) => macro_def,
155-
LoadedMacro::ProcMacro(ext) => return Some(ext),
156-
};
153+
let ext = Lrc::new(match self.cstore.load_macro_untracked(def_id, &self.session) {
154+
LoadedMacro::MacroDef(item) =>
155+
self.compile_macro(&item, self.cstore.crate_edition_untracked(def_id.krate)),
156+
LoadedMacro::ProcMacro(ext) => ext,
157+
});
157158

158-
let ext = self.compile_macro(&macro_def, self.cstore.crate_edition_untracked(def_id.krate));
159159
self.macro_map.insert(def_id, ext.clone());
160160
Some(ext)
161161
}
@@ -1104,7 +1104,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
11041104
let expansion = parent_scope.expansion;
11051105
let (ext, ident, span, is_legacy) = match &item.node {
11061106
ItemKind::MacroDef(def) => {
1107-
let ext = self.r.compile_macro(item, self.r.session.edition());
1107+
let ext = Lrc::new(self.r.compile_macro(item, self.r.session.edition()));
11081108
(ext, item.ident, item.span, def.legacy)
11091109
}
11101110
ItemKind::Fn(..) => match Self::proc_macro_stub(item) {

‎src/librustc_resolve/macros.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -800,7 +800,7 @@ impl<'a> Resolver<'a> {
800800

801801
/// Compile the macro into a `SyntaxExtension` and possibly replace it with a pre-defined
802802
/// extension partially or entirely for built-in macros and legacy plugin macros.
803-
crate fn compile_macro(&mut self, item: &ast::Item, edition: Edition) -> Lrc<SyntaxExtension> {
803+
crate fn compile_macro(&mut self, item: &ast::Item, edition: Edition) -> SyntaxExtension {
804804
let mut result = macro_rules::compile(
805805
&self.session.parse_sess, self.session.features_untracked(), item, edition
806806
);
@@ -822,6 +822,6 @@ impl<'a> Resolver<'a> {
822822
}
823823
}
824824

825-
Lrc::new(result)
825+
result
826826
}
827827
}

‎src/libsyntax/ext/base.rs

+65-2
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
use crate::ast::{self, NodeId, Attribute, Name, PatKind};
2-
use crate::attr::{HasAttrs, Stability, Deprecation};
2+
use crate::attr::{self, HasAttrs, Stability, Deprecation};
33
use crate::source_map::SourceMap;
44
use crate::edition::Edition;
55
use crate::ext::expand::{self, AstFragment, Invocation};
66
use crate::ext::hygiene::{ExpnId, Transparency};
77
use crate::mut_visit::{self, MutVisitor};
8-
use crate::parse::{self, parser, DirectoryOwnership};
8+
use crate::parse::{self, parser, ParseSess, DirectoryOwnership};
99
use crate::parse::token;
1010
use crate::ptr::P;
1111
use crate::symbol::{kw, sym, Ident, Symbol};
@@ -601,6 +601,69 @@ impl SyntaxExtension {
601601
}
602602
}
603603

604+
/// Constructs a syntax extension with the given properties
605+
/// and other properties converted from attributes.
606+
pub fn new(
607+
sess: &ParseSess,
608+
kind: SyntaxExtensionKind,
609+
span: Span,
610+
helper_attrs: Vec<Symbol>,
611+
edition: Edition,
612+
name: Name,
613+
attrs: &[ast::Attribute],
614+
) -> SyntaxExtension {
615+
let allow_internal_unstable =
616+
attr::find_by_name(attrs, sym::allow_internal_unstable).map(|attr| {
617+
attr.meta_item_list()
618+
.map(|list| {
619+
list.iter()
620+
.filter_map(|it| {
621+
let name = it.ident().map(|ident| ident.name);
622+
if name.is_none() {
623+
sess.span_diagnostic.span_err(
624+
it.span(), "allow internal unstable expects feature names"
625+
)
626+
}
627+
name
628+
})
629+
.collect::<Vec<Symbol>>()
630+
.into()
631+
})
632+
.unwrap_or_else(|| {
633+
sess.span_diagnostic.span_warn(
634+
attr.span,
635+
"allow_internal_unstable expects list of feature names. In the future \
636+
this will become a hard error. Please use `allow_internal_unstable(\
637+
foo, bar)` to only allow the `foo` and `bar` features",
638+
);
639+
vec![sym::allow_internal_unstable_backcompat_hack].into()
640+
})
641+
});
642+
643+
let mut local_inner_macros = false;
644+
if let Some(macro_export) = attr::find_by_name(attrs, sym::macro_export) {
645+
if let Some(l) = macro_export.meta_item_list() {
646+
local_inner_macros = attr::list_contains_name(&l, sym::local_inner_macros);
647+
}
648+
}
649+
650+
let is_builtin = attr::contains_name(attrs, sym::rustc_builtin_macro);
651+
652+
SyntaxExtension {
653+
kind,
654+
span,
655+
allow_internal_unstable,
656+
allow_internal_unsafe: attr::contains_name(attrs, sym::allow_internal_unsafe),
657+
local_inner_macros,
658+
stability: attr::find_stability(&sess, attrs, span),
659+
deprecation: attr::find_deprecation(&sess, attrs, span),
660+
helper_attrs,
661+
edition,
662+
is_builtin,
663+
is_derive_copy: is_builtin && name == sym::Copy,
664+
}
665+
}
666+
604667
pub fn dummy_bang(edition: Edition) -> SyntaxExtension {
605668
fn expander<'cx>(_: &'cx mut ExtCtxt<'_>, span: Span, _: &[TokenTree])
606669
-> Box<dyn MacResult + 'cx> {

‎src/libsyntax/ext/proc_macro_server.rs

+3-4
Original file line numberDiff line numberDiff line change
@@ -360,12 +360,11 @@ pub(crate) struct Rustc<'a> {
360360

361361
impl<'a> Rustc<'a> {
362362
pub fn new(cx: &'a ExtCtxt<'_>) -> Self {
363-
// No way to determine def location for a proc macro right now, so use call location.
364-
let location = cx.current_expansion.id.expn_data().call_site;
363+
let expn_data = cx.current_expansion.id.expn_data();
365364
Rustc {
366365
sess: cx.parse_sess,
367-
def_site: cx.with_def_site_ctxt(location),
368-
call_site: cx.with_call_site_ctxt(location),
366+
def_site: cx.with_def_site_ctxt(expn_data.def_site),
367+
call_site: cx.with_call_site_ctxt(expn_data.call_site),
369368
}
370369
}
371370

‎src/libsyntax/ext/tt/macro_rules.rs

+13-57
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
use crate::ast;
2+
use crate::attr::{self, TransparencyError};
13
use crate::edition::Edition;
24
use crate::ext::base::{DummyResult, ExtCtxt, MacResult, TTMacroExpander};
35
use crate::ext::base::{SyntaxExtension, SyntaxExtensionKind};
@@ -15,7 +17,6 @@ use crate::parse::token::{self, NtTT, Token};
1517
use crate::parse::{Directory, ParseSess};
1618
use crate::symbol::{kw, sym, Symbol};
1719
use crate::tokenstream::{DelimSpan, TokenStream, TokenTree};
18-
use crate::{ast, attr, attr::TransparencyError};
1920

2021
use errors::{DiagnosticBuilder, FatalError};
2122
use log::debug;
@@ -290,6 +291,7 @@ pub fn compile(
290291
def: &ast::Item,
291292
edition: Edition,
292293
) -> SyntaxExtension {
294+
let diag = &sess.span_diagnostic;
293295
let lhs_nm = ast::Ident::new(sym::lhs, def.span);
294296
let rhs_nm = ast::Ident::new(sym::rhs, def.span);
295297
let tt_spec = ast::Ident::new(sym::tt, def.span);
@@ -423,71 +425,25 @@ pub fn compile(
423425
let (transparency, transparency_error) = attr::find_transparency(&def.attrs, body.legacy);
424426
match transparency_error {
425427
Some(TransparencyError::UnknownTransparency(value, span)) =>
426-
sess.span_diagnostic.span_err(
427-
span, &format!("unknown macro transparency: `{}`", value)
428-
),
428+
diag.span_err(span, &format!("unknown macro transparency: `{}`", value)),
429429
Some(TransparencyError::MultipleTransparencyAttrs(old_span, new_span)) =>
430-
sess.span_diagnostic.span_err(
431-
vec![old_span, new_span], "multiple macro transparency attributes"
432-
),
430+
diag.span_err(vec![old_span, new_span], "multiple macro transparency attributes"),
433431
None => {}
434432
}
435433

436434
let expander: Box<_> = Box::new(MacroRulesMacroExpander {
437435
name: def.ident, span: def.span, transparency, lhses, rhses, valid
438436
});
439437

440-
let allow_internal_unstable =
441-
attr::find_by_name(&def.attrs, sym::allow_internal_unstable).map(|attr| {
442-
attr.meta_item_list()
443-
.map(|list| {
444-
list.iter()
445-
.filter_map(|it| {
446-
let name = it.ident().map(|ident| ident.name);
447-
if name.is_none() {
448-
sess.span_diagnostic.span_err(
449-
it.span(),
450-
"allow internal unstable expects feature names",
451-
)
452-
}
453-
name
454-
})
455-
.collect::<Vec<Symbol>>()
456-
.into()
457-
})
458-
.unwrap_or_else(|| {
459-
sess.span_diagnostic.span_warn(
460-
attr.span,
461-
"allow_internal_unstable expects list of feature names. In the \
462-
future this will become a hard error. Please use `allow_internal_unstable(\
463-
foo, bar)` to only allow the `foo` and `bar` features",
464-
);
465-
vec![sym::allow_internal_unstable_backcompat_hack].into()
466-
})
467-
});
468-
469-
let mut local_inner_macros = false;
470-
if let Some(macro_export) = attr::find_by_name(&def.attrs, sym::macro_export) {
471-
if let Some(l) = macro_export.meta_item_list() {
472-
local_inner_macros = attr::list_contains_name(&l, sym::local_inner_macros);
473-
}
474-
}
475-
476-
let is_builtin = attr::contains_name(&def.attrs, sym::rustc_builtin_macro);
477-
478-
SyntaxExtension {
479-
kind: SyntaxExtensionKind::LegacyBang(expander),
480-
span: def.span,
481-
allow_internal_unstable,
482-
allow_internal_unsafe: attr::contains_name(&def.attrs, sym::allow_internal_unsafe),
483-
local_inner_macros,
484-
stability: attr::find_stability(&sess, &def.attrs, def.span),
485-
deprecation: attr::find_deprecation(&sess, &def.attrs, def.span),
486-
helper_attrs: Vec::new(),
438+
SyntaxExtension::new(
439+
sess,
440+
SyntaxExtensionKind::LegacyBang(expander),
441+
def.span,
442+
Vec::new(),
487443
edition,
488-
is_builtin,
489-
is_derive_copy: is_builtin && def.ident.name == sym::Copy,
490-
}
444+
def.ident.name,
445+
&def.attrs,
446+
)
491447
}
492448

493449
fn check_lhs_nt_follows(

‎src/libsyntax/parse/parser.rs

+5-4
Original file line numberDiff line numberDiff line change
@@ -375,10 +375,11 @@ impl<'a> Parser<'a> {
375375
if let Some(directory) = directory {
376376
parser.directory = directory;
377377
} else if !parser.token.span.is_dummy() {
378-
if let FileName::Real(mut path) =
379-
sess.source_map().span_to_unmapped_path(parser.token.span) {
380-
path.pop();
381-
parser.directory.path = Cow::from(path);
378+
if let Some(FileName::Real(path)) =
379+
&sess.source_map().lookup_char_pos(parser.token.span.lo()).file.unmapped_path {
380+
if let Some(directory_path) = path.parent() {
381+
parser.directory.path = Cow::from(directory_path.to_path_buf());
382+
}
382383
}
383384
}
384385

‎src/libsyntax_ext/lib.rs

+8
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,18 @@
77
#![feature(decl_macro)]
88
#![feature(mem_take)]
99
#![feature(nll)]
10+
#![feature(proc_macro_internals)]
11+
#![feature(proc_macro_quote)]
1012
#![feature(rustc_diagnostic_macros)]
1113

14+
extern crate proc_macro;
15+
1216
use crate::deriving::*;
1317

1418
use syntax::ast::Ident;
1519
use syntax::edition::Edition;
1620
use syntax::ext::base::{SyntaxExtension, SyntaxExtensionKind, MacroExpanderFn};
21+
use syntax::ext::proc_macro::BangProcMacro;
1722
use syntax::symbol::sym;
1823

1924
mod error_codes;
@@ -100,4 +105,7 @@ pub fn register_builtin_macros(resolver: &mut dyn syntax::ext::base::Resolver, e
100105
RustcDecodable: decodable::expand_deriving_rustc_decodable,
101106
RustcEncodable: encodable::expand_deriving_rustc_encodable,
102107
}
108+
109+
let client = proc_macro::bridge::client::Client::expand1(proc_macro::quote);
110+
register(sym::quote, SyntaxExtensionKind::Bang(Box::new(BangProcMacro { client })));
103111
}

‎src/test/ui/auxiliary/cond_plugin.rs

+1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
#![crate_type = "proc-macro"]
55
#![feature(proc_macro_hygiene)]
6+
#![feature(proc_macro_quote)]
67

78
extern crate proc_macro;
89

‎src/test/ui/auxiliary/proc_macro_def.rs

+1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
#![crate_type = "proc-macro"]
55
#![feature(proc_macro_hygiene)]
6+
#![feature(proc_macro_quote)]
67

78
extern crate proc_macro;
89

‎src/test/ui/macros/auxiliary/proc_macro_sequence.rs

+15-5
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
extern crate proc_macro;
88

9-
use proc_macro::{quote, Span, TokenStream};
9+
use proc_macro::{quote, Span, TokenStream, TokenTree};
1010

1111
fn assert_same_span(a: Span, b: Span) {
1212
assert_eq!(a.start(), b.start());
@@ -24,12 +24,22 @@ pub fn make_foo(_: TokenStream) -> TokenStream {
2424
};
2525

2626
// Check that all spans are equal.
27-
let mut span = None;
27+
// FIXME: `quote!` gives def-site spans to idents and literals,
28+
// but leaves (default) call-site spans on groups and punctuation.
29+
let mut span_call = None;
30+
let mut span_def = None;
2831
for tt in result.clone() {
29-
match span {
30-
None => span = Some(tt.span()),
31-
Some(span) => assert_same_span(tt.span(), span),
32+
match tt {
33+
TokenTree::Ident(..) | TokenTree::Literal(..) => match span_def {
34+
None => span_def = Some(tt.span()),
35+
Some(span) => assert_same_span(tt.span(), span),
36+
}
37+
TokenTree::Punct(..) | TokenTree::Group(..) => match span_call {
38+
None => span_call = Some(tt.span()),
39+
Some(span) => assert_same_span(tt.span(), span),
40+
}
3241
}
42+
3343
}
3444

3545
result

‎src/test/ui/macros/same-sequence-span.stderr

+8-4
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,15 @@ LL | $(= $z:tt)*
1717
error: `$x:expr` may be followed by `$y:tt`, which is not allowed for `expr` fragments
1818
--> $DIR/same-sequence-span.rs:20:1
1919
|
20-
LL | proc_macro_sequence::make_foo!();
21-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
20+
LL | proc_macro_sequence::make_foo!();
21+
| ^--------------------------------
22+
| |
23+
| _in this macro invocation
2224
| |
23-
| not allowed after `expr` fragments
24-
| in this macro invocation
25+
LL | |
26+
LL | |
27+
LL | | fn main() {}
28+
... |
2529
|
2630
= note: allowed there are: `=>`, `,` or `;`
2731

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// check-pass
2+
// aux-build:attributes-on-definitions.rs
3+
4+
#![forbid(unsafe_code)]
5+
6+
extern crate attributes_on_definitions;
7+
8+
attributes_on_definitions::with_attrs!();
9+
//~^ WARN use of deprecated item
10+
// No errors about the use of unstable and unsafe code inside the macro.
11+
12+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
warning: use of deprecated item 'attributes_on_definitions::with_attrs': test
2+
--> $DIR/attributes-on-definitions.rs:8:1
3+
|
4+
LL | attributes_on_definitions::with_attrs!();
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
6+
|
7+
= note: `#[warn(deprecated)]` on by default
8+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// force-host
2+
// no-prefer-dynamic
3+
4+
#![feature(allow_internal_unsafe)]
5+
#![feature(allow_internal_unstable)]
6+
7+
#![crate_type = "proc-macro"]
8+
9+
extern crate proc_macro;
10+
use proc_macro::*;
11+
12+
#[proc_macro]
13+
#[allow_internal_unstable(proc_macro_internals)]
14+
#[allow_internal_unsafe]
15+
#[deprecated(since = "1.0.0", note = "test")]
16+
pub fn with_attrs(_: TokenStream) -> TokenStream {
17+
"
18+
extern crate proc_macro;
19+
use ::proc_macro::bridge;
20+
21+
fn contains_unsafe() { unsafe {} }
22+
".parse().unwrap()
23+
}

‎src/test/ui/proc-macro/multispan.stderr

+105-28
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,19 @@
11
error: hello to you, too!
2-
--> $DIR/multispan.rs:14:5
3-
|
4-
LL | hello!(hi);
5-
| ^^^^^^^^^^^ in this macro invocation
2+
--> $DIR/auxiliary/multispan.rs:31:1
3+
|
4+
LL | / pub fn hello(input: TokenStream) -> TokenStream {
5+
LL | | if let Err(diag) = parse(input) {
6+
LL | | diag.emit();
7+
LL | | }
8+
LL | |
9+
LL | | TokenStream::new()
10+
LL | | }
11+
| |_^
12+
|
13+
::: $DIR/multispan.rs:14:5
14+
|
15+
LL | hello!(hi);
16+
| ----------- in this macro invocation
617
|
718
note: found these 'hi's
819
--> $DIR/multispan.rs:14:12
@@ -11,10 +22,21 @@ LL | hello!(hi);
1122
| ^^
1223

1324
error: hello to you, too!
14-
--> $DIR/multispan.rs:17:5
15-
|
16-
LL | hello!(hi hi);
17-
| ^^^^^^^^^^^^^^ in this macro invocation
25+
--> $DIR/auxiliary/multispan.rs:31:1
26+
|
27+
LL | / pub fn hello(input: TokenStream) -> TokenStream {
28+
LL | | if let Err(diag) = parse(input) {
29+
LL | | diag.emit();
30+
LL | | }
31+
LL | |
32+
LL | | TokenStream::new()
33+
LL | | }
34+
| |_^
35+
|
36+
::: $DIR/multispan.rs:17:5
37+
|
38+
LL | hello!(hi hi);
39+
| -------------- in this macro invocation
1840
|
1941
note: found these 'hi's
2042
--> $DIR/multispan.rs:17:12
@@ -23,10 +45,21 @@ LL | hello!(hi hi);
2345
| ^^ ^^
2446

2547
error: hello to you, too!
26-
--> $DIR/multispan.rs:20:5
27-
|
28-
LL | hello!(hi hi hi);
29-
| ^^^^^^^^^^^^^^^^^ in this macro invocation
48+
--> $DIR/auxiliary/multispan.rs:31:1
49+
|
50+
LL | / pub fn hello(input: TokenStream) -> TokenStream {
51+
LL | | if let Err(diag) = parse(input) {
52+
LL | | diag.emit();
53+
LL | | }
54+
LL | |
55+
LL | | TokenStream::new()
56+
LL | | }
57+
| |_^
58+
|
59+
::: $DIR/multispan.rs:20:5
60+
|
61+
LL | hello!(hi hi hi);
62+
| ----------------- in this macro invocation
3063
|
3164
note: found these 'hi's
3265
--> $DIR/multispan.rs:20:12
@@ -35,10 +68,21 @@ LL | hello!(hi hi hi);
3568
| ^^ ^^ ^^
3669

3770
error: hello to you, too!
38-
--> $DIR/multispan.rs:23:5
39-
|
40-
LL | hello!(hi hey hi yo hi beep beep hi hi);
41-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ in this macro invocation
71+
--> $DIR/auxiliary/multispan.rs:31:1
72+
|
73+
LL | / pub fn hello(input: TokenStream) -> TokenStream {
74+
LL | | if let Err(diag) = parse(input) {
75+
LL | | diag.emit();
76+
LL | | }
77+
LL | |
78+
LL | | TokenStream::new()
79+
LL | | }
80+
| |_^
81+
|
82+
::: $DIR/multispan.rs:23:5
83+
|
84+
LL | hello!(hi hey hi yo hi beep beep hi hi);
85+
| ---------------------------------------- in this macro invocation
4286
|
4387
note: found these 'hi's
4488
--> $DIR/multispan.rs:23:12
@@ -47,10 +91,21 @@ LL | hello!(hi hey hi yo hi beep beep hi hi);
4791
| ^^ ^^ ^^ ^^ ^^
4892

4993
error: hello to you, too!
50-
--> $DIR/multispan.rs:24:5
51-
|
52-
LL | hello!(hi there, hi how are you? hi... hi.);
53-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ in this macro invocation
94+
--> $DIR/auxiliary/multispan.rs:31:1
95+
|
96+
LL | / pub fn hello(input: TokenStream) -> TokenStream {
97+
LL | | if let Err(diag) = parse(input) {
98+
LL | | diag.emit();
99+
LL | | }
100+
LL | |
101+
LL | | TokenStream::new()
102+
LL | | }
103+
| |_^
104+
|
105+
::: $DIR/multispan.rs:24:5
106+
|
107+
LL | hello!(hi there, hi how are you? hi... hi.);
108+
| -------------------------------------------- in this macro invocation
54109
|
55110
note: found these 'hi's
56111
--> $DIR/multispan.rs:24:12
@@ -59,10 +114,21 @@ LL | hello!(hi there, hi how are you? hi... hi.);
59114
| ^^ ^^ ^^ ^^
60115

61116
error: hello to you, too!
62-
--> $DIR/multispan.rs:25:5
63-
|
64-
LL | hello!(whoah. hi di hi di ho);
65-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ in this macro invocation
117+
--> $DIR/auxiliary/multispan.rs:31:1
118+
|
119+
LL | / pub fn hello(input: TokenStream) -> TokenStream {
120+
LL | | if let Err(diag) = parse(input) {
121+
LL | | diag.emit();
122+
LL | | }
123+
LL | |
124+
LL | | TokenStream::new()
125+
LL | | }
126+
| |_^
127+
|
128+
::: $DIR/multispan.rs:25:5
129+
|
130+
LL | hello!(whoah. hi di hi di ho);
131+
| ------------------------------ in this macro invocation
66132
|
67133
note: found these 'hi's
68134
--> $DIR/multispan.rs:25:19
@@ -71,10 +137,21 @@ LL | hello!(whoah. hi di hi di ho);
71137
| ^^ ^^
72138

73139
error: hello to you, too!
74-
--> $DIR/multispan.rs:26:5
75-
|
76-
LL | hello!(hi good hi and good bye);
77-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ in this macro invocation
140+
--> $DIR/auxiliary/multispan.rs:31:1
141+
|
142+
LL | / pub fn hello(input: TokenStream) -> TokenStream {
143+
LL | | if let Err(diag) = parse(input) {
144+
LL | | diag.emit();
145+
LL | | }
146+
LL | |
147+
LL | | TokenStream::new()
148+
LL | | }
149+
| |_^
150+
|
151+
::: $DIR/multispan.rs:26:5
152+
|
153+
LL | hello!(hi good hi and good bye);
154+
| -------------------------------- in this macro invocation
78155
|
79156
note: found these 'hi's
80157
--> $DIR/multispan.rs:26:12

‎src/test/ui/proc-macro/three-equals.stderr

+15-4
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,19 @@
11
error: found 2 equal signs, need exactly 3
2-
--> $DIR/three-equals.rs:15:5
3-
|
4-
LL | three_equals!(==);
5-
| ^^^^^^^^^^^^^^^^^^ in this macro invocation
2+
--> $DIR/auxiliary/three-equals.rs:42:1
3+
|
4+
LL | / pub fn three_equals(input: TokenStream) -> TokenStream {
5+
LL | | if let Err(diag) = parse(input) {
6+
LL | | diag.emit();
7+
LL | | return TokenStream::new();
8+
... |
9+
LL | | "3".parse().unwrap()
10+
LL | | }
11+
| |_^
12+
|
13+
::: $DIR/three-equals.rs:15:5
14+
|
15+
LL | three_equals!(==);
16+
| ------------------ in this macro invocation
617
|
718
= help: input must be: `===`
819

0 commit comments

Comments
 (0)
Please sign in to comment.