Skip to content

Commit d016ceb

Browse files
committed
add a check_public_visible_dependencies flag
1 parent 9e437ac commit d016ceb

File tree

3 files changed

+47
-16
lines changed

3 files changed

+47
-16
lines changed

src/cargo/core/resolver/mod.rs

+45-16
Original file line numberDiff line numberDiff line change
@@ -107,13 +107,25 @@ mod types;
107107
///
108108
/// * `print_warnings` - whether or not to print backwards-compatibility
109109
/// warnings and such
110+
///
111+
/// * `check_public_visible_dependencies` - a flag for whether to enforce the restrictions
112+
/// introduced in the "public & private dependencies" RFC (1977). The current implementation
113+
/// makes sure that there is only one version of each name visible to each package.
114+
///
115+
/// But there are 2 stable ways to directly depend on different versions of the same name.
116+
/// 1. Use the renamed dependencies functionality
117+
/// 2. Use 'cfg({})' dependencies functionality
118+
///
119+
/// When we have a decision for how to implement is without breaking existing functionality
120+
/// this flag can be removed.
110121
pub fn resolve(
111122
summaries: &[(Summary, Method<'_>)],
112123
replacements: &[(PackageIdSpec, Dependency)],
113124
registry: &mut dyn Registry,
114125
try_to_use: &HashSet<PackageId>,
115126
config: Option<&Config>,
116127
print_warnings: bool,
128+
check_public_visible_dependencies: bool,
117129
) -> CargoResult<Resolve> {
118130
let cx = Context::new();
119131
let _p = profile::start("resolving");
@@ -122,7 +134,13 @@ pub fn resolve(
122134
None => false,
123135
};
124136
let mut registry = RegistryQueryer::new(registry, replacements, try_to_use, minimal_versions);
125-
let cx = activate_deps_loop(cx, &mut registry, summaries, config)?;
137+
let cx = activate_deps_loop(
138+
cx,
139+
&mut registry,
140+
summaries,
141+
config,
142+
check_public_visible_dependencies,
143+
)?;
126144

127145
let mut cksums = HashMap::new();
128146
for summary in cx.activations.values().flat_map(|v| v.iter()) {
@@ -170,6 +188,7 @@ fn activate_deps_loop(
170188
registry: &mut RegistryQueryer<'_>,
171189
summaries: &[(Summary, Method<'_>)],
172190
config: Option<&Config>,
191+
check_public_visible_dependencies: bool,
173192
) -> CargoResult<Context> {
174193
let mut backtrack_stack = Vec::new();
175194
let mut remaining_deps = RemainingDeps::new();
@@ -185,7 +204,14 @@ fn activate_deps_loop(
185204
summary: summary.clone(),
186205
replace: None,
187206
};
188-
let res = activate(&mut cx, registry, None, candidate, method);
207+
let res = activate(
208+
&mut cx,
209+
registry,
210+
None,
211+
candidate,
212+
method,
213+
check_public_visible_dependencies,
214+
);
189215
match res {
190216
Ok(Some((frame, _))) => remaining_deps.push(frame),
191217
Ok(None) => (),
@@ -262,6 +288,7 @@ fn activate_deps_loop(
262288
&cx,
263289
&dep,
264290
parent.package_id(),
291+
check_public_visible_dependencies,
265292
);
266293

267294
let (candidate, has_another) = next.ok_or(()).or_else(|_| {
@@ -301,6 +328,7 @@ fn activate_deps_loop(
301328
&parent,
302329
backtracked,
303330
&conflicting_activations,
331+
check_public_visible_dependencies,
304332
) {
305333
Some((candidate, has_another, frame)) => {
306334
// Reset all of our local variables used with the
@@ -377,7 +405,14 @@ fn activate_deps_loop(
377405
dep.package_name(),
378406
candidate.summary.version()
379407
);
380-
let res = activate(&mut cx, registry, Some((&parent, &dep)), candidate, &method);
408+
let res = activate(
409+
&mut cx,
410+
registry,
411+
Some((&parent, &dep)),
412+
candidate,
413+
&method,
414+
check_public_visible_dependencies,
415+
);
381416

382417
let successfully_activated = match res {
383418
// Success! We've now activated our `candidate` in our context
@@ -492,6 +527,7 @@ fn activate_deps_loop(
492527
&parent,
493528
backtracked,
494529
&conflicting_activations,
530+
check_public_visible_dependencies,
495531
)
496532
.is_none()
497533
}
@@ -589,6 +625,7 @@ fn activate(
589625
parent: Option<(&Summary, &Dependency)>,
590626
candidate: Candidate,
591627
method: &Method<'_>,
628+
check_public_visible_dependencies: bool,
592629
) -> ActivateResult<Option<(DepsFrame, Duration)>> {
593630
let candidate_pid = candidate.summary.package_id();
594631
if let Some((parent, dep)) = parent {
@@ -601,12 +638,7 @@ fn activate(
601638
)
602639
// and associate dep with that edge
603640
.push(dep.clone());
604-
// For now the interaction of public dependency conflicts with renamed and
605-
// 'cfg({})' dependencies is not clear. So we disable public checks if the
606-
// other functionality is used.
607-
// TODO: this disable is not a long term solution.
608-
// This needs to be removed before public dependencies are stabilized!
609-
if dep.platform().is_none() && dep.explicit_name_in_toml().is_none() {
641+
if check_public_visible_dependencies {
610642
// one tricky part is that `candidate_pid` may already be active and
611643
// have public dependencies of its own. So we not only need to mark
612644
// `candidate_pid` as visible to its parents but also all of its existing
@@ -752,6 +784,7 @@ impl RemainingCandidates {
752784
cx: &Context,
753785
dep: &Dependency,
754786
parent: PackageId,
787+
check_public_visible_dependencies: bool,
755788
) -> Option<(Candidate, bool)> {
756789
let prev_active = cx.prev_active(dep);
757790

@@ -795,13 +828,7 @@ impl RemainingCandidates {
795828
// we have to reject this candidate. Additionally this candidate may already have been
796829
// activated and have public dependants of its own,
797830
// all of witch also need to be checked the same way.
798-
799-
// For now the interaction of public dependency conflicts with renamed and
800-
// 'cfg({})' dependencies is not clear. So we disable public checks if the
801-
// other functionality is used.
802-
// TODO: this disable is not a long term solution.
803-
// This needs to be removed before public dependencies are stabilized!
804-
if dep.platform().is_none() && dep.explicit_name_in_toml().is_none() {
831+
if check_public_visible_dependencies {
805832
let existing_public_deps: Vec<PackageId> = cx
806833
.public_dependency
807834
.get(&b.summary.package_id())
@@ -888,13 +915,15 @@ fn find_candidate(
888915
parent: &Summary,
889916
backtracked: bool,
890917
conflicting_activations: &ConflictMap,
918+
check_public_visible_dependencies: bool,
891919
) -> Option<(Candidate, bool, BacktrackFrame)> {
892920
while let Some(mut frame) = backtrack_stack.pop() {
893921
let next = frame.remaining_candidates.next(
894922
&mut frame.conflicting_activations,
895923
&frame.context,
896924
&frame.dep,
897925
frame.parent.package_id(),
926+
check_public_visible_dependencies,
898927
);
899928
let (candidate, has_another) = match next {
900929
Some(pair) => pair,

src/cargo/ops/resolve.rs

+1
Original file line numberDiff line numberDiff line change
@@ -338,6 +338,7 @@ pub fn resolve_with_previous<'cfg>(
338338
&try_to_use,
339339
Some(ws.config()),
340340
warn,
341+
false, // TODO: use "public and private dependencies" feature flag
341342
)?;
342343
resolved.register_used_patches(registry.patches());
343344
if register_patches {

tests/testsuite/support/resolver.rs

+1
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@ pub fn resolve_with_config_raw(
115115
&HashSet::new(),
116116
config,
117117
false,
118+
true,
118119
);
119120

120121
// The largest test in our suite takes less then 30 sec.

0 commit comments

Comments
 (0)