@@ -272,7 +272,8 @@ pub trait CommandExt: Sized {
272272 } ;
273273 self . _arg (
274274 optional_multi_opt ( "target" , "TRIPLE" , target)
275- . help_heading ( heading:: COMPILATION_OPTIONS ) ,
275+ . help_heading ( heading:: COMPILATION_OPTIONS )
276+ . add ( clap_complete:: ArgValueCandidates :: new ( get_target_triples) ) ,
276277 )
277278 . _arg ( unsupported_short_arg)
278279 }
@@ -1067,6 +1068,62 @@ fn get_targets_from_metadata() -> CargoResult<Vec<Target>> {
10671068 Ok ( targets)
10681069}
10691070
1071+ fn get_target_triples ( ) -> Vec < clap_complete:: CompletionCandidate > {
1072+ let mut candidates = Vec :: new ( ) ;
1073+
1074+ if is_rustup ( ) {
1075+ if let Ok ( targets) = get_target_triples_from_rustup ( ) {
1076+ candidates. extend ( targets) ;
1077+ }
1078+ } else {
1079+ if let Ok ( targets) = get_target_triples_from_rustc ( ) {
1080+ candidates. extend ( targets) ;
1081+ }
1082+ }
1083+
1084+ candidates
1085+ }
1086+
1087+ fn get_target_triples_from_rustup ( ) -> CargoResult < Vec < clap_complete:: CompletionCandidate > > {
1088+ let output = std:: process:: Command :: new ( "rustup" )
1089+ . arg ( "target" )
1090+ . arg ( "list" )
1091+ . output ( ) ?;
1092+
1093+ if !output. status . success ( ) {
1094+ return Ok ( vec ! [ ] ) ;
1095+ }
1096+
1097+ let stdout = String :: from_utf8 ( output. stdout ) ?;
1098+
1099+ Ok ( stdout
1100+ . lines ( )
1101+ . map ( |line| {
1102+ let target = line. split_once ( ' ' ) ;
1103+ match target {
1104+ None => clap_complete:: CompletionCandidate :: new ( line. to_owned ( ) ) . hide ( true ) ,
1105+ Some ( ( target, _installed) ) => clap_complete:: CompletionCandidate :: new ( target) ,
1106+ }
1107+ } )
1108+ . collect ( ) )
1109+ }
1110+
1111+ fn get_target_triples_from_rustc ( ) -> CargoResult < Vec < clap_complete:: CompletionCandidate > > {
1112+ let cwd = std:: env:: current_dir ( ) ?;
1113+ let gctx = GlobalContext :: new ( shell:: Shell :: new ( ) , cwd. clone ( ) , cargo_home_with_cwd ( & cwd) ?) ;
1114+ let ws = Workspace :: new ( & find_root_manifest_for_wd ( & PathBuf :: from ( & cwd) ) ?, & gctx) ;
1115+
1116+ let rustc = gctx. load_global_rustc ( ws. as_ref ( ) . ok ( ) ) ?;
1117+
1118+ let ( stdout, _stderr) =
1119+ rustc. cached_output ( rustc. process ( ) . arg ( "--print" ) . arg ( "target-list" ) , 0 ) ?;
1120+
1121+ Ok ( stdout
1122+ . lines ( )
1123+ . map ( |line| clap_complete:: CompletionCandidate :: new ( line. to_owned ( ) ) )
1124+ . collect ( ) )
1125+ }
1126+
10701127#[ track_caller]
10711128pub fn ignore_unknown < T : Default > ( r : Result < T , clap:: parser:: MatchesError > ) -> T {
10721129 match r {
0 commit comments