Skip to content

Commit 5cba540

Browse files
andholpil
authored andcommitted
refactor: remove dyn for PackageFetcher ♻️
Changed PackageFetcher to use impl or a generic. This will avoid dynamic dispatch and there is only one implementation for production so monomorphization will not increase the bin size.
1 parent 6bc6033 commit 5cba540

File tree

2 files changed

+44
-40
lines changed

2 files changed

+44
-40
lines changed

compiler-cli/src/dependencies.rs

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -81,12 +81,11 @@ pub fn tree(paths: &ProjectPaths, options: TreeOptions) -> Result<()> {
8181
fn get_manifest_details(paths: &ProjectPaths) -> Result<(PackageConfig, Manifest)> {
8282
let runtime = tokio::runtime::Runtime::new().expect("Unable to start Tokio async runtime");
8383
let config = crate::config::root_config(paths)?;
84-
let package_fetcher: Box<dyn dependency::PackageFetcher> =
85-
PackageFetcher::boxed(runtime.handle().clone());
84+
let package_fetcher = PackageFetcher::new(runtime.handle().clone());
8685
let (_, manifest) = get_manifest(
8786
paths,
8887
runtime.handle().clone(),
89-
&*package_fetcher,
88+
&package_fetcher,
9089
Mode::Dev,
9190
&config,
9291
&cli::Reporter::new(),
@@ -388,14 +387,13 @@ pub fn download<Telem: Telemetry>(
388387

389388
// Start event loop so we can run async functions to call the Hex API
390389
let runtime = tokio::runtime::Runtime::new().expect("Unable to start Tokio async runtime");
391-
let package_fetcher: Box<dyn dependency::PackageFetcher> =
392-
PackageFetcher::boxed(runtime.handle().clone());
390+
let package_fetcher = PackageFetcher::new(runtime.handle().clone());
393391

394392
// Determine what versions we need
395393
let (manifest_updated, manifest) = get_manifest(
396394
paths,
397395
runtime.handle().clone(),
398-
&*package_fetcher,
396+
&package_fetcher,
399397
mode,
400398
&config,
401399
&telemetry,
@@ -426,7 +424,7 @@ pub fn download<Telem: Telemetry>(
426424
LocalPackages::from_manifest(&manifest).write_to_disc(paths)?;
427425

428426
let major_versions_available =
429-
dependency::check_for_major_version_updates(&manifest, &*package_fetcher);
427+
dependency::check_for_major_version_updates(&manifest, &package_fetcher);
430428
if !major_versions_available.is_empty() {
431429
eprintln!(
432430
"{}",
@@ -673,7 +671,7 @@ impl LocalPackages {
673671
fn get_manifest<'a, Telem: Telemetry>(
674672
paths: &ProjectPaths,
675673
runtime: tokio::runtime::Handle,
676-
package_fetcher: &'a dyn dependency::PackageFetcher,
674+
package_fetcher: &impl dependency::PackageFetcher,
677675
mode: Mode,
678676
config: &PackageConfig,
679677
telemetry: &Telem,
@@ -881,7 +879,7 @@ impl PartialEq for ProvidedPackageSource {
881879

882880
fn resolve_versions<Telem: Telemetry>(
883881
runtime: tokio::runtime::Handle,
884-
package_fetcher: &dyn dependency::PackageFetcher,
882+
package_fetcher: &impl dependency::PackageFetcher,
885883
mode: Mode,
886884
project_paths: &ProjectPaths,
887885
config: &PackageConfig,
@@ -1314,12 +1312,12 @@ struct PackageFetcher {
13141312
}
13151313

13161314
impl PackageFetcher {
1317-
pub fn boxed(runtime: tokio::runtime::Handle) -> Box<Self> {
1318-
Box::new(Self {
1315+
pub fn new(runtime: tokio::runtime::Handle) -> Self {
1316+
Self {
13191317
runtime_cache: RefCell::new(HashMap::new()),
13201318
runtime,
13211319
http: HttpClient::new(),
1322-
})
1320+
}
13231321
}
13241322

13251323
/// Caches the result of `get_dependencies` so that we don't need to make a network request.

compiler-core/src/dependency.rs

Lines changed: 34 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ pub type PackageVersions = HashMap<String, Version>;
1717
type PubgrubRange = pubgrub::range::Range<Version>;
1818

1919
pub fn resolve_versions<Requirements>(
20-
package_fetcher: &dyn PackageFetcher,
20+
package_fetcher: &impl PackageFetcher,
2121
provided_packages: HashMap<EcoString, hexpm::Package>,
2222
root_name: EcoString,
2323
dependencies: Requirements,
@@ -69,7 +69,7 @@ where
6969
pub type PackageVersionDiffs = HashMap<String, (Version, Version)>;
7070

7171
fn resolve_major_versions(
72-
package_fetcher: &dyn PackageFetcher,
72+
package_fetcher: &impl PackageFetcher,
7373
versions: PackageVersions,
7474
) -> PackageVersionDiffs {
7575
versions
@@ -99,7 +99,7 @@ fn resolve_major_versions(
9999
/// constraints.
100100
pub fn check_for_major_version_updates(
101101
manifest: &manifest::Manifest,
102-
package_fetcher: &dyn PackageFetcher,
102+
package_fetcher: &impl PackageFetcher,
103103
) -> HashMap<String, (Version, Version)> {
104104
// get the resolved versions of the direct dependencies to check for major
105105
// version updates.
@@ -200,9 +200,9 @@ pub trait PackageFetcher {
200200
fn get_dependencies(&self, package: &str) -> Result<hexpm::Package, Box<dyn StdError>>;
201201
}
202202

203-
struct DependencyProvider<'a> {
203+
struct DependencyProvider<'a, T: PackageFetcher> {
204204
packages: RefCell<HashMap<EcoString, hexpm::Package>>,
205-
remote: &'a dyn PackageFetcher,
205+
remote: &'a T,
206206
locked: &'a HashMap<EcoString, Version>,
207207
// Map of packages where an exact version was requested
208208
// We need this because by default pubgrub checks exact version by checking if a version is between the exact
@@ -211,9 +211,12 @@ struct DependencyProvider<'a> {
211211
optional_dependencies: RefCell<HashMap<EcoString, pubgrub::range::Range<Version>>>,
212212
}
213213

214-
impl<'a> DependencyProvider<'a> {
214+
impl<'a, T> DependencyProvider<'a, T>
215+
where
216+
T: PackageFetcher,
217+
{
215218
fn new(
216-
remote: &'a dyn PackageFetcher,
219+
remote: &'a T,
217220
mut packages: HashMap<EcoString, hexpm::Package>,
218221
root: hexpm::Package,
219222
locked: &'a HashMap<EcoString, Version>,
@@ -262,7 +265,10 @@ impl<'a> DependencyProvider<'a> {
262265

263266
type PackageName = String;
264267

265-
impl pubgrub::solver::DependencyProvider<PackageName, Version> for DependencyProvider<'_> {
268+
impl<T> pubgrub::solver::DependencyProvider<PackageName, Version> for DependencyProvider<'_, T>
269+
where
270+
T: PackageFetcher,
271+
{
266272
fn choose_package_version<Name: Borrow<PackageName>, Ver: Borrow<PubgrubRange>>(
267273
&self,
268274
potential_packages: impl Iterator<Item = (Name, Ver)>,
@@ -368,7 +374,7 @@ mod tests {
368374
}
369375
}
370376

371-
fn make_remote() -> Box<Remote> {
377+
fn make_remote() -> Remote {
372378
let mut deps = HashMap::new();
373379
let _ = deps.insert(
374380
"gleam_stdlib".into(),
@@ -566,7 +572,7 @@ mod tests {
566572

567573
insert_simplified_deps(simple_deps_for_major_version_check, &mut deps);
568574

569-
Box::new(Remote { deps })
575+
Remote { deps }
570576
}
571577

572578
fn insert_simplified_deps(
@@ -611,7 +617,7 @@ mod tests {
611617
fn resolution_with_locked() {
612618
let locked_stdlib = ("gleam_stdlib".into(), Version::parse("0.1.0").unwrap());
613619
let result = resolve_versions(
614-
&*make_remote(),
620+
&make_remote(),
615621
HashMap::new(),
616622
"app".into(),
617623
vec![("gleam_stdlib".into(), Range::new("~> 0.1".into()))].into_iter(),
@@ -629,7 +635,7 @@ mod tests {
629635
#[test]
630636
fn resolution_without_deps() {
631637
let result = resolve_versions(
632-
&*make_remote(),
638+
&make_remote(),
633639
HashMap::new(),
634640
"app".into(),
635641
vec![].into_iter(),
@@ -642,7 +648,7 @@ mod tests {
642648
#[test]
643649
fn resolution_1_dep() {
644650
let result = resolve_versions(
645-
&*make_remote(),
651+
&make_remote(),
646652
HashMap::new(),
647653
"app".into(),
648654
vec![("gleam_stdlib".into(), Range::new("~> 0.1".into()))].into_iter(),
@@ -660,7 +666,7 @@ mod tests {
660666
#[test]
661667
fn resolution_with_nested_deps() {
662668
let result = resolve_versions(
663-
&*make_remote(),
669+
&make_remote(),
664670
HashMap::new(),
665671
"app".into(),
666672
vec![("gleam_otp".into(), Range::new("~> 0.1".into()))].into_iter(),
@@ -681,7 +687,7 @@ mod tests {
681687
#[test]
682688
fn resolution_with_optional_deps() {
683689
let result = resolve_versions(
684-
&*make_remote(),
690+
&make_remote(),
685691
HashMap::new(),
686692
"app".into(),
687693
vec![("package_with_optional".into(), Range::new("~> 0.1".into()))].into_iter(),
@@ -702,7 +708,7 @@ mod tests {
702708
#[test]
703709
fn resolution_with_optional_deps_explicitly_provided() {
704710
let result = resolve_versions(
705-
&*make_remote(),
711+
&make_remote(),
706712
HashMap::new(),
707713
"app".into(),
708714
vec![
@@ -730,7 +736,7 @@ mod tests {
730736
#[test]
731737
fn resolution_with_optional_deps_incompatible() {
732738
let result = resolve_versions(
733-
&*make_remote(),
739+
&make_remote(),
734740
HashMap::new(),
735741
"app".into(),
736742
vec![
@@ -746,7 +752,7 @@ mod tests {
746752
#[test]
747753
fn resolution_with_optional_deps_required_by_nested_deps() {
748754
let result = resolve_versions(
749-
&*make_remote(),
755+
&make_remote(),
750756
HashMap::new(),
751757
"app".into(),
752758
vec![
@@ -778,7 +784,7 @@ mod tests {
778784
#[test]
779785
fn resolution_locked_to_older_version() {
780786
let result = resolve_versions(
781-
&*make_remote(),
787+
&make_remote(),
782788
HashMap::new(),
783789
"app".into(),
784790
vec![("gleam_otp".into(), Range::new("~> 0.1.0".into()))].into_iter(),
@@ -799,7 +805,7 @@ mod tests {
799805
#[test]
800806
fn resolution_retired_versions_not_used_by_default() {
801807
let result = resolve_versions(
802-
&*make_remote(),
808+
&make_remote(),
803809
HashMap::new(),
804810
"app".into(),
805811
vec![("package_with_retired".into(), Range::new("> 0.0.0".into()))].into_iter(),
@@ -821,7 +827,7 @@ mod tests {
821827
#[test]
822828
fn resolution_retired_versions_can_be_used_if_locked() {
823829
let result = resolve_versions(
824-
&*make_remote(),
830+
&make_remote(),
825831
HashMap::new(),
826832
"app".into(),
827833
vec![("package_with_retired".into(), Range::new("> 0.0.0".into()))].into_iter(),
@@ -845,7 +851,7 @@ mod tests {
845851
#[test]
846852
fn resolution_prerelease_can_be_selected() {
847853
let result = resolve_versions(
848-
&*make_remote(),
854+
&make_remote(),
849855
HashMap::new(),
850856
"app".into(),
851857
vec![("gleam_otp".into(), Range::new("~> 0.3.0-rc1".into()))].into_iter(),
@@ -866,7 +872,7 @@ mod tests {
866872
#[test]
867873
fn resolution_exact_prerelease_can_be_selected() {
868874
let result = resolve_versions(
869-
&*make_remote(),
875+
&make_remote(),
870876
HashMap::new(),
871877
"app".into(),
872878
vec![("gleam_otp".into(), Range::new("0.3.0-rc1".into()))].into_iter(),
@@ -887,7 +893,7 @@ mod tests {
887893
#[test]
888894
fn resolution_not_found_dep() {
889895
let _ = resolve_versions(
890-
&*make_remote(),
896+
&make_remote(),
891897
HashMap::new(),
892898
"app".into(),
893899
vec![("unknown".into(), Range::new("~> 0.1".into()))].into_iter(),
@@ -899,7 +905,7 @@ mod tests {
899905
#[test]
900906
fn resolution_no_matching_version() {
901907
let _ = resolve_versions(
902-
&*make_remote(),
908+
&make_remote(),
903909
HashMap::new(),
904910
"app".into(),
905911
vec![("gleam_stdlib".into(), Range::new("~> 99.0".into()))].into_iter(),
@@ -911,7 +917,7 @@ mod tests {
911917
#[test]
912918
fn resolution_locked_version_doesnt_satisfy_requirements() {
913919
let err = resolve_versions(
914-
&*make_remote(),
920+
&make_remote(),
915921
HashMap::new(),
916922
"app".into(),
917923
vec![("gleam_stdlib".into(), Range::new("~> 0.1.0".into()))].into_iter(),
@@ -933,7 +939,7 @@ mod tests {
933939
#[test]
934940
fn resolution_with_exact_dep() {
935941
let result = resolve_versions(
936-
&*make_remote(),
942+
&make_remote(),
937943
HashMap::new(),
938944
"app".into(),
939945
vec![("gleam_stdlib".into(), Range::new("0.1.0".into()))].into_iter(),
@@ -1034,7 +1040,7 @@ mod tests {
10341040
},
10351041
],
10361042
};
1037-
let result = check_for_major_version_updates(&manifest, &*make_remote());
1043+
let result = check_for_major_version_updates(&manifest, &make_remote());
10381044

10391045
// indirect package with major version will not be in the result even though a major
10401046
// version of it is available

0 commit comments

Comments
 (0)