Skip to content

Commit ad3dbe1

Browse files
committed
Auto merge of #7750 - ehuss:named-config-profiles, r=alexcrichton
Add named config profiles. This adds support for named config profiles. Previously, only `dev` and `release` were allowed in config files, it now supports all profile names. I think it would be strange to have arbitrarily named profiles in `Cargo.toml`, but not allow them in config. This is a deviation from the RFC, but RFC 2282 was written before named profiles which I think changes the landscape. This diff is a little large due to some refactoring to make it work well. Overview of the changes: - Removed `ProfileKind` and only use an `InternedString` to track the name of the profile. I didn't feel like the enum carried its cognitive weight, and it seems to simplify some things. - `Profiles` is no longer stored in the manifest. There was no need to do a bunch of processing for each manifest. `Manifest` now only retains the low-level `TomlProfiles`. A single `Profiles` now lives in `BuildContext`. - The profile name requested by the user is no longer passed around. It is given to `Profiles::new` and retained inside `Profiles`. - `Profiles::get_profile` no longer follows the priority stack and inheritance each time a profile is requested. Instead, the profile is computed once (in `Profile::new`) and merged into a single profile. This simplifies getting a profile, and makes it easier to deal with getting the config values in one place. - I switched profile names to be `InternedString` instead of `String`. There's not a strong reason to do this, other than it seemed a little strange to be creating lots of `String`s. - I also added `PartialEq<str>` for `InternedString`. It has come up a few times in the past, and it seems useful. I'm not sure if it was excluded intentionally? - The validation that the profile exists is now done in one place (`Profiles::new`). - I removed the back-compatibility for the `overrides` key (which was renamed to `package` back in October). Notes: - Some of the error messages aren't as good as before, because they don't tell you where the error is located (`Cargo.toml` or `.cargo/config`). This is because the location data is lost by the time validation is done. Hopefully it will be obvious from the profile name and error message. I tried to improve error messages wherever I could. - There are more calls to `clone()` than I would like, but they are kinda hard to avoid. Should be fewer than before. - I noticed a bug with `-Zpanic-abort-tests` not supporting named profiles. I'll fix that separately. - I think this fixes some bugs where package overrides in config weren't merging properly with package overrides defined in `Cargo.toml`.
2 parents 56a5503 + dafacbb commit ad3dbe1

27 files changed

+749
-624
lines changed

src/bin/cargo/commands/bench.rs

+2-6
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
use crate::command_prelude::*;
2-
32
use cargo::ops::{self, TestOptions};
43

