Skip to content

Commit 09d5e96

Browse files
committed
Auto merge of #13693 - epage:resolve-toml, r=Muscraft
refactor(toml): Split out an explicit step to resolve `Cargo.toml` ### What does this PR try to resolve? This builds on #13664 and #13666. Currently, once we have deserialized `Cargo.toml`, we pass it to a large machinery (`to_real_manifest`, `to_virtual_manifest`) so that - `Cargo.toml` is resolved - `Summary` is created - `Manifest` is created This splits out the resolving of `Cargo.toml` which is mostly workspace inheritance today. While splitting logic conjoined like this can be a bit messy in the short term, the hope is that overall this makes the logic easier to follow (more condensed, focused sections to view; more explicit inputs/outputs). In particular, I hope that this will make it clearer and easier to shift more logic into the resolving step, specifically the inferring of build targets for #13456. ### How should we test and review this PR? This is broken up into very small steps in the hope that it makes it easier to analyze a step. ### Additional information
2 parents f4ea1d1 + 58b6501 commit 09d5e96

File tree

4 files changed

+1905
-1630
lines changed

4 files changed

+1905
-1630
lines changed

crates/cargo-util-schemas/src/manifest/mod.rs

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,16 @@ impl TomlManifest {
105105
pub fn features(&self) -> Option<&BTreeMap<FeatureName, Vec<String>>> {
106106
self.features.as_ref()
107107
}
108+
109+
pub fn resolved_badges(
110+
&self,
111+
) -> Result<Option<&BTreeMap<String, BTreeMap<String, String>>>, UnresolvedError> {
112+
self.badges.as_ref().map(|l| l.resolved()).transpose()
113+
}
114+
115+
pub fn resolved_lints(&self) -> Result<Option<&TomlLints>, UnresolvedError> {
116+
self.lints.as_ref().map(|l| l.resolved()).transpose()
117+
}
108118
}
109119

110120
#[derive(Debug, Deserialize, Serialize, Clone)]
@@ -194,6 +204,83 @@ pub struct TomlPackage {
194204
pub _invalid_cargo_features: Option<InvalidCargoFeatures>,
195205
}
196206

207+
impl TomlPackage {
208+
pub fn resolved_edition(&self) -> Result<Option<&String>, UnresolvedError> {
209+
self.edition.as_ref().map(|v| v.resolved()).transpose()
210+
}
211+
212+
pub fn resolved_rust_version(&self) -> Result<Option<&RustVersion>, UnresolvedError> {
213+
self.rust_version.as_ref().map(|v| v.resolved()).transpose()
214+
}
215+
216+
pub fn resolved_version(&self) -> Result<Option<&semver::Version>, UnresolvedError> {
217+
self.version.as_ref().map(|v| v.resolved()).transpose()
218+
}
219+
220+
pub fn resolved_authors(&self) -> Result<Option<&Vec<String>>, UnresolvedError> {
221+
self.authors.as_ref().map(|v| v.resolved()).transpose()
222+
}
223+
224+
pub fn resolved_exclude(&self) -> Result<Option<&Vec<String>>, UnresolvedError> {
225+
self.exclude.as_ref().map(|v| v.resolved()).transpose()
226+
}
227+
228+
pub fn resolved_include(&self) -> Result<Option<&Vec<String>>, UnresolvedError> {
229+
self.include.as_ref().map(|v| v.resolved()).transpose()
230+
}
231+
232+
pub fn resolved_publish(&self) -> Result<Option<&VecStringOrBool>, UnresolvedError> {
233+
self.publish.as_ref().map(|v| v.resolved()).transpose()
234+
}
235+
236+
pub fn resolved_description(&self) -> Result<Option<&String>, UnresolvedError> {
237+
self.description.as_ref().map(|v| v.resolved()).transpose()
238+
}
239+
240+
pub fn resolved_homepage(&self) -> Result<Option<&String>, UnresolvedError> {
241+
self.homepage.as_ref().map(|v| v.resolved()).transpose()
242+
}
243+
244+
pub fn resolved_documentation(&self) -> Result<Option<&String>, UnresolvedError> {
245+
self.documentation
246+
.as_ref()
247+
.map(|v| v.resolved())
248+
.transpose()
249+
}
250+
251+
pub fn resolved_readme(&self) -> Result<Option<&String>, UnresolvedError> {
252+
self.readme
253+
.as_ref()
254+
.map(|v| {
255+
v.resolved().and_then(|sb| match sb {
256+
StringOrBool::Bool(_) => Err(UnresolvedError),
257+
StringOrBool::String(value) => Ok(value),
258+
})
259+
})
260+
.transpose()
261+
}
262+
263+
pub fn resolved_keywords(&self) -> Result<Option<&Vec<String>>, UnresolvedError> {
264+
self.keywords.as_ref().map(|v| v.resolved()).transpose()
265+
}
266+
267+
pub fn resolved_categories(&self) -> Result<Option<&Vec<String>>, UnresolvedError> {
268+
self.categories.as_ref().map(|v| v.resolved()).transpose()
269+
}
270+
271+
pub fn resolved_license(&self) -> Result<Option<&String>, UnresolvedError> {
272+
self.license.as_ref().map(|v| v.resolved()).transpose()
273+
}
274+
275+
pub fn resolved_license_file(&self) -> Result<Option<&String>, UnresolvedError> {
276+
self.license_file.as_ref().map(|v| v.resolved()).transpose()
277+
}
278+
279+
pub fn resolved_repository(&self) -> Result<Option<&String>, UnresolvedError> {
280+
self.repository.as_ref().map(|v| v.resolved()).transpose()
281+
}
282+
}
283+
197284
/// An enum that allows for inheriting keys from a workspace in a Cargo.toml.
198285
#[derive(Serialize, Copy, Clone, Debug)]
199286
#[serde(untagged)]
@@ -205,6 +292,10 @@ pub enum InheritableField<T> {
205292
}
206293

