Auto merge of #137914 - matthiaskrgr:rollup-phaxe6f, r=matthiaskrgr
Rollup of 6 pull requests Successful merges: - #137103 ({json|html}docck: catch and error on deprecated syntax) - #137632 (rustdoc: when merging target features, keep the highest stability) - #137684 (Add rustdoc support for `--emit=dep-info[=path]`) - #137794 (make qnx pass a test) - #137801 (tests: Unignore target modifier tests on all platforms) - #137826 (test(codegen): add looping_over_ne_bytes test for #133528) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
e16a049adb
26 changed files with 267 additions and 152 deletions
|
@ -10,7 +10,7 @@ use rustc_middle::query::Providers;
|
||||||
use rustc_middle::ty::TyCtxt;
|
use rustc_middle::ty::TyCtxt;
|
||||||
use rustc_session::parse::feature_err;
|
use rustc_session::parse::feature_err;
|
||||||
use rustc_span::{Span, Symbol, sym};
|
use rustc_span::{Span, Symbol, sym};
|
||||||
use rustc_target::target_features;
|
use rustc_target::target_features::{self, Stability};
|
||||||
|
|
||||||
use crate::errors;
|
use crate::errors;
|
||||||
|
|
||||||
|
@ -87,12 +87,17 @@ pub(crate) fn from_target_feature_attr(
|
||||||
// But ensure the ABI does not forbid enabling this.
|
// But ensure the ABI does not forbid enabling this.
|
||||||
// Here we do assume that LLVM doesn't add even more implied features
|
// Here we do assume that LLVM doesn't add even more implied features
|
||||||
// we don't know about, at least no features that would have ABI effects!
|
// we don't know about, at least no features that would have ABI effects!
|
||||||
if abi_feature_constraints.incompatible.contains(&name.as_str()) {
|
// We skip this logic in rustdoc, where we want to allow all target features of
|
||||||
tcx.dcx().emit_err(errors::ForbiddenTargetFeatureAttr {
|
// all targets, so we can't check their ABI compatibility and anyway we are not
|
||||||
span: item.span(),
|
// generating code so "it's fine".
|
||||||
feature: name.as_str(),
|
if !tcx.sess.opts.actually_rustdoc {
|
||||||
reason: "this feature is incompatible with the target ABI",
|
if abi_feature_constraints.incompatible.contains(&name.as_str()) {
|
||||||
});
|
tcx.dcx().emit_err(errors::ForbiddenTargetFeatureAttr {
|
||||||
|
span: item.span(),
|
||||||
|
feature: name.as_str(),
|
||||||
|
reason: "this feature is incompatible with the target ABI",
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
target_features.push(TargetFeature { name, implied: name != feature_sym })
|
target_features.push(TargetFeature { name, implied: name != feature_sym })
|
||||||
}
|
}
|
||||||
|
@ -142,11 +147,38 @@ pub(crate) fn provide(providers: &mut Providers) {
|
||||||
rust_target_features: |tcx, cnum| {
|
rust_target_features: |tcx, cnum| {
|
||||||
assert_eq!(cnum, LOCAL_CRATE);
|
assert_eq!(cnum, LOCAL_CRATE);
|
||||||
if tcx.sess.opts.actually_rustdoc {
|
if tcx.sess.opts.actually_rustdoc {
|
||||||
// rustdoc needs to be able to document functions that use all the features, so
|
// HACK: rustdoc would like to pretend that we have all the target features, so we
|
||||||
// whitelist them all
|
// have to merge all the lists into one. To ensure an unstable target never prevents
|
||||||
rustc_target::target_features::all_rust_features()
|
// a stable one from working, we merge the stability info of all instances of the
|
||||||
.map(|(a, b)| (a.to_string(), b))
|
// same target feature name, with the "most stable" taking precedence. And then we
|
||||||
.collect()
|
// hope that this doesn't cause issues anywhere else in the compiler...
|
||||||
|
let mut result: UnordMap<String, Stability> = Default::default();
|
||||||
|
for (name, stability) in rustc_target::target_features::all_rust_features() {
|
||||||
|
use std::collections::hash_map::Entry;
|
||||||
|
match result.entry(name.to_owned()) {
|
||||||
|
Entry::Vacant(vacant_entry) => {
|
||||||
|
vacant_entry.insert(stability);
|
||||||
|
}
|
||||||
|
Entry::Occupied(mut occupied_entry) => {
|
||||||
|
// Merge the two stabilities, "more stable" taking precedence.
|
||||||
|
match (occupied_entry.get(), stability) {
|
||||||
|
(Stability::Stable, _)
|
||||||
|
| (
|
||||||
|
Stability::Unstable { .. },
|
||||||
|
Stability::Unstable { .. } | Stability::Forbidden { .. },
|
||||||
|
)
|
||||||
|
| (Stability::Forbidden { .. }, Stability::Forbidden { .. }) => {
|
||||||
|
// The stability in the entry is at least as good as the new one, just keep it.
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
// Overwrite stabilite.
|
||||||
|
occupied_entry.insert(stability);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result
|
||||||
} else {
|
} else {
|
||||||
tcx.sess
|
tcx.sess
|
||||||
.target
|
.target
|
||||||
|
|
|
@ -297,10 +297,24 @@ LINE_PATTERN = re.compile(
|
||||||
re.X | re.UNICODE,
|
re.X | re.UNICODE,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
DEPRECATED_LINE_PATTERN = re.compile(
|
||||||
|
r"""
|
||||||
|
//\s+@
|
||||||
|
""",
|
||||||
|
re.X | re.UNICODE,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def get_commands(template):
|
def get_commands(template):
|
||||||
with io.open(template, encoding="utf-8") as f:
|
with io.open(template, encoding="utf-8") as f:
|
||||||
for lineno, line in concat_multi_lines(f):
|
for lineno, line in concat_multi_lines(f):
|
||||||
|
if DEPRECATED_LINE_PATTERN.search(line):
|
||||||
|
print_err(
|
||||||
|
lineno,
|
||||||
|
line,
|
||||||
|
"Deprecated command syntax, replace `// @` with `//@ `",
|
||||||
|
)
|
||||||
|
continue
|
||||||
m = LINE_PATTERN.search(line)
|
m = LINE_PATTERN.search(line)
|
||||||
if not m:
|
if not m:
|
||||||
continue
|
continue
|
||||||
|
|
|
@ -315,23 +315,30 @@ pub(crate) enum ModuleSorting {
|
||||||
Alphabetical,
|
Alphabetical,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||||
pub(crate) enum EmitType {
|
pub(crate) enum EmitType {
|
||||||
Unversioned,
|
Unversioned,
|
||||||
Toolchain,
|
Toolchain,
|
||||||
InvocationSpecific,
|
InvocationSpecific,
|
||||||
|
DepInfo(Option<PathBuf>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FromStr for EmitType {
|
impl FromStr for EmitType {
|
||||||
type Err = ();
|
type Err = ();
|
||||||
|
|
||||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||||
use EmitType::*;
|
|
||||||
match s {
|
match s {
|
||||||
"unversioned-shared-resources" => Ok(Unversioned),
|
"unversioned-shared-resources" => Ok(Self::Unversioned),
|
||||||
"toolchain-shared-resources" => Ok(Toolchain),
|
"toolchain-shared-resources" => Ok(Self::Toolchain),
|
||||||
"invocation-specific" => Ok(InvocationSpecific),
|
"invocation-specific" => Ok(Self::InvocationSpecific),
|
||||||
_ => Err(()),
|
"dep-info" => Ok(Self::DepInfo(None)),
|
||||||
|
option => {
|
||||||
|
if let Some(file) = option.strip_prefix("dep-info=") {
|
||||||
|
Ok(Self::DepInfo(Some(Path::new(file).into())))
|
||||||
|
} else {
|
||||||
|
Err(())
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -340,6 +347,15 @@ impl RenderOptions {
|
||||||
pub(crate) fn should_emit_crate(&self) -> bool {
|
pub(crate) fn should_emit_crate(&self) -> bool {
|
||||||
self.emit.is_empty() || self.emit.contains(&EmitType::InvocationSpecific)
|
self.emit.is_empty() || self.emit.contains(&EmitType::InvocationSpecific)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn dep_info(&self) -> Option<Option<&Path>> {
|
||||||
|
for emit in &self.emit {
|
||||||
|
if let EmitType::DepInfo(file) = emit {
|
||||||
|
return Some(file.as_deref());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create the input (string or file path)
|
/// Create the input (string or file path)
|
||||||
|
|
|
@ -15,11 +15,12 @@ use rustc_hir::def::Res;
|
||||||
use rustc_hir::def_id::{DefId, DefIdMap, DefIdSet, LocalDefId};
|
use rustc_hir::def_id::{DefId, DefIdMap, DefIdSet, LocalDefId};
|
||||||
use rustc_hir::intravisit::{self, Visitor};
|
use rustc_hir::intravisit::{self, Visitor};
|
||||||
use rustc_hir::{HirId, Path};
|
use rustc_hir::{HirId, Path};
|
||||||
use rustc_interface::interface;
|
|
||||||
use rustc_lint::{MissingDoc, late_lint_mod};
|
use rustc_lint::{MissingDoc, late_lint_mod};
|
||||||
use rustc_middle::hir::nested_filter;
|
use rustc_middle::hir::nested_filter;
|
||||||
use rustc_middle::ty::{self, ParamEnv, Ty, TyCtxt};
|
use rustc_middle::ty::{self, ParamEnv, Ty, TyCtxt};
|
||||||
use rustc_session::config::{self, CrateType, ErrorOutputType, Input, ResolveDocLinks};
|
use rustc_session::config::{
|
||||||
|
self, CrateType, ErrorOutputType, Input, OutFileName, OutputType, OutputTypes, ResolveDocLinks,
|
||||||
|
};
|
||||||
pub(crate) use rustc_session::config::{Options, UnstableOptions};
|
pub(crate) use rustc_session::config::{Options, UnstableOptions};
|
||||||
use rustc_session::{Session, lint};
|
use rustc_session::{Session, lint};
|
||||||
use rustc_span::source_map;
|
use rustc_span::source_map;
|
||||||
|
@ -219,7 +220,7 @@ pub(crate) fn create_config(
|
||||||
remap_path_prefix,
|
remap_path_prefix,
|
||||||
..
|
..
|
||||||
}: RustdocOptions,
|
}: RustdocOptions,
|
||||||
RenderOptions { document_private, .. }: &RenderOptions,
|
render_options: &RenderOptions,
|
||||||
) -> rustc_interface::Config {
|
) -> rustc_interface::Config {
|
||||||
// Add the doc cfg into the doc build.
|
// Add the doc cfg into the doc build.
|
||||||
cfgs.push("doc".to_string());
|
cfgs.push("doc".to_string());
|
||||||
|
@ -245,8 +246,11 @@ pub(crate) fn create_config(
|
||||||
|
|
||||||
let crate_types =
|
let crate_types =
|
||||||
if proc_macro_crate { vec![CrateType::ProcMacro] } else { vec![CrateType::Rlib] };
|
if proc_macro_crate { vec![CrateType::ProcMacro] } else { vec![CrateType::Rlib] };
|
||||||
let resolve_doc_links =
|
let resolve_doc_links = if render_options.document_private {
|
||||||
if *document_private { ResolveDocLinks::All } else { ResolveDocLinks::Exported };
|
ResolveDocLinks::All
|
||||||
|
} else {
|
||||||
|
ResolveDocLinks::Exported
|
||||||
|
};
|
||||||
let test = scrape_examples_options.map(|opts| opts.scrape_tests).unwrap_or(false);
|
let test = scrape_examples_options.map(|opts| opts.scrape_tests).unwrap_or(false);
|
||||||
// plays with error output here!
|
// plays with error output here!
|
||||||
let sessopts = config::Options {
|
let sessopts = config::Options {
|
||||||
|
@ -269,10 +273,18 @@ pub(crate) fn create_config(
|
||||||
crate_name,
|
crate_name,
|
||||||
test,
|
test,
|
||||||
remap_path_prefix,
|
remap_path_prefix,
|
||||||
|
output_types: if let Some(file) = render_options.dep_info() {
|
||||||
|
OutputTypes::new(&[(
|
||||||
|
OutputType::DepInfo,
|
||||||
|
file.map(|f| OutFileName::Real(f.to_path_buf())),
|
||||||
|
)])
|
||||||
|
} else {
|
||||||
|
OutputTypes::new(&[])
|
||||||
|
},
|
||||||
..Options::default()
|
..Options::default()
|
||||||
};
|
};
|
||||||
|
|
||||||
interface::Config {
|
rustc_interface::Config {
|
||||||
opts: sessopts,
|
opts: sessopts,
|
||||||
crate_cfg: cfgs,
|
crate_cfg: cfgs,
|
||||||
crate_check_cfg: check_cfgs,
|
crate_check_cfg: check_cfgs,
|
||||||
|
|
|
@ -153,7 +153,7 @@ fn write_rendered_cross_crate_info(
|
||||||
include_sources: bool,
|
include_sources: bool,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
let m = &opt.should_merge;
|
let m = &opt.should_merge;
|
||||||
if opt.emit.is_empty() || opt.emit.contains(&EmitType::InvocationSpecific) {
|
if opt.should_emit_crate() {
|
||||||
if include_sources {
|
if include_sources {
|
||||||
write_rendered_cci::<SourcesPart, _>(SourcesPart::blank, dst, crates, m)?;
|
write_rendered_cci::<SourcesPart, _>(SourcesPart::blank, dst, crates, m)?;
|
||||||
}
|
}
|
||||||
|
|
|
@ -561,7 +561,7 @@ fn opts() -> Vec<RustcOptGroup> {
|
||||||
"",
|
"",
|
||||||
"emit",
|
"emit",
|
||||||
"Comma separated list of types of output for rustdoc to emit",
|
"Comma separated list of types of output for rustdoc to emit",
|
||||||
"[unversioned-shared-resources,toolchain-shared-resources,invocation-specific]",
|
"[unversioned-shared-resources,toolchain-shared-resources,invocation-specific,dep-info]",
|
||||||
),
|
),
|
||||||
opt(Unstable, FlagMulti, "", "no-run", "Compile doctests without running them", ""),
|
opt(Unstable, FlagMulti, "", "no-run", "Compile doctests without running them", ""),
|
||||||
opt(
|
opt(
|
||||||
|
@ -890,7 +890,13 @@ fn main_args(early_dcx: &mut EarlyDiagCtxt, at_args: &[String]) {
|
||||||
// if we ran coverage, bail early, we don't need to also generate docs at this point
|
// if we ran coverage, bail early, we don't need to also generate docs at this point
|
||||||
// (also we didn't load in any of the useful passes)
|
// (also we didn't load in any of the useful passes)
|
||||||
return;
|
return;
|
||||||
} else if run_check {
|
}
|
||||||
|
|
||||||
|
if render_opts.dep_info().is_some() {
|
||||||
|
rustc_interface::passes::write_dep_info(tcx);
|
||||||
|
}
|
||||||
|
|
||||||
|
if run_check {
|
||||||
// Since we're in "check" mode, no need to generate anything beyond this point.
|
// Since we're in "check" mode, no need to generate anything beyond this point.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
use std::process::ExitCode;
|
use std::process::ExitCode;
|
||||||
use std::sync::OnceLock;
|
use std::sync::LazyLock;
|
||||||
use std::{env, fs};
|
use std::{env, fs};
|
||||||
|
|
||||||
use regex::{Regex, RegexBuilder};
|
use regex::{Regex, RegexBuilder};
|
||||||
|
@ -151,8 +151,7 @@ impl CommandKind {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static LINE_PATTERN: OnceLock<Regex> = OnceLock::new();
|
static LINE_PATTERN: LazyLock<Regex> = LazyLock::new(|| {
|
||||||
fn line_pattern() -> Regex {
|
|
||||||
RegexBuilder::new(
|
RegexBuilder::new(
|
||||||
r#"
|
r#"
|
||||||
//@\s+
|
//@\s+
|
||||||
|
@ -165,7 +164,19 @@ fn line_pattern() -> Regex {
|
||||||
.unicode(true)
|
.unicode(true)
|
||||||
.build()
|
.build()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
}
|
});
|
||||||
|
|
||||||
|
static DEPRECATED_LINE_PATTERN: LazyLock<Regex> = LazyLock::new(|| {
|
||||||
|
RegexBuilder::new(
|
||||||
|
r#"
|
||||||
|
//\s+@
|
||||||
|
"#,
|
||||||
|
)
|
||||||
|
.ignore_whitespace(true)
|
||||||
|
.unicode(true)
|
||||||
|
.build()
|
||||||
|
.unwrap()
|
||||||
|
});
|
||||||
|
|
||||||
fn print_err(msg: &str, lineno: usize) {
|
fn print_err(msg: &str, lineno: usize) {
|
||||||
eprintln!("Invalid command: {} on line {}", msg, lineno)
|
eprintln!("Invalid command: {} on line {}", msg, lineno)
|
||||||
|
@ -184,21 +195,23 @@ fn get_commands(template: &str) -> Result<Vec<Command>, ()> {
|
||||||
for (lineno, line) in file.split('\n').enumerate() {
|
for (lineno, line) in file.split('\n').enumerate() {
|
||||||
let lineno = lineno + 1;
|
let lineno = lineno + 1;
|
||||||
|
|
||||||
let cap = match LINE_PATTERN.get_or_init(line_pattern).captures(line) {
|
if DEPRECATED_LINE_PATTERN.is_match(line) {
|
||||||
Some(c) => c,
|
print_err("Deprecated command syntax, replace `// @` with `//@ `", lineno);
|
||||||
None => continue,
|
errors = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
let Some(cap) = LINE_PATTERN.captures(line) else {
|
||||||
|
continue;
|
||||||
};
|
};
|
||||||
|
|
||||||
let negated = cap.name("negated").unwrap().as_str() == "!";
|
let negated = &cap["negated"] == "!";
|
||||||
|
|
||||||
let args_str = &cap["args"];
|
let args_str = &cap["args"];
|
||||||
let args = match shlex::split(args_str) {
|
let Some(args) = shlex::split(args_str) else {
|
||||||
Some(args) => args,
|
print_err(&format!("Invalid arguments to shlex::split: `{args_str}`",), lineno);
|
||||||
None => {
|
errors = true;
|
||||||
print_err(&format!("Invalid arguments to shlex::split: `{args_str}`",), lineno);
|
continue;
|
||||||
errors = true;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Some((kind, path)) = CommandKind::parse(&cap["cmd"], negated, &args) {
|
if let Some((kind, path)) = CommandKind::parse(&cap["cmd"], negated, &args) {
|
||||||
|
|
|
@ -132,4 +132,11 @@ impl Rustdoc {
|
||||||
self.cmd.arg(format);
|
self.cmd.arg(format);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Specify type(s) of output files to generate.
|
||||||
|
pub fn emit<S: AsRef<str>>(&mut self, kinds: S) -> &mut Self {
|
||||||
|
let kinds = kinds.as_ref();
|
||||||
|
self.cmd.arg(format!("--emit={kinds}"));
|
||||||
|
self
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
17
tests/codegen/issues/looping-over-ne-bytes-133528.rs
Normal file
17
tests/codegen/issues/looping-over-ne-bytes-133528.rs
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
//@ compile-flags: -Copt-level=3
|
||||||
|
//@ min-llvm-version: 20
|
||||||
|
#![crate_type = "lib"]
|
||||||
|
|
||||||
|
/// Ensure the function is properly optimized
|
||||||
|
/// In the issue #133528, the function was not getting optimized
|
||||||
|
/// whereas, a version with `bytes` wrapped into a `black_box` was optimized
|
||||||
|
/// It was probably a LLVM bug that was fixed in LLVM 20
|
||||||
|
|
||||||
|
// CHECK-LABEL: @looping_over_ne_bytes
|
||||||
|
// CHECK: icmp eq i64 %input, -1
|
||||||
|
// CHECK-NEXT: ret i1
|
||||||
|
#[no_mangle]
|
||||||
|
fn looping_over_ne_bytes(input: u64) -> bool {
|
||||||
|
let bytes = input.to_ne_bytes();
|
||||||
|
bytes.iter().all(|x| *x == !0)
|
||||||
|
}
|
|
@ -153,7 +153,7 @@ Options:
|
||||||
--generate-redirect-map
|
--generate-redirect-map
|
||||||
Generate JSON file at the top level instead of
|
Generate JSON file at the top level instead of
|
||||||
generating HTML redirection files
|
generating HTML redirection files
|
||||||
--emit [unversioned-shared-resources,toolchain-shared-resources,invocation-specific]
|
--emit [unversioned-shared-resources,toolchain-shared-resources,invocation-specific,dep-info]
|
||||||
Comma separated list of types of output for rustdoc to
|
Comma separated list of types of output for rustdoc to
|
||||||
emit
|
emit
|
||||||
--no-run Compile doctests without running them
|
--no-run Compile doctests without running them
|
||||||
|
|
1
tests/run-make/rustdoc-dep-info/bar.rs
Normal file
1
tests/run-make/rustdoc-dep-info/bar.rs
Normal file
|
@ -0,0 +1 @@
|
||||||
|
include!("foo.rs");
|
1
tests/run-make/rustdoc-dep-info/doc.md
Normal file
1
tests/run-make/rustdoc-dep-info/doc.md
Normal file
|
@ -0,0 +1 @@
|
||||||
|
blablabla
|
1
tests/run-make/rustdoc-dep-info/foo.rs
Normal file
1
tests/run-make/rustdoc-dep-info/foo.rs
Normal file
|
@ -0,0 +1 @@
|
||||||
|
pub fn foo() {}
|
6
tests/run-make/rustdoc-dep-info/lib.rs
Normal file
6
tests/run-make/rustdoc-dep-info/lib.rs
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
#![crate_name = "foo"]
|
||||||
|
|
||||||
|
#[cfg_attr(doc, doc = include_str!("doc.md"))]
|
||||||
|
pub struct Bar;
|
||||||
|
|
||||||
|
mod bar;
|
21
tests/run-make/rustdoc-dep-info/rmake.rs
Normal file
21
tests/run-make/rustdoc-dep-info/rmake.rs
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
// This is a simple smoke test for rustdoc's `--emit dep-info` feature. It prints out
|
||||||
|
// information about dependencies in a Makefile-compatible format, as a `.d` file.
|
||||||
|
|
||||||
|
use run_make_support::assertion_helpers::assert_contains;
|
||||||
|
use run_make_support::{path, rfs, rustdoc};
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
// We're only emitting dep info, so we shouldn't be running static analysis to
|
||||||
|
// figure out that this program is erroneous.
|
||||||
|
rustdoc().input("lib.rs").arg("-Zunstable-options").emit("dep-info").run();
|
||||||
|
|
||||||
|
let content = rfs::read_to_string("foo.d");
|
||||||
|
assert_contains(&content, "lib.rs:");
|
||||||
|
assert_contains(&content, "foo.rs:");
|
||||||
|
assert_contains(&content, "bar.rs:");
|
||||||
|
assert_contains(&content, "doc.md:");
|
||||||
|
|
||||||
|
// Now we check that we can provide a file name to the `dep-info` argument.
|
||||||
|
rustdoc().input("lib.rs").arg("-Zunstable-options").emit("dep-info=bla.d").run();
|
||||||
|
assert!(path("bla.d").exists());
|
||||||
|
}
|
28
tests/rustdoc-ui/target-feature-stability.rs
Normal file
28
tests/rustdoc-ui/target-feature-stability.rs
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
//! This is a regression test for <https://github.com/rust-lang/rust/issues/137366>, ensuring
|
||||||
|
//! that we can use the `neon` target feature on ARM32 targets in rustdoc despite there
|
||||||
|
//! being a "forbidden" feature of the same name for aarch64, and rustdoc merging the
|
||||||
|
//! target features of all targets.
|
||||||
|
//@ check-pass
|
||||||
|
//@ revisions: arm aarch64
|
||||||
|
//@[arm] compile-flags: --target armv7-unknown-linux-gnueabihf
|
||||||
|
//@[arm] needs-llvm-components: arm
|
||||||
|
//@[aarch64] compile-flags: --target aarch64-unknown-none-softfloat
|
||||||
|
//@[aarch64] needs-llvm-components: aarch64
|
||||||
|
|
||||||
|
#![crate_type = "lib"]
|
||||||
|
#![feature(no_core, lang_items)]
|
||||||
|
#![feature(arm_target_feature)]
|
||||||
|
#![no_core]
|
||||||
|
|
||||||
|
#[lang = "sized"]
|
||||||
|
pub trait Sized {}
|
||||||
|
|
||||||
|
// `fp-armv8` is "forbidden" on aarch64 as we tie it to `neon`.
|
||||||
|
#[target_feature(enable = "fp-armv8")]
|
||||||
|
pub fn fun1() {}
|
||||||
|
|
||||||
|
// This would usually be rejected as it changes the ABI.
|
||||||
|
// But we disable that check in rustdoc since we are building "for all targets" and the
|
||||||
|
// check can't really handle that.
|
||||||
|
#[target_feature(enable = "soft-float")]
|
||||||
|
pub fn fun2() {}
|
|
@ -10,14 +10,15 @@
|
||||||
|
|
||||||
#[cfg_attr(
|
#[cfg_attr(
|
||||||
any(
|
any(
|
||||||
target_os = "linux",
|
|
||||||
target_os = "android",
|
target_os = "android",
|
||||||
target_os = "freebsd",
|
|
||||||
target_os = "netbsd",
|
|
||||||
target_os = "openbsd",
|
|
||||||
target_os = "dragonfly",
|
target_os = "dragonfly",
|
||||||
|
target_os = "freebsd",
|
||||||
|
target_os = "haiku",
|
||||||
target_os = "illumos",
|
target_os = "illumos",
|
||||||
target_os = "haiku"
|
target_os = "linux",
|
||||||
|
target_os = "netbsd",
|
||||||
|
target_os = "nto",
|
||||||
|
target_os = "openbsd",
|
||||||
),
|
),
|
||||||
link_section = ".init_array"
|
link_section = ".init_array"
|
||||||
)]
|
)]
|
||||||
|
|
|
@ -1,20 +1,7 @@
|
||||||
//@ compile-flags: --target i686-unknown-linux-gnu -Cpanic=abort
|
//@ no-prefer-dynamic
|
||||||
// Auxiliary build problems with aarch64-apple:
|
//@ compile-flags: --target i686-unknown-linux-gnu
|
||||||
// Shared library linking cc seems to convert "-m32" flag into -arch armv4t
|
|
||||||
// Auxiliary build problems with i686-mingw: linker `cc` not found
|
|
||||||
//@ only-x86
|
|
||||||
//@ ignore-windows
|
|
||||||
//@ ignore-apple
|
|
||||||
//@ needs-llvm-components: x86
|
//@ needs-llvm-components: x86
|
||||||
|
|
||||||
|
#![feature(no_core)]
|
||||||
#![crate_type = "rlib"]
|
#![crate_type = "rlib"]
|
||||||
#![no_core]
|
#![no_core]
|
||||||
#![feature(no_core, lang_items, repr_simd)]
|
|
||||||
|
|
||||||
#[lang = "sized"]
|
|
||||||
trait Sized {}
|
|
||||||
#[lang = "copy"]
|
|
||||||
trait Copy {}
|
|
||||||
|
|
||||||
pub fn somefun() {}
|
|
||||||
|
|
||||||
pub struct S;
|
|
||||||
|
|
|
@ -1,20 +1,7 @@
|
||||||
//@ compile-flags: --target i686-unknown-linux-gnu -Zregparm=2 -Cpanic=abort
|
//@ no-prefer-dynamic
|
||||||
// Auxiliary build problems with aarch64-apple:
|
//@ compile-flags: --target i686-unknown-linux-gnu -Zregparm=2
|
||||||
// Shared library linking cc seems to convert "-m32" flag into -arch armv4t
|
|
||||||
// Auxiliary build problems with i686-mingw: linker `cc` not found
|
|
||||||
//@ only-x86
|
|
||||||
//@ ignore-windows
|
|
||||||
//@ ignore-apple
|
|
||||||
//@ needs-llvm-components: x86
|
//@ needs-llvm-components: x86
|
||||||
|
|
||||||
|
#![feature(no_core)]
|
||||||
#![crate_type = "rlib"]
|
#![crate_type = "rlib"]
|
||||||
#![no_core]
|
#![no_core]
|
||||||
#![feature(no_core, lang_items, repr_simd)]
|
|
||||||
|
|
||||||
#[lang = "sized"]
|
|
||||||
trait Sized {}
|
|
||||||
#[lang = "copy"]
|
|
||||||
trait Copy {}
|
|
||||||
|
|
||||||
pub fn somefun() {}
|
|
||||||
|
|
||||||
pub struct S;
|
|
||||||
|
|
|
@ -1,20 +1,7 @@
|
||||||
//@ compile-flags: --target i686-unknown-linux-gnu -Zregparm=2 -Zreg-struct-return=true -Cpanic=abort
|
//@ no-prefer-dynamic
|
||||||
// Auxiliary build problems with aarch64-apple:
|
//@ compile-flags: --target i686-unknown-linux-gnu -Zregparm=2 -Zreg-struct-return=true
|
||||||
// Shared library linking cc seems to convert "-m32" flag into -arch armv4t
|
|
||||||
// Auxiliary build problems with i686-mingw: linker `cc` not found
|
|
||||||
//@ only-x86
|
|
||||||
//@ ignore-windows
|
|
||||||
//@ ignore-apple
|
|
||||||
//@ needs-llvm-components: x86
|
//@ needs-llvm-components: x86
|
||||||
|
|
||||||
|
#![feature(no_core)]
|
||||||
#![crate_type = "rlib"]
|
#![crate_type = "rlib"]
|
||||||
#![no_core]
|
#![no_core]
|
||||||
#![feature(no_core, lang_items, repr_simd)]
|
|
||||||
|
|
||||||
#[lang = "sized"]
|
|
||||||
trait Sized {}
|
|
||||||
#[lang = "copy"]
|
|
||||||
trait Copy {}
|
|
||||||
|
|
||||||
pub fn somefun() {}
|
|
||||||
|
|
||||||
pub struct S;
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
error: mixing `-Zreg-struct-return` will cause an ABI mismatch in crate `defaults_check`
|
error: mixing `-Zreg-struct-return` will cause an ABI mismatch in crate `defaults_check`
|
||||||
--> $DIR/defaults_check.rs:20:1
|
--> $DIR/defaults_check.rs:15:1
|
||||||
|
|
|
|
||||||
LL | #![crate_type = "rlib"]
|
LL | #![feature(no_core)]
|
||||||
| ^
|
| ^
|
||||||
|
|
|
|
||||||
= help: the `-Zreg-struct-return` flag modifies the ABI so Rust crates compiled with different values of this flag cannot be used together safely
|
= help: the `-Zreg-struct-return` flag modifies the ABI so Rust crates compiled with different values of this flag cannot be used together safely
|
||||||
|
|
|
@ -1,27 +1,20 @@
|
||||||
// Tests that default unspecified target modifier value in dependency crate is ok linked
|
// Tests that default unspecified target modifier value in dependency crate is ok linked
|
||||||
// with the same value, explicitly specified
|
// with the same value, explicitly specified
|
||||||
//@ aux-crate:default_reg_struct_return=default_reg_struct_return.rs
|
|
||||||
|
//@ aux-build:default_reg_struct_return.rs
|
||||||
//@ compile-flags: --target i686-unknown-linux-gnu -Cpanic=abort
|
//@ compile-flags: --target i686-unknown-linux-gnu -Cpanic=abort
|
||||||
//@ revisions:error ok ok_explicit
|
//@ needs-llvm-components: x86
|
||||||
|
|
||||||
|
//@ revisions: ok ok_explicit error
|
||||||
//@[ok] compile-flags:
|
//@[ok] compile-flags:
|
||||||
//@[ok_explicit] compile-flags: -Zreg-struct-return=false
|
//@[ok_explicit] compile-flags: -Zreg-struct-return=false
|
||||||
//@[error] compile-flags: -Zreg-struct-return=true
|
//@[error] compile-flags: -Zreg-struct-return=true
|
||||||
|
//@[ok] check-pass
|
||||||
|
//@[ok_explicit] check-pass
|
||||||
|
|
||||||
// Auxiliary build problems with aarch64-apple:
|
#![feature(no_core)]
|
||||||
// Shared library linking cc seems to convert "-m32" flag into -arch armv4t
|
|
||||||
// Auxiliary build problems with i686-mingw: linker `cc` not found
|
|
||||||
//@ only-x86
|
|
||||||
//@ ignore-windows
|
|
||||||
//@ ignore-apple
|
|
||||||
//@ needs-llvm-components: x86
|
|
||||||
//@[ok] build-pass
|
|
||||||
//@[ok_explicit] build-pass
|
|
||||||
|
|
||||||
#![crate_type = "rlib"]
|
|
||||||
//[error]~^ ERROR mixing `-Zreg-struct-return` will cause an ABI mismatch in crate `defaults_check`
|
//[error]~^ ERROR mixing `-Zreg-struct-return` will cause an ABI mismatch in crate `defaults_check`
|
||||||
|
#![crate_type = "rlib"]
|
||||||
#![no_core]
|
#![no_core]
|
||||||
#![feature(no_core, lang_items, repr_simd)]
|
|
||||||
|
|
||||||
fn foo() {
|
extern crate default_reg_struct_return;
|
||||||
default_reg_struct_return::somefun();
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
error: mixing `-Zregparm` will cause an ABI mismatch in crate `incompatible_regparm`
|
error: mixing `-Zregparm` will cause an ABI mismatch in crate `incompatible_regparm`
|
||||||
--> $DIR/incompatible_regparm.rs:16:1
|
--> $DIR/incompatible_regparm.rs:11:1
|
||||||
|
|
|
|
||||||
LL | #![crate_type = "rlib"]
|
LL | #![feature(no_core)]
|
||||||
| ^
|
| ^
|
||||||
|
|
|
|
||||||
= help: the `-Zregparm` flag modifies the ABI so Rust crates compiled with different values of this flag cannot be used together safely
|
= help: the `-Zregparm` flag modifies the ABI so Rust crates compiled with different values of this flag cannot be used together safely
|
||||||
|
|
|
@ -1,23 +1,16 @@
|
||||||
//@ aux-crate:wrong_regparm=wrong_regparm.rs
|
//@ aux-build:wrong_regparm.rs
|
||||||
//@ compile-flags: --target i686-unknown-linux-gnu -Zregparm=1 -Cpanic=abort
|
//@ compile-flags: --target i686-unknown-linux-gnu -Zregparm=1
|
||||||
// Auxiliary build problems with aarch64-apple:
|
|
||||||
// Shared library linking cc seems to convert "-m32" flag into -arch armv4t
|
|
||||||
// Auxiliary build problems with i686-mingw: linker `cc` not found
|
|
||||||
//@ only-x86
|
|
||||||
//@ ignore-windows
|
|
||||||
//@ ignore-apple
|
|
||||||
//@ needs-llvm-components: x86
|
//@ needs-llvm-components: x86
|
||||||
//@ revisions:error_generated allow_regparm_mismatch allow_no_value
|
|
||||||
|
|
||||||
|
//@ revisions:allow_regparm_mismatch allow_no_value error_generated
|
||||||
//@[allow_regparm_mismatch] compile-flags: -Cunsafe-allow-abi-mismatch=regparm
|
//@[allow_regparm_mismatch] compile-flags: -Cunsafe-allow-abi-mismatch=regparm
|
||||||
//@[allow_regparm_mismatch] build-pass
|
|
||||||
//@[allow_no_value] compile-flags: -Cunsafe-allow-abi-mismatch
|
//@[allow_no_value] compile-flags: -Cunsafe-allow-abi-mismatch
|
||||||
|
//@[error_generated] compile-flags:
|
||||||
|
//@[allow_regparm_mismatch] check-pass
|
||||||
|
|
||||||
#![crate_type = "rlib"]
|
#![feature(no_core)]
|
||||||
//[error_generated]~^ ERROR mixing `-Zregparm` will cause an ABI mismatch in crate `incompatible_regparm`
|
//[error_generated]~^ ERROR mixing `-Zregparm` will cause an ABI mismatch in crate `incompatible_regparm`
|
||||||
|
#![crate_type = "rlib"]
|
||||||
#![no_core]
|
#![no_core]
|
||||||
#![feature(no_core, lang_items, repr_simd)]
|
|
||||||
|
|
||||||
fn foo() {
|
extern crate wrong_regparm;
|
||||||
wrong_regparm::somefun();
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,23 +1,15 @@
|
||||||
//@ aux-crate:wrong_regparm_and_ret=wrong_regparm_and_ret.rs
|
//@ aux-build:wrong_regparm_and_ret.rs
|
||||||
//@ compile-flags: --target i686-unknown-linux-gnu -Cpanic=abort
|
//@ compile-flags: --target i686-unknown-linux-gnu
|
||||||
// Auxiliary build problems with aarch64-apple:
|
|
||||||
// Shared library linking cc seems to convert "-m32" flag into -arch armv4t
|
|
||||||
// Auxiliary build problems with i686-mingw: linker `cc` not found
|
|
||||||
//@ only-x86
|
|
||||||
//@ ignore-windows
|
|
||||||
//@ ignore-apple
|
|
||||||
//@ needs-llvm-components: x86
|
//@ needs-llvm-components: x86
|
||||||
|
|
||||||
//@ revisions:two_allowed unknown_allowed
|
//@ revisions:two_allowed unknown_allowed
|
||||||
|
|
||||||
//@[two_allowed] compile-flags: -Cunsafe-allow-abi-mismatch=regparm,reg-struct-return
|
//@[two_allowed] compile-flags: -Cunsafe-allow-abi-mismatch=regparm,reg-struct-return
|
||||||
//@[two_allowed] build-pass
|
|
||||||
//@[unknown_allowed] compile-flags: -Cunsafe-allow-abi-mismatch=unknown_flag -Zregparm=2 -Zreg-struct-return=true
|
//@[unknown_allowed] compile-flags: -Cunsafe-allow-abi-mismatch=unknown_flag -Zregparm=2 -Zreg-struct-return=true
|
||||||
|
//@[two_allowed] check-pass
|
||||||
|
|
||||||
#![crate_type = "rlib"]
|
#![feature(no_core)]
|
||||||
//[unknown_allowed]~^ ERROR unknown target modifier `unknown_flag`, requested by `-Cunsafe-allow-abi-mismatch=unknown_flag`
|
//[unknown_allowed]~^ ERROR unknown target modifier `unknown_flag`, requested by `-Cunsafe-allow-abi-mismatch=unknown_flag`
|
||||||
|
#![crate_type = "rlib"]
|
||||||
#![no_core]
|
#![no_core]
|
||||||
#![feature(no_core, lang_items, repr_simd)]
|
|
||||||
|
|
||||||
fn foo() {
|
extern crate wrong_regparm_and_ret;
|
||||||
wrong_regparm_and_ret::somefun();
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
error: unknown target modifier `unknown_flag`, requested by `-Cunsafe-allow-abi-mismatch=unknown_flag`
|
error: unknown target modifier `unknown_flag`, requested by `-Cunsafe-allow-abi-mismatch=unknown_flag`
|
||||||
--> $DIR/two_flags.rs:16:1
|
--> $DIR/two_flags.rs:10:1
|
||||||
|
|
|
|
||||||
LL | #![crate_type = "rlib"]
|
LL | #![feature(no_core)]
|
||||||
| ^
|
| ^
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
error: aborting due to 1 previous error
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue