mirror of https://github.com/rust-lang/cargo
Compare commits
8 Commits
c3a723ddf5
...
922fc3715b
Author | SHA1 | Date |
---|---|---|
Sebastian Ziebell | 922fc3715b | |
bors | cf7b3c4cf3 | |
Scott Schafer | 6c2334613c | |
bors | 97181c67e1 | |
Weihang Lo | f8aead9338 | |
bors | 9e57a8d830 | |
Ed Page | f5892f210e | |
Ed Page | 3740bbb36c |
|
@ -1286,10 +1286,6 @@ pub trait TestEnv: Sized {
|
|||
.env_remove("USER") // not set on some rust-lang docker images
|
||||
.env_remove("XDG_CONFIG_HOME") // see #2345
|
||||
.env_remove("OUT_DIR"); // see #13204
|
||||
if cfg!(target_os = "macos") {
|
||||
// Work-around a bug in macOS 10.15, see `link_or_copy` for details.
|
||||
self = self.env("__CARGO_COPY_DONT_LINK_DO_NOT_USE_THIS", "1");
|
||||
}
|
||||
if cfg!(windows) {
|
||||
self = self.env("USERPROFILE", paths::home());
|
||||
}
|
||||
|
|
|
@ -565,26 +565,18 @@ fn _link_or_copy(src: &Path, dst: &Path) -> Result<()> {
|
|||
src
|
||||
};
|
||||
symlink(src, dst)
|
||||
} else if env::var_os("__CARGO_COPY_DONT_LINK_DO_NOT_USE_THIS").is_some() {
|
||||
// This is a work-around for a bug in macOS 10.15. When running on
|
||||
// APFS, there seems to be a strange race condition with
|
||||
// Gatekeeper where it will forcefully kill a process launched via
|
||||
// `cargo run` with SIGKILL. Copying seems to avoid the problem.
|
||||
// This shouldn't affect anyone except Cargo's test suite because
|
||||
// it is very rare, and only seems to happen under heavy load and
|
||||
// rapidly creating lots of executables and running them.
|
||||
// See https://github.com/rust-lang/cargo/issues/7821 for the
|
||||
// gory details.
|
||||
fs::copy(src, dst).map(|_| ())
|
||||
} else {
|
||||
if cfg!(target_os = "macos") {
|
||||
// This is a work-around for a bug on macos. There seems to be a race condition
|
||||
// with APFS when hard-linking binaries. Gatekeeper does not have signing or
|
||||
// hash information stored in kernel when running the process. Therefore killing it.
|
||||
// This problem does not appear when copying files as kernel has time to process it.
|
||||
// Note that: fs::copy on macos is using CopyOnWrite (syscall fclonefileat) which should be
|
||||
// as fast as hardlinking.
|
||||
// See https://github.com/rust-lang/cargo/issues/10060 for the details
|
||||
// There seems to be a race condition with APFS when hard-linking
|
||||
// binaries. Gatekeeper does not have signing or hash information
|
||||
// stored in kernel when running the process. Therefore killing it.
|
||||
// This problem does not appear when copying files as kernel has
|
||||
// time to process it. Note that: fs::copy on macos is using
|
||||
// CopyOnWrite (syscall fclonefileat) which should be as fast as
|
||||
// hardlinking. See these issues for the details:
|
||||
//
|
||||
// * https://github.com/rust-lang/cargo/issues/7821
|
||||
// * https://github.com/rust-lang/cargo/issues/10060
|
||||
fs::copy(src, dst).map_or_else(
|
||||
|e| {
|
||||
if e.raw_os_error()
|
||||
|
|
|
@ -1149,25 +1149,11 @@ impl<'gctx> Workspace<'gctx> {
|
|||
}
|
||||
|
||||
pub fn emit_warnings(&self) -> CargoResult<()> {
|
||||
let ws_lints = self
|
||||
.root_maybe()
|
||||
.workspace_config()
|
||||
.inheritable()
|
||||
.and_then(|i| i.lints().ok())
|
||||
.unwrap_or_default();
|
||||
|
||||
let ws_cargo_lints = ws_lints
|
||||
.get("cargo")
|
||||
.cloned()
|
||||
.unwrap_or_default()
|
||||
.into_iter()
|
||||
.collect();
|
||||
|
||||
for (path, maybe_pkg) in &self.packages.packages {
|
||||
let path = path.join("Cargo.toml");
|
||||
if let MaybePackage::Package(pkg) = maybe_pkg {
|
||||
if self.gctx.cli_unstable().cargo_lints {
|
||||
self.emit_lints(pkg, &path, &ws_cargo_lints)?
|
||||
self.emit_lints(pkg, &path)?
|
||||
}
|
||||
}
|
||||
let warnings = match maybe_pkg {
|
||||
|
@ -1195,12 +1181,7 @@ impl<'gctx> Workspace<'gctx> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
pub fn emit_lints(
|
||||
&self,
|
||||
pkg: &Package,
|
||||
path: &Path,
|
||||
ws_cargo_lints: &manifest::TomlToolLints,
|
||||
) -> CargoResult<()> {
|
||||
pub fn emit_lints(&self, pkg: &Package, path: &Path) -> CargoResult<()> {
|
||||
let mut error_count = 0;
|
||||
let toml_lints = pkg
|
||||
.manifest()
|
||||
|
@ -1214,16 +1195,6 @@ impl<'gctx> Workspace<'gctx> {
|
|||
.cloned()
|
||||
.unwrap_or(manifest::TomlToolLints::default());
|
||||
|
||||
// We should only be using workspace lints if the `[lints]` table is
|
||||
// present in the manifest, and `workspace` is set to `true`
|
||||
let ws_cargo_lints = pkg
|
||||
.manifest()
|
||||
.resolved_toml()
|
||||
.lints
|
||||
.as_ref()
|
||||
.is_some_and(|l| l.workspace)
|
||||
.then(|| ws_cargo_lints);
|
||||
|
||||
let ws_contents = match self.root_maybe() {
|
||||
MaybePackage::Package(pkg) => pkg.manifest().contents(),
|
||||
MaybePackage::Virtual(v) => v.contents(),
|
||||
|
@ -1238,36 +1209,14 @@ impl<'gctx> Workspace<'gctx> {
|
|||
pkg,
|
||||
&path,
|
||||
&cargo_lints,
|
||||
ws_cargo_lints,
|
||||
ws_contents,
|
||||
ws_document,
|
||||
self.root_manifest(),
|
||||
self.gctx,
|
||||
)?;
|
||||
check_im_a_teapot(
|
||||
pkg,
|
||||
&path,
|
||||
&cargo_lints,
|
||||
ws_cargo_lints,
|
||||
&mut error_count,
|
||||
self.gctx,
|
||||
)?;
|
||||
check_implicit_features(
|
||||
pkg,
|
||||
&path,
|
||||
&cargo_lints,
|
||||
ws_cargo_lints,
|
||||
&mut error_count,
|
||||
self.gctx,
|
||||
)?;
|
||||
unused_dependencies(
|
||||
pkg,
|
||||
&path,
|
||||
&cargo_lints,
|
||||
ws_cargo_lints,
|
||||
&mut error_count,
|
||||
self.gctx,
|
||||
)?;
|
||||
check_im_a_teapot(pkg, &path, &cargo_lints, &mut error_count, self.gctx)?;
|
||||
check_implicit_features(pkg, &path, &cargo_lints, &mut error_count, self.gctx)?;
|
||||
unused_dependencies(pkg, &path, &cargo_lints, &mut error_count, self.gctx)?;
|
||||
if error_count > 0 {
|
||||
Err(crate::util::errors::AlreadyPrintedError::new(anyhow!(
|
||||
"encountered {error_count} errors(s) while running lints"
|
||||
|
|
|
@ -19,7 +19,6 @@ pub fn analyze_cargo_lints_table(
|
|||
pkg: &Package,
|
||||
path: &Path,
|
||||
pkg_lints: &TomlToolLints,
|
||||
ws_lints: Option<&TomlToolLints>,
|
||||
ws_contents: &str,
|
||||
ws_document: &ImDocument<String>,
|
||||
ws_path: &Path,
|
||||
|
@ -30,20 +29,11 @@ pub fn analyze_cargo_lints_table(
|
|||
let manifest_path = rel_cwd_manifest_path(path, gctx);
|
||||
let ws_path = rel_cwd_manifest_path(ws_path, gctx);
|
||||
let mut unknown_lints = Vec::new();
|
||||
for (lint_name, specified_in) in pkg_lints
|
||||
.keys()
|
||||
.map(|name| (name, SpecifiedIn::Package))
|
||||
.chain(
|
||||
ws_lints
|
||||
.map(|l| l.keys())
|
||||
.unwrap_or_default()
|
||||
.map(|name| (name, SpecifiedIn::Workspace)),
|
||||
)
|
||||
{
|
||||
for lint_name in pkg_lints.keys().map(|name| name) {
|
||||
let Some((name, default_level, edition_lint_opts, feature_gate)) =
|
||||
find_lint_or_group(lint_name)
|
||||
else {
|
||||
unknown_lints.push((lint_name, specified_in));
|
||||
unknown_lints.push(lint_name);
|
||||
continue;
|
||||
};
|
||||
|
||||
|
@ -52,7 +42,6 @@ pub fn analyze_cargo_lints_table(
|
|||
*default_level,
|
||||
*edition_lint_opts,
|
||||
pkg_lints,
|
||||
ws_lints,
|
||||
manifest.edition(),
|
||||
);
|
||||
|
||||
|
@ -66,7 +55,6 @@ pub fn analyze_cargo_lints_table(
|
|||
verify_feature_enabled(
|
||||
name,
|
||||
feature_gate,
|
||||
reason,
|
||||
manifest,
|
||||
&manifest_path,
|
||||
ws_contents,
|
||||
|
@ -83,7 +71,6 @@ pub fn analyze_cargo_lints_table(
|
|||
manifest,
|
||||
&manifest_path,
|
||||
pkg_lints,
|
||||
ws_lints,
|
||||
ws_contents,
|
||||
ws_document,
|
||||
&ws_path,
|
||||
|
@ -130,7 +117,6 @@ fn find_lint_or_group<'a>(
|
|||
fn verify_feature_enabled(
|
||||
lint_name: &str,
|
||||
feature_gate: &Feature,
|
||||
reason: LintLevelReason,
|
||||
manifest: &Manifest,
|
||||
manifest_path: &str,
|
||||
ws_contents: &str,
|
||||
|
@ -151,55 +137,55 @@ fn verify_feature_enabled(
|
|||
"consider adding `cargo-features = [\"{}\"]` to the top of the manifest",
|
||||
dash_feature_name
|
||||
);
|
||||
let message = match reason {
|
||||
LintLevelReason::Package => {
|
||||
let span =
|
||||
get_span(manifest.document(), &["lints", "cargo", lint_name], false).unwrap();
|
||||
|
||||
Level::Error
|
||||
.title(&title)
|
||||
.snippet(
|
||||
Snippet::source(manifest.contents())
|
||||
.origin(&manifest_path)
|
||||
.annotation(Level::Error.span(span).label(&label))
|
||||
.fold(true),
|
||||
)
|
||||
.footer(Level::Help.title(&help))
|
||||
}
|
||||
LintLevelReason::Workspace => {
|
||||
let lint_span = get_span(
|
||||
ws_document,
|
||||
&["workspace", "lints", "cargo", lint_name],
|
||||
false,
|
||||
let message = if let Some(span) =
|
||||
get_span(manifest.document(), &["lints", "cargo", lint_name], false)
|
||||
{
|
||||
Level::Error
|
||||
.title(&title)
|
||||
.snippet(
|
||||
Snippet::source(manifest.contents())
|
||||
.origin(&manifest_path)
|
||||
.annotation(Level::Error.span(span).label(&label))
|
||||
.fold(true),
|
||||
)
|
||||
.unwrap();
|
||||
let inherit_span_key =
|
||||
get_span(manifest.document(), &["lints", "workspace"], false).unwrap();
|
||||
let inherit_span_value =
|
||||
get_span(manifest.document(), &["lints", "workspace"], true).unwrap();
|
||||
.footer(Level::Help.title(&help))
|
||||
} else {
|
||||
let lint_span = get_span(
|
||||
ws_document,
|
||||
&["workspace", "lints", "cargo", lint_name],
|
||||
false,
|
||||
)
|
||||
.expect(&format!(
|
||||
"could not find `cargo::{lint_name}` in `[lints]`, or `[workspace.lints]` "
|
||||
));
|
||||
|
||||
Level::Error
|
||||
.title(&title)
|
||||
.snippet(
|
||||
Snippet::source(ws_contents)
|
||||
.origin(&ws_path)
|
||||
.annotation(Level::Error.span(lint_span).label(&label))
|
||||
.fold(true),
|
||||
)
|
||||
.footer(
|
||||
Level::Note.title(&second_title).snippet(
|
||||
Snippet::source(manifest.contents())
|
||||
.origin(&manifest_path)
|
||||
.annotation(
|
||||
Level::Note
|
||||
.span(inherit_span_key.start..inherit_span_value.end),
|
||||
)
|
||||
.fold(true),
|
||||
),
|
||||
)
|
||||
.footer(Level::Help.title(&help))
|
||||
}
|
||||
_ => unreachable!("LintLevelReason should be one that is user specified"),
|
||||
let inherited_note = if let (Some(inherit_span_key), Some(inherit_span_value)) = (
|
||||
get_span(manifest.document(), &["lints", "workspace"], false),
|
||||
get_span(manifest.document(), &["lints", "workspace"], true),
|
||||
) {
|
||||
Level::Note.title(&second_title).snippet(
|
||||
Snippet::source(manifest.contents())
|
||||
.origin(&manifest_path)
|
||||
.annotation(
|
||||
Level::Note.span(inherit_span_key.start..inherit_span_value.end),
|
||||
)
|
||||
.fold(true),
|
||||
)
|
||||
} else {
|
||||
Level::Note.title(&second_title)
|
||||
};
|
||||
|
||||
Level::Error
|
||||
.title(&title)
|
||||
.snippet(
|
||||
Snippet::source(ws_contents)
|
||||
.origin(&ws_path)
|
||||
.annotation(Level::Error.span(lint_span).label(&label))
|
||||
.fold(true),
|
||||
)
|
||||
.footer(inherited_note)
|
||||
.footer(Level::Help.title(&help))
|
||||
};
|
||||
|
||||
*error_count += 1;
|
||||
|
@ -287,7 +273,6 @@ impl Lint {
|
|||
pub fn level(
|
||||
&self,
|
||||
pkg_lints: &TomlToolLints,
|
||||
ws_lints: Option<&TomlToolLints>,
|
||||
edition: Edition,
|
||||
unstable_features: &Features,
|
||||
) -> (LintLevel, LintLevelReason) {
|
||||
|
@ -310,7 +295,6 @@ impl Lint {
|
|||
g.default_level,
|
||||
g.edition_lint_opts,
|
||||
pkg_lints,
|
||||
ws_lints,
|
||||
edition,
|
||||
),
|
||||
)
|
||||
|
@ -322,7 +306,6 @@ impl Lint {
|
|||
self.default_level,
|
||||
self.edition_lint_opts,
|
||||
pkg_lints,
|
||||
ws_lints,
|
||||
edition,
|
||||
),
|
||||
)))
|
||||
|
@ -378,7 +361,6 @@ pub enum LintLevelReason {
|
|||
Default,
|
||||
Edition(Edition),
|
||||
Package,
|
||||
Workspace,
|
||||
}
|
||||
|
||||
impl Display for LintLevelReason {
|
||||
|
@ -387,7 +369,6 @@ impl Display for LintLevelReason {
|
|||
LintLevelReason::Default => write!(f, "by default"),
|
||||
LintLevelReason::Edition(edition) => write!(f, "in edition {}", edition),
|
||||
LintLevelReason::Package => write!(f, "in `[lints]`"),
|
||||
LintLevelReason::Workspace => write!(f, "in `[workspace.lints]`"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -398,22 +379,15 @@ impl LintLevelReason {
|
|||
LintLevelReason::Default => false,
|
||||
LintLevelReason::Edition(_) => false,
|
||||
LintLevelReason::Package => true,
|
||||
LintLevelReason::Workspace => true,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enum SpecifiedIn {
|
||||
Package,
|
||||
Workspace,
|
||||
}
|
||||
|
||||
fn level_priority(
|
||||
name: &str,
|
||||
default_level: LintLevel,
|
||||
edition_lint_opts: Option<(Edition, LintLevel)>,
|
||||
pkg_lints: &TomlToolLints,
|
||||
ws_lints: Option<&TomlToolLints>,
|
||||
edition: Edition,
|
||||
) -> (LintLevel, LintLevelReason, i8) {
|
||||
let (unspecified_level, reason) = if let Some(level) = edition_lint_opts
|
||||
|
@ -436,12 +410,6 @@ fn level_priority(
|
|||
LintLevelReason::Package,
|
||||
defined_level.priority(),
|
||||
)
|
||||
} else if let Some(defined_level) = ws_lints.and_then(|l| l.get(name)) {
|
||||
(
|
||||
defined_level.level().into(),
|
||||
LintLevelReason::Workspace,
|
||||
defined_level.priority(),
|
||||
)
|
||||
} else {
|
||||
(unspecified_level, reason, 0)
|
||||
}
|
||||
|
@ -460,17 +428,12 @@ pub fn check_im_a_teapot(
|
|||
pkg: &Package,
|
||||
path: &Path,
|
||||
pkg_lints: &TomlToolLints,
|
||||
ws_lints: Option<&TomlToolLints>,
|
||||
error_count: &mut usize,
|
||||
gctx: &GlobalContext,
|
||||
) -> CargoResult<()> {
|
||||
let manifest = pkg.manifest();
|
||||
let (lint_level, reason) = IM_A_TEAPOT.level(
|
||||
pkg_lints,
|
||||
ws_lints,
|
||||
manifest.edition(),
|
||||
manifest.unstable_features(),
|
||||
);
|
||||
let (lint_level, reason) =
|
||||
IM_A_TEAPOT.level(pkg_lints, manifest.edition(), manifest.unstable_features());
|
||||
|
||||
if lint_level == LintLevel::Allow {
|
||||
return Ok(());
|
||||
|
@ -534,7 +497,6 @@ pub fn check_implicit_features(
|
|||
pkg: &Package,
|
||||
path: &Path,
|
||||
pkg_lints: &TomlToolLints,
|
||||
ws_lints: Option<&TomlToolLints>,
|
||||
error_count: &mut usize,
|
||||
gctx: &GlobalContext,
|
||||
) -> CargoResult<()> {
|
||||
|
@ -547,7 +509,7 @@ pub fn check_implicit_features(
|
|||
}
|
||||
|
||||
let (lint_level, reason) =
|
||||
IMPLICIT_FEATURES.level(pkg_lints, ws_lints, edition, manifest.unstable_features());
|
||||
IMPLICIT_FEATURES.level(pkg_lints, edition, manifest.unstable_features());
|
||||
if lint_level == LintLevel::Allow {
|
||||
return Ok(());
|
||||
}
|
||||
|
@ -611,30 +573,25 @@ const UNKNOWN_LINTS: Lint = Lint {
|
|||
};
|
||||
|
||||
fn output_unknown_lints(
|
||||
unknown_lints: Vec<(&String, SpecifiedIn)>,
|
||||
unknown_lints: Vec<&String>,
|
||||
manifest: &Manifest,
|
||||
manifest_path: &str,
|
||||
pkg_lints: &TomlToolLints,
|
||||
ws_lints: Option<&TomlToolLints>,
|
||||
ws_contents: &str,
|
||||
ws_document: &ImDocument<String>,
|
||||
ws_path: &str,
|
||||
error_count: &mut usize,
|
||||
gctx: &GlobalContext,
|
||||
) -> CargoResult<()> {
|
||||
let (lint_level, reason) = UNKNOWN_LINTS.level(
|
||||
pkg_lints,
|
||||
ws_lints,
|
||||
manifest.edition(),
|
||||
manifest.unstable_features(),
|
||||
);
|
||||
let (lint_level, reason) =
|
||||
UNKNOWN_LINTS.level(pkg_lints, manifest.edition(), manifest.unstable_features());
|
||||
if lint_level == LintLevel::Allow {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let level = lint_level.to_diagnostic_level();
|
||||
let mut emitted_source = None;
|
||||
for (lint_name, specified_in) in unknown_lints {
|
||||
for lint_name in unknown_lints {
|
||||
if lint_level == LintLevel::Forbid || lint_level == LintLevel::Deny {
|
||||
*error_count += 1;
|
||||
}
|
||||
|
@ -651,50 +608,50 @@ fn output_unknown_lints(
|
|||
let help =
|
||||
matching.map(|(name, kind)| format!("there is a {kind} with a similar name: `{name}`"));
|
||||
|
||||
let mut message = match specified_in {
|
||||
SpecifiedIn::Package => {
|
||||
let span =
|
||||
get_span(manifest.document(), &["lints", "cargo", lint_name], false).unwrap();
|
||||
let mut message = if let Some(span) =
|
||||
get_span(manifest.document(), &["lints", "cargo", lint_name], false)
|
||||
{
|
||||
level.title(&title).snippet(
|
||||
Snippet::source(manifest.contents())
|
||||
.origin(&manifest_path)
|
||||
.annotation(Level::Error.span(span))
|
||||
.fold(true),
|
||||
)
|
||||
} else {
|
||||
let lint_span = get_span(
|
||||
ws_document,
|
||||
&["workspace", "lints", "cargo", lint_name],
|
||||
false,
|
||||
)
|
||||
.expect(&format!(
|
||||
"could not find `cargo::{lint_name}` in `[lints]`, or `[workspace.lints]` "
|
||||
));
|
||||
|
||||
level.title(&title).snippet(
|
||||
let inherited_note = if let (Some(inherit_span_key), Some(inherit_span_value)) = (
|
||||
get_span(manifest.document(), &["lints", "workspace"], false),
|
||||
get_span(manifest.document(), &["lints", "workspace"], true),
|
||||
) {
|
||||
Level::Note.title(&second_title).snippet(
|
||||
Snippet::source(manifest.contents())
|
||||
.origin(&manifest_path)
|
||||
.annotation(Level::Error.span(span))
|
||||
.annotation(
|
||||
Level::Note.span(inherit_span_key.start..inherit_span_value.end),
|
||||
)
|
||||
.fold(true),
|
||||
)
|
||||
}
|
||||
SpecifiedIn::Workspace => {
|
||||
let lint_span = get_span(
|
||||
ws_document,
|
||||
&["workspace", "lints", "cargo", lint_name],
|
||||
false,
|
||||
)
|
||||
.unwrap();
|
||||
let inherit_span_key =
|
||||
get_span(manifest.document(), &["lints", "workspace"], false).unwrap();
|
||||
let inherit_span_value =
|
||||
get_span(manifest.document(), &["lints", "workspace"], true).unwrap();
|
||||
} else {
|
||||
Level::Note.title(&second_title)
|
||||
};
|
||||
|
||||
level
|
||||
.title(&title)
|
||||
.snippet(
|
||||
Snippet::source(ws_contents)
|
||||
.origin(&ws_path)
|
||||
.annotation(Level::Error.span(lint_span))
|
||||
.fold(true),
|
||||
)
|
||||
.footer(
|
||||
Level::Note.title(&second_title).snippet(
|
||||
Snippet::source(manifest.contents())
|
||||
.origin(&manifest_path)
|
||||
.annotation(
|
||||
Level::Note
|
||||
.span(inherit_span_key.start..inherit_span_value.end),
|
||||
)
|
||||
.fold(true),
|
||||
),
|
||||
)
|
||||
}
|
||||
level
|
||||
.title(&title)
|
||||
.snippet(
|
||||
Snippet::source(ws_contents)
|
||||
.origin(&ws_path)
|
||||
.annotation(Level::Error.span(lint_span))
|
||||
.fold(true),
|
||||
)
|
||||
.footer(inherited_note)
|
||||
};
|
||||
|
||||
if emitted_source.is_none() {
|
||||
|
@ -728,7 +685,6 @@ pub fn unused_dependencies(
|
|||
pkg: &Package,
|
||||
path: &Path,
|
||||
pkg_lints: &TomlToolLints,
|
||||
ws_lints: Option<&TomlToolLints>,
|
||||
error_count: &mut usize,
|
||||
gctx: &GlobalContext,
|
||||
) -> CargoResult<()> {
|
||||
|
@ -739,12 +695,8 @@ pub fn unused_dependencies(
|
|||
return Ok(());
|
||||
}
|
||||
|
||||
let (lint_level, reason) = UNUSED_OPTIONAL_DEPENDENCY.level(
|
||||
pkg_lints,
|
||||
ws_lints,
|
||||
edition,
|
||||
manifest.unstable_features(),
|
||||
);
|
||||
let (lint_level, reason) =
|
||||
UNUSED_OPTIONAL_DEPENDENCY.level(pkg_lints, edition, manifest.unstable_features());
|
||||
if lint_level == LintLevel::Allow {
|
||||
return Ok(());
|
||||
}
|
||||
|
|
|
@ -492,7 +492,15 @@ fn resolve_toml(
|
|||
}
|
||||
resolved_toml.target = (!resolved_target.is_empty()).then_some(resolved_target);
|
||||
|
||||
resolved_toml.lints = original_toml.lints.clone();
|
||||
let resolved_lints = original_toml
|
||||
.lints
|
||||
.clone()
|
||||
.map(|value| lints_inherit_with(value, || inherit()?.lints()))
|
||||
.transpose()?;
|
||||
resolved_toml.lints = resolved_lints.map(|lints| manifest::InheritableLints {
|
||||
workspace: false,
|
||||
lints,
|
||||
});
|
||||
|
||||
resolved_toml.badges = original_toml.badges.clone();
|
||||
} else {
|
||||
|
@ -1336,18 +1344,18 @@ fn to_real_manifest(
|
|||
}
|
||||
}
|
||||
|
||||
let resolved_lints = resolved_toml
|
||||
.lints
|
||||
.clone()
|
||||
.map(|value| {
|
||||
lints_inherit_with(value, || {
|
||||
load_inheritable_fields(gctx, manifest_file, &workspace_config)?.lints()
|
||||
})
|
||||
})
|
||||
.transpose()?;
|
||||
|
||||
verify_lints(resolved_lints.as_ref(), gctx, warnings)?;
|
||||
let rustflags = lints_to_rustflags(&resolved_lints.unwrap_or_default());
|
||||
verify_lints(
|
||||
resolved_toml.resolved_lints().expect("previously resolved"),
|
||||
gctx,
|
||||
warnings,
|
||||
)?;
|
||||
let default = manifest::TomlLints::default();
|
||||
let rustflags = lints_to_rustflags(
|
||||
resolved_toml
|
||||
.resolved_lints()
|
||||
.expect("previously resolved")
|
||||
.unwrap_or(&default),
|
||||
);
|
||||
|
||||
let metadata = ManifestMetadata {
|
||||
description: resolved_package
|
||||
|
|
|
@ -261,48 +261,60 @@ pub fn resolve_bins(
|
|||
errors: &mut Vec<String>,
|
||||
has_lib: bool,
|
||||
) -> CargoResult<Vec<TomlBinTarget>> {
|
||||
let inferred = inferred_bins(package_root, package_name);
|
||||
if is_resolved(toml_bins, autodiscover) {
|
||||
let toml_bins = toml_bins.cloned().unwrap_or_default();
|
||||
for bin in &toml_bins {
|
||||
validate_bin_name(bin, warnings)?;
|
||||
validate_bin_crate_types(bin, edition, warnings, errors)?;
|
||||
validate_bin_proc_macro(bin, edition, warnings, errors)?;
|
||||
}
|
||||
Ok(toml_bins)
|
||||
} else {
|
||||
let inferred = inferred_bins(package_root, package_name);
|
||||
|
||||
let mut bins = toml_targets_and_inferred(
|
||||
toml_bins,
|
||||
&inferred,
|
||||
package_root,
|
||||
autodiscover,
|
||||
edition,
|
||||
warnings,
|
||||
"binary",
|
||||
"bin",
|
||||
"autobins",
|
||||
);
|
||||
let mut bins = toml_targets_and_inferred(
|
||||
toml_bins,
|
||||
&inferred,
|
||||
package_root,
|
||||
autodiscover,
|
||||
edition,
|
||||
warnings,
|
||||
"binary",
|
||||
"bin",
|
||||
"autobins",
|
||||
);
|
||||
|
||||
for bin in &mut bins {
|
||||
// Check early to improve error messages
|
||||
validate_bin_name(bin, warnings)?;
|
||||
for bin in &mut bins {
|
||||
// Check early to improve error messages
|
||||
validate_bin_name(bin, warnings)?;
|
||||
|
||||
validate_bin_crate_types(bin, edition, warnings, errors)?;
|
||||
validate_bin_proc_macro(bin, edition, warnings, errors)?;
|
||||
validate_bin_crate_types(bin, edition, warnings, errors)?;
|
||||
validate_bin_proc_macro(bin, edition, warnings, errors)?;
|
||||
|
||||
let path = target_path(bin, &inferred, "bin", package_root, edition, &mut |_| {
|
||||
if let Some(legacy_path) = legacy_bin_path(package_root, name_or_panic(bin), has_lib) {
|
||||
warnings.push(format!(
|
||||
"path `{}` was erroneously implicitly accepted for binary `{}`,\n\
|
||||
let path = target_path(bin, &inferred, "bin", package_root, edition, &mut |_| {
|
||||
if let Some(legacy_path) =
|
||||
legacy_bin_path(package_root, name_or_panic(bin), has_lib)
|
||||
{
|
||||
warnings.push(format!(
|
||||
"path `{}` was erroneously implicitly accepted for binary `{}`,\n\
|
||||
please set bin.path in Cargo.toml",
|
||||
legacy_path.display(),
|
||||
name_or_panic(bin)
|
||||
));
|
||||
Some(legacy_path)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
});
|
||||
let path = match path {
|
||||
Ok(path) => path,
|
||||
Err(e) => anyhow::bail!("{}", e),
|
||||
};
|
||||
bin.path = Some(PathValue(path));
|
||||
}
|
||||
legacy_path.display(),
|
||||
name_or_panic(bin)
|
||||
));
|
||||
Some(legacy_path)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
});
|
||||
let path = match path {
|
||||
Ok(path) => path,
|
||||
Err(e) => anyhow::bail!("{}", e),
|
||||
};
|
||||
bin.path = Some(PathValue(path));
|
||||
}
|
||||
|
||||
Ok(bins)
|
||||
Ok(bins)
|
||||
}
|
||||
}
|
||||
|
||||
#[tracing::instrument(skip_all)]
|
||||
|
@ -370,13 +382,13 @@ pub fn resolve_examples(
|
|||
warnings: &mut Vec<String>,
|
||||
errors: &mut Vec<String>,
|
||||
) -> CargoResult<Vec<TomlExampleTarget>> {
|
||||
let inferred = infer_from_directory(&package_root, Path::new(DEFAULT_EXAMPLE_DIR_NAME));
|
||||
let mut inferred = || infer_from_directory(&package_root, Path::new(DEFAULT_EXAMPLE_DIR_NAME));
|
||||
|
||||
let targets = resolve_targets(
|
||||
"example",
|
||||
"example",
|
||||
toml_examples,
|
||||
&inferred,
|
||||
&mut inferred,
|
||||
package_root,
|
||||
edition,
|
||||
autodiscover,
|
||||
|
@ -427,13 +439,13 @@ pub fn resolve_tests(
|
|||
warnings: &mut Vec<String>,
|
||||
errors: &mut Vec<String>,
|
||||
) -> CargoResult<Vec<TomlTestTarget>> {
|
||||
let inferred = infer_from_directory(&package_root, Path::new(DEFAULT_TEST_DIR_NAME));
|
||||
let mut inferred = || infer_from_directory(&package_root, Path::new(DEFAULT_TEST_DIR_NAME));
|
||||
|
||||
let targets = resolve_targets(
|
||||
"test",
|
||||
"test",
|
||||
toml_tests,
|
||||
&inferred,
|
||||
&mut inferred,
|
||||
package_root,
|
||||
edition,
|
||||
autodiscover,
|
||||
|
@ -492,13 +504,13 @@ pub fn resolve_benches(
|
|||
Some(legacy_path)
|
||||
};
|
||||
|
||||
let inferred = infer_from_directory(&package_root, Path::new(DEFAULT_BENCH_DIR_NAME));
|
||||
let mut inferred = || infer_from_directory(&package_root, Path::new(DEFAULT_BENCH_DIR_NAME));
|
||||
|
||||
let targets = resolve_targets_with_legacy_path(
|
||||
"benchmark",
|
||||
"bench",
|
||||
toml_benches,
|
||||
&inferred,
|
||||
&mut inferred,
|
||||
package_root,
|
||||
edition,
|
||||
autodiscover,
|
||||
|
@ -536,11 +548,24 @@ fn to_bench_targets(
|
|||
Ok(result)
|
||||
}
|
||||
|
||||
fn is_resolved(toml_targets: Option<&Vec<TomlTarget>>, autodiscover: Option<bool>) -> bool {
|
||||
if autodiscover != Some(false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
let Some(toml_targets) = toml_targets else {
|
||||
return true;
|
||||
};
|
||||
toml_targets
|
||||
.iter()
|
||||
.all(|t| t.name.is_some() && t.path.is_some())
|
||||
}
|
||||
|
||||
fn resolve_targets(
|
||||
target_kind_human: &str,
|
||||
target_kind: &str,
|
||||
toml_targets: Option<&Vec<TomlTarget>>,
|
||||
inferred: &[(String, PathBuf)],
|
||||
inferred: &mut dyn FnMut() -> Vec<(String, PathBuf)>,
|
||||
package_root: &Path,
|
||||
edition: Edition,
|
||||
autodiscover: Option<bool>,
|
||||
|
@ -567,7 +592,7 @@ fn resolve_targets_with_legacy_path(
|
|||
target_kind_human: &str,
|
||||
target_kind: &str,
|
||||
toml_targets: Option<&Vec<TomlTarget>>,
|
||||
inferred: &[(String, PathBuf)],
|
||||
inferred: &mut dyn FnMut() -> Vec<(String, PathBuf)>,
|
||||
package_root: &Path,
|
||||
edition: Edition,
|
||||
autodiscover: Option<bool>,
|
||||
|
@ -576,47 +601,60 @@ fn resolve_targets_with_legacy_path(
|
|||
legacy_path: &mut dyn FnMut(&TomlTarget) -> Option<PathBuf>,
|
||||
autodiscover_flag_name: &str,
|
||||
) -> CargoResult<Vec<TomlTarget>> {
|
||||
let toml_targets = toml_targets_and_inferred(
|
||||
toml_targets,
|
||||
inferred,
|
||||
package_root,
|
||||
autodiscover,
|
||||
edition,
|
||||
warnings,
|
||||
target_kind_human,
|
||||
target_kind,
|
||||
autodiscover_flag_name,
|
||||
);
|
||||
if is_resolved(toml_targets, autodiscover) {
|
||||
let toml_targets = toml_targets.cloned().unwrap_or_default();
|
||||
for target in &toml_targets {
|
||||
// Check early to improve error messages
|
||||
validate_target_name(target, target_kind_human, target_kind, warnings)?;
|
||||
|
||||
for target in &toml_targets {
|
||||
// Check early to improve error messages
|
||||
validate_target_name(target, target_kind_human, target_kind, warnings)?;
|
||||
|
||||
validate_proc_macro(target, target_kind_human, edition, warnings)?;
|
||||
validate_crate_types(target, target_kind_human, edition, warnings)?;
|
||||
}
|
||||
|
||||
let mut result = Vec::new();
|
||||
for mut target in toml_targets {
|
||||
let path = target_path(
|
||||
&target,
|
||||
inferred,
|
||||
target_kind,
|
||||
validate_proc_macro(target, target_kind_human, edition, warnings)?;
|
||||
validate_crate_types(target, target_kind_human, edition, warnings)?;
|
||||
}
|
||||
Ok(toml_targets)
|
||||
} else {
|
||||
let inferred = inferred();
|
||||
let toml_targets = toml_targets_and_inferred(
|
||||
toml_targets,
|
||||
&inferred,
|
||||
package_root,
|
||||
autodiscover,
|
||||
edition,
|
||||
legacy_path,
|
||||
warnings,
|
||||
target_kind_human,
|
||||
target_kind,
|
||||
autodiscover_flag_name,
|
||||
);
|
||||
let path = match path {
|
||||
Ok(path) => path,
|
||||
Err(e) => {
|
||||
errors.push(e);
|
||||
continue;
|
||||
}
|
||||
};
|
||||
target.path = Some(PathValue(path));
|
||||
result.push(target);
|
||||
|
||||
for target in &toml_targets {
|
||||
// Check early to improve error messages
|
||||
validate_target_name(target, target_kind_human, target_kind, warnings)?;
|
||||
|
||||
validate_proc_macro(target, target_kind_human, edition, warnings)?;
|
||||
validate_crate_types(target, target_kind_human, edition, warnings)?;
|
||||
}
|
||||
|
||||
let mut result = Vec::new();
|
||||
for mut target in toml_targets {
|
||||
let path = target_path(
|
||||
&target,
|
||||
&inferred,
|
||||
target_kind,
|
||||
package_root,
|
||||
edition,
|
||||
legacy_path,
|
||||
);
|
||||
let path = match path {
|
||||
Ok(path) => path,
|
||||
Err(e) => {
|
||||
errors.push(e);
|
||||
continue;
|
||||
}
|
||||
};
|
||||
target.path = Some(PathValue(path));
|
||||
result.push(target);
|
||||
}
|
||||
Ok(result)
|
||||
}
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
fn inferred_lib(package_root: &Path) -> Option<PathBuf> {
|
||||
|
|
|
@ -975,7 +975,7 @@ error: `im_a_teapot` is specified
|
|||
13 | im-a-teapot = true
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: `cargo::im_a_teapot` is set to `forbid` in `[workspace.lints]`
|
||||
= note: `cargo::im_a_teapot` is set to `forbid` in `[lints]`
|
||||
",
|
||||
)
|
||||
.run();
|
||||
|
|
Loading…
Reference in New Issue