@@ -33,24 +33,38 @@ impl OverrideFile {
3333#[ derive( Debug , Default , Deserialize , PartialEq , Eq ) ]
3434struct ToolchainSection {
3535 channel : Option < String > ,
36+ path : Option < PathBuf > ,
3637 components : Option < Vec < String > > ,
3738 targets : Option < Vec < String > > ,
3839 profile : Option < String > ,
3940}
4041
4142impl ToolchainSection {
4243 fn is_empty ( & self ) -> bool {
43- self . channel . is_none ( ) && self . components . is_none ( ) && self . targets . is_none ( )
44+ self . channel . is_none ( )
45+ && self . components . is_none ( )
46+ && self . targets . is_none ( )
47+ && self . path . is_none ( )
4448 }
4549}
4650
4751impl < T : Into < String > > From < T > for OverrideFile {
4852 fn from ( channel : T ) -> Self {
49- Self {
50- toolchain : ToolchainSection {
51- channel : Some ( channel. into ( ) ) ,
52- ..Default :: default ( )
53- } ,
53+ let override_ = channel. into ( ) ;
54+ if Path :: new ( & override_) . is_absolute ( ) {
55+ Self {
56+ toolchain : ToolchainSection {
57+ path : Some ( PathBuf :: from ( override_) ) ,
58+ ..Default :: default ( )
59+ } ,
60+ }
61+ } else {
62+ Self {
63+ toolchain : ToolchainSection {
64+ channel : Some ( override_) ,
65+ ..Default :: default ( )
66+ } ,
67+ }
5468 }
5569 }
5670}
@@ -74,7 +88,7 @@ impl Display for OverrideReason {
7488 }
7589}
7690
77- #[ derive( Default ) ]
91+ #[ derive( Default , Debug ) ]
7892struct OverrideCfg < ' a > {
7993 toolchain : Option < Toolchain < ' a > > ,
8094 components : Vec < String > ,
@@ -83,11 +97,27 @@ struct OverrideCfg<'a> {
8397}
8498
8599impl < ' a > OverrideCfg < ' a > {
86- fn from_file ( cfg : & ' a Cfg , file : OverrideFile ) -> Result < Self > {
100+ fn from_file (
101+ cfg : & ' a Cfg ,
102+ cfg_path : Option < impl AsRef < Path > > ,
103+ file : OverrideFile ,
104+ ) -> Result < Self > {
87105 Ok ( Self {
88- toolchain : match file. toolchain . channel {
89- Some ( name) => Some ( Toolchain :: from ( cfg, & name) ?) ,
90- None => None ,
106+ toolchain : match ( file. toolchain . channel , file. toolchain . path ) {
107+ ( Some ( name) , None ) => Some ( Toolchain :: from ( cfg, & name) ?) ,
108+ ( None , Some ( path) ) => {
109+ if file. toolchain . targets . is_some ( )
110+ || file. toolchain . components . is_some ( )
111+ || file. toolchain . profile . is_some ( )
112+ {
113+ return Err ( ErrorKind :: CannotSpecifyPathAndOptions ( path. into ( ) ) . into ( ) ) ;
114+ }
115+ Some ( Toolchain :: from_path ( cfg, cfg_path, & path) ?)
116+ }
117+ ( Some ( channel) , Some ( path) ) => {
118+ return Err ( ErrorKind :: CannotSpecifyChannelAndPath ( channel, path. into ( ) ) . into ( ) )
119+ }
120+ ( None , None ) => None ,
91121 } ,
92122 components : file. toolchain . components . unwrap_or_default ( ) ,
93123 targets : file. toolchain . targets . unwrap_or_default ( ) ,
@@ -522,15 +552,21 @@ impl Cfg {
522552 }
523553 OverrideReason :: OverrideDB ( ref path) => format ! (
524554 "the directory override for '{}' specifies an uninstalled toolchain" ,
525- path. display( )
555+ utils :: canonicalize_path ( path, self . notify_handler . as_ref ( ) ) . display( ) ,
526556 ) ,
527557 OverrideReason :: ToolchainFile ( ref path) => format ! (
528558 "the toolchain file at '{}' specifies an uninstalled toolchain" ,
529- path. display( )
559+ utils :: canonicalize_path ( path, self . notify_handler . as_ref ( ) ) . display( ) ,
530560 ) ,
531561 } ;
532562
533- let override_cfg = OverrideCfg :: from_file ( self , file) ?;
563+ let cfg_file = if let OverrideReason :: ToolchainFile ( ref path) = reason {
564+ Some ( path)
565+ } else {
566+ None
567+ } ;
568+
569+ let override_cfg = OverrideCfg :: from_file ( self , cfg_file, file) ?;
534570 if let Some ( toolchain) = & override_cfg. toolchain {
535571 // Overridden toolchains can be literally any string, but only
536572 // distributable toolchains will be auto-installed by the wrapping
@@ -557,8 +593,7 @@ impl Cfg {
557593 settings : & Settings ,
558594 ) -> Result < Option < ( OverrideFile , OverrideReason ) > > {
559595 let notify = self . notify_handler . as_ref ( ) ;
560- let dir = utils:: canonicalize_path ( dir, notify) ;
561- let mut dir = Some ( & * dir) ;
596+ let mut dir = Some ( dir) ;
562597
563598 while let Some ( d) = dir {
564599 // First check the override database
@@ -955,6 +990,7 @@ mod tests {
955990 OverrideFile {
956991 toolchain: ToolchainSection {
957992 channel: Some ( contents. into( ) ) ,
993+ path: None ,
958994 components: None ,
959995 targets: None ,
960996 profile: None ,
@@ -978,6 +1014,7 @@ profile = "default"
9781014 OverrideFile {
9791015 toolchain: ToolchainSection {
9801016 channel: Some ( "nightly-2020-07-10" . into( ) ) ,
1017+ path: None ,
9811018 components: Some ( vec![ "rustfmt" . into( ) , "rustc-dev" . into( ) ] ) ,
9821019 targets: Some ( vec![
9831020 "wasm32-unknown-unknown" . into( ) ,
@@ -1001,6 +1038,28 @@ channel = "nightly-2020-07-10"
10011038 OverrideFile {
10021039 toolchain: ToolchainSection {
10031040 channel: Some ( "nightly-2020-07-10" . into( ) ) ,
1041+ path: None ,
1042+ components: None ,
1043+ targets: None ,
1044+ profile: None ,
1045+ }
1046+ }
1047+ ) ;
1048+ }
1049+
1050+ #[ test]
1051+ fn parse_toml_toolchain_file_only_path ( ) {
1052+ let contents = r#"[toolchain]
1053+ path = "foobar"
1054+ "# ;
1055+
1056+ let result = Cfg :: parse_override_file ( contents, ParseMode :: Both ) ;
1057+ assert_eq ! (
1058+ result. unwrap( ) ,
1059+ OverrideFile {
1060+ toolchain: ToolchainSection {
1061+ channel: None ,
1062+ path: Some ( "foobar" . into( ) ) ,
10041063 components: None ,
10051064 targets: None ,
10061065 profile: None ,
@@ -1022,6 +1081,7 @@ components = []
10221081 OverrideFile {
10231082 toolchain: ToolchainSection {
10241083 channel: Some ( "nightly-2020-07-10" . into( ) ) ,
1084+ path: None ,
10251085 components: Some ( vec![ ] ) ,
10261086 targets: None ,
10271087 profile: None ,
@@ -1043,6 +1103,7 @@ targets = []
10431103 OverrideFile {
10441104 toolchain: ToolchainSection {
10451105 channel: Some ( "nightly-2020-07-10" . into( ) ) ,
1106+ path: None ,
10461107 components: None ,
10471108 targets: Some ( vec![ ] ) ,
10481109 profile: None ,
@@ -1063,6 +1124,7 @@ components = [ "rustfmt" ]
10631124 OverrideFile {
10641125 toolchain: ToolchainSection {
10651126 channel: None ,
1127+ path: None ,
10661128 components: Some ( vec![ "rustfmt" . into( ) ] ) ,
10671129 targets: None ,
10681130 profile: None ,
0 commit comments