@@ -555,19 +555,26 @@ impl Cfg {
555
555
// Then look for 'rust-toolchain'
556
556
let toolchain_file = d. join ( "rust-toolchain" ) ;
557
557
if let Ok ( contents) = utils:: read_file ( "toolchain file" , & toolchain_file) {
558
- if let Some ( override_file) = Cfg :: parse_override_file ( contents) ? {
558
+ if let ( Some ( override_file) , toml_err ) = Cfg :: parse_override_file ( contents) {
559
559
if let Some ( toolchain_name) = & override_file. toolchain . channel {
560
560
let all_toolchains = self . list_toolchains ( ) ?;
561
561
if !all_toolchains. iter ( ) . any ( |s| s == toolchain_name) {
562
562
// The given name is not resolvable as a toolchain, so
563
563
// instead check it's plausible for installation later
564
- dist:: validate_channel_name ( & toolchain_name) . chain_err ( || {
565
- format ! (
566
- "invalid channel name '{}' in '{}'" ,
567
- toolchain_name,
568
- toolchain_file. display( )
569
- )
570
- } ) ?;
564
+ let mut validation = dist:: validate_channel_name ( & toolchain_name)
565
+ . chain_err ( || {
566
+ format ! (
567
+ "error parsing override file as legacy format: invalid channel name '{}' in '{}'" ,
568
+ toolchain_name,
569
+ toolchain_file. display( )
570
+ )
571
+ } ) ;
572
+ // If there was an error parsing the toolchain file as TOML, report it now.
573
+ // This can help if the toolchain file is actually TOML but there was a syntax error.
574
+ if let Some ( err) = toml_err {
575
+ validation = validation. chain_err ( || err) ;
576
+ }
577
+ validation?;
571
578
}
572
579
}
573
580
@@ -582,15 +589,27 @@ impl Cfg {
582
589
Ok ( None )
583
590
}
584
591
585
- fn parse_override_file < S : AsRef < str > > ( contents : S ) -> Result < Option < OverrideFile > > {
592
+ fn parse_override_file < S : AsRef < str > > (
593
+ contents : S ,
594
+ ) -> ( Option < OverrideFile > , Option < ErrorKind > ) {
586
595
let contents = contents. as_ref ( ) ;
587
596
588
- if contents. lines ( ) . any ( |line| line. starts_with ( "[toolchain]" ) ) {
589
- toml:: from_str :: < OverrideFile > ( contents)
590
- . map ( |file| if file. is_empty ( ) { None } else { Some ( file) } )
591
- . map_err ( |e| ErrorKind :: ParsingOverride ( e) . into ( ) )
592
- } else {
593
- Ok ( contents. lines ( ) . next ( ) . map ( |line| line. trim ( ) . into ( ) ) )
597
+ // Avoid TOML parsing error for backwards compatibility with the legacy format
598
+ if contents. is_empty ( ) {
599
+ return ( None , None ) ;
600
+ }
601
+
602
+ // Try to parse as TOML ...
603
+ match toml:: from_str :: < OverrideFile > ( contents)
604
+ . map ( |file| if file. is_empty ( ) { None } else { Some ( file) } )
605
+ . map_err ( ErrorKind :: ParsingOverride )
606
+ {
607
+ Ok ( override_file) => ( override_file, None ) ,
608
+ // ... in case of error, try to parse as the legacy format
609
+ Err ( toml_err) => (
610
+ contents. lines ( ) . next ( ) . map ( |line| line. trim ( ) . into ( ) ) ,
611
+ Some ( toml_err) ,
612
+ ) ,
594
613
}
595
614
}
596
615
@@ -862,16 +881,17 @@ mod tests {
862
881
fn parse_legacy_toolchain_file ( ) {
863
882
let contents = "nightly-2020-07-10" ;
864
883
865
- let result = Cfg :: parse_override_file ( contents) ;
884
+ let ( override_file , toml_err ) = Cfg :: parse_override_file ( contents) ;
866
885
assert_eq ! (
867
- result . unwrap ( ) ,
886
+ override_file ,
868
887
Some ( OverrideFile {
869
888
toolchain: ToolchainSection {
870
889
channel: Some ( contents. into( ) ) ,
871
890
..Default :: default ( )
872
891
}
873
892
} )
874
893
) ;
894
+ assert ! ( toml_err. is_some( ) ) ;
875
895
}
876
896
877
897
#[ test]
@@ -883,9 +903,9 @@ components = [ "rustfmt", "rustc-dev" ]
883
903
targets = [ "wasm32-unknown-unknown", "thumbv2-none-eabi" ]
884
904
"# ;
885
905
886
- let result = Cfg :: parse_override_file ( contents) ;
906
+ let ( override_file , toml_err ) = Cfg :: parse_override_file ( contents) ;
887
907
assert_eq ! (
888
- result . unwrap ( ) ,
908
+ override_file ,
889
909
Some ( OverrideFile {
890
910
toolchain: ToolchainSection {
891
911
channel: Some ( "nightly-2020-07-10" . into( ) ) ,
@@ -897,6 +917,7 @@ targets = [ "wasm32-unknown-unknown", "thumbv2-none-eabi" ]
897
917
}
898
918
} )
899
919
) ;
920
+ assert ! ( toml_err. is_none( ) ) ;
900
921
}
901
922
902
923
#[ test]
@@ -906,9 +927,9 @@ targets = [ "wasm32-unknown-unknown", "thumbv2-none-eabi" ]
906
927
channel = "nightly-2020-07-10"
907
928
"# ;
908
929
909
- let result = Cfg :: parse_override_file ( contents) ;
930
+ let ( override_file , toml_err ) = Cfg :: parse_override_file ( contents) ;
910
931
assert_eq ! (
911
- result . unwrap ( ) ,
932
+ override_file ,
912
933
Some ( OverrideFile {
913
934
toolchain: ToolchainSection {
914
935
channel: Some ( "nightly-2020-07-10" . into( ) ) ,
@@ -917,6 +938,7 @@ channel = "nightly-2020-07-10"
917
938
}
918
939
} )
919
940
) ;
941
+ assert ! ( toml_err. is_none( ) ) ;
920
942
}
921
943
922
944
#[ test]
@@ -927,9 +949,9 @@ channel = "nightly-2020-07-10"
927
949
components = []
928
950
"# ;
929
951
930
- let result = Cfg :: parse_override_file ( contents) ;
952
+ let ( override_file , toml_err ) = Cfg :: parse_override_file ( contents) ;
931
953
assert_eq ! (
932
- result . unwrap ( ) ,
954
+ override_file ,
933
955
Some ( OverrideFile {
934
956
toolchain: ToolchainSection {
935
957
channel: Some ( "nightly-2020-07-10" . into( ) ) ,
@@ -938,6 +960,7 @@ components = []
938
960
}
939
961
} )
940
962
) ;
963
+ assert ! ( toml_err. is_none( ) ) ;
941
964
}
942
965
943
966
#[ test]
@@ -948,9 +971,9 @@ channel = "nightly-2020-07-10"
948
971
targets = []
949
972
"# ;
950
973
951
- let result = Cfg :: parse_override_file ( contents) ;
974
+ let ( override_file , toml_err ) = Cfg :: parse_override_file ( contents) ;
952
975
assert_eq ! (
953
- result . unwrap ( ) ,
976
+ override_file ,
954
977
Some ( OverrideFile {
955
978
toolchain: ToolchainSection {
956
979
channel: Some ( "nightly-2020-07-10" . into( ) ) ,
@@ -959,6 +982,7 @@ targets = []
959
982
}
960
983
} )
961
984
) ;
985
+ assert ! ( toml_err. is_none( ) ) ;
962
986
}
963
987
964
988
#[ test]
@@ -968,9 +992,9 @@ targets = []
968
992
components = [ "rustfmt" ]
969
993
"# ;
970
994
971
- let result = Cfg :: parse_override_file ( contents) ;
995
+ let ( override_file , toml_err ) = Cfg :: parse_override_file ( contents) ;
972
996
assert_eq ! (
973
- result . unwrap ( ) ,
997
+ override_file ,
974
998
Some ( OverrideFile {
975
999
toolchain: ToolchainSection {
976
1000
channel: None ,
@@ -979,6 +1003,7 @@ components = [ "rustfmt" ]
979
1003
}
980
1004
} )
981
1005
) ;
1006
+ assert ! ( toml_err. is_none( ) ) ;
982
1007
}
983
1008
984
1009
#[ test]
@@ -987,15 +1012,36 @@ components = [ "rustfmt" ]
987
1012
[toolchain]
988
1013
"# ;
989
1014
990
- let result = Cfg :: parse_override_file ( contents) ;
991
- assert_eq ! ( result. unwrap( ) , None ) ;
1015
+ let ( override_file, toml_err) = Cfg :: parse_override_file ( contents) ;
1016
+ assert ! ( override_file. is_none( ) ) ;
1017
+ assert ! ( toml_err. is_none( ) ) ;
992
1018
}
993
1019
994
1020
#[ test]
995
1021
fn parse_empty_toolchain_file ( ) {
996
1022
let contents = "" ;
997
1023
998
- let result = Cfg :: parse_override_file ( contents) ;
999
- assert_eq ! ( result. unwrap( ) , None ) ;
1024
+ let ( override_file, toml_err) = Cfg :: parse_override_file ( contents) ;
1025
+ assert ! ( override_file. is_none( ) ) ;
1026
+ assert ! ( toml_err. is_none( ) ) ;
1027
+ }
1028
+
1029
+ #[ test]
1030
+ fn parse_toml_syntax_error ( ) {
1031
+ let contents = r#"[toolchain]
1032
+ channel = nightly
1033
+ "# ;
1034
+
1035
+ let ( override_file, toml_err) = Cfg :: parse_override_file ( contents) ;
1036
+ assert_eq ! (
1037
+ override_file,
1038
+ Some ( OverrideFile {
1039
+ toolchain: ToolchainSection {
1040
+ channel: Some ( "[toolchain]" . into( ) ) ,
1041
+ ..Default :: default ( )
1042
+ }
1043
+ } )
1044
+ ) ;
1045
+ assert ! ( toml_err. is_some( ) ) ;
1000
1046
}
1001
1047
}
0 commit comments