Skip to content

Update semver-exempt API to nightly-2025-04-16 #497

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 16, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 20 additions & 46 deletions src/fallback.rs
Original file line number Diff line number Diff line change
Expand Up @@ -311,34 +311,6 @@ impl IntoIterator for TokenStream {
}
}

#[cfg(procmacro2_semver_exempt)]
#[derive(Clone, PartialEq, Eq)]
pub(crate) struct SourceFile {
path: PathBuf,
}

#[cfg(procmacro2_semver_exempt)]
impl SourceFile {
/// Get the path to this source file as a string.
pub(crate) fn path(&self) -> PathBuf {
self.path.clone()
}

pub(crate) fn is_real(&self) -> bool {
false
}
}

#[cfg(procmacro2_semver_exempt)]
impl 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()
}
}

#[cfg(all(span_locations, not(fuzzing)))]
thread_local! {
static SOURCE_MAP: RefCell<SourceMap> = RefCell::new(SourceMap {
Expand Down Expand Up @@ -484,14 +456,14 @@ impl SourceMap {
}

#[cfg(procmacro2_semver_exempt)]
fn filepath(&self, span: Span) -> PathBuf {
fn filepath(&self, span: Span) -> String {
for (i, file) in self.files.iter().enumerate() {
if file.span_within(span) {
return PathBuf::from(if i == 0 {
return if i == 0 {
"<unspecified>".to_owned()
} else {
format!("<parsed string {}>", i)
});
};
}
}
unreachable!("Invalid span with no related FileInfo!");
Expand Down Expand Up @@ -555,21 +527,6 @@ impl Span {
other
}

#[cfg(procmacro2_semver_exempt)]
pub(crate) fn source_file(&self) -> SourceFile {
#[cfg(fuzzing)]
return SourceFile {
path: PathBuf::from("<unspecified>"),
};

#[cfg(not(fuzzing))]
SOURCE_MAP.with(|sm| {
let sm = sm.borrow();
let path = sm.filepath(*self);
SourceFile { path }
})
}

#[cfg(span_locations)]
pub(crate) fn byte_range(&self) -> Range<usize> {
#[cfg(fuzzing)]
Expand Down Expand Up @@ -611,6 +568,23 @@ impl Span {
})
}

#[cfg(procmacro2_semver_exempt)]
pub(crate) fn file(&self) -> String {
#[cfg(fuzzing)]
return "<unspecified>".to_owned();

#[cfg(not(fuzzing))]
SOURCE_MAP.with(|sm| {
let sm = sm.borrow();
sm.filepath(*self)
})
}

#[cfg(procmacro2_semver_exempt)]
pub(crate) fn local_file(&self) -> Option<PathBuf> {
None
}

#[cfg(not(span_locations))]
pub(crate) fn join(&self, _other: Span) -> Option<Span> {
Some(Span {})
Expand Down
87 changes: 27 additions & 60 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -338,57 +338,6 @@ impl Display for LexError {

impl Error for LexError {}

/// The source file of a given `Span`.
///
/// This type is semver exempt and not exposed by default.
#[cfg(all(procmacro2_semver_exempt, any(not(wrap_proc_macro), super_unstable)))]
#[cfg_attr(docsrs, doc(cfg(procmacro2_semver_exempt)))]
#[derive(Clone, PartialEq, Eq)]
pub struct SourceFile {
inner: imp::SourceFile,
_marker: ProcMacroAutoTraits,
}

#[cfg(all(procmacro2_semver_exempt, any(not(wrap_proc_macro), super_unstable)))]
impl SourceFile {
fn _new(inner: imp::SourceFile) -> Self {
SourceFile {
inner,
_marker: MARKER,
}
}

/// Get the path to this source file.
///
/// ### Note
///
/// If the code span associated with this `SourceFile` was generated by an
/// external macro, this may 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
/// may not actually be valid.
///
/// [`is_real`]: #method.is_real
pub fn path(&self) -> PathBuf {
self.inner.path()
}

/// Returns `true` if this source file is a real source file, and not
/// generated by an external macro's expansion.
pub fn is_real(&self) -> bool {
self.inner.is_real()
}
}

#[cfg(all(procmacro2_semver_exempt, any(not(wrap_proc_macro), super_unstable)))]
impl Debug for SourceFile {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
Debug::fmt(&self.inner, f)
}
}

/// A region of source code, along with macro expansion information.
#[derive(Copy, Clone)]
pub struct Span {
Expand Down Expand Up @@ -470,15 +419,6 @@ impl Span {
self.unwrap()
}

/// The original source file into which this span points.
///
/// This method is semver exempt and not exposed by default.
#[cfg(all(procmacro2_semver_exempt, any(not(wrap_proc_macro), super_unstable)))]
#[cfg_attr(docsrs, doc(cfg(procmacro2_semver_exempt)))]
pub fn source_file(&self) -> SourceFile {
SourceFile::_new(self.inner.source_file())
}

/// Returns the span's byte position range in the source file.
///
/// This method requires the `"span-locations"` feature to be enabled.
Expand Down Expand Up @@ -524,6 +464,33 @@ impl Span {
self.inner.end()
}

/// 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>"`.
///
/// This method is semver exempt and not exposed by default.
#[cfg(all(procmacro2_semver_exempt, any(not(wrap_proc_macro), super_unstable)))]
#[cfg_attr(docsrs, doc(cfg(procmacro2_semver_exempt)))]
pub fn file(&self) -> String {
self.inner.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.
///
/// This method is semver exempt and not exposed by default.
#[cfg(all(procmacro2_semver_exempt, any(not(wrap_proc_macro), super_unstable)))]
#[cfg_attr(docsrs, doc(cfg(procmacro2_semver_exempt)))]
pub fn local_file(&self) -> Option<PathBuf> {
self.inner.local_file()
}

/// Create a new span encompassing `self` and `other`.
///
/// Returns `None` if `self` and `other` are from different files.
Expand Down
63 changes: 16 additions & 47 deletions src/wrapper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -360,45 +360,6 @@ impl Iterator for TokenTreeIter {
}
}

#[derive(Clone, PartialEq, Eq)]
#[cfg(super_unstable)]
pub(crate) enum SourceFile {
Compiler(proc_macro::SourceFile),
Fallback(fallback::SourceFile),
}

#[cfg(super_unstable)]
impl SourceFile {
fn nightly(sf: proc_macro::SourceFile) -> Self {
SourceFile::Compiler(sf)
}

/// Get the path to this source file as a string.
pub(crate) fn path(&self) -> PathBuf {
match self {
SourceFile::Compiler(a) => a.path(),
SourceFile::Fallback(a) => a.path(),
}
}

pub(crate) fn is_real(&self) -> bool {
match self {
SourceFile::Compiler(a) => a.is_real(),
SourceFile::Fallback(a) => a.is_real(),
}
}
}

#[cfg(super_unstable)]
impl Debug for SourceFile {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
SourceFile::Compiler(a) => Debug::fmt(a, f),
SourceFile::Fallback(a) => Debug::fmt(a, f),
}
}
}

#[derive(Copy, Clone)]
pub(crate) enum Span {
Compiler(proc_macro::Span),
Expand Down Expand Up @@ -456,14 +417,6 @@ impl Span {
}
}

#[cfg(super_unstable)]
pub(crate) fn source_file(&self) -> SourceFile {
match self {
Span::Compiler(s) => SourceFile::nightly(s.source_file()),
Span::Fallback(s) => SourceFile::Fallback(s.source_file()),
}
}

#[cfg(span_locations)]
pub(crate) fn byte_range(&self) -> Range<usize> {
match self {
Expand Down Expand Up @@ -506,6 +459,22 @@ impl Span {
}
}

#[cfg(super_unstable)]
pub(crate) fn file(&self) -> String {
match self {
Span::Compiler(s) => s.file(),
Span::Fallback(s) => s.file(),
}
}

#[cfg(super_unstable)]
pub(crate) fn local_file(&self) -> Option<PathBuf> {
match self {
Span::Compiler(s) => s.local_file(),
Span::Fallback(s) => s.local_file(),
}
}

pub(crate) fn join(&self, other: Span) -> Option<Span> {
let ret = match (self, other) {
#[cfg(proc_macro_span)]
Expand Down
9 changes: 3 additions & 6 deletions tests/marker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,19 +56,17 @@ assert_impl!(TokenTree is not Send or Sync);

#[cfg(procmacro2_semver_exempt)]
mod semver_exempt {
use proc_macro2::{LineColumn, SourceFile};
use proc_macro2::LineColumn;

assert_impl!(LineColumn is Send and Sync);

assert_impl!(SourceFile is not Send or Sync);
}

mod unwind_safe {
#[cfg(procmacro2_semver_exempt)]
use proc_macro2::LineColumn;
use proc_macro2::{
Delimiter, Group, Ident, LexError, Literal, Punct, Spacing, Span, TokenStream, TokenTree,
};
#[cfg(procmacro2_semver_exempt)]
use proc_macro2::{LineColumn, SourceFile};
use std::panic::{RefUnwindSafe, UnwindSafe};

macro_rules! assert_unwind_safe {
Expand All @@ -95,6 +93,5 @@ mod unwind_safe {
#[cfg(procmacro2_semver_exempt)]
assert_unwind_safe! {
LineColumn
SourceFile
}
}
17 changes: 5 additions & 12 deletions tests/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -549,9 +549,8 @@ fn default_span() {
let end = Span::call_site().end();
assert_eq!(end.line, 1);
assert_eq!(end.column, 0);
let source_file = Span::call_site().source_file();
assert_eq!(source_file.path().to_string_lossy(), "<unspecified>");
assert!(!source_file.is_real());
assert_eq!(Span::call_site().file(), "<unspecified>");
assert!(Span::call_site().local_file().is_none());
}

#[cfg(procmacro2_semver_exempt)]
Expand All @@ -568,11 +567,8 @@ fn span_join() {
.into_iter()
.collect::<Vec<_>>();

assert!(source1[0].span().source_file() != source2[0].span().source_file());
assert_eq!(
source1[0].span().source_file(),
source1[1].span().source_file()
);
assert!(source1[0].span().file() != source2[0].span().file());
assert_eq!(source1[0].span().file(), source1[1].span().file());

let joined1 = source1[0].span().join(source1[1].span());
let joined2 = source1[0].span().join(source2[0].span());
Expand All @@ -586,10 +582,7 @@ fn span_join() {
assert_eq!(end.line, 2);
assert_eq!(end.column, 3);

assert_eq!(
joined1.unwrap().source_file(),
source1[0].span().source_file()
);
assert_eq!(joined1.unwrap().file(), source1[0].span().file());
}

#[test]
Expand Down