Skip to content

Commit 4e80659

Browse files
committed
implement cyclic inclusion handling
Signed-off-by: onur-ozkan <[email protected]>
1 parent 89e3bef commit 4e80659

File tree

1 file changed

+38
-13
lines changed

1 file changed

+38
-13
lines changed

Diff for: src/bootstrap/src/core/config/config.rs

+38-13
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
use std::cell::{Cell, RefCell};
77
use std::collections::{BTreeSet, HashMap, HashSet};
88
use std::fmt::{self, Display};
9+
use std::hash::Hash;
910
use std::io::IsTerminal;
1011
use std::path::{Path, PathBuf, absolute};
1112
use std::process::Command;
@@ -748,19 +749,25 @@ enum ReplaceOpt {
748749
}
749750

750751
trait Merge {
751-
fn merge(&mut self, other: Self, replace: ReplaceOpt);
752+
fn merge(
753+
&mut self,
754+
included_extensions: &mut HashSet<PathBuf>,
755+
other: Self,
756+
replace: ReplaceOpt,
757+
);
752758
}
753759

754760
impl Merge for TomlConfig {
755761
fn merge(
756762
&mut self,
763+
included_extensions: &mut HashSet<PathBuf>,
757764
TomlConfig { build, install, llvm, gcc, rust, dist, target, profile, change_id, include }: Self,
758765
replace: ReplaceOpt,
759766
) {
760767
fn do_merge<T: Merge>(x: &mut Option<T>, y: Option<T>, replace: ReplaceOpt) {
761768
if let Some(new) = y {
762769
if let Some(original) = x {
763-
original.merge(new, replace);
770+
original.merge(&mut Default::default(), new, replace);
764771
} else {
765772
*x = Some(new);
766773
}
@@ -775,11 +782,20 @@ impl Merge for TomlConfig {
775782
);
776783
exit!(2);
777784
});
778-
self.merge(included_toml, ReplaceOpt::Override);
785+
786+
assert!(
787+
included_extensions.insert(include_path.clone()),
788+
"Cyclic inclusion detected: '{}' is being included again before its previous inclusion was fully processed.",
789+
include_path.display()
790+
);
791+
792+
self.merge(included_extensions, included_toml, ReplaceOpt::Override);
793+
794+
included_extensions.remove(&include_path);
779795
}
780796

781-
self.change_id.inner.merge(change_id.inner, replace);
782-
self.profile.merge(profile, replace);
797+
self.change_id.inner.merge(&mut Default::default(), change_id.inner, replace);
798+
self.profile.merge(&mut Default::default(), profile, replace);
783799

784800
do_merge(&mut self.build, build, replace);
785801
do_merge(&mut self.install, install, replace);
@@ -794,7 +810,7 @@ impl Merge for TomlConfig {
794810
(Some(original_target), Some(new_target)) => {
795811
for (triple, new) in new_target {
796812
if let Some(original) = original_target.get_mut(&triple) {
797-
original.merge(new, replace);
813+
original.merge(&mut Default::default(), new, replace);
798814
} else {
799815
original_target.insert(triple, new);
800816
}
@@ -815,7 +831,7 @@ macro_rules! define_config {
815831
}
816832

817833
impl Merge for $name {
818-
fn merge(&mut self, other: Self, replace: ReplaceOpt) {
834+
fn merge(&mut self, _included_extensions: &mut HashSet<PathBuf>, other: Self, replace: ReplaceOpt) {
819835
$(
820836
match replace {
821837
ReplaceOpt::IgnoreDuplicate => {
@@ -915,7 +931,12 @@ macro_rules! define_config {
915931
}
916932

917933
impl<T> Merge for Option<T> {
918-
fn merge(&mut self, other: Self, replace: ReplaceOpt) {
934+
fn merge(
935+
&mut self,
936+
_included_extensions: &mut HashSet<PathBuf>,
937+
other: Self,
938+
replace: ReplaceOpt,
939+
) {
919940
match replace {
920941
ReplaceOpt::IgnoreDuplicate => {
921942
if self.is_none() {
@@ -1609,7 +1630,7 @@ impl Config {
16091630
);
16101631
exit!(2);
16111632
});
1612-
toml.merge(included_toml, ReplaceOpt::IgnoreDuplicate);
1633+
toml.merge(&mut Default::default(), included_toml, ReplaceOpt::IgnoreDuplicate);
16131634
}
16141635

16151636
for include_path in toml.include.clone().unwrap_or_default() {
@@ -1620,7 +1641,7 @@ impl Config {
16201641
);
16211642
exit!(2);
16221643
});
1623-
toml.merge(included_toml, ReplaceOpt::Override);
1644+
toml.merge(&mut Default::default(), included_toml, ReplaceOpt::Override);
16241645
}
16251646

16261647
let mut override_toml = TomlConfig::default();
@@ -1631,7 +1652,7 @@ impl Config {
16311652

16321653
let mut err = match get_table(option) {
16331654
Ok(v) => {
1634-
override_toml.merge(v, ReplaceOpt::ErrorOnDuplicate);
1655+
override_toml.merge(&mut Default::default(), v, ReplaceOpt::ErrorOnDuplicate);
16351656
continue;
16361657
}
16371658
Err(e) => e,
@@ -1642,7 +1663,11 @@ impl Config {
16421663
if !value.contains('"') {
16431664
match get_table(&format!(r#"{key}="{value}""#)) {
16441665
Ok(v) => {
1645-
override_toml.merge(v, ReplaceOpt::ErrorOnDuplicate);
1666+
override_toml.merge(
1667+
&mut Default::default(),
1668+
v,
1669+
ReplaceOpt::ErrorOnDuplicate,
1670+
);
16461671
continue;
16471672
}
16481673
Err(e) => err = e,
@@ -1652,7 +1677,7 @@ impl Config {
16521677
eprintln!("failed to parse override `{option}`: `{err}");
16531678
exit!(2)
16541679
}
1655-
toml.merge(override_toml, ReplaceOpt::Override);
1680+
toml.merge(&mut Default::default(), override_toml, ReplaceOpt::Override);
16561681

16571682
config.change_id = toml.change_id.inner;
16581683

0 commit comments

Comments
 (0)