207294
impl<T> InheritableField<T> {
295+
pub fn resolved(&self) -> Result<&T, UnresolvedError> {
296+
self.as_value().ok_or(UnresolvedError)
297+
}
298+
208299
pub fn as_value(&self) -> Option<&T> {
209300
match self {
210301
InheritableField::Inherit(_) => None,
@@ -504,6 +595,13 @@ impl InheritableDependency {
504595
InheritableDependency::Inherit(w) => w._unused_keys.keys().cloned().collect(),
505596
}
506597
}
598+
599+
pub fn resolved(&self) -> Result<&TomlDependency, UnresolvedError> {
600+
match self {
601+
InheritableDependency::Value(d) => Ok(d),
602+
InheritableDependency::Inherit(_) => Err(UnresolvedError),
603+
}
604+
}
507605
}
508606

509607
impl<'de> de::Deserialize<'de> for InheritableDependency {
@@ -1297,6 +1395,16 @@ pub struct InheritableLints {
12971395
pub lints: TomlLints,
12981396
}
12991397

1398+
impl InheritableLints {
1399+
pub fn resolved(&self) -> Result<&TomlLints, UnresolvedError> {
1400+
if self.workspace {
1401+
Err(UnresolvedError)
1402+
} else {
1403+
Ok(&self.lints)
1404+
}
1405+
}
1406+
}
1407+
13001408
fn is_false(b: &bool) -> bool {
13011409
!b
13021410
}
@@ -1512,3 +1620,9 @@ impl<'de> de::Deserialize<'de> for PathValue {
15121620
Ok(PathValue(String::deserialize(deserializer)?.into()))
15131621
}
15141622
}
1623+
1624+
/// Error validating names in Cargo.
1625+
#[derive(Debug, thiserror::Error)]
1626+
#[error("manifest field was not resolved")]
1627+
#[non_exhaustive]
1628+
pub struct UnresolvedError;

src/cargo/core/features.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ pub type AllowFeatures = BTreeSet<String>;
151151
/// - Update [`CLI_VALUES`] to include the new edition.
152152
/// - Set [`LATEST_UNSTABLE`] to Some with the new edition.
153153
/// - Add an unstable feature to the [`features!`] macro invocation below for the new edition.
154-
/// - Gate on that new feature in [`toml::to_real_manifest`].
154+
/// - Gate on that new feature in [`toml`].
155155
/// - Update the shell completion files.
156156
/// - Update any failing tests (hopefully there are very few).
157157
/// - Update unstable.md to add a new section for this new edition (see [this example]).
@@ -178,7 +178,7 @@ pub type AllowFeatures = BTreeSet<String>;
178178
/// [`LATEST_STABLE`]: Edition::LATEST_STABLE
179179
/// [this example]: https://github.com/rust-lang/cargo/blob/3ebb5f15a940810f250b68821149387af583a79e/src/doc/src/reference/unstable.md?plain=1#L1238-L1264
180180
/// [`is_stable`]: Edition::is_stable
181-
/// [`toml::to_real_manifest`]: crate::util::toml::to_real_manifest
181+
/// [`toml`]: crate::util::toml
182182
/// [`features!`]: macro.features.html
183183
#[derive(
184184
Default, Clone, Copy, Debug, Hash, PartialOrd, Ord, Eq, PartialEq, Serialize, Deserialize,

src/cargo/core/workspace.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -449,7 +449,6 @@ impl<'gctx> Workspace<'gctx> {
449449
// NOTE: Since we use ConfigRelativePath, this root isn't used as
450450
// any relative paths are resolved before they'd be joined with root.
451451
Path::new("unused-relative-path"),
452-
self.unstable_features(),
453452
/* kind */ None,
454453
)
455454
})

0 commit comments

Comments
 (0)