Skip to content

Commit d9feff2

Browse files
committed
Auto merge of #5811 - alexcrichton:rename-crate-feature-names, r=ehuss
Use listed dependency name for feature names This commit updates the implementation of renamed dependencies to use the listed name of a dependency in Cargo.toml for the name of the associated feature, rather than using the package name. This'll allow disambiguating between different packages of the same name and was the intention all along! Closes #5753
2 parents 4b95e8c + 5295cad commit d9feff2

File tree

16 files changed

+236
-67
lines changed

16 files changed

+236
-67
lines changed

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ impl<'a, 'cfg> BuildContext<'a, 'cfg> {
104104

105105
let crate_name = dep.target.crate_name();
106106
let mut names = deps.iter()
107-
.map(|d| d.rename().unwrap_or(&crate_name));
107+
.map(|d| d.rename().map(|s| s.as_str()).unwrap_or(&crate_name));
108108
let name = names.next().unwrap_or(&crate_name);
109109
for n in names {
110110
if n == name {

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ fn compute_deps<'a, 'cfg>(
118118

119119
// If the dependency is optional, then we're only activating it
120120
// if the corresponding feature was activated
121-
if dep.is_optional() && !bcx.resolve.features(id).contains(&*dep.name()) {
121+
if dep.is_optional() && !bcx.resolve.features(id).contains(&*dep.name_in_toml()) {
122122
return false;
123123
}
124124

src/cargo/core/dependency.rs

+55-9
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ struct Inner {
2828
specified_req: bool,
2929
kind: Kind,
3030
only_match_name: bool,
31-
rename: Option<String>,
31+
rename: Option<InternedString>,
3232

3333
optional: bool,
3434
default_features: bool,
@@ -65,15 +65,15 @@ impl ser::Serialize for Dependency {
6565
S: ser::Serializer,
6666
{
6767
SerializedDependency {
68-
name: &*self.name(),
68+
name: &*self.package_name(),
6969
source: self.source_id(),
7070
req: self.version_req().to_string(),
7171
kind: self.kind(),
7272
optional: self.is_optional(),
7373
uses_default_features: self.uses_default_features(),
7474
features: self.features(),
7575
target: self.platform(),
76-
rename: self.rename(),
76+
rename: self.rename().map(|s| s.as_str()),
7777
}.serialize(s)
7878
}
7979
}
@@ -208,7 +208,49 @@ impl Dependency {
208208
&self.inner.req
209209
}
210210

211-
pub fn name(&self) -> InternedString {
211+
/// This is the name of this `Dependency` as listed in `Cargo.toml`.
212+
///
213+
/// Or in other words, this is what shows up in the `[dependencies]` section
214+
/// on the left hand side. This is **not** the name of the package that's
215+
/// being depended on as the dependency can be renamed. For that use
216+
/// `package_name` below.
217+
///
218+
/// Both of the dependencies below return `foo` for `name_in_toml`:
219+
///
220+
/// ```toml
221+
/// [dependencies]
222+
/// foo = "0.1"
223+
/// ```
224+
///
225+
/// and ...
226+
///
227+
/// ```toml
228+
/// [dependencies]
229+
/// foo = { version = "0.1", package = 'bar' }
230+
/// ```
231+
pub fn name_in_toml(&self) -> InternedString {
232+
self.rename().unwrap_or(self.inner.name)
233+
}
234+
235+
/// The name of the package that this `Dependency` depends on.
236+
///
237+
/// Usually this is what's written on the left hand side of a dependencies
238+
/// section, but it can also be renamed via the `package` key.
239+
///
240+
/// Both of the dependencies below return `foo` for `package_name`:
241+
///
242+
/// ```toml
243+
/// [dependencies]
244+
/// foo = "0.1"
245+
/// ```
246+
///
247+
/// and ...
248+
///
249+
/// ```toml
250+
/// [dependencies]
251+
/// bar = { version = "0.1", package = 'foo' }
252+
/// ```
253+
pub fn package_name(&self) -> InternedString {
212254
self.inner.name
213255
}
214256

@@ -239,8 +281,12 @@ impl Dependency {
239281
self.inner.platform.as_ref()
240282
}
241283

242-
pub fn rename(&self) -> Option<&str> {
243-
self.inner.rename.as_ref().map(|s| &**s)
284+
/// The renamed name of this dependency, if any.
285+
///
286+
/// If the `package` key is used in `Cargo.toml` then this returns the same
287+
/// value as `name_in_toml`.
288+
pub fn rename(&self) -> Option<InternedString> {
289+
self.inner.rename
244290
}
245291

246292
pub fn set_kind(&mut self, kind: Kind) -> &mut Dependency {
@@ -285,7 +331,7 @@ impl Dependency {
285331
}
286332

287333
pub fn set_rename(&mut self, rename: &str) -> &mut Dependency {
288-
Rc::make_mut(&mut self.inner).rename = Some(rename.to_string());
334+
Rc::make_mut(&mut self.inner).rename = Some(InternedString::new(rename));
289335
self
290336
}
291337

@@ -295,7 +341,7 @@ impl Dependency {
295341
assert!(self.inner.req.matches(id.version()));
296342
trace!(
297343
"locking dep from `{}` with `{}` at {} to {}",
298-
self.name(),
344+
self.package_name(),
299345
self.version_req(),
300346
self.source_id(),
301347
id
@@ -346,7 +392,7 @@ impl Dependency {
346392

347393
/// Returns true if the package (`sum`) can fulfill this dependency request.
348394
pub fn matches_ignoring_source(&self, id: &PackageId) -> bool {
349-
self.name() == id.name() && self.version_req().matches(id.version())
395+
self.package_name() == id.name() && self.version_req().matches(id.version())
350396
}
351397

352398
/// Returns true if the package (`id`) can fulfill this dependency request.

src/cargo/core/registry.rs

+14-14
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,7 @@ impl<'cfg> PackageRegistry<'cfg> {
197197
// of summaries which should be the same length as `deps` above.
198198
let unlocked_summaries = deps.iter()
199199
.map(|dep| {
200-
debug!("registring a patch for `{}` with `{}`", url, dep.name());
200+
debug!("registring a patch for `{}` with `{}`", url, dep.package_name());
201201

202202
// Go straight to the source for resolving `dep`. Load it as we
203203
// normally would and then ask it directly for the list of summaries
@@ -207,7 +207,7 @@ impl<'cfg> PackageRegistry<'cfg> {
207207
format_err!(
208208
"failed to load source for a dependency \
209209
on `{}`",
210-
dep.name()
210+
dep.package_name()
211211
)
212212
})?;
213213

@@ -223,22 +223,22 @@ impl<'cfg> PackageRegistry<'cfg> {
223223
"patch for `{}` in `{}` did not resolve to any crates. If this is \
224224
unexpected, you may wish to consult: \
225225
https://github.com/rust-lang/cargo/issues/4678",
226-
dep.name(),
226+
dep.package_name(),
227227
url
228228
),
229229
};
230230
if summaries.next().is_some() {
231231
bail!(
232232
"patch for `{}` in `{}` resolved to more than one candidate",
233-
dep.name(),
233+
dep.package_name(),
234234
url
235235
)
236236
}
237237
if summary.package_id().source_id().url() == url {
238238
bail!(
239239
"patch for `{}` in `{}` points to the same source, but \
240240
patches must point to different sources",
241-
dep.name(),
241+
dep.package_name(),
242242
url
243243
);
244244
}
@@ -306,7 +306,7 @@ impl<'cfg> PackageRegistry<'cfg> {
306306
fn query_overrides(&mut self, dep: &Dependency) -> CargoResult<Option<Summary>> {
307307
for s in self.overrides.iter() {
308308
let src = self.sources.get_mut(s).unwrap();
309-
let dep = Dependency::new_override(&*dep.name(), s);
309+
let dep = Dependency::new_override(&*dep.package_name(), s);
310310
let mut results = src.query_vec(&dep)?;
311311
if !results.is_empty() {
312312
return Ok(Some(results.remove(0)));
@@ -369,21 +369,21 @@ http://doc.crates.io/specifying-dependencies.html#overriding-dependencies
369369
modified to not match the previously resolved version\n\n\
370370
{}",
371371
override_summary.package_id().name(),
372-
dep.name(),
372+
dep.package_name(),
373373
boilerplate
374374
);
375375
self.source_config.config().shell().warn(&msg)?;
376376
return Ok(());
377377
}
378378

379-
if let Some(id) = real_deps.get(0) {
379+
if let Some(dep) = real_deps.get(0) {
380380
let msg = format!(
381381
"\
382382
path override for crate `{}` has altered the original list of
383383
dependencies; the dependency on `{}` was removed\n\n
384384
{}",
385385
override_summary.package_id().name(),
386-
id.name(),
386+
dep.package_name(),
387387
boilerplate
388388
);
389389
self.source_config.config().shell().warn(&msg)?;
@@ -439,7 +439,7 @@ impl<'cfg> Registry for PackageRegistry<'cfg> {
439439
with `{}`, \
440440
looking at sources",
441441
patches.len(),
442-
dep.name(),
442+
dep.package_name(),
443443
dep.source_id(),
444444
dep.version_req()
445445
);
@@ -451,7 +451,7 @@ impl<'cfg> Registry for PackageRegistry<'cfg> {
451451
format_err!(
452452
"failed to load source for a dependency \
453453
on `{}`",
454-
dep.name()
454+
dep.package_name()
455455
)
456456
})?;
457457

@@ -542,7 +542,7 @@ fn lock(locked: &LockedMap, patches: &HashMap<Url, Vec<PackageId>>, summary: Sum
542542
None => summary,
543543
};
544544
summary.map_dependencies(|dep| {
545-
trace!("\t{}/{}/{}", dep.name(), dep.version_req(), dep.source_id());
545+
trace!("\t{}/{}/{}", dep.package_name(), dep.version_req(), dep.source_id());
546546

547547
// If we've got a known set of overrides for this summary, then
548548
// one of a few cases can arise:
@@ -578,7 +578,7 @@ fn lock(locked: &LockedMap, patches: &HashMap<Url, Vec<PackageId>>, summary: Sum
578578
// If anything does then we lock it to that and move on.
579579
let v = locked
580580
.get(dep.source_id())
581-
.and_then(|map| map.get(&*dep.name()))
581+
.and_then(|map| map.get(&*dep.package_name()))
582582
.and_then(|vec| vec.iter().find(|&&(ref id, _)| dep.matches_id(id)));
583583
if let Some(&(ref id, _)) = v {
584584
trace!("\tsecond hit on {}", id);
@@ -592,7 +592,7 @@ fn lock(locked: &LockedMap, patches: &HashMap<Url, Vec<PackageId>>, summary: Sum
592592
let v = patches.get(dep.source_id().url()).map(|vec| {
593593
let dep2 = dep.clone();
594594
let mut iter = vec.iter().filter(move |p| {
595-
dep2.name() == p.name() && dep2.version_req().matches(p.version())
595+
dep2.matches_ignoring_source(p)
596596
});
597597
(iter.next(), iter)
598598
});

src/cargo/core/resolver/conflict_cache.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ impl ConflictCache {
8181
.entry(dep.clone())
8282
.or_insert_with(Vec::new);
8383
if !past.contains(con) {
84-
trace!("{} adding a skip {:?}", dep.name(), con);
84+
trace!("{} adding a skip {:?}", dep.package_name(), con);
8585
past.push(con.clone());
8686
for c in con.keys() {
8787
self.dep_from_pid

src/cargo/core/resolver/context.rs

+11-11
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ impl Context {
128128

129129
pub fn prev_active(&self, dep: &Dependency) -> &[Summary] {
130130
self.activations
131-
.get(&(dep.name(), dep.source_id().clone()))
131+
.get(&(dep.package_name(), dep.source_id().clone()))
132132
.map(|v| &v[..])
133133
.unwrap_or(&[])
134134
}
@@ -178,27 +178,27 @@ impl Context {
178178
for dep in deps {
179179
// Skip optional dependencies, but not those enabled through a
180180
// feature
181-
if dep.is_optional() && !reqs.deps.contains_key(&dep.name()) {
181+
if dep.is_optional() && !reqs.deps.contains_key(&dep.name_in_toml()) {
182182
continue;
183183
}
184184
// So we want this dependency. Move the features we want from
185185
// `feature_deps` to `ret` and register ourselves as using this
186186
// name.
187-
let base = reqs.deps.get(&dep.name()).unwrap_or(&default_dep);
188-
used_features.insert(dep.name());
187+
let base = reqs.deps.get(&dep.name_in_toml()).unwrap_or(&default_dep);
188+
used_features.insert(dep.name_in_toml());
189189
let always_required = !dep.is_optional()
190190
&& !s
191191
.dependencies()
192192
.iter()
193-
.any(|d| d.is_optional() && d.name() == dep.name());
193+
.any(|d| d.is_optional() && d.name_in_toml() == dep.name_in_toml());
194194
if always_required && base.0 {
195195
self.warnings.push(format!(
196196
"Package `{}` does not have feature `{}`. It has a required dependency \
197197
with that name, but only optional dependencies can be used as features. \
198198
This is currently a warning to ease the transition, but it will become an \
199199
error in the future.",
200200
s.package_id(),
201-
dep.name()
201+
dep.name_in_toml()
202202
));
203203
}
204204
let mut base = base.1.clone();
@@ -220,8 +220,8 @@ impl Context {
220220
let remaining = reqs
221221
.deps
222222
.keys()
223-
.filter(|&s| !used_features.contains(s))
224-
.map(|s| s.as_str())
223+
.cloned()
224+
.filter(|s| !used_features.contains(s))
225225
.collect::<Vec<_>>();
226226
if !remaining.is_empty() {
227227
let features = remaining.join(", ");
@@ -298,10 +298,10 @@ fn build_requirements<'a, 'b: 'a>(
298298
all_features: true, ..
299299
} => {
300300
for key in s.features().keys() {
301-
reqs.require_feature(InternedString::new(&key))?;
301+
reqs.require_feature(*key)?;
302302
}
303303
for dep in s.dependencies().iter().filter(|d| d.is_optional()) {
304-
reqs.require_dependency(dep.name());
304+
reqs.require_dependency(dep.name_in_toml());
305305
}
306306
}
307307
Method::Required {
@@ -389,7 +389,7 @@ impl<'r> Requirements<'r> {
389389
for fv in self
390390
.summary
391391
.features()
392-
.get(&feat)
392+
.get(feat.as_str())
393393
.expect("must be a valid feature")
394394
{
395395
match *fv {

0 commit comments

Comments
 (0)