1use crate::core::resolver::context::ResolverContext;
13use crate::core::resolver::errors::describe_path_in_context;
14use crate::core::resolver::types::{ConflictReason, DepInfo, FeaturesSet};
15use crate::core::resolver::{
16 ActivateError, ActivateResult, CliFeatures, RequestedFeatures, ResolveOpts, VersionOrdering,
17 VersionPreferences,
18};
19use crate::core::{
20 Dependency, FeatureValue, PackageId, PackageIdSpec, PackageIdSpecQuery, Registry, Summary,
21};
22use crate::sources::source::QueryKind;
23use crate::util::LocalPollAdapter;
24use crate::util::closest_msg;
25use crate::util::errors::CargoResult;
26use crate::util::interning::{INTERNED_DEFAULT, InternedString};
27
28use anyhow::Context as _;
29use std::cell::RefCell;
30use std::collections::{BTreeSet, HashMap, HashSet};
31use std::fmt::Write;
32use std::rc::Rc;
33use std::task::Poll;
34use tracing::debug;
35
36pub struct RegistryQueryerAsync<'a, T: Registry> {
37 pub registry: &'a T,
38 replacements: &'a [(PackageIdSpec, Dependency)],
39 version_prefs: &'a VersionPreferences,
40 used_replacements: RefCell<HashMap<PackageId, Summary>>,
42}
43
44impl<'a, T: Registry> RegistryQueryerAsync<'a, T> {
45 pub fn new(
46 registry: &'a T,
47 replacements: &'a [(PackageIdSpec, Dependency)],
48 version_prefs: &'a VersionPreferences,
49 ) -> Self {
50 RegistryQueryerAsync {
51 registry,
52 replacements,
53 version_prefs,
54 used_replacements: RefCell::new(HashMap::new()),
55 }
56 }
57
58 async fn query(
65 &self,
66 key: &(Dependency, Option<VersionOrdering>),
67 ) -> CargoResult<Rc<Vec<Summary>>> {
68 let (dep, first_version) = key;
69 let mut summaries = Vec::new();
70 self.registry
71 .query(dep, QueryKind::Exact, &mut |s| {
72 summaries.push(s.into_summary());
73 })
74 .await?;
75
76 for summary in summaries.iter() {
77 let mut potential_matches = self
78 .replacements
79 .iter()
80 .filter(|(spec, _)| spec.matches(summary.package_id()));
81
82 let Some((spec, dep)) = potential_matches.next() else {
83 continue;
84 };
85 debug!(
86 "found an override for {} {}",
87 dep.package_name(),
88 dep.version_req()
89 );
90
91 let mut summaries = self
92 .registry
93 .query_vec(dep, QueryKind::Exact)
94 .await?
95 .into_iter();
96 let s = summaries
97 .next()
98 .ok_or_else(|| {
99 anyhow::format_err!(
100 "no matching package for override `{}` found\n\
101 location searched: {}\n\
102 version required: {}",
103 spec,
104 dep.source_id(),
105 dep.version_req()
106 )
107 })?
108 .into_summary();
109 let summaries = summaries.collect::<Vec<_>>();
110 if !summaries.is_empty() {
111 let bullets = summaries
112 .iter()
113 .map(|s| format!(" * {}", s.package_id()))
114 .collect::<Vec<_>>();
115 return Err(anyhow::anyhow!(
116 "the replacement specification `{}` matched \
117 multiple packages:\n * {}\n{}",
118 spec,
119 s.package_id(),
120 bullets.join("\n")
121 ));
122 }
123
124 assert_eq!(
125 s.name(),
126 summary.name(),
127 "dependency should be hard coded to have the same name"
128 );
129 if s.version() != summary.version() {
130 return Err(anyhow::anyhow!(
131 "replacement specification `{}` matched {} and tried to override it with {}\n\
132 avoid matching unrelated packages by being more specific",
133 spec,
134 summary.version(),
135 s.version(),
136 ));
137 }
138
139 let replace = if s.source_id() == summary.source_id() {
140 debug!("Preventing\n{:?}\nfrom replacing\n{:?}", summary, s);
141 None
142 } else {
143 Some(s)
144 };
145 let matched_spec = spec.clone();
146
147 if let Some((spec, _)) = potential_matches.next() {
149 return Err(anyhow::anyhow!(
150 "overlapping replacement specifications found:\n\n \
151 * {}\n * {}\n\nboth specifications match: {}",
152 matched_spec,
153 spec,
154 summary.package_id()
155 ));
156 }
157
158 for dep in summary.dependencies() {
159 debug!("\t{} => {}", dep.package_name(), dep.version_req());
160 }
161 if let Some(r) = replace {
162 self.used_replacements
163 .borrow_mut()
164 .insert(summary.package_id(), r);
165 }
166 }
167
168 self.version_prefs
169 .sort_summaries(&mut summaries, *first_version);
170 Ok(Rc::new(summaries))
171 }
172}
173
174pub struct RegistryQueryer<'a, T: Registry> {
177 inner: Rc<RegistryQueryerAsync<'a, T>>,
178 poller: LocalPollAdapter<
179 'a,
180 Rc<RegistryQueryerAsync<'a, T>>,
181 (Dependency, Option<VersionOrdering>),
182 CargoResult<Rc<Vec<Summary>>>,
183 >,
184
185 summary_cache: HashMap<
191 (Option<PackageId>, Summary, ResolveOpts),
192 (Rc<(HashSet<InternedString>, Rc<Vec<DepInfo>>)>, bool),
193 >,
194}
195
196impl<'a, T: Registry> RegistryQueryer<'a, T> {
197 pub fn new(
198 registry: &'a T,
199 replacements: &'a [(PackageIdSpec, Dependency)],
200 version_prefs: &'a VersionPreferences,
201 ) -> Self {
202 let inner = Rc::new(RegistryQueryerAsync::new(
203 registry,
204 replacements,
205 version_prefs,
206 ));
207 Self {
208 inner: inner.clone(),
209 poller: LocalPollAdapter::new(inner),
210 summary_cache: HashMap::new(),
211 }
212 }
213
214 pub fn registry(&self) -> &T {
215 self.inner.registry
216 }
217
218 pub fn query(
219 &mut self,
220 dep: &Dependency,
221 first_version: Option<VersionOrdering>,
222 ) -> Poll<CargoResult<Rc<Vec<Summary>>>> {
223 self.poller
224 .poll(RegistryQueryerAsync::query, (dep.clone(), first_version))
225 }
226
227 pub fn wait(&mut self) -> CargoResult<bool> {
228 let pending = self.poller.pending_count();
229 let mut all_ready = self.poller.wait();
231 debug!(target: "cargo::core::resolver::restarting", pending);
232
233 self.summary_cache.retain(|_, (_, r)| {
235 if !*r {
236 all_ready = false;
237 }
238 *r
239 });
240
241 Ok(all_ready)
242 }
243
244 pub fn used_replacement_for(&self, p: PackageId) -> Option<(PackageId, PackageId)> {
245 self.inner
246 .used_replacements
247 .borrow()
248 .get(&p)
249 .map(|r| (p, r.package_id()))
250 }
251
252 pub fn replacement_summary(&self, p: PackageId) -> Option<Summary> {
253 self.inner.used_replacements.borrow().get(&p).cloned()
254 }
255
256 pub fn build_deps(
261 &mut self,
262 cx: &ResolverContext,
263 parent: Option<PackageId>,
264 candidate: &Summary,
265 opts: &ResolveOpts,
266 first_version: Option<VersionOrdering>,
267 ) -> ActivateResult<Rc<(HashSet<InternedString>, Rc<Vec<DepInfo>>)>> {
268 if let Some(out) = self
271 .summary_cache
272 .get(&(parent, candidate.clone(), opts.clone()))
273 {
274 return Ok(out.0.clone());
275 }
276 let (used_features, deps) = resolve_features(parent, candidate, opts)?;
280
281 let mut all_ready = true;
284 let mut deps = deps
285 .into_iter()
286 .filter_map(|(dep, features)| match self.query(&dep, first_version) {
287 Poll::Ready(Ok(candidates)) => Some(Ok((dep, candidates, features))),
288 Poll::Pending => {
289 all_ready = false;
290 None
293 }
294 Poll::Ready(Err(e)) => Some(Err(e).with_context(|| {
295 format!(
296 "failed to get `{}` as a dependency of {}",
297 dep.package_name(),
298 describe_path_in_context(cx, &candidate.package_id()),
299 )
300 })),
301 })
302 .collect::<CargoResult<Vec<DepInfo>>>()?;
303
304 deps.sort_by_key(|(_, a, _)| a.len());
309
310 let out = Rc::new((used_features, Rc::new(deps)));
311
312 self.summary_cache.insert(
315 (parent, candidate.clone(), opts.clone()),
316 (out.clone(), all_ready),
317 );
318
319 Ok(out)
320 }
321}
322
323pub fn resolve_features<'b>(
326 parent: Option<PackageId>,
327 s: &'b Summary,
328 opts: &'b ResolveOpts,
329) -> ActivateResult<(HashSet<InternedString>, Vec<(Dependency, FeaturesSet)>)> {
330 let deps = s.dependencies();
332 let deps = deps.iter().filter(|d| d.is_transitive() || opts.dev_deps);
333
334 let reqs = build_requirements(parent, s, opts)?;
335 let mut ret = Vec::new();
336 let default_dep = BTreeSet::new();
337 let mut valid_dep_names = HashSet::new();
338
339 for dep in deps {
341 if dep.is_optional() && !reqs.deps.contains_key(&dep.name_in_toml()) {
344 continue;
345 }
346 valid_dep_names.insert(dep.name_in_toml());
347 let mut base = reqs
351 .deps
352 .get(&dep.name_in_toml())
353 .unwrap_or(&default_dep)
354 .clone();
355 base.extend(dep.features().iter());
356 ret.push((dep.clone(), Rc::new(base)));
357 }
358
359 if parent.is_none() {
364 for dep_name in reqs.deps.keys() {
365 if !valid_dep_names.contains(dep_name) {
366 let e = RequirementError::MissingDependency(*dep_name);
367 return Err(e.into_activate_error(parent, s));
368 }
369 }
370 }
371
372 Ok((reqs.into_features(), ret))
373}
374
375fn build_requirements<'a, 'b: 'a>(
379 parent: Option<PackageId>,
380 s: &'a Summary,
381 opts: &'b ResolveOpts,
382) -> ActivateResult<Requirements<'a>> {
383 let mut reqs = Requirements::new(s);
384
385 let handle_default = |uses_default_features, reqs: &mut Requirements<'_>| {
386 if uses_default_features && s.features().contains_key("default") {
387 if let Err(e) = reqs.require_feature(INTERNED_DEFAULT) {
388 return Err(e.into_activate_error(parent, s));
389 }
390 }
391 Ok(())
392 };
393
394 match &opts.features {
395 RequestedFeatures::CliFeatures(CliFeatures {
396 features,
397 all_features,
398 uses_default_features,
399 }) => {
400 if *all_features {
401 for key in s.features().keys() {
402 if let Err(e) = reqs.require_feature(*key) {
403 return Err(e.into_activate_error(parent, s));
404 }
405 }
406 }
407
408 for fv in features.iter() {
409 if let Err(e) = reqs.require_value(fv) {
410 return Err(e.into_activate_error(parent, s));
411 }
412 }
413 handle_default(*uses_default_features, &mut reqs)?;
414 }
415 RequestedFeatures::DepFeatures {
416 features,
417 uses_default_features,
418 } => {
419 for feature in features.iter() {
420 if let Err(e) = reqs.require_feature(*feature) {
421 return Err(e.into_activate_error(parent, s));
422 }
423 }
424 handle_default(*uses_default_features, &mut reqs)?;
425 }
426 }
427
428 Ok(reqs)
429}
430
431#[derive(Debug)]
433struct Requirements<'a> {
434 summary: &'a Summary,
435 deps: HashMap<InternedString, BTreeSet<InternedString>>,
440 features: HashSet<InternedString>,
443}
444
445enum RequirementError {
450 MissingFeature(InternedString),
452 MissingDependency(InternedString),
454 Cycle(InternedString),
459}
460
461impl Requirements<'_> {
462 fn new(summary: &Summary) -> Requirements<'_> {
463 Requirements {
464 summary,
465 deps: HashMap::new(),
466 features: HashSet::new(),
467 }
468 }
469
470 fn into_features(self) -> HashSet<InternedString> {
471 self.features
472 }
473
474 fn require_dep_feature(
475 &mut self,
476 package: InternedString,
477 feat: InternedString,
478 weak: bool,
479 ) -> Result<(), RequirementError> {
480 if !weak
484 && self
485 .summary
486 .dependencies()
487 .iter()
488 .any(|dep| dep.name_in_toml() == package && dep.is_optional())
489 {
490 if self.summary.features().contains_key(&package) {
494 self.require_feature(package)?;
495 }
496 }
497 self.deps.entry(package).or_default().insert(feat);
498 Ok(())
499 }
500
501 fn require_dependency(&mut self, pkg: InternedString) {
502 self.deps.entry(pkg).or_default();
503 }
504
505 fn require_feature(&mut self, feat: InternedString) -> Result<(), RequirementError> {
506 if !self.features.insert(feat) {
507 return Ok(());
509 }
510
511 let Some(fvs) = self.summary.features().get(&feat) else {
512 return Err(RequirementError::MissingFeature(feat));
513 };
514
515 for fv in fvs {
516 if let FeatureValue::Feature(dep_feat) = fv {
517 if *dep_feat == feat {
518 return Err(RequirementError::Cycle(feat));
519 }
520 }
521 self.require_value(fv)?;
522 }
523 Ok(())
524 }
525
526 fn require_value(&mut self, fv: &FeatureValue) -> Result<(), RequirementError> {
527 match fv {
528 FeatureValue::Feature(feat) => self.require_feature(*feat)?,
529 FeatureValue::Dep { dep_name } => self.require_dependency(*dep_name),
530 FeatureValue::DepFeature {
531 dep_name,
532 dep_feature,
533 weak,
537 } => self.require_dep_feature(*dep_name, *dep_feature, *weak)?,
538 };
539 Ok(())
540 }
541}
542
543impl RequirementError {
544 fn into_activate_error(self, parent: Option<PackageId>, summary: &Summary) -> ActivateError {
545 match self {
546 RequirementError::MissingFeature(feat) => {
547 let deps: Vec<_> = summary
548 .dependencies()
549 .iter()
550 .filter(|dep| dep.name_in_toml() == feat)
551 .collect();
552 if deps.is_empty() {
553 return match parent {
554 None => {
555 let closest = closest_msg(
556 &feat.as_str(),
557 summary.features().keys(),
558 |key| &key,
559 "feature",
560 );
561 ActivateError::Fatal(anyhow::format_err!(
562 "package `{}` does not have the feature `{}`{}",
563 summary.package_id(),
564 feat,
565 closest
566 ))
567 }
568 Some(p) => ActivateError::Conflict(p, ConflictReason::MissingFeature(feat)),
569 };
570 }
571 if deps.iter().any(|dep| dep.is_optional()) {
572 match parent {
573 None => {
574 let mut features =
575 features_enabling_dependency_sorted(summary, feat).peekable();
576 let mut suggestion = String::new();
577 if features.peek().is_some() {
578 suggestion = format!(
579 "\nDependency `{}` would be enabled by these features:",
580 feat
581 );
582 for feature in (&mut features).take(3) {
583 let _ = write!(&mut suggestion, "\n\t- `{}`", feature);
584 }
585 if features.peek().is_some() {
586 suggestion.push_str("\n\t ...");
587 }
588 }
589 ActivateError::Fatal(anyhow::format_err!(
590 "\
591package `{}` does not have feature `{}`
592
593help: an optional dependency \
594with that name exists, but the `features` table includes it with the \"dep:\" \
595syntax so it does not have an implicit feature with that name{}",
596 summary.package_id(),
597 feat,
598 suggestion
599 ))
600 }
601 Some(p) => ActivateError::Conflict(
602 p,
603 ConflictReason::NonImplicitDependencyAsFeature(feat),
604 ),
605 }
606 } else {
607 match parent {
608 None => ActivateError::Fatal(anyhow::format_err!(
609 "package `{}` does not have feature `{}`
610
611help: a dependency with that name exists but it is required dependency and only optional dependencies can be used as features.",
612 summary.package_id(),
613 feat,
614 )),
615 Some(p) => ActivateError::Conflict(
616 p,
617 ConflictReason::RequiredDependencyAsFeature(feat),
618 ),
619 }
620 }
621 }
622 RequirementError::MissingDependency(dep_name) => {
623 match parent {
624 None => ActivateError::Fatal(anyhow::format_err!(
625 "package `{}` does not have a dependency named `{}`",
626 summary.package_id(),
627 dep_name
628 )),
629 Some(p) => ActivateError::Conflict(p, ConflictReason::MissingFeature(dep_name)),
632 }
633 }
634 RequirementError::Cycle(feat) => ActivateError::Fatal(anyhow::format_err!(
635 "cyclic feature dependency: feature `{}` depends on itself",
636 feat
637 )),
638 }
639 }
640}
641
642fn features_enabling_dependency_sorted(
646 summary: &Summary,
647 target_dep: InternedString,
648) -> impl Iterator<Item = InternedString> + '_ {
649 let iter = summary
650 .features()
651 .iter()
652 .filter(move |(_, values)| {
653 for value in *values {
654 match value {
655 FeatureValue::Dep { dep_name }
656 | FeatureValue::DepFeature {
657 dep_name,
658 weak: false,
659 ..
660 } if dep_name == &target_dep => return true,
661 _ => (),
662 }
663 }
664 false
665 })
666 .map(|(name, _)| *name);
667 iter
669}