mirror of
https://github.com/rust-lang/rust.git
synced 2025-04-15 05:26:47 +00:00
Merge 5113f5e602
into 65fa0ab924
This commit is contained in:
commit
6f7a90527e
@ -1,5 +1,4 @@
|
||||
use std::ops::{Bound, Range};
|
||||
use std::sync::Arc;
|
||||
|
||||
use ast::token::IdentIsRaw;
|
||||
use pm::bridge::{
|
||||
@ -18,7 +17,7 @@ use rustc_parse::parser::Parser;
|
||||
use rustc_parse::{exp, new_parser_from_source_str, source_str_to_stream, unwrap_or_emit_fatal};
|
||||
use rustc_session::parse::ParseSess;
|
||||
use rustc_span::def_id::CrateNum;
|
||||
use rustc_span::{BytePos, FileName, Pos, SourceFile, Span, Symbol, sym};
|
||||
use rustc_span::{BytePos, FileName, Pos, Span, Symbol, sym};
|
||||
use smallvec::{SmallVec, smallvec};
|
||||
|
||||
use crate::base::ExtCtxt;
|
||||
@ -467,7 +466,6 @@ impl<'a, 'b> Rustc<'a, 'b> {
|
||||
impl server::Types for Rustc<'_, '_> {
|
||||
type FreeFunctions = FreeFunctions;
|
||||
type TokenStream = TokenStream;
|
||||
type SourceFile = Arc<SourceFile>;
|
||||
type Span = Span;
|
||||
type Symbol = Symbol;
|
||||
}
|
||||
@ -673,28 +671,6 @@ impl server::TokenStream for Rustc<'_, '_> {
|
||||
}
|
||||
}
|
||||
|
||||
impl server::SourceFile for Rustc<'_, '_> {
|
||||
fn eq(&mut self, file1: &Self::SourceFile, file2: &Self::SourceFile) -> bool {
|
||||
Arc::ptr_eq(file1, file2)
|
||||
}
|
||||
|
||||
fn path(&mut self, file: &Self::SourceFile) -> String {
|
||||
match &file.name {
|
||||
FileName::Real(name) => name
|
||||
.local_path()
|
||||
.expect("attempting to get a file path in an imported file in `proc_macro::SourceFile::path`")
|
||||
.to_str()
|
||||
.expect("non-UTF8 file path in `proc_macro::SourceFile::path`")
|
||||
.to_string(),
|
||||
_ => file.name.prefer_local().to_string(),
|
||||
}
|
||||
}
|
||||
|
||||
fn is_real(&mut self, file: &Self::SourceFile) -> bool {
|
||||
file.is_real_file()
|
||||
}
|
||||
}
|
||||
|
||||
impl server::Span for Rustc<'_, '_> {
|
||||
fn debug(&mut self, span: Self::Span) -> String {
|
||||
if self.ecx.ecfg.span_debug {
|
||||
@ -704,8 +680,29 @@ impl server::Span for Rustc<'_, '_> {
|
||||
}
|
||||
}
|
||||
|
||||
fn source_file(&mut self, span: Self::Span) -> Self::SourceFile {
|
||||
self.psess().source_map().lookup_char_pos(span.lo()).file
|
||||
fn file(&mut self, span: Self::Span) -> String {
|
||||
self.psess()
|
||||
.source_map()
|
||||
.lookup_char_pos(span.lo())
|
||||
.file
|
||||
.name
|
||||
.prefer_remapped_unconditionaly()
|
||||
.to_string()
|
||||
}
|
||||
|
||||
fn local_file(&mut self, span: Self::Span) -> Option<String> {
|
||||
self.psess()
|
||||
.source_map()
|
||||
.lookup_char_pos(span.lo())
|
||||
.file
|
||||
.name
|
||||
.clone()
|
||||
.into_local_path()
|
||||
.map(|p| {
|
||||
p.to_str()
|
||||
.expect("non-UTF8 file path in `proc_macro::SourceFile::path`")
|
||||
.to_string()
|
||||
})
|
||||
}
|
||||
|
||||
fn parent(&mut self, span: Self::Span) -> Option<Self::Span> {
|
||||
|
@ -25,7 +25,10 @@ fn invocation_relative_path_to_absolute(span: Span, path: &str) -> PathBuf {
|
||||
path.to_path_buf()
|
||||
} else {
|
||||
// `/a/b/c/foo/bar.rs` contains the current macro invocation
|
||||
#[cfg(bootstrap)]
|
||||
let mut source_file_path = span.source_file().path();
|
||||
#[cfg(not(bootstrap))]
|
||||
let mut source_file_path = span.local_file().unwrap();
|
||||
// `/a/b/c/foo/`
|
||||
source_file_path.pop();
|
||||
// `/a/b/c/foo/../locales/en-US/example.ftl`
|
||||
|
@ -111,12 +111,6 @@ impl Clone for TokenStream {
|
||||
}
|
||||
}
|
||||
|
||||
impl Clone for SourceFile {
|
||||
fn clone(&self) -> Self {
|
||||
self.clone()
|
||||
}
|
||||
}
|
||||
|
||||
impl Span {
|
||||
pub(crate) fn def_site() -> Span {
|
||||
Bridge::with(|bridge| bridge.globals.def_site)
|
||||
|
@ -81,16 +81,8 @@ macro_rules! with_api {
|
||||
$self: $S::TokenStream
|
||||
) -> Vec<TokenTree<$S::TokenStream, $S::Span, $S::Symbol>>;
|
||||
},
|
||||
SourceFile {
|
||||
fn drop($self: $S::SourceFile);
|
||||
fn clone($self: &$S::SourceFile) -> $S::SourceFile;
|
||||
fn eq($self: &$S::SourceFile, other: &$S::SourceFile) -> bool;
|
||||
fn path($self: &$S::SourceFile) -> String;
|
||||
fn is_real($self: &$S::SourceFile) -> bool;
|
||||
},
|
||||
Span {
|
||||
fn debug($self: $S::Span) -> String;
|
||||
fn source_file($self: $S::Span) -> $S::SourceFile;
|
||||
fn parent($self: $S::Span) -> Option<$S::Span>;
|
||||
fn source($self: $S::Span) -> $S::Span;
|
||||
fn byte_range($self: $S::Span) -> Range<usize>;
|
||||
@ -98,6 +90,8 @@ macro_rules! with_api {
|
||||
fn end($self: $S::Span) -> $S::Span;
|
||||
fn line($self: $S::Span) -> usize;
|
||||
fn column($self: $S::Span) -> usize;
|
||||
fn file($self: $S::Span) -> String;
|
||||
fn local_file($self: $S::Span) -> Option<String>;
|
||||
fn join($self: $S::Span, other: $S::Span) -> Option<$S::Span>;
|
||||
fn subspan($self: $S::Span, start: Bound<usize>, end: Bound<usize>) -> Option<$S::Span>;
|
||||
fn resolved_at($self: $S::Span, at: $S::Span) -> $S::Span;
|
||||
@ -120,7 +114,6 @@ macro_rules! with_api_handle_types {
|
||||
'owned:
|
||||
FreeFunctions,
|
||||
TokenStream,
|
||||
SourceFile,
|
||||
|
||||
'interned:
|
||||
Span,
|
||||
|
@ -82,7 +82,6 @@ with_api_handle_types!(define_server_handles);
|
||||
pub trait Types {
|
||||
type FreeFunctions: 'static;
|
||||
type TokenStream: 'static + Clone;
|
||||
type SourceFile: 'static + Clone;
|
||||
type Span: 'static + Copy + Eq + Hash;
|
||||
type Symbol: 'static;
|
||||
}
|
||||
|
@ -491,12 +491,6 @@ impl Span {
|
||||
Span(bridge::client::Span::mixed_site())
|
||||
}
|
||||
|
||||
/// The original source file into which this span points.
|
||||
#[unstable(feature = "proc_macro_span", issue = "54725")]
|
||||
pub fn source_file(&self) -> SourceFile {
|
||||
SourceFile(self.0.source_file())
|
||||
}
|
||||
|
||||
/// The `Span` for the tokens in the previous macro expansion from which
|
||||
/// `self` was generated from, if any.
|
||||
#[unstable(feature = "proc_macro_span", issue = "54725")]
|
||||
@ -546,6 +540,25 @@ impl Span {
|
||||
self.0.column()
|
||||
}
|
||||
|
||||
/// The path to the source file in which this span occurs, for display purposes.
|
||||
///
|
||||
/// This might not correspond to a valid file system path.
|
||||
/// It might be remapped, or might be an artificial path such as `"<macro expansion>"`.
|
||||
#[unstable(feature = "proc_macro_span", issue = "54725")]
|
||||
pub fn file(&self) -> String {
|
||||
self.0.file()
|
||||
}
|
||||
|
||||
/// The path to the source file in which this span occurs on disk.
|
||||
///
|
||||
/// This is the actual path on disk. It is unaffected by path remapping.
|
||||
///
|
||||
/// This path should not be embedded in the output of the macro; prefer `file()` instead.
|
||||
#[unstable(feature = "proc_macro_span", issue = "54725")]
|
||||
pub fn local_file(&self) -> Option<PathBuf> {
|
||||
self.0.local_file().map(|s| PathBuf::from(s))
|
||||
}
|
||||
|
||||
/// Creates a new span encompassing `self` and `other`.
|
||||
///
|
||||
/// Returns `None` if `self` and `other` are from different files.
|
||||
@ -614,58 +627,6 @@ impl fmt::Debug for Span {
|
||||
}
|
||||
}
|
||||
|
||||
/// The source file of a given `Span`.
|
||||
#[unstable(feature = "proc_macro_span", issue = "54725")]
|
||||
#[derive(Clone)]
|
||||
pub struct SourceFile(bridge::client::SourceFile);
|
||||
|
||||
impl SourceFile {
|
||||
/// Gets the path to this source file.
|
||||
///
|
||||
/// ### Note
|
||||
/// If the code span associated with this `SourceFile` was generated by an external macro, this
|
||||
/// macro, this might not be an actual path on the filesystem. Use [`is_real`] to check.
|
||||
///
|
||||
/// Also note that even if `is_real` returns `true`, if `--remap-path-prefix` was passed on
|
||||
/// the command line, the path as given might not actually be valid.
|
||||
///
|
||||
/// [`is_real`]: Self::is_real
|
||||
#[unstable(feature = "proc_macro_span", issue = "54725")]
|
||||
pub fn path(&self) -> PathBuf {
|
||||
PathBuf::from(self.0.path())
|
||||
}
|
||||
|
||||
/// Returns `true` if this source file is a real source file, and not generated by an external
|
||||
/// macro's expansion.
|
||||
#[unstable(feature = "proc_macro_span", issue = "54725")]
|
||||
pub fn is_real(&self) -> bool {
|
||||
// This is a hack until intercrate spans are implemented and we can have real source files
|
||||
// for spans generated in external macros.
|
||||
// https://github.com/rust-lang/rust/pull/43604#issuecomment-333334368
|
||||
self.0.is_real()
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "proc_macro_span", issue = "54725")]
|
||||
impl fmt::Debug for SourceFile {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
f.debug_struct("SourceFile")
|
||||
.field("path", &self.path())
|
||||
.field("is_real", &self.is_real())
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "proc_macro_span", issue = "54725")]
|
||||
impl PartialEq for SourceFile {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.0.eq(&other.0)
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "proc_macro_span", issue = "54725")]
|
||||
impl Eq for SourceFile {}
|
||||
|
||||
/// A single token or a delimited sequence of token trees (e.g., `[1, (), ..]`).
|
||||
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
|
||||
#[derive(Clone)]
|
||||
|
@ -11,7 +11,7 @@ use std::{
|
||||
|
||||
use intern::Symbol;
|
||||
use proc_macro::bridge::{self, server};
|
||||
use span::{FileId, Span, FIXUP_ERASED_FILE_AST_ID_MARKER};
|
||||
use span::{Span, FIXUP_ERASED_FILE_AST_ID_MARKER};
|
||||
use tt::{TextRange, TextSize};
|
||||
|
||||
use crate::server_impl::{literal_kind_to_internal, token_stream::TokenStreamBuilder, TopSubtree};
|
||||
@ -27,10 +27,6 @@ mod tt {
|
||||
|
||||
type TokenStream = crate::server_impl::TokenStream<Span>;
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
|
||||
pub struct SourceFile {
|
||||
file_id: FileId,
|
||||
}
|
||||
pub struct FreeFunctions;
|
||||
|
||||
pub struct RaSpanServer {
|
||||
@ -46,7 +42,6 @@ pub struct RaSpanServer {
|
||||
impl server::Types for RaSpanServer {
|
||||
type FreeFunctions = FreeFunctions;
|
||||
type TokenStream = TokenStream;
|
||||
type SourceFile = SourceFile;
|
||||
type Span = Span;
|
||||
type Symbol = Symbol;
|
||||
}
|
||||
@ -245,25 +240,17 @@ impl server::TokenStream for RaSpanServer {
|
||||
}
|
||||
}
|
||||
|
||||
impl server::SourceFile for RaSpanServer {
|
||||
fn eq(&mut self, file1: &Self::SourceFile, file2: &Self::SourceFile) -> bool {
|
||||
file1 == file2
|
||||
}
|
||||
fn path(&mut self, _file: &Self::SourceFile) -> String {
|
||||
// FIXME
|
||||
String::new()
|
||||
}
|
||||
fn is_real(&mut self, _file: &Self::SourceFile) -> bool {
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
impl server::Span for RaSpanServer {
|
||||
fn debug(&mut self, span: Self::Span) -> String {
|
||||
format!("{:?}", span)
|
||||
}
|
||||
fn source_file(&mut self, span: Self::Span) -> Self::SourceFile {
|
||||
SourceFile { file_id: span.anchor.file_id.file_id() }
|
||||
fn file(&mut self, _: Self::Span) -> String {
|
||||
// FIXME
|
||||
String::new()
|
||||
}
|
||||
fn local_file(&mut self, _: Self::Span) -> Option<String> {
|
||||
// FIXME
|
||||
None
|
||||
}
|
||||
fn save_span(&mut self, _span: Self::Span) -> usize {
|
||||
// FIXME, quote is incompatible with third-party tools
|
||||
|
@ -24,8 +24,6 @@ type Literal = tt::Literal;
|
||||
type Span = tt::TokenId;
|
||||
type TokenStream = crate::server_impl::TokenStream<Span>;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct SourceFile;
|
||||
pub struct FreeFunctions;
|
||||
|
||||
pub struct TokenIdServer {
|
||||
@ -37,7 +35,6 @@ pub struct TokenIdServer {
|
||||
impl server::Types for TokenIdServer {
|
||||
type FreeFunctions = FreeFunctions;
|
||||
type TokenStream = TokenStream;
|
||||
type SourceFile = SourceFile;
|
||||
type Span = Span;
|
||||
type Symbol = Symbol;
|
||||
}
|
||||
@ -223,24 +220,15 @@ impl server::TokenStream for TokenIdServer {
|
||||
}
|
||||
}
|
||||
|
||||
impl server::SourceFile for TokenIdServer {
|
||||
fn eq(&mut self, _file1: &Self::SourceFile, _file2: &Self::SourceFile) -> bool {
|
||||
true
|
||||
}
|
||||
fn path(&mut self, _file: &Self::SourceFile) -> String {
|
||||
String::new()
|
||||
}
|
||||
fn is_real(&mut self, _file: &Self::SourceFile) -> bool {
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
impl server::Span for TokenIdServer {
|
||||
fn debug(&mut self, span: Self::Span) -> String {
|
||||
format!("{:?}", span.0)
|
||||
}
|
||||
fn source_file(&mut self, _span: Self::Span) -> Self::SourceFile {
|
||||
SourceFile {}
|
||||
fn file(&mut self, _span: Self::Span) -> String {
|
||||
String::new()
|
||||
}
|
||||
fn local_file(&mut self, _span: Self::Span) -> Option<String> {
|
||||
None
|
||||
}
|
||||
fn save_span(&mut self, _span: Self::Span) -> usize {
|
||||
0
|
||||
|
@ -3,9 +3,10 @@
|
||||
|
||||
extern crate proc_macro;
|
||||
|
||||
use proc_macro::*;
|
||||
use std::str::FromStr;
|
||||
|
||||
use proc_macro::*;
|
||||
|
||||
// Flatten the TokenStream, removing any toplevel `Delimiter::None`s for
|
||||
// comparison.
|
||||
fn flatten(ts: TokenStream) -> Vec<TokenTree> {
|
||||
@ -136,9 +137,8 @@ pub fn check_expand_expr_file(ts: TokenStream) -> TokenStream {
|
||||
.to_string();
|
||||
assert_eq!(input_t, parse_t);
|
||||
|
||||
// Check that the literal matches `Span::call_site().source_file().path()`
|
||||
let expect_t =
|
||||
Literal::string(&Span::call_site().source_file().path().to_string_lossy()).to_string();
|
||||
// Check that the literal matches `Span::call_site().file()`
|
||||
let expect_t = Literal::string(&Span::call_site().file()).to_string();
|
||||
assert_eq!(input_t, expect_t);
|
||||
|
||||
TokenStream::new()
|
||||
|
@ -79,7 +79,7 @@ fn check_useful_span(token: TokenTree, expected_filename: &str) {
|
||||
let span = token.span();
|
||||
assert!(span.column() < span.end().column());
|
||||
|
||||
let source_path = span.source_file().path();
|
||||
let source_path = span.local_file().unwrap();
|
||||
let filename = source_path.components().last().unwrap();
|
||||
assert_eq!(filename, Component::Normal(expected_filename.as_ref()));
|
||||
}
|
||||
|
@ -11,20 +11,9 @@ pub fn reemit(input: TokenStream) -> TokenStream {
|
||||
}
|
||||
|
||||
#[proc_macro]
|
||||
pub fn assert_fake_source_file(input: TokenStream) -> TokenStream {
|
||||
pub fn assert_local_file(input: TokenStream) -> TokenStream {
|
||||
for tk in input {
|
||||
let source_file = tk.span().source_file();
|
||||
assert!(!source_file.is_real(), "Source file is real: {:?}", source_file);
|
||||
}
|
||||
|
||||
"".parse().unwrap()
|
||||
}
|
||||
|
||||
#[proc_macro]
|
||||
pub fn assert_source_file(input: TokenStream) -> TokenStream {
|
||||
for tk in input {
|
||||
let source_file = tk.span().source_file();
|
||||
assert!(source_file.is_real(), "Source file is not real: {:?}", source_file);
|
||||
assert!(tk.span().local_file().is_some(), "No local file for span: {:?}", tk.span());
|
||||
}
|
||||
|
||||
"".parse().unwrap()
|
||||
|
@ -8,26 +8,24 @@ extern crate span_test_macros;
|
||||
|
||||
extern crate span_api_tests;
|
||||
|
||||
// FIXME(69775): Investigate `assert_fake_source_file`.
|
||||
|
||||
use span_api_tests::{reemit, assert_source_file, macro_stringify};
|
||||
use span_api_tests::{reemit, assert_local_file, macro_stringify};
|
||||
|
||||
macro_rules! say_hello {
|
||||
($macname:ident) => ( $macname! { "Hello, world!" })
|
||||
}
|
||||
|
||||
assert_source_file! { "Hello, world!" }
|
||||
assert_local_file! { "Hello, world!" }
|
||||
|
||||
say_hello! { assert_source_file }
|
||||
say_hello! { assert_local_file }
|
||||
|
||||
reemit_legacy! {
|
||||
assert_source_file! { "Hello, world!" }
|
||||
assert_local_file! { "Hello, world!" }
|
||||
}
|
||||
|
||||
say_hello_extern! { assert_source_file }
|
||||
say_hello_extern! { assert_local_file }
|
||||
|
||||
reemit! {
|
||||
assert_source_file! { "Hello, world!" }
|
||||
assert_local_file! { "Hello, world!" }
|
||||
}
|
||||
|
||||
fn main() {
|
||||
|
Loading…
Reference in New Issue
Block a user