|  | 
| 1 |  | -use rustc_data_structures::fx::{FxHashMap, FxHashSet}; | 
|  | 1 | +use rustc_data_structures::fx::{FxHashSet, FxIndexMap}; | 
| 2 | 2 | use rustc_data_structures::temp_dir::MaybeTempDir; | 
| 3 | 3 | use rustc_errors::Handler; | 
| 4 | 4 | use rustc_fs_util::fix_windows_verbatim_for_gcc; | 
| 5 | 5 | use rustc_hir::def_id::CrateNum; | 
| 6 |  | -use rustc_middle::middle::cstore::{DllCallingConvention, DllImport}; | 
|  | 6 | +use rustc_middle::middle::cstore::DllImport; | 
| 7 | 7 | use rustc_middle::middle::dependency_format::Linkage; | 
| 8 | 8 | use rustc_session::config::{self, CFGuard, CrateType, DebugInfo, LdImpl, Strip}; | 
| 9 | 9 | use rustc_session::config::{OutputFilenames, OutputType, PrintRequest}; | 
| @@ -35,7 +35,6 @@ use object::{Architecture, BinaryFormat, Endianness, FileFlags, SectionFlags, Se | 
| 35 | 35 | use tempfile::Builder as TempFileBuilder; | 
| 36 | 36 | 
 | 
| 37 | 37 | use std::ffi::OsString; | 
| 38 |  | -use std::iter::FromIterator; | 
| 39 | 38 | use std::path::{Path, PathBuf}; | 
| 40 | 39 | use std::process::{ExitStatus, Output, Stdio}; | 
| 41 | 40 | use std::{ascii, char, env, fmt, fs, io, mem, str}; | 
| @@ -455,64 +454,39 @@ fn collate_raw_dylibs( | 
| 455 | 454 |     sess: &Session, | 
| 456 | 455 |     used_libraries: &[NativeLib], | 
| 457 | 456 | ) -> Vec<(String, Vec<DllImport>)> { | 
| 458 |  | -    let mut dylib_table: FxHashMap<String, FxHashSet<DllImport>> = FxHashMap::default(); | 
|  | 457 | +    // Use index maps to preserve original order of imports and libraries. | 
|  | 458 | +    let mut dylib_table = FxIndexMap::<String, FxIndexMap<Symbol, &DllImport>>::default(); | 
| 459 | 459 | 
 | 
| 460 | 460 |     for lib in used_libraries { | 
| 461 | 461 |         if lib.kind == NativeLibKind::RawDylib { | 
| 462 |  | -            let name = lib.name.unwrap_or_else(|| | 
| 463 |  | -                bug!("`link` attribute with kind = \"raw-dylib\" and no name should have caused error earlier") | 
| 464 |  | -            ); | 
| 465 |  | -            let name = if matches!(lib.verbatim, Some(true)) { | 
| 466 |  | -                name.to_string() | 
| 467 |  | -            } else { | 
| 468 |  | -                format!("{}.dll", name) | 
| 469 |  | -            }; | 
| 470 |  | -            dylib_table.entry(name).or_default().extend(lib.dll_imports.iter().cloned()); | 
| 471 |  | -        } | 
| 472 |  | -    } | 
| 473 |  | - | 
| 474 |  | -    // Rustc already signals an error if we have two imports with the same name but different | 
| 475 |  | -    // calling conventions (or function signatures), so we don't have pay attention to those | 
| 476 |  | -    // when ordering. | 
| 477 |  | -    // FIXME: when we add support for ordinals, figure out if we need to do anything if we | 
| 478 |  | -    // have two DllImport values with the same name but different ordinals. | 
| 479 |  | -    let mut result: Vec<(String, Vec<DllImport>)> = dylib_table | 
| 480 |  | -        .into_iter() | 
| 481 |  | -        .map(|(lib_name, import_table)| { | 
| 482 |  | -            let mut imports = Vec::from_iter(import_table.into_iter()); | 
| 483 |  | -            imports.sort_unstable_by_key(|x: &DllImport| x.name.as_str()); | 
| 484 |  | -            (lib_name, imports) | 
| 485 |  | -        }) | 
| 486 |  | -        .collect::<Vec<_>>(); | 
| 487 |  | -    result.sort_unstable_by(|a: &(String, Vec<DllImport>), b: &(String, Vec<DllImport>)| { | 
| 488 |  | -        a.0.cmp(&b.0) | 
| 489 |  | -    }); | 
| 490 |  | -    let result = result; | 
| 491 |  | - | 
| 492 |  | -    // Check for multiple imports with the same name but different calling conventions or | 
| 493 |  | -    // (when relevant) argument list sizes.  Rustc only signals an error for this if the | 
| 494 |  | -    // declarations are at the same scope level; if one shadows the other, we only get a lint | 
| 495 |  | -    // warning. | 
| 496 |  | -    for (library, imports) in &result { | 
| 497 |  | -        let mut import_table: FxHashMap<Symbol, DllCallingConvention> = FxHashMap::default(); | 
| 498 |  | -        for import in imports { | 
| 499 |  | -            if let Some(old_convention) = | 
| 500 |  | -                import_table.insert(import.name, import.calling_convention) | 
| 501 |  | -            { | 
| 502 |  | -                if import.calling_convention != old_convention { | 
| 503 |  | -                    sess.span_fatal( | 
| 504 |  | -                        import.span, | 
| 505 |  | -                        &format!( | 
| 506 |  | -                            "multiple definitions of external function `{}` from library `{}` have different calling conventions", | 
| 507 |  | -                            import.name, | 
| 508 |  | -                            library, | 
| 509 |  | -                    )); | 
|  | 462 | +            let ext = if matches!(lib.verbatim, Some(true)) { "" } else { ".dll" }; | 
|  | 463 | +            let name = format!("{}{}", lib.name.expect("unnamed raw-dylib library"), ext); | 
|  | 464 | +            let imports = dylib_table.entry(name.clone()).or_default(); | 
|  | 465 | +            for import in &lib.dll_imports { | 
|  | 466 | +                if let Some(old_import) = imports.insert(import.name, import) { | 
|  | 467 | +                    // FIXME: when we add support for ordinals, figure out if we need to do anything | 
|  | 468 | +                    // if we have two DllImport values with the same name but different ordinals. | 
|  | 469 | +                    if import.calling_convention != old_import.calling_convention { | 
|  | 470 | +                        sess.span_err( | 
|  | 471 | +                            import.span, | 
|  | 472 | +                            &format!( | 
|  | 473 | +                                "multiple declarations of external function `{}` from \ | 
|  | 474 | +                                 library `{}` have different calling conventions", | 
|  | 475 | +                                import.name, name, | 
|  | 476 | +                            ), | 
|  | 477 | +                        ); | 
|  | 478 | +                    } | 
| 510 | 479 |                 } | 
| 511 | 480 |             } | 
| 512 | 481 |         } | 
| 513 | 482 |     } | 
| 514 | 483 | 
 | 
| 515 |  | -    result | 
|  | 484 | +    dylib_table | 
|  | 485 | +        .into_iter() | 
|  | 486 | +        .map(|(name, imports)| { | 
|  | 487 | +            (name, imports.into_iter().map(|(_, import)| import.clone()).collect()) | 
|  | 488 | +        }) | 
|  | 489 | +        .collect() | 
| 516 | 490 | } | 
| 517 | 491 | 
 | 
| 518 | 492 | /// Create a static archive. | 
|  | 
0 commit comments