Skip to content

Commit 1f14fa3

Browse files
committed
Basic standard library support.
1 parent 9a8d695 commit 1f14fa3

23 files changed

+1228
-307
lines changed

ci/azure-test-all.yml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,13 @@ steps:
1616
- bash: rustup component add clippy || echo "clippy not available"
1717
displayName: "Install clippy (maybe)"
1818

19+
# This is needed for standard library tests.
20+
- bash: |
21+
if [ "$TOOLCHAIN" = "nightly" ]; then
22+
rustup component add rust-src
23+
fi
24+
displayName: "Install rust-src (maybe)"
25+
1926
# Deny warnings on CI to avoid warnings getting into the codebase, and note the
2027
# `force-system-lib-on-osx` which is intended to fix compile issues on OSX where
2128
# compiling curl from source on OSX yields linker errors on Azure.

src/cargo/core/compiler/build_config.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,14 @@ impl CompileMode {
221221
}
222222
}
223223

224+
/// Returns `true` if this is something that passes `--test` to rustc.
225+
pub fn is_rustc_test(self) -> bool {
226+
match self {
227+
CompileMode::Test | CompileMode::Bench | CompileMode::Check { test: true } => true,
228+
_ => false,
229+
}
230+
}
231+
224232
/// Returns `true` if this is the *execution* of a `build.rs` script.
225233
pub fn is_run_custom_build(self) -> bool {
226234
self == CompileMode::RunCustomBuild

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

Lines changed: 1 addition & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use crate::core::compiler::unit::UnitInterner;
88
use crate::core::compiler::{BuildConfig, BuildOutput, Kind, Unit};
99
use crate::core::profiles::Profiles;
1010
use crate::core::{Dependency, Workspace};
11-
use crate::core::{PackageId, PackageSet, Resolve};
11+
use crate::core::{PackageId, PackageSet};
1212
use crate::util::errors::CargoResult;
1313
use crate::util::{profile, Cfg, Config, Rustc};
1414

@@ -26,8 +26,6 @@ pub struct BuildContext<'a, 'cfg> {
2626
pub ws: &'a Workspace<'cfg>,
2727
/// The cargo configuration.
2828
pub config: &'cfg Config,
29-
/// The dependency graph for our build.
30-
pub resolve: &'a Resolve,
3129
pub profiles: &'a Profiles,
3230
pub build_config: &'a BuildConfig,
3331
/// Extra compiler args for either `rustc` or `rustdoc`.
@@ -48,7 +46,6 @@ pub struct BuildContext<'a, 'cfg> {
4846
impl<'a, 'cfg> BuildContext<'a, 'cfg> {
4947
pub fn new(
5048
ws: &'a Workspace<'cfg>,
51-
resolve: &'a Resolve,
5249
packages: &'a PackageSet<'cfg>,
5350
config: &'cfg Config,
5451
build_config: &'a BuildConfig,
@@ -75,7 +72,6 @@ impl<'a, 'cfg> BuildContext<'a, 'cfg> {
7572

7673
Ok(BuildContext {
7774
ws,
78-
resolve,
7975
packages,
8076
config,
8177
rustc,
@@ -90,16 +86,6 @@ impl<'a, 'cfg> BuildContext<'a, 'cfg> {
9086
})
9187
}
9288

93-
pub fn extern_crate_name(&self, unit: &Unit<'a>, dep: &Unit<'a>) -> CargoResult<String> {
94-
self.resolve
95-
.extern_crate_name(unit.pkg.package_id(), dep.pkg.package_id(), dep.target)
96-
}
97-
98-
pub fn is_public_dependency(&self, unit: &Unit<'a>, dep: &Unit<'a>) -> bool {
99-
self.resolve
100-
.is_public_dep(unit.pkg.package_id(), dep.pkg.package_id())
101-
}
102-
10389
/// Whether a dependency should be compiled for the host or target platform,
10490
/// specified by `Kind`.
10591
pub fn dep_platform_activated(&self, dep: &Dependency, kind: Kind) -> bool {

src/cargo/core/compiler/compilation.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use std::path::PathBuf;
66
use semver::Version;
77

88
use super::BuildContext;
9-
use crate::core::{Edition, Package, PackageId, Target};
9+
use crate::core::{Edition, InternedString, Package, PackageId, Target};
1010
use crate::util::{self, join_paths, process, CargoResult, CfgExpr, Config, ProcessBuilder};
1111

1212
pub struct Doctest {
@@ -16,7 +16,7 @@ pub struct Doctest {
1616
pub target: Target,
1717
/// Extern dependencies needed by `rustdoc`. The path is the location of
1818
/// the compiled lib.
19-
pub deps: Vec<(String, PathBuf)>,
19+
pub deps: Vec<(InternedString, PathBuf)>,
2020
}
2121

2222
/// A structure returning the result of a compilation.

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

Lines changed: 23 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
#![allow(deprecated)]
22
use std::collections::{BTreeSet, HashMap, HashSet};
33
use std::ffi::OsStr;
4-
use std::fmt::Write;
54
use std::path::PathBuf;
65
use std::sync::{Arc, Mutex};
76

@@ -10,7 +9,7 @@ use jobserver::Client;
109

1110
use crate::core::compiler::compilation;
1211
use crate::core::compiler::Unit;
13-
use crate::core::{PackageId, Resolve};
12+
use crate::core::PackageId;
1413
use crate::util::errors::{CargoResult, CargoResultExt};
1514
use crate::util::{internal, profile, Config};
1615

@@ -19,6 +18,7 @@ use super::custom_build::{self, BuildDeps, BuildScriptOutputs, BuildScripts};
1918
use super::fingerprint::Fingerprint;
2019
use super::job_queue::JobQueue;
2120
use super::layout::Layout;
21+
use super::unit_dependencies::{UnitDep, UnitGraph};
2222
use super::{BuildContext, Compilation, CompileMode, Executor, FileFlavor, Kind};
2323

2424
mod compilation_files;
@@ -48,17 +48,14 @@ pub struct Context<'a, 'cfg> {
4848
/// Linking information for each `Unit`.
4949
/// See `build_map` for details.
5050
pub build_scripts: HashMap<Unit<'a>, Arc<BuildScripts>>,
51-
/// Used to check the `links` field in the manifest is not duplicated and
52-
/// is used correctly.
53-
pub links: Links,
5451
/// Job server client to manage concurrency with other processes.
5552
pub jobserver: Client,
5653
/// "Primary" packages are the ones the user selected on the command-line
5754
/// with `-p` flags. If no flags are specified, then it is the defaults
5855
/// based on the current directory and the default workspace members.
5956
primary_packages: HashSet<PackageId>,
6057
/// The dependency graph of units to compile.
61-
unit_dependencies: HashMap<Unit<'a>, Vec<Unit<'a>>>,
58+
unit_dependencies: UnitGraph<'a>,
6259
/// An abstraction of the files and directories that will be generated by
6360
/// the compilation. This is `None` until after `unit_dependencies` has
6461
/// been computed.
@@ -80,7 +77,7 @@ impl<'a, 'cfg> Context<'a, 'cfg> {
8077
pub fn new(
8178
config: &'cfg Config,
8279
bcx: &'a BuildContext<'a, 'cfg>,
83-
unit_dependencies: HashMap<Unit<'a>, Vec<Unit<'a>>>,
80+
unit_dependencies: UnitGraph<'a>,
8481
) -> CargoResult<Self> {
8582
// Load up the jobserver that we'll use to manage our parallelism. This
8683
// is the same as the GNU make implementation of a jobserver, and
@@ -111,7 +108,6 @@ impl<'a, 'cfg> Context<'a, 'cfg> {
111108
compiled: HashSet::new(),
112109
build_scripts: HashMap::new(),
113110
build_explicit_deps: HashMap::new(),
114-
links: Links::new(),
115111
jobserver,
116112
primary_packages: HashSet::new(),
117113
unit_dependencies,
@@ -201,18 +197,15 @@ impl<'a, 'cfg> Context<'a, 'cfg> {
201197
// pass `--extern` for rlib deps and skip out on all other
202198
// artifacts.
203199
let mut doctest_deps = Vec::new();
204-
for dep in self.dep_targets(unit) {
205-
if dep.target.is_lib() && dep.mode == CompileMode::Build {
206-
let outputs = self.outputs(&dep)?;
200+
for dep in self.unit_deps(unit) {
201+
if dep.unit.target.is_lib() && dep.unit.mode == CompileMode::Build {
202+
let outputs = self.outputs(&dep.unit)?;
207203
let outputs = outputs.iter().filter(|output| {
208204
output.path.extension() == Some(OsStr::new("rlib"))
209-
|| dep.target.for_host()
205+
|| dep.unit.target.for_host()
210206
});
211207
for output in outputs {
212-
doctest_deps.push((
213-
self.bcx.extern_crate_name(unit, &dep)?,
214-
output.path.clone(),
215-
));
208+
doctest_deps.push((dep.extern_crate_name, output.path.clone()));
216209
}
217210
}
218211
}
@@ -356,10 +349,19 @@ impl<'a, 'cfg> Context<'a, 'cfg> {
356349

357350
/// For a package, return all targets which are registered as dependencies
358351
/// for that package.
352+
/// NOTE: This is deprecated, use `unit_deps` instead.
359353
//
360354
// TODO: this ideally should be `-> &[Unit<'a>]`.
361355
pub fn dep_targets(&self, unit: &Unit<'a>) -> Vec<Unit<'a>> {
362-
self.unit_dependencies[unit].clone()
356+
self.unit_dependencies[unit]
357+
.iter()
358+
.map(|dep| dep.unit)
359+
.collect()
360+
}
361+
362+
/// Direct dependencies for the given unit.
363+
pub fn unit_deps(&self, unit: &Unit<'a>) -> &[UnitDep<'a>] {
364+
&self.unit_dependencies[unit]
363365
}
364366

365367
pub fn is_primary_package(&self, unit: &Unit<'a>) -> bool {
@@ -369,12 +371,9 @@ impl<'a, 'cfg> Context<'a, 'cfg> {
369371
/// Returns the list of filenames read by cargo to generate the `BuildContext`
370372
/// (all `Cargo.toml`, etc.).
371373
pub fn build_plan_inputs(&self) -> CargoResult<Vec<PathBuf>> {
374+
// Keep sorted for consistency.
372375
let mut inputs = BTreeSet::new();
373-
// Note that we're using the `package_cache`, which should have been
374-
// populated by `build_unit_dependencies`, and only those packages are
375-
// considered as all the inputs.
376-
//
377-
// (Notably, we skip dev-deps here if they aren't present.)
376+
// Note: dev-deps are skipped if they are not present in the unit graph.
378377
for unit in self.unit_dependencies.keys() {
379378
inputs.insert(unit.pkg.manifest_path().to_path_buf());
380379
}
@@ -485,8 +484,8 @@ impl<'a, 'cfg> Context<'a, 'cfg> {
485484
fn record_units_requiring_metadata(&mut self) {
486485
for (key, deps) in self.unit_dependencies.iter() {
487486
for dep in deps {
488-
if self.only_requires_rmeta(key, dep) {
489-
self.rmeta_required.insert(*dep);
487+
if self.only_requires_rmeta(key, &dep.unit) {
488+
self.rmeta_required.insert(dep.unit);
490489
}
491490
}
492491
}
@@ -513,70 +512,3 @@ impl<'a, 'cfg> Context<'a, 'cfg> {
513512
self.rmeta_required.contains(unit)
514513
}
515514
}
516-
517-
#[derive(Default)]
518-
pub struct Links {
519-
validated: HashSet<PackageId>,
520-
links: HashMap<String, PackageId>,
521-
}
522-
523-
impl Links {
524-
pub fn new() -> Links {
525-
Links {
526-
validated: HashSet::new(),
527-
links: HashMap::new(),
528-
}
529-
}
530-
531-
pub fn validate(&mut self, resolve: &Resolve, unit: &Unit<'_>) -> CargoResult<()> {
532-
if !self.validated.insert(unit.pkg.package_id()) {
533-
return Ok(());
534-
}
535-
let lib = match unit.pkg.manifest().links() {
536-
Some(lib) => lib,
537-
None => return Ok(()),
538-
};
539-
if let Some(&prev) = self.links.get(lib) {
540-
let pkg = unit.pkg.package_id();
541-
542-
let describe_path = |pkgid: PackageId| -> String {
543-
let dep_path = resolve.path_to_top(&pkgid);
544-
let mut dep_path_desc = format!("package `{}`", dep_path[0]);
545-
for dep in dep_path.iter().skip(1) {
546-
write!(dep_path_desc, "\n ... which is depended on by `{}`", dep).unwrap();
547-
}
548-
dep_path_desc
549-
};
550-
551-
failure::bail!(
552-
"multiple packages link to native library `{}`, \
553-
but a native library can be linked only once\n\
554-
\n\
555-
{}\nlinks to native library `{}`\n\
556-
\n\
557-
{}\nalso links to native library `{}`",
558-
lib,
559-
describe_path(prev),
560-
lib,
561-
describe_path(pkg),
562-
lib
563-
)
564-
}
565-
if !unit
566-
.pkg
567-
.manifest()
568-
.targets()
569-
.iter()
570-
.any(|t| t.is_custom_build())
571-
{
572-
failure::bail!(
573-
"package `{}` specifies that it links to `{}` but does not \
574-
have a custom build script",
575-
unit.pkg.package_id(),
576-
lib
577-
)
578-
}
579-
self.links.insert(lib.to_string(), unit.pkg.package_id());
580-
Ok(())
581-
}
582-
}

0 commit comments

Comments
 (0)