54
pub fn cli() -> App {
@@ -80,11 +79,8 @@ pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult {
8079
ProfileChecking::Checked,
8180
)?;
8281

83-
compile_opts.build_config.profile_kind = args.get_profile_kind(
84-
config,
85-
ProfileKind::Custom("bench".to_owned()),
86-
ProfileChecking::Checked,
87-
)?;
82+
compile_opts.build_config.requested_profile =
83+
args.get_profile_name(config, "bench", ProfileChecking::Checked)?;
8884

8985
let ops = TestOptions {
9086
no_run: args.is_present("no-run"),

src/bin/cargo/commands/clean.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult {
2929
config,
3030
spec: values(args, "package"),
3131
target: args.target(),
32-
profile_kind: args.get_profile_kind(config, ProfileKind::Dev, ProfileChecking::Checked)?,
32+
requested_profile: args.get_profile_name(config, "dev", ProfileChecking::Checked)?,
3333
profile_specified: args.is_present("profile") || args.is_present("release"),
3434
doc: args.is_present("doc"),
3535
};

src/bin/cargo/commands/install.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -116,8 +116,8 @@ pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult {
116116
ProfileChecking::Checked,
117117
)?;
118118

119-
compile_opts.build_config.profile_kind =
120-
args.get_profile_kind(config, ProfileKind::Release, ProfileChecking::Checked)?;
119+
compile_opts.build_config.requested_profile =
120+
args.get_profile_name(config, "release", ProfileChecking::Checked)?;
121121

122122
let krates = args
123123
.values_of("crate")

src/bin/cargo/commands/test.rs

+2-5
Original file line numberDiff line numberDiff line change
@@ -108,11 +108,8 @@ pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult {
108108
ProfileChecking::Checked,
109109
)?;
110110

111-
compile_opts.build_config.profile_kind = args.get_profile_kind(
112-
config,
113-
ProfileKind::Custom("test".to_owned()),
114-
ProfileChecking::Checked,
115-
)?;
111+
compile_opts.build_config.requested_profile =
112+
args.get_profile_name(config, "test", ProfileChecking::Checked)?;
116113

117114
// `TESTNAME` is actually an argument of the test binary, but it's
118115
// important, so we explicitly mention it and reconfigure.

src/cargo/core/compiler/build_config.rs

+5-27
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,9 @@
1-
use std::cell::RefCell;
2-
3-
use serde::ser;
4-
51
use crate::core::compiler::{CompileKind, CompileTarget};
2+
use crate::core::interning::InternedString;
63
use crate::util::ProcessBuilder;
74
use crate::util::{CargoResult, Config, RustfixDiagnosticServer};
8-
9-
#[derive(Debug, Clone)]
10-
pub enum ProfileKind {
11-
Dev,
12-
Release,
13-
Custom(String),
14-
}
15-
16-
impl ProfileKind {
17-
pub fn name(&self) -> &str {
18-
match self {
19-
ProfileKind::Dev => "dev",
20-
ProfileKind::Release => "release",
21-
ProfileKind::Custom(name) => name,
22-
}
23-
}
24-
}
5+
use serde::ser;
6+
use std::cell::RefCell;
257

268
/// Configuration information for a rustc build.
279
#[derive(Debug)]
@@ -31,7 +13,7 @@ pub struct BuildConfig {
3113
/// Number of rustc jobs to run in parallel.
3214
pub jobs: u32,
3315
/// Build profile
34-
pub profile_kind: ProfileKind,
16+
pub requested_profile: InternedString,
3517
/// The mode we are compiling in.
3618
pub mode: CompileMode,
3719
/// `true` to print stdout in JSON format (for machine reading).
@@ -92,7 +74,7 @@ impl BuildConfig {
9274
Ok(BuildConfig {
9375
requested_kind,
9476
jobs,
95-
profile_kind: ProfileKind::Dev,
77+
requested_profile: InternedString::new("dev"),
9678
mode,
9779
message_format: MessageFormat::Human,
9880
force_rebuild: false,
@@ -111,10 +93,6 @@ impl BuildConfig {
11193
}
11294
}
11395

114-
pub fn profile_name(&self) -> &str {
115-
self.profile_kind.name()
116-
}
117-
11896
pub fn test(&self) -> bool {
11997
self.mode == CompileMode::Test || self.mode == CompileMode::Bench
12098
}

src/cargo/core/compiler/build_context/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ pub struct BuildContext<'a, 'cfg> {
2626
pub ws: &'a Workspace<'cfg>,
2727
/// The cargo configuration.
2828
pub config: &'cfg Config,
29-
pub profiles: &'a Profiles,
29+
pub profiles: Profiles,
3030
pub build_config: &'a BuildConfig,
3131
/// Extra compiler args for either `rustc` or `rustdoc`.
3232
pub extra_compiler_args: HashMap<Unit<'a>, Vec<String>>,
@@ -58,7 +58,7 @@ impl<'a, 'cfg> BuildContext<'a, 'cfg> {
5858
packages: &'a PackageSet<'cfg>,
5959
config: &'cfg Config,
6060
build_config: &'a BuildConfig,
61-
profiles: &'a Profiles,
61+
profiles: Profiles,
6262
units: &'a UnitInterner<'a>,
6363
extra_compiler_args: HashMap<Unit<'a>, Vec<String>>,
6464
) -> CargoResult<BuildContext<'a, 'cfg>> {

src/cargo/core/compiler/context/mod.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -281,8 +281,7 @@ impl<'a, 'cfg> Context<'a, 'cfg> {
281281
export_dir: Option<PathBuf>,
282282
units: &[Unit<'a>],
283283
) -> CargoResult<()> {
284-
let profile_kind = &self.bcx.build_config.profile_kind;
285-
let dest = self.bcx.profiles.get_dir_name(profile_kind);
284+
let dest = self.bcx.profiles.get_dir_name();
286285
let host_layout = Layout::new(self.bcx.ws, None, &dest)?;
287286
let mut targets = HashMap::new();
288287
if let CompileKind::Target(target) = self.bcx.build_config.requested_kind {

src/cargo/core/compiler/job_queue.rs

+3-6
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ use super::job::{
1919
};
2020
use super::timings::Timings;
2121
use super::{BuildContext, BuildPlan, CompileMode, Context, Unit};
22-
use crate::core::compiler::ProfileKind;
2322
use crate::core::{PackageId, TargetKind};
2423
use crate::handle_error;
2524
use crate::util;
@@ -44,7 +43,6 @@ pub struct JobQueue<'a, 'cfg> {
4443
progress: Progress<'cfg>,
4544
next_id: u32,
4645
timings: Timings<'a, 'cfg>,
47-
profile_kind: ProfileKind,
4846
}
4947

5048
pub struct JobState<'a> {
@@ -148,7 +146,6 @@ impl<'a, 'cfg> JobQueue<'a, 'cfg> {
148146
progress,
149147
next_id: 0,
150148
timings,
151-
profile_kind: bcx.build_config.profile_kind.clone(),
152149
}
153150
}
154151

@@ -415,15 +412,15 @@ impl<'a, 'cfg> JobQueue<'a, 'cfg> {
415412
}
416413
self.progress.clear();
417414

418-
let build_type = self.profile_kind.name();
415+
let profile_name = cx.bcx.build_config.requested_profile;
419416
// NOTE: this may be a bit inaccurate, since this may not display the
420417
// profile for what was actually built. Profile overrides can change
421418
// these settings, and in some cases different targets are built with
422419
// different profiles. To be accurate, it would need to collect a
423420
// list of Units built, and maybe display a list of the different
424421
// profiles used. However, to keep it simple and compatible with old
425422
// behavior, we just display what the base profile is.
426-
let profile = cx.bcx.profiles.base_profile(&self.profile_kind)?;
423+
let profile = cx.bcx.profiles.base_profile();
427424
let mut opt_type = String::from(if profile.opt_level.as_str() == "0" {
428425
"unoptimized"
429426
} else {
@@ -440,7 +437,7 @@ impl<'a, 'cfg> JobQueue<'a, 'cfg> {
440437
} else if self.queue.is_empty() && queue.is_empty() {
441438
let message = format!(
442439
"{} [{}] target(s) in {}",
443-
build_type, opt_type, time_elapsed
440+
profile_name, opt_type, time_elapsed
444441
);
445442
if !cx.bcx.build_config.build_plan {
446443
cx.bcx.config.shell().status("Finished", message)?;

src/cargo/core/compiler/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ use anyhow::Error;
2727
use lazycell::LazyCell;
2828
use log::debug;
2929

30-
pub use self::build_config::{BuildConfig, CompileMode, MessageFormat, ProfileKind};
30+
pub use self::build_config::{BuildConfig, CompileMode, MessageFormat};
3131
pub use self::build_context::{BuildContext, FileFlavor, TargetInfo};
3232
use self::build_plan::BuildPlan;
3333
pub use self::compilation::{Compilation, Doctest};

src/cargo/core/compiler/standard_lib.rs

+1-3
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,7 @@ pub fn resolve_std<'cfg>(
6666
/*replace*/ Vec::new(),
6767
patch,
6868
ws_config,
69-
// Profiles are not used here, but we need something to pass in.
70-
ws.profiles().clone(),
69+
/*profiles*/ None,
7170
crate::core::Features::default(),
7271
);
7372

@@ -139,7 +138,6 @@ pub fn generate_std_roots<'a>(
139138
/*is_member*/ false,
140139
unit_for,
141140
mode,
142-
bcx.build_config.profile_kind.clone(),
143141
);
144142
let features = std_resolve.features_sorted(pkg.package_id());
145143
Ok(bcx.units.intern(

src/cargo/core/compiler/timings.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ impl<'a, 'cfg> Timings<'a, 'cfg> {
116116
})
117117
.collect();
118118
let start_str = humantime::format_rfc3339_seconds(SystemTime::now()).to_string();
119-
let profile = bcx.build_config.profile_kind.name().to_owned();
119+
let profile = bcx.build_config.requested_profile.to_string();
120120

121121
Timings {
122122
config: bcx.config,

src/cargo/core/compiler/unit_dependencies.rs

-1
Original file line numberDiff line numberDiff line change
@@ -546,7 +546,6 @@ fn new_unit_dep<'a>(
546546
state.bcx.ws.is_member(pkg),
547547
unit_for,
548548
mode,
549-
state.bcx.build_config.profile_kind.clone(),
550549
);
551550
new_unit_dep_with_profile(state, parent, pkg, target, unit_for, kind, mode, profile)
552551
}

src/cargo/core/interning.rs

+12
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,18 @@ impl PartialEq for InternedString {
4848
}
4949
}
5050

51+
impl PartialEq<str> for InternedString {
52+
fn eq(&self, other: &str) -> bool {
53+
*self == other
54+
}
55+
}
56+
57+
impl<'a> PartialEq<&'a str> for InternedString {
58+
fn eq(&self, other: &&str) -> bool {
59+
**self == **other
60+
}
61+
}
62+
5163
impl Eq for InternedString {}
5264

5365
impl InternedString {

src/cargo/core/manifest.rs

+9-10
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,10 @@ use serde::Serialize;
1010
use url::Url;
1111

1212
use crate::core::interning::InternedString;
13-
use crate::core::profiles::Profiles;
1413
use crate::core::{Dependency, PackageId, PackageIdSpec, SourceId, Summary};
1514
use crate::core::{Edition, Feature, Features, WorkspaceConfig};
1615
use crate::util::errors::*;
17-
use crate::util::toml::TomlManifest;
16+
use crate::util::toml::{TomlManifest, TomlProfiles};
1817
use crate::util::{short_hash, Config, Filesystem};
1918

2019
pub enum EitherManifest {
@@ -33,7 +32,7 @@ pub struct Manifest {
3332
include: Vec<String>,
3433
metadata: ManifestMetadata,
3534
custom_metadata: Option<toml::Value>,
36-
profiles: Profiles,
35+
profiles: Option<TomlProfiles>,
3736
publish: Option<Vec<String>>,
3837
publish_lockfile: bool,
3938
replace: Vec<(PackageIdSpec, Dependency)>,
@@ -64,7 +63,7 @@ pub struct VirtualManifest {
6463
replace: Vec<(PackageIdSpec, Dependency)>,
6564
patch: HashMap<Url, Vec<Dependency>>,
6665
workspace: WorkspaceConfig,
67-
profiles: Profiles,
66+
profiles: Option<TomlProfiles>,
6867
warnings: Warnings,
6968
features: Features,
7069
}
@@ -399,7 +398,7 @@ impl Manifest {
399398
links: Option<String>,
400399
metadata: ManifestMetadata,
401400
custom_metadata: Option<toml::Value>,
402-
profiles: Profiles,
401+
profiles: Option<TomlProfiles>,
403402
publish: Option<Vec<String>>,
404403
publish_lockfile: bool,
405404
replace: Vec<(PackageIdSpec, Dependency)>,
@@ -475,8 +474,8 @@ impl Manifest {
475474
pub fn warnings(&self) -> &Warnings {
476475
&self.warnings
477476
}
478-
pub fn profiles(&self) -> &Profiles {
479-
&self.profiles
477+
pub fn profiles(&self) -> Option<&TomlProfiles> {
478+
self.profiles.as_ref()
480479
}
481480
pub fn publish(&self) -> &Option<Vec<String>> {
482481
&self.publish
@@ -563,7 +562,7 @@ impl VirtualManifest {
563562
replace: Vec<(PackageIdSpec, Dependency)>,
564563
patch: HashMap<Url, Vec<Dependency>>,
565564
workspace: WorkspaceConfig,
566-
profiles: Profiles,
565+
profiles: Option<TomlProfiles>,
567566
features: Features,
568567
) -> VirtualManifest {
569568
VirtualManifest {
@@ -588,8 +587,8 @@ impl VirtualManifest {
588587
&self.workspace
589588
}
590589

591-
pub fn profiles(&self) -> &Profiles {
592-
&self.profiles
590+
pub fn profiles(&self) -> Option<&TomlProfiles> {
591+
self.profiles.as_ref()
593592
}
594593

595594
pub fn warnings_mut(&mut self) -> &mut Warnings {

0 commit comments

Comments
 (0)