Skip to content
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

unstable proc_macro tracked::* rename/restructure #87173

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
Open
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
4 changes: 2 additions & 2 deletions compiler/rustc_expand/src/proc_macro_server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -402,8 +402,8 @@ impl server::FreeFunctions for Rustc<'_, '_> {
.insert((Symbol::intern(var), value.map(Symbol::intern)));
}

fn track_path(&mut self, path: &str) {
self.sess().file_depinfo.borrow_mut().insert(Symbol::intern(path));
fn track_path(&mut self, path: std::path::PathBuf) {
self.sess().file_depinfo.borrow_mut().insert(path);
}

fn literal_from_str(&mut self, s: &str) -> Result<Literal<Self::Span, Self::Symbol>, ()> {
Expand Down
5 changes: 2 additions & 3 deletions compiler/rustc_interface/src/passes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -469,13 +469,12 @@ fn write_out_deps(tcx: TyCtxt<'_>, outputs: &OutputFilenames, out_filenames: &[P
// (e.g. accessed in proc macros).
let file_depinfo = sess.parse_sess.file_depinfo.borrow();

let normalize_path = |path: PathBuf| {
let normalize_path = |path: PathBuf| -> String {
let file = FileName::from(path);
escape_dep_filename(&file.prefer_local().to_string())
};

let extra_tracked_files =
file_depinfo.iter().map(|path_sym| normalize_path(PathBuf::from(path_sym.as_str())));
let extra_tracked_files = file_depinfo.iter().map(|path| normalize_path(path.to_owned()));
files.extend(extra_tracked_files);

// We also need to track used PGO profile files
Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_session/src/parse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,8 @@ pub struct ParseSess {
/// Environment variables accessed during the build and their values when they exist.
pub env_depinfo: Lock<FxHashSet<(Symbol, Option<Symbol>)>>,
/// File paths accessed during the build.
pub file_depinfo: Lock<FxHashSet<Symbol>>,
/// Paths are relative to ???.
pub file_depinfo: Lock<FxHashSet<std::path::PathBuf>>,
/// Whether cfg(version) should treat the current release as incomplete
pub assume_incomplete_release: bool,
/// Spans passed to `proc_macro::quote_span`. Each span has a numerical
Expand Down
4 changes: 3 additions & 1 deletion library/proc_macro/src/bridge/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ use std::mem;
use std::ops::Bound;
use std::ops::Range;
use std::panic;
use std::path;
use std::sync::atomic::AtomicUsize;
use std::sync::Once;
use std::thread;
Expand Down Expand Up @@ -56,7 +57,7 @@ macro_rules! with_api {
FreeFunctions {
fn drop($self: $S::FreeFunctions);
fn track_env_var(var: &str, value: Option<&str>);
fn track_path(path: &str);
fn track_path(path: std::path::PathBuf);
fn literal_from_str(s: &str) -> Result<Literal<$S::Span, $S::Symbol>, ()>;
fn emit_diagnostic(diagnostic: Diagnostic<$S::Span>);
},
Expand Down Expand Up @@ -300,6 +301,7 @@ mark_noop! {
LitKind,
Level,
Spacing,
path::PathBuf,
}

rpc_encode_decode!(
Expand Down
13 changes: 13 additions & 0 deletions library/proc_macro/src/bridge/rpc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
use std::any::Any;
use std::io::Write;
use std::num::NonZeroU32;
use std::path;
use std::str;

pub(super) type Writer = super::buffer::Buffer;
Expand Down Expand Up @@ -244,6 +245,18 @@ impl<'a, S, T: for<'s> DecodeMut<'a, 's, S>> DecodeMut<'a, '_, S> for Vec<T> {
}
}

impl<S> Encode<S> for path::PathBuf {
fn encode(self, w: &mut Writer, s: &mut S) {
self.to_str().expect("`PathBuf`s must be valid UTF-8 for now!").encode(w, s);
}
}

impl<S> DecodeMut<'_, '_, S> for path::PathBuf {
fn decode(r: &mut Reader<'_>, s: &mut S) -> Self {
path::PathBuf::from(<&str>::decode(r, s))
}
}

/// Simplified version of panic payloads, ignoring
/// types other than `&'static str` and `String`.
pub enum PanicMessage {
Expand Down
24 changes: 16 additions & 8 deletions library/proc_macro/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1489,8 +1489,8 @@ impl fmt::Debug for Literal {
}
}

/// Tracked access to environment variables.
#[unstable(feature = "proc_macro_tracked_env", issue = "99515")]
#[unstable(feature = "proc_macro_tracked_env", issue = "74690")]
Comment on lines -1493 to +1492
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is the tracking issue changed? #74690 is a closed issue.

/// Tracked access to env variables.
pub mod tracked_env {
use std::env::{self, VarError};
use std::ffi::OsStr;
Expand All @@ -1500,7 +1500,7 @@ pub mod tracked_env {
/// compilation, and will be able to rerun the build when the value of that variable changes.
/// Besides the dependency tracking this function should be equivalent to `env::var` from the
/// standard library, except that the argument must be UTF-8.
#[unstable(feature = "proc_macro_tracked_env", issue = "99515")]
#[unstable(feature = "proc_macro_tracked_env", issue = "74690")]
pub fn var<K: AsRef<OsStr> + AsRef<str>>(key: K) -> Result<String, VarError> {
let key: &str = key.as_ref();
let value = env::var(key);
Expand All @@ -1510,15 +1510,23 @@ pub mod tracked_env {
}

/// Tracked access to additional files.
#[unstable(feature = "track_path", issue = "99515")]
#[unstable(feature = "proc_macro_tracked_path", issue = "99515")]
pub mod tracked_path {
use std::path::{Path, PathBuf};

/// Track a file explicitly.
/// Track a file as if it was a dependency.
///
/// The file is located relative to the current file where the proc-macro
/// is used (similarly to how modules are found). The provided path is
/// interpreted in a platform-specific way at compile time. So, for
Comment on lines +1519 to +1521
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it not relative to the current working directory? So if I do File::open("a.txt") and tracked_path::path("a.txt"), can that refer to a different file?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I understand the docs correct, this would behave similar to using the include!() family in the macro expansion, which indeed uses a different directory to be relative to than File::open() inside the proc macro. The behavior of include!() is almost certainly what you want. The current working directory that rustc is invoked with when using cargo is effectively undefined.

/// instance, an invocation with a Windows path
/// containing backslashes `\` would not compile correctly on Unix.
Comment on lines +1521 to +1523
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I find the note on windows/unix paths quite confusing. Who is that note for? What user error is it trying to prevent?

///
/// Errors if the provided `Path` cannot be encoded as a `str`
///
/// Commonly used for tracking asset preprocessing.
#[unstable(feature = "track_path", issue = "99515")]
pub fn path<P: AsRef<str>>(path: P) {
let path: &str = path.as_ref();
pub fn path<P: AsRef<Path>>(path: P) {
let path = PathBuf::from(path.as_ref());
crate::bridge::client::FreeFunctions::track_path(path);
}
}
4 changes: 2 additions & 2 deletions src/tools/clippy/src/driver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ fn track_files(parse_sess: &mut ParseSess) {
// Used by `clippy::cargo` lints and to determine the MSRV. `cargo clippy` executes `clippy-driver`
// with the current directory set to `CARGO_MANIFEST_DIR` so a relative path is fine
if Path::new("Cargo.toml").exists() {
file_depinfo.insert(Symbol::intern("Cargo.toml"));
file_depinfo.insert(std::path::PathBuf::from("Cargo.toml"));
}

// `clippy.toml` will be automatically tracked as it's loaded with `sess.source_map().load_file()`
Expand All @@ -95,7 +95,7 @@ fn track_files(parse_sess: &mut ParseSess) {
if let Ok(current_exe) = env::current_exe()
&& let Some(current_exe) = current_exe.to_str()
{
file_depinfo.insert(Symbol::intern(current_exe));
file_depinfo.insert(std::path::PathBuf::from(current_exe));
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ impl server::FreeFunctions for RustAnalyzer {
// FIXME: track env var accesses
// https://github.com/rust-lang/rust/pull/71858
}
fn track_path(&mut self, _path: &str) {}
fn track_path(&mut self, _path: std::path::PathBuf) {}

fn literal_from_str(
&mut self,
Expand Down
2 changes: 1 addition & 1 deletion tests/run-make/env-dep-info/macro_def.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#![feature(proc_macro_tracked_env)]
#![crate_type = "proc-macro"]
#![feature(proc_macro_tracked_env)]

extern crate proc_macro;
use proc_macro::*;
Expand Down
14 changes: 13 additions & 1 deletion tests/run-make/track-path-dep-info/macro_def.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,23 @@
#![feature(track_path)]
#![crate_type = "proc-macro"]
#![feature(proc_macro_tracked_path)]

extern crate proc_macro;
use proc_macro::*;

use std::str;

#[proc_macro]
pub fn access_tracked_paths(_: TokenStream) -> TokenStream {
tracked_path::path("emojis.txt");

// currently only valid utf-8 paths are supported
if false {
let invalid = [1_u8, 2,123, 254, 0, 0, 1, 1];
let invalid: &str = unsafe {
str::from_utf8_unchecked(&invalid[..])
};
tracked_path::path(invalid);
}

TokenStream::new()
}
Loading