librustdoc::config: removed Input from Options

The `librustdoc::config::Options` struct no longer includes
`rustc_session::config::Input`. This is so that Input can be optional.
In rfc#3662, the crate input is not required if `--merge=finalize`.

Replacing Input with Option<Input> was decided against. In most places
that Input is needed, it should be statically known to not be optional
(means fewer unwraps). We just want to have an Input-free Options in
librustdoc::main_args, where we can run the write shared procedure.
This commit is contained in:
EtomicBomb 2024-08-26 21:40:52 -07:00 committed by ethan
parent ec867f03bc
commit 3782251c2c
5 changed files with 34 additions and 35 deletions

View File

@ -57,8 +57,6 @@ fn try_from(value: &str) -> Result<Self, Self::Error> {
#[derive(Clone)] #[derive(Clone)]
pub(crate) struct Options { pub(crate) struct Options {
// Basic options / Options passed directly to rustc // Basic options / Options passed directly to rustc
/// The crate root or Markdown file to load.
pub(crate) input: Input,
/// The name of the crate being documented. /// The name of the crate being documented.
pub(crate) crate_name: Option<String>, pub(crate) crate_name: Option<String>,
/// Whether or not this is a bin crate /// Whether or not this is a bin crate
@ -179,7 +177,6 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
} }
f.debug_struct("Options") f.debug_struct("Options")
.field("input", &self.input.source_name())
.field("crate_name", &self.crate_name) .field("crate_name", &self.crate_name)
.field("bin_crate", &self.bin_crate) .field("bin_crate", &self.bin_crate)
.field("proc_macro_crate", &self.proc_macro_crate) .field("proc_macro_crate", &self.proc_macro_crate)
@ -348,7 +345,7 @@ pub(crate) fn from_matches(
early_dcx: &mut EarlyDiagCtxt, early_dcx: &mut EarlyDiagCtxt,
matches: &getopts::Matches, matches: &getopts::Matches,
args: Vec<String>, args: Vec<String>,
) -> Option<(Options, RenderOptions)> { ) -> Option<(Input, Options, RenderOptions)> {
// Check for unstable options. // Check for unstable options.
nightly_options::check_nightly_options(early_dcx, matches, &opts()); nightly_options::check_nightly_options(early_dcx, matches, &opts());
@ -751,7 +748,6 @@ fn println_condition(condition: Condition) {
let unstable_features = let unstable_features =
rustc_feature::UnstableFeatures::from_environment(crate_name.as_deref()); rustc_feature::UnstableFeatures::from_environment(crate_name.as_deref());
let options = Options { let options = Options {
input,
bin_crate, bin_crate,
proc_macro_crate, proc_macro_crate,
error_format, error_format,
@ -824,15 +820,13 @@ fn println_condition(condition: Condition) {
html_no_source, html_no_source,
output_to_stdout, output_to_stdout,
}; };
Some((options, render_options)) Some((input, options, render_options))
} }
}
/// Returns `true` if the file given as `self.input` is a Markdown file. /// Returns `true` if the file given as `self.input` is a Markdown file.
pub(crate) fn markdown_input(&self) -> Option<&Path> { pub(crate) fn markdown_input(input: &Input) -> Option<&Path> {
self.input input.opt_path().filter(|p| matches!(p.extension(), Some(e) if e == "md" || e == "markdown"))
.opt_path()
.filter(|p| matches!(p.extension(), Some(e) if e == "md" || e == "markdown"))
}
} }
fn parse_remap_path_prefix( fn parse_remap_path_prefix(

View File

@ -20,7 +20,7 @@
use rustc_lint::{late_lint_mod, MissingDoc}; use rustc_lint::{late_lint_mod, MissingDoc};
use rustc_middle::hir::nested_filter; use rustc_middle::hir::nested_filter;
use rustc_middle::ty::{ParamEnv, Ty, TyCtxt}; use rustc_middle::ty::{ParamEnv, Ty, TyCtxt};
use rustc_session::config::{self, CrateType, ErrorOutputType, ResolveDocLinks}; use rustc_session::config::{self, CrateType, ErrorOutputType, Input, ResolveDocLinks};
pub(crate) use rustc_session::config::{Options, UnstableOptions}; pub(crate) use rustc_session::config::{Options, UnstableOptions};
use rustc_session::{lint, Session}; use rustc_session::{lint, Session};
use rustc_span::symbol::sym; use rustc_span::symbol::sym;
@ -177,8 +177,8 @@ pub(crate) fn new_dcx(
/// Parse, resolve, and typecheck the given crate. /// Parse, resolve, and typecheck the given crate.
pub(crate) fn create_config( pub(crate) fn create_config(
input: Input,
RustdocOptions { RustdocOptions {
input,
crate_name, crate_name,
proc_macro_crate, proc_macro_crate,
error_format, error_format,

View File

@ -19,7 +19,7 @@
use rustc_hir::def_id::LOCAL_CRATE; use rustc_hir::def_id::LOCAL_CRATE;
use rustc_hir::CRATE_HIR_ID; use rustc_hir::CRATE_HIR_ID;
use rustc_interface::interface; use rustc_interface::interface;
use rustc_session::config::{self, CrateType, ErrorOutputType}; use rustc_session::config::{self, CrateType, ErrorOutputType, Input};
use rustc_session::lint; use rustc_session::lint;
use rustc_span::edition::Edition; use rustc_span::edition::Edition;
use rustc_span::symbol::sym; use rustc_span::symbol::sym;
@ -88,7 +88,11 @@ fn get_doctest_dir() -> io::Result<TempDir> {
TempFileBuilder::new().prefix("rustdoctest").tempdir() TempFileBuilder::new().prefix("rustdoctest").tempdir()
} }
pub(crate) fn run(dcx: DiagCtxtHandle<'_>, options: RustdocOptions) -> Result<(), ErrorGuaranteed> { pub(crate) fn run(
dcx: DiagCtxtHandle<'_>,
input: Input,
options: RustdocOptions,
) -> Result<(), ErrorGuaranteed> {
let invalid_codeblock_attributes_name = crate::lint::INVALID_CODEBLOCK_ATTRIBUTES.name; let invalid_codeblock_attributes_name = crate::lint::INVALID_CODEBLOCK_ATTRIBUTES.name;
// See core::create_config for what's going on here. // See core::create_config for what's going on here.
@ -135,7 +139,7 @@ pub(crate) fn run(dcx: DiagCtxtHandle<'_>, options: RustdocOptions) -> Result<()
opts: sessopts, opts: sessopts,
crate_cfg: cfgs, crate_cfg: cfgs,
crate_check_cfg: options.check_cfgs.clone(), crate_check_cfg: options.check_cfgs.clone(),
input: options.input.clone(), input: input.clone(),
output_file: None, output_file: None,
output_dir: None, output_dir: None,
file_loader: None, file_loader: None,

View File

@ -3,6 +3,7 @@
use std::fs::read_to_string; use std::fs::read_to_string;
use std::sync::{Arc, Mutex}; use std::sync::{Arc, Mutex};
use rustc_session::config::Input;
use rustc_span::FileName; use rustc_span::FileName;
use tempfile::tempdir; use tempfile::tempdir;
@ -69,9 +70,8 @@ fn visit_header(&mut self, name: &str, level: u32) {
} }
/// Runs any tests/code examples in the markdown file `options.input`. /// Runs any tests/code examples in the markdown file `options.input`.
pub(crate) fn test(options: Options) -> Result<(), String> { pub(crate) fn test(input: &Input, options: Options) -> Result<(), String> {
use rustc_session::config::Input; let input_str = match input {
let input_str = match &options.input {
Input::File(path) => { Input::File(path) => {
read_to_string(path).map_err(|err| format!("{}: {err}", path.display()))? read_to_string(path).map_err(|err| format!("{}: {err}", path.display()))?
} }
@ -79,7 +79,7 @@ pub(crate) fn test(options: Options) -> Result<(), String> {
}; };
// Obviously not a real crate name, but close enough for purposes of doctests. // Obviously not a real crate name, but close enough for purposes of doctests.
let crate_name = options.input.filestem().to_string(); let crate_name = input.filestem().to_string();
let temp_dir = let temp_dir =
tempdir().map_err(|error| format!("failed to create temporary directory: {error:?}"))?; tempdir().map_err(|error| format!("failed to create temporary directory: {error:?}"))?;
let args_file = temp_dir.path().join("rustdoc-cfgs"); let args_file = temp_dir.path().join("rustdoc-cfgs");
@ -96,8 +96,7 @@ pub(crate) fn test(options: Options) -> Result<(), String> {
let mut md_collector = MdCollector { let mut md_collector = MdCollector {
tests: vec![], tests: vec![],
cur_path: vec![], cur_path: vec![],
filename: options filename: input
.input
.opt_path() .opt_path()
.map(ToOwned::to_owned) .map(ToOwned::to_owned)
.map(FileName::from) .map(FileName::from)

View File

@ -727,22 +727,24 @@ fn main_args(
// Note that we discard any distinction between different non-zero exit // Note that we discard any distinction between different non-zero exit
// codes from `from_matches` here. // codes from `from_matches` here.
let (options, render_options) = match config::Options::from_matches(early_dcx, &matches, args) { let (input, options, render_options) =
Some(opts) => opts, match config::Options::from_matches(early_dcx, &matches, args) {
None => return Ok(()), Some(opts) => opts,
}; None => return Ok(()),
};
let dcx = let dcx =
core::new_dcx(options.error_format, None, options.diagnostic_width, &options.unstable_opts); core::new_dcx(options.error_format, None, options.diagnostic_width, &options.unstable_opts);
let dcx = dcx.handle(); let dcx = dcx.handle();
match (options.should_test, options.markdown_input()) { match (options.should_test, config::markdown_input(&input)) {
(true, Some(_)) => return wrap_return(dcx, doctest::test_markdown(options)), (true, Some(_)) => return wrap_return(dcx, doctest::test_markdown(&input, options)),
(true, None) => return doctest::run(dcx, options), (true, None) => return doctest::run(dcx, input, options),
(false, Some(input)) => { (false, Some(md_input)) => {
let input = input.to_owned(); let md_input = md_input.to_owned();
let edition = options.edition; let edition = options.edition;
let config = core::create_config(options, &render_options, using_internal_features); let config =
core::create_config(input, options, &render_options, using_internal_features);
// `markdown::render` can invoke `doctest::make_test`, which // `markdown::render` can invoke `doctest::make_test`, which
// requires session globals and a thread pool, so we use // requires session globals and a thread pool, so we use
@ -750,7 +752,7 @@ fn main_args(
return wrap_return( return wrap_return(
dcx, dcx,
interface::run_compiler(config, |_compiler| { interface::run_compiler(config, |_compiler| {
markdown::render(&input, render_options, edition) markdown::render(&md_input, render_options, edition)
}), }),
); );
} }
@ -775,7 +777,7 @@ fn main_args(
let scrape_examples_options = options.scrape_examples_options.clone(); let scrape_examples_options = options.scrape_examples_options.clone();
let bin_crate = options.bin_crate; let bin_crate = options.bin_crate;
let config = core::create_config(options, &render_options, using_internal_features); let config = core::create_config(input, options, &render_options, using_internal_features);
interface::run_compiler(config, |compiler| { interface::run_compiler(config, |compiler| {
let sess = &compiler.sess; let sess = &compiler.sess;