| author | bors <bors@rust-lang.org> 2026-03-18 11:10:07 UTC |
| committer | bors <bors@rust-lang.org> 2026-03-18 11:10:07 UTC |
| log | 53d60bb1c5d325b43419c7618287a1405dec36d0 |
| tree | 52fe19ff9017c893ab5a083f9d0a94e9f9747ff4 |
| parent | 70dd5b8d0e00ce34ecb7612c3b76a0b2f6601ab6 |
| parent | 205d100ef54cbe148c2da2efa2b555740808c907 |
Rollup of 3 pull requests
Successful merges:
- rust-lang/rust#153580 (Handle statics and TLS in raw-dylib for ELF)
- rust-lang/rust#154020 (Moved tests/ui/issues/issue-23891.rs to tests/ui/macros/)
- rust-lang/rust#154028 (Rename trait `IntoQueryParam` to `IntoQueryKey`)17 files changed, 271 insertions(+), 170 deletions(-)
compiler/rustc_codegen_ssa/src/back/link/raw_dylib.rs+39-13| ... | ... | @@ -9,7 +9,7 @@ use rustc_data_structures::stable_hasher::StableHasher; |
| 9 | 9 | use rustc_hashes::Hash128; |
| 10 | 10 | use rustc_hir::attrs::NativeLibKind; |
| 11 | 11 | use rustc_session::Session; |
| 12 | use rustc_session::cstore::DllImport; | |
| 12 | use rustc_session::cstore::{DllImport, DllImportSymbolType}; | |
| 13 | 13 | use rustc_span::Symbol; |
| 14 | 14 | use rustc_target::spec::Arch; |
| 15 | 15 | |
| ... | ... | @@ -95,14 +95,14 @@ pub(super) fn create_raw_dylib_dll_import_libs<'a>( |
| 95 | 95 | true, |
| 96 | 96 | ) |
| 97 | 97 | }), |
| 98 | is_data: !import.is_fn, | |
| 98 | is_data: import.symbol_type != DllImportSymbolType::Function, | |
| 99 | 99 | } |
| 100 | 100 | } else { |
| 101 | 101 | ImportLibraryItem { |
| 102 | 102 | name: import.name.to_string(), |
| 103 | 103 | ordinal: import.ordinal(), |
| 104 | 104 | symbol_name: None, |
| 105 | is_data: !import.is_fn, | |
| 105 | is_data: import.symbol_type != DllImportSymbolType::Function, | |
| 106 | 106 | } |
| 107 | 107 | } |
| 108 | 108 | }) |
| ... | ... | @@ -271,10 +271,10 @@ fn create_elf_raw_dylib_stub(sess: &Session, soname: &str, symbols: &[DllImport] |
| 271 | 271 | vers.push((version_name, dynstr)); |
| 272 | 272 | id |
| 273 | 273 | }; |
| 274 | syms.push((name, dynstr, Some(ver), symbol.is_fn)); | |
| 274 | syms.push((name, dynstr, Some(ver), symbol.symbol_type, symbol.size)); | |
| 275 | 275 | } else { |
| 276 | 276 | let dynstr = stub.add_dynamic_string(symbol_name.as_bytes()); |
| 277 | syms.push((symbol_name, dynstr, None, symbol.is_fn)); | |
| 277 | syms.push((symbol_name, dynstr, None, symbol.symbol_type, symbol.size)); | |
| 278 | 278 | } |
| 279 | 279 | } |
| 280 | 280 | |
| ... | ... | @@ -296,6 +296,8 @@ fn create_elf_raw_dylib_stub(sess: &Session, soname: &str, symbols: &[DllImport] |
| 296 | 296 | stub.reserve_shstrtab_section_index(); |
| 297 | 297 | let text_section_name = stub.add_section_name(".text".as_bytes()); |
| 298 | 298 | let text_section = stub.reserve_section_index(); |
| 299 | let data_section_name = stub.add_section_name(".data".as_bytes()); | |
| 300 | let data_section = stub.reserve_section_index(); | |
| 299 | 301 | stub.reserve_dynsym_section_index(); |
| 300 | 302 | stub.reserve_dynstr_section_index(); |
| 301 | 303 | if !vers.is_empty() { |
| ... | ... | @@ -375,7 +377,7 @@ fn create_elf_raw_dylib_stub(sess: &Session, soname: &str, symbols: &[DllImport] |
| 375 | 377 | // Section headers |
| 376 | 378 | stub.write_null_section_header(); |
| 377 | 379 | stub.write_shstrtab_section_header(); |
| 378 | // Create a dummy .text section for our dummy symbols. | |
| 380 | // Create a dummy .text section for our dummy non-data symbols. | |
| 379 | 381 | stub.write_section_header(&write::SectionHeader { |
| 380 | 382 | name: Some(text_section_name), |
| 381 | 383 | sh_type: elf::SHT_PROGBITS, |
| ... | ... | @@ -385,7 +387,20 @@ fn create_elf_raw_dylib_stub(sess: &Session, soname: &str, symbols: &[DllImport] |
| 385 | 387 | sh_size: 0, |
| 386 | 388 | sh_link: 0, |
| 387 | 389 | sh_info: 0, |
| 388 | sh_addralign: 1, | |
| 390 | sh_addralign: 16, | |
| 391 | sh_entsize: 0, | |
| 392 | }); | |
| 393 | // And also a dummy .data section for our dummy data symbols. | |
| 394 | stub.write_section_header(&write::SectionHeader { | |
| 395 | name: Some(data_section_name), | |
| 396 | sh_type: elf::SHT_PROGBITS, | |
| 397 | sh_flags: (elf::SHF_WRITE | elf::SHF_ALLOC) as u64, | |
| 398 | sh_addr: 0, | |
| 399 | sh_offset: 0, | |
| 400 | sh_size: 0, | |
| 401 | sh_link: 0, | |
| 402 | sh_info: 0, | |
| 403 | sh_addralign: 16, | |
| 389 | 404 | sh_entsize: 0, |
| 390 | 405 | }); |
| 391 | 406 | stub.write_dynsym_section_header(0, 1); |
| ... | ... | @@ -398,17 +413,28 @@ fn create_elf_raw_dylib_stub(sess: &Session, soname: &str, symbols: &[DllImport] |
| 398 | 413 | |
| 399 | 414 | // .dynsym |
| 400 | 415 | stub.write_null_dynamic_symbol(); |
| 401 | for (_name, dynstr, _ver, is_fn) in syms.iter().copied() { | |
| 402 | let sym_type = if is_fn { elf::STT_FUNC } else { elf::STT_NOTYPE }; | |
| 416 | // Linkers like LLD require at least somewhat reasonable symbol values rather than zero, | |
| 417 | // otherwise all the symbols might get put at the same address. Thus we increment the value | |
| 418 | // every time we write a symbol. | |
| 419 | let mut st_value = 0; | |
| 420 | for (_name, dynstr, _ver, symbol_type, size) in syms.iter().copied() { | |
| 421 | let sym_type = match symbol_type { | |
| 422 | DllImportSymbolType::Function => elf::STT_FUNC, | |
| 423 | DllImportSymbolType::Static => elf::STT_OBJECT, | |
| 424 | DllImportSymbolType::ThreadLocal => elf::STT_TLS, | |
| 425 | }; | |
| 426 | let section = | |
| 427 | if symbol_type == DllImportSymbolType::Static { data_section } else { text_section }; | |
| 403 | 428 | stub.write_dynamic_symbol(&write::Sym { |
| 404 | 429 | name: Some(dynstr), |
| 405 | 430 | st_info: (elf::STB_GLOBAL << 4) | sym_type, |
| 406 | 431 | st_other: elf::STV_DEFAULT, |
| 407 | section: Some(text_section), | |
| 432 | section: Some(section), | |
| 408 | 433 | st_shndx: 0, // ignored by object in favor of the `section` field |
| 409 | st_value: 0, | |
| 410 | st_size: 0, | |
| 434 | st_value, | |
| 435 | st_size: size.bytes(), | |
| 411 | 436 | }); |
| 437 | st_value += 8; | |
| 412 | 438 | } |
| 413 | 439 | |
| 414 | 440 | // .dynstr |
| ... | ... | @@ -418,7 +444,7 @@ fn create_elf_raw_dylib_stub(sess: &Session, soname: &str, symbols: &[DllImport] |
| 418 | 444 | if !vers.is_empty() { |
| 419 | 445 | // .gnu_version |
| 420 | 446 | stub.write_null_gnu_versym(); |
| 421 | for (_name, _dynstr, ver, _is_fn) in syms.iter().copied() { | |
| 447 | for (_name, _dynstr, ver, _symbol_type, _size) in syms.iter().copied() { | |
| 422 | 448 | stub.write_gnu_versym(if let Some(ver) = ver { |
| 423 | 449 | assert!((2 + ver as u16) < elf::VERSYM_HIDDEN); |
| 424 | 450 | elf::VERSYM_HIDDEN | (2 + ver as u16) |
compiler/rustc_codegen_ssa/src/common.rs+4-4| ... | ... | @@ -5,7 +5,7 @@ use rustc_hir::attrs::PeImportNameType; |
| 5 | 5 | use rustc_middle::ty::layout::TyAndLayout; |
| 6 | 6 | use rustc_middle::ty::{self, Instance, TyCtxt}; |
| 7 | 7 | use rustc_middle::{bug, mir, span_bug}; |
| 8 | use rustc_session::cstore::{DllCallingConvention, DllImport}; | |
| 8 | use rustc_session::cstore::{DllCallingConvention, DllImport, DllImportSymbolType}; | |
| 9 | 9 | use rustc_span::Span; |
| 10 | 10 | use rustc_target::spec::{Abi, Env, Os, Target}; |
| 11 | 11 | |
| ... | ... | @@ -199,7 +199,7 @@ pub fn i686_decorated_name( |
| 199 | 199 | decorated_name.push('\x01'); |
| 200 | 200 | } |
| 201 | 201 | |
| 202 | let prefix = if add_prefix && dll_import.is_fn { | |
| 202 | let prefix = if add_prefix && dll_import.symbol_type == DllImportSymbolType::Function { | |
| 203 | 203 | match dll_import.calling_convention { |
| 204 | 204 | DllCallingConvention::C | DllCallingConvention::Vectorcall(_) => None, |
| 205 | 205 | DllCallingConvention::Stdcall(_) => (!mingw |
| ... | ... | @@ -207,7 +207,7 @@ pub fn i686_decorated_name( |
| 207 | 207 | .then_some('_'), |
| 208 | 208 | DllCallingConvention::Fastcall(_) => Some('@'), |
| 209 | 209 | } |
| 210 | } else if !dll_import.is_fn && !mingw { | |
| 210 | } else if dll_import.symbol_type != DllImportSymbolType::Function && !mingw { | |
| 211 | 211 | // For static variables, prefix with '_' on MSVC. |
| 212 | 212 | Some('_') |
| 213 | 213 | } else { |
| ... | ... | @@ -219,7 +219,7 @@ pub fn i686_decorated_name( |
| 219 | 219 | |
| 220 | 220 | decorated_name.push_str(name); |
| 221 | 221 | |
| 222 | if add_suffix && dll_import.is_fn { | |
| 222 | if add_suffix && dll_import.symbol_type == DllImportSymbolType::Function { | |
| 223 | 223 | use std::fmt::Write; |
| 224 | 224 | |
| 225 | 225 | match dll_import.calling_convention { |
compiler/rustc_metadata/src/native_libs.rs+33-8| ... | ... | @@ -5,12 +5,17 @@ use rustc_abi::ExternAbi; |
| 5 | 5 | use rustc_attr_parsing::eval_config_entry; |
| 6 | 6 | use rustc_data_structures::fx::FxHashSet; |
| 7 | 7 | use rustc_hir::attrs::{NativeLibKind, PeImportNameType}; |
| 8 | use rustc_hir::def::DefKind; | |
| 8 | 9 | use rustc_hir::find_attr; |
| 10 | use rustc_middle::bug; | |
| 11 | use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags; | |
| 9 | 12 | use rustc_middle::query::LocalCrate; |
| 10 | 13 | use rustc_middle::ty::{self, List, Ty, TyCtxt}; |
| 11 | 14 | use rustc_session::Session; |
| 12 | 15 | use rustc_session::config::CrateType; |
| 13 | use rustc_session::cstore::{DllCallingConvention, DllImport, ForeignModule, NativeLib}; | |
| 16 | use rustc_session::cstore::{ | |
| 17 | DllCallingConvention, DllImport, DllImportSymbolType, ForeignModule, NativeLib, | |
| 18 | }; | |
| 14 | 19 | use rustc_session::search_paths::PathKind; |
| 15 | 20 | use rustc_span::Symbol; |
| 16 | 21 | use rustc_span::def_id::{DefId, LOCAL_CRATE}; |
| ... | ... | @@ -451,12 +456,32 @@ impl<'tcx> Collector<'tcx> { |
| 451 | 456 | } |
| 452 | 457 | } |
| 453 | 458 | |
| 454 | DllImport { | |
| 455 | name, | |
| 456 | import_name_type, | |
| 457 | calling_convention, | |
| 458 | span, | |
| 459 | is_fn: self.tcx.def_kind(item).is_fn_like(), | |
| 460 | } | |
| 459 | let def_kind = self.tcx.def_kind(item); | |
| 460 | let symbol_type = if def_kind.is_fn_like() { | |
| 461 | DllImportSymbolType::Function | |
| 462 | } else if matches!(def_kind, DefKind::Static { .. }) { | |
| 463 | if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::THREAD_LOCAL) { | |
| 464 | DllImportSymbolType::ThreadLocal | |
| 465 | } else { | |
| 466 | DllImportSymbolType::Static | |
| 467 | } | |
| 468 | } else { | |
| 469 | bug!("Unexpected type for raw-dylib: {}", def_kind.descr(item)); | |
| 470 | }; | |
| 471 | ||
| 472 | let size = match symbol_type { | |
| 473 | // We cannot determine the size of a function at compile time, but it shouldn't matter anyway. | |
| 474 | DllImportSymbolType::Function => rustc_abi::Size::ZERO, | |
| 475 | DllImportSymbolType::Static | DllImportSymbolType::ThreadLocal => { | |
| 476 | let ty = self.tcx.type_of(item).instantiate_identity(); | |
| 477 | self.tcx | |
| 478 | .layout_of(ty::TypingEnv::fully_monomorphized().as_query_input(ty)) | |
| 479 | .ok() | |
| 480 | .map(|layout| layout.size) | |
| 481 | .unwrap_or_else(|| bug!("Non-function symbols must have a size")) | |
| 482 | } | |
| 483 | }; | |
| 484 | ||
| 485 | DllImport { name, import_name_type, calling_convention, span, symbol_type, size } | |
| 461 | 486 | } |
| 462 | 487 | } |
compiler/rustc_middle/src/query/into_query_key.rs created+70| ... | ... | @@ -0,0 +1,70 @@ |
| 1 | use rustc_hir::OwnerId; | |
| 2 | use rustc_hir::def_id::{DefId, LocalDefId, LocalModDefId, ModDefId}; | |
| 3 | ||
| 4 | /// Argument-conversion trait used by some queries and other `TyCtxt` methods. | |
| 5 | /// | |
| 6 | /// A function that accepts an `impl IntoQueryKey<DefId>` argument can be thought | |
| 7 | /// of as taking a [`DefId`], except that callers can also pass a [`LocalDefId`] | |
| 8 | /// or values of other narrower ID types, as long as they have a trivial conversion | |
| 9 | /// to `DefId`. | |
| 10 | /// | |
| 11 | /// Using a dedicated trait instead of [`Into`] makes the purpose of the conversion | |
| 12 | /// more explicit, and makes occurrences easier to search for. | |
| 13 | pub trait IntoQueryKey<K> { | |
| 14 | /// Argument conversion from `Self` to `K`. | |
| 15 | /// This should always be a very cheap conversion, e.g. [`LocalDefId::to_def_id`]. | |
| 16 | fn into_query_key(self) -> K; | |
| 17 | } | |
| 18 | ||
| 19 | /// Any type can be converted to itself. | |
| 20 | /// | |
| 21 | /// This is useful in generic or macro-generated code where we don't know whether | |
| 22 | /// conversion is actually needed, so that we can do a conversion unconditionally. | |
| 23 | impl<K> IntoQueryKey<K> for K { | |
| 24 | #[inline(always)] | |
| 25 | fn into_query_key(self) -> K { | |
| 26 | self | |
| 27 | } | |
| 28 | } | |
| 29 | ||
| 30 | impl IntoQueryKey<LocalDefId> for OwnerId { | |
| 31 | #[inline(always)] | |
| 32 | fn into_query_key(self) -> LocalDefId { | |
| 33 | self.def_id | |
| 34 | } | |
| 35 | } | |
| 36 | ||
| 37 | impl IntoQueryKey<DefId> for LocalDefId { | |
| 38 | #[inline(always)] | |
| 39 | fn into_query_key(self) -> DefId { | |
| 40 | self.to_def_id() | |
| 41 | } | |
| 42 | } | |
| 43 | ||
| 44 | impl IntoQueryKey<DefId> for OwnerId { | |
| 45 | #[inline(always)] | |
| 46 | fn into_query_key(self) -> DefId { | |
| 47 | self.to_def_id() | |
| 48 | } | |
| 49 | } | |
| 50 | ||
| 51 | impl IntoQueryKey<DefId> for ModDefId { | |
| 52 | #[inline(always)] | |
| 53 | fn into_query_key(self) -> DefId { | |
| 54 | self.to_def_id() | |
| 55 | } | |
| 56 | } | |
| 57 | ||
| 58 | impl IntoQueryKey<DefId> for LocalModDefId { | |
| 59 | #[inline(always)] | |
| 60 | fn into_query_key(self) -> DefId { | |
| 61 | self.to_def_id() | |
| 62 | } | |
| 63 | } | |
| 64 | ||
| 65 | impl IntoQueryKey<LocalDefId> for LocalModDefId { | |
| 66 | #[inline(always)] | |
| 67 | fn into_query_key(self) -> LocalDefId { | |
| 68 | self.into() | |
| 69 | } | |
| 70 | } |
compiler/rustc_middle/src/query/mod.rs+4-2| ... | ... | @@ -1,11 +1,12 @@ |
| 1 | 1 | use rustc_hir::def_id::LocalDefId; |
| 2 | 2 | |
| 3 | 3 | pub use self::caches::{DefIdCache, DefaultCache, QueryCache, SingleCache, VecCache}; |
| 4 | pub use self::into_query_key::IntoQueryKey; | |
| 4 | 5 | pub use self::job::{QueryJob, QueryJobId, QueryLatch, QueryWaiter}; |
| 5 | 6 | pub use self::keys::{AsLocalQueryKey, LocalCrate, QueryKey}; |
| 6 | 7 | pub use self::plumbing::{ |
| 7 | ActiveKeyStatus, CycleError, EnsureMode, IntoQueryParam, QueryMode, QueryState, QuerySystem, | |
| 8 | QueryVTable, TyCtxtAt, TyCtxtEnsureDone, TyCtxtEnsureOk, TyCtxtEnsureResult, | |
| 8 | ActiveKeyStatus, CycleError, EnsureMode, QueryMode, QueryState, QuerySystem, QueryVTable, | |
| 9 | TyCtxtAt, TyCtxtEnsureDone, TyCtxtEnsureOk, TyCtxtEnsureResult, | |
| 9 | 10 | }; |
| 10 | 11 | pub use self::stack::QueryStackFrame; |
| 11 | 12 | pub use crate::queries::Providers; |
| ... | ... | @@ -15,6 +16,7 @@ pub(crate) mod arena_cached; |
| 15 | 16 | mod caches; |
| 16 | 17 | pub mod erase; |
| 17 | 18 | pub(crate) mod inner; |
| 19 | mod into_query_key; | |
| 18 | 20 | mod job; |
| 19 | 21 | mod keys; |
| 20 | 22 | pub(crate) mod modifiers; |
compiler/rustc_middle/src/query/plumbing.rs+8-74| ... | ... | @@ -6,10 +6,7 @@ use rustc_data_structures::hash_table::HashTable; |
| 6 | 6 | use rustc_data_structures::sharded::Sharded; |
| 7 | 7 | use rustc_data_structures::sync::{AtomicU64, WorkerLocal}; |
| 8 | 8 | use rustc_errors::Diag; |
| 9 | use rustc_hir::def_id::{DefId, LocalDefId}; | |
| 10 | use rustc_hir::hir_id::OwnerId; | |
| 11 | 9 | use rustc_span::Span; |
| 12 | pub use sealed::IntoQueryParam; | |
| 13 | 10 | |
| 14 | 11 | use crate::dep_graph::{DepKind, DepNodeIndex, SerializedDepNodeIndex}; |
| 15 | 12 | use crate::ich::StableHashingContext; |
| ... | ... | @@ -271,8 +268,8 @@ impl<'tcx> TyCtxt<'tcx> { |
| 271 | 268 | } |
| 272 | 269 | |
| 273 | 270 | macro_rules! query_helper_param_ty { |
| 274 | (DefId) => { impl $crate::query::IntoQueryParam<DefId> }; | |
| 275 | (LocalDefId) => { impl $crate::query::IntoQueryParam<LocalDefId> }; | |
| 271 | (DefId) => { impl $crate::query::IntoQueryKey<DefId> }; | |
| 272 | (LocalDefId) => { impl $crate::query::IntoQueryKey<LocalDefId> }; | |
| 276 | 273 | ($K:ty) => { $K }; |
| 277 | 274 | } |
| 278 | 275 | |
| ... | ... | @@ -413,7 +410,7 @@ macro_rules! define_callbacks { |
| 413 | 410 | crate::query::inner::query_ensure_ok_or_done( |
| 414 | 411 | self.tcx, |
| 415 | 412 | &self.tcx.query_system.query_vtables.$name, |
| 416 | $crate::query::IntoQueryParam::into_query_param(key), | |
| 413 | $crate::query::IntoQueryKey::into_query_key(key), | |
| 417 | 414 | $crate::query::EnsureMode::Ok, |
| 418 | 415 | ) |
| 419 | 416 | } |
| ... | ... | @@ -433,7 +430,7 @@ macro_rules! define_callbacks { |
| 433 | 430 | crate::query::inner::query_ensure_result( |
| 434 | 431 | self.tcx, |
| 435 | 432 | &self.tcx.query_system.query_vtables.$name, |
| 436 | $crate::query::IntoQueryParam::into_query_param(key), | |
| 433 | $crate::query::IntoQueryKey::into_query_key(key), | |
| 437 | 434 | ) |
| 438 | 435 | } |
| 439 | 436 | )* |
| ... | ... | @@ -447,7 +444,7 @@ macro_rules! define_callbacks { |
| 447 | 444 | crate::query::inner::query_ensure_ok_or_done( |
| 448 | 445 | self.tcx, |
| 449 | 446 | &self.tcx.query_system.query_vtables.$name, |
| 450 | $crate::query::IntoQueryParam::into_query_param(key), | |
| 447 | $crate::query::IntoQueryKey::into_query_key(key), | |
| 451 | 448 | $crate::query::EnsureMode::Done, |
| 452 | 449 | ); |
| 453 | 450 | } |
| ... | ... | @@ -476,7 +473,7 @@ macro_rules! define_callbacks { |
| 476 | 473 | self.tcx, |
| 477 | 474 | self.span, |
| 478 | 475 | &self.tcx.query_system.query_vtables.$name, |
| 479 | $crate::query::IntoQueryParam::into_query_param(key), | |
| 476 | $crate::query::IntoQueryKey::into_query_key(key), | |
| 480 | 477 | )) |
| 481 | 478 | } |
| 482 | 479 | )* |
| ... | ... | @@ -484,13 +481,13 @@ macro_rules! define_callbacks { |
| 484 | 481 | |
| 485 | 482 | $( |
| 486 | 483 | #[cfg($feedable)] |
| 487 | impl<'tcx, K: $crate::query::IntoQueryParam<$name::Key<'tcx>> + Copy> | |
| 484 | impl<'tcx, K: $crate::query::IntoQueryKey<$name::Key<'tcx>> + Copy> | |
| 488 | 485 | TyCtxtFeed<'tcx, K> |
| 489 | 486 | { |
| 490 | 487 | $(#[$attr])* |
| 491 | 488 | #[inline(always)] |
| 492 | 489 | pub fn $name(self, value: $name::ProvidedValue<'tcx>) { |
| 493 | let key = self.key().into_query_param(); | |
| 490 | let key = self.key().into_query_key(); | |
| 494 | 491 | let erased_value = $name::provided_to_erased(self.tcx, value); |
| 495 | 492 | $crate::query::inner::query_feed( |
| 496 | 493 | self.tcx, |
| ... | ... | @@ -647,69 +644,6 @@ macro_rules! define_callbacks { |
| 647 | 644 | pub(crate) use define_callbacks; |
| 648 | 645 | pub(crate) use query_helper_param_ty; |
| 649 | 646 | |
| 650 | mod sealed { | |
| 651 | use rustc_hir::def_id::{LocalModDefId, ModDefId}; | |
| 652 | ||
| 653 | use super::{DefId, LocalDefId, OwnerId}; | |
| 654 | ||
| 655 | /// An analogue of the `Into` trait that's intended only for query parameters. | |
| 656 | /// | |
| 657 | /// This exists to allow queries to accept either `DefId` or `LocalDefId` while requiring that the | |
| 658 | /// user call `to_def_id` to convert between them everywhere else. | |
| 659 | pub trait IntoQueryParam<P> { | |
| 660 | fn into_query_param(self) -> P; | |
| 661 | } | |
| 662 | ||
| 663 | impl<P> IntoQueryParam<P> for P { | |
| 664 | #[inline(always)] | |
| 665 | fn into_query_param(self) -> P { | |
| 666 | self | |
| 667 | } | |
| 668 | } | |
| 669 | ||
| 670 | impl IntoQueryParam<LocalDefId> for OwnerId { | |
| 671 | #[inline(always)] | |
| 672 | fn into_query_param(self) -> LocalDefId { | |
| 673 | self.def_id | |
| 674 | } | |
| 675 | } | |
| 676 | ||
| 677 | impl IntoQueryParam<DefId> for LocalDefId { | |
| 678 | #[inline(always)] | |
| 679 | fn into_query_param(self) -> DefId { | |
| 680 | self.to_def_id() | |
| 681 | } | |
| 682 | } | |
| 683 | ||
| 684 | impl IntoQueryParam<DefId> for OwnerId { | |
| 685 | #[inline(always)] | |
| 686 | fn into_query_param(self) -> DefId { | |
| 687 | self.to_def_id() | |
| 688 | } | |
| 689 | } | |
| 690 | ||
| 691 | impl IntoQueryParam<DefId> for ModDefId { | |
| 692 | #[inline(always)] | |
| 693 | fn into_query_param(self) -> DefId { | |
| 694 | self.to_def_id() | |
| 695 | } | |
| 696 | } | |
| 697 | ||
| 698 | impl IntoQueryParam<DefId> for LocalModDefId { | |
| 699 | #[inline(always)] | |
| 700 | fn into_query_param(self) -> DefId { | |
| 701 | self.to_def_id() | |
| 702 | } | |
| 703 | } | |
| 704 | ||
| 705 | impl IntoQueryParam<LocalDefId> for LocalModDefId { | |
| 706 | #[inline(always)] | |
| 707 | fn into_query_param(self) -> LocalDefId { | |
| 708 | self.into() | |
| 709 | } | |
| 710 | } | |
| 711 | } | |
| 712 | ||
| 713 | 647 | #[cold] |
| 714 | 648 | pub(crate) fn default_query(name: &str, key: &dyn std::fmt::Debug) -> ! { |
| 715 | 649 | bug!( |
compiler/rustc_middle/src/ty/context.rs+10-12| ... | ... | @@ -61,7 +61,7 @@ use crate::middle::codegen_fn_attrs::{CodegenFnAttrs, TargetFeature}; |
| 61 | 61 | use crate::middle::resolve_bound_vars; |
| 62 | 62 | use crate::mir::interpret::{self, Allocation, ConstAllocation}; |
| 63 | 63 | use crate::mir::{Body, Local, Place, PlaceElem, ProjectionKind, Promoted}; |
| 64 | use crate::query::{IntoQueryParam, LocalCrate, Providers, QuerySystem, TyCtxtAt}; | |
| 64 | use crate::query::{IntoQueryKey, LocalCrate, Providers, QuerySystem, TyCtxtAt}; | |
| 65 | 65 | use crate::thir::Thir; |
| 66 | 66 | use crate::traits; |
| 67 | 67 | use crate::traits::solve::{ExternalConstraints, ExternalConstraintsData, PredefinedOpaques}; |
| ... | ... | @@ -1111,10 +1111,9 @@ impl<'tcx> TyCtxt<'tcx> { |
| 1111 | 1111 | } |
| 1112 | 1112 | |
| 1113 | 1113 | /// Check if the given `def_id` is a `type const` (mgca) |
| 1114 | pub fn is_type_const<I: Copy + IntoQueryParam<DefId>>(self, def_id: I) -> bool { | |
| 1115 | // No need to call the query directly in this case always false. | |
| 1116 | let def_kind = self.def_kind(def_id.into_query_param()); | |
| 1117 | match def_kind { | |
| 1114 | pub fn is_type_const(self, def_id: impl IntoQueryKey<DefId>) -> bool { | |
| 1115 | let def_id = def_id.into_query_key(); | |
| 1116 | match self.def_kind(def_id) { | |
| 1118 | 1117 | DefKind::Const { is_type_const } | DefKind::AssocConst { is_type_const } => { |
| 1119 | 1118 | is_type_const |
| 1120 | 1119 | } |
| ... | ... | @@ -1168,8 +1167,8 @@ impl<'tcx> TyCtxt<'tcx> { |
| 1168 | 1167 | self.features_query(()) |
| 1169 | 1168 | } |
| 1170 | 1169 | |
| 1171 | pub fn def_key(self, id: impl IntoQueryParam<DefId>) -> rustc_hir::definitions::DefKey { | |
| 1172 | let id = id.into_query_param(); | |
| 1170 | pub fn def_key(self, id: impl IntoQueryKey<DefId>) -> rustc_hir::definitions::DefKey { | |
| 1171 | let id = id.into_query_key(); | |
| 1173 | 1172 | // Accessing the DefKey is ok, since it is part of DefPathHash. |
| 1174 | 1173 | if let Some(id) = id.as_local() { |
| 1175 | 1174 | self.definitions_untracked().def_key(id) |
| ... | ... | @@ -2705,7 +2704,8 @@ impl<'tcx> TyCtxt<'tcx> { |
| 2705 | 2704 | self.sess.opts.unstable_opts.build_sdylib_interface |
| 2706 | 2705 | } |
| 2707 | 2706 | |
| 2708 | pub fn intrinsic(self, def_id: impl IntoQueryParam<DefId> + Copy) -> Option<ty::IntrinsicDef> { | |
| 2707 | pub fn intrinsic(self, def_id: impl IntoQueryKey<DefId>) -> Option<ty::IntrinsicDef> { | |
| 2708 | let def_id = def_id.into_query_key(); | |
| 2709 | 2709 | match self.def_kind(def_id) { |
| 2710 | 2710 | DefKind::Fn | DefKind::AssocFn => self.intrinsic_raw(def_id), |
| 2711 | 2711 | _ => None, |
| ... | ... | @@ -2774,10 +2774,8 @@ impl<'tcx> TyCtxt<'tcx> { |
| 2774 | 2774 | find_attr!(self, def_id, DoNotRecommend { .. }) |
| 2775 | 2775 | } |
| 2776 | 2776 | |
| 2777 | pub fn is_trivial_const<P>(self, def_id: P) -> bool | |
| 2778 | where | |
| 2779 | P: IntoQueryParam<DefId>, | |
| 2780 | { | |
| 2777 | pub fn is_trivial_const(self, def_id: impl IntoQueryKey<DefId>) -> bool { | |
| 2778 | let def_id = def_id.into_query_key(); | |
| 2781 | 2779 | self.trivial_const(def_id).is_some() |
| 2782 | 2780 | } |
| 2783 | 2781 |
compiler/rustc_middle/src/ty/context/impl_interner.rs-2| ... | ... | @@ -14,7 +14,6 @@ use rustc_type_ir::{CollectAndApply, Interner, TypeFoldable, search_graph}; |
| 14 | 14 | |
| 15 | 15 | use crate::dep_graph::{DepKind, DepNodeIndex}; |
| 16 | 16 | use crate::infer::canonical::CanonicalVarKinds; |
| 17 | use crate::query::IntoQueryParam; | |
| 18 | 17 | use crate::traits::cache::WithDepNode; |
| 19 | 18 | use crate::traits::solve::{ |
| 20 | 19 | self, CanonicalInput, ExternalConstraints, ExternalConstraintsData, QueryResult, inspect, |
| ... | ... | @@ -720,7 +719,6 @@ impl<'tcx> Interner for TyCtxt<'tcx> { |
| 720 | 719 | } |
| 721 | 720 | |
| 722 | 721 | fn item_name(self, id: DefId) -> Symbol { |
| 723 | let id = id.into_query_param(); | |
| 724 | 722 | self.opt_item_name(id).unwrap_or_else(|| { |
| 725 | 723 | bug!("item_name: no name for {:?}", self.def_path(id)); |
| 726 | 724 | }) |
compiler/rustc_middle/src/ty/mod.rs+28-22| ... | ... | @@ -117,7 +117,7 @@ use crate::ich::StableHashingContext; |
| 117 | 117 | use crate::metadata::{AmbigModChild, ModChild}; |
| 118 | 118 | use crate::middle::privacy::EffectiveVisibilities; |
| 119 | 119 | use crate::mir::{Body, CoroutineLayout, CoroutineSavedLocal, SourceInfo}; |
| 120 | use crate::query::{IntoQueryParam, Providers}; | |
| 120 | use crate::query::{IntoQueryKey, Providers}; | |
| 121 | 121 | use crate::ty; |
| 122 | 122 | use crate::ty::codec::{TyDecoder, TyEncoder}; |
| 123 | 123 | pub use crate::ty::diagnostics::*; |
| ... | ... | @@ -1031,12 +1031,14 @@ impl<'tcx> TypingEnv<'tcx> { |
| 1031 | 1031 | /// converted to use proper canonical inputs instead. |
| 1032 | 1032 | pub fn non_body_analysis( |
| 1033 | 1033 | tcx: TyCtxt<'tcx>, |
| 1034 | def_id: impl IntoQueryParam<DefId>, | |
| 1034 | def_id: impl IntoQueryKey<DefId>, | |
| 1035 | 1035 | ) -> TypingEnv<'tcx> { |
| 1036 | let def_id = def_id.into_query_key(); | |
| 1036 | 1037 | TypingEnv { typing_mode: TypingMode::non_body_analysis(), param_env: tcx.param_env(def_id) } |
| 1037 | 1038 | } |
| 1038 | 1039 | |
| 1039 | pub fn post_analysis(tcx: TyCtxt<'tcx>, def_id: impl IntoQueryParam<DefId>) -> TypingEnv<'tcx> { | |
| 1040 | pub fn post_analysis(tcx: TyCtxt<'tcx>, def_id: impl IntoQueryKey<DefId>) -> TypingEnv<'tcx> { | |
| 1041 | let def_id = def_id.into_query_key(); | |
| 1040 | 1042 | tcx.typing_env_normalized_for_post_analysis(def_id) |
| 1041 | 1043 | } |
| 1042 | 1044 | |
| ... | ... | @@ -1528,8 +1530,8 @@ impl<'tcx> TyCtxt<'tcx> { |
| 1528 | 1530 | } |
| 1529 | 1531 | |
| 1530 | 1532 | /// Look up the name of a definition across crates. This does not look at HIR. |
| 1531 | pub fn opt_item_name(self, def_id: impl IntoQueryParam<DefId>) -> Option<Symbol> { | |
| 1532 | let def_id = def_id.into_query_param(); | |
| 1533 | pub fn opt_item_name(self, def_id: impl IntoQueryKey<DefId>) -> Option<Symbol> { | |
| 1534 | let def_id = def_id.into_query_key(); | |
| 1533 | 1535 | if let Some(cnum) = def_id.as_crate_root() { |
| 1534 | 1536 | Some(self.crate_name(cnum)) |
| 1535 | 1537 | } else { |
| ... | ... | @@ -1549,8 +1551,8 @@ impl<'tcx> TyCtxt<'tcx> { |
| 1549 | 1551 | /// [`opt_item_name`] instead. |
| 1550 | 1552 | /// |
| 1551 | 1553 | /// [`opt_item_name`]: Self::opt_item_name |
| 1552 | pub fn item_name(self, id: impl IntoQueryParam<DefId>) -> Symbol { | |
| 1553 | let id = id.into_query_param(); | |
| 1554 | pub fn item_name(self, id: impl IntoQueryKey<DefId>) -> Symbol { | |
| 1555 | let id = id.into_query_key(); | |
| 1554 | 1556 | self.opt_item_name(id).unwrap_or_else(|| { |
| 1555 | 1557 | bug!("item_name: no name for {:?}", self.def_path(id)); |
| 1556 | 1558 | }) |
| ... | ... | @@ -1559,8 +1561,8 @@ impl<'tcx> TyCtxt<'tcx> { |
| 1559 | 1561 | /// Look up the name and span of a definition. |
| 1560 | 1562 | /// |
| 1561 | 1563 | /// See [`item_name`][Self::item_name] for more information. |
| 1562 | pub fn opt_item_ident(self, def_id: impl IntoQueryParam<DefId>) -> Option<Ident> { | |
| 1563 | let def_id = def_id.into_query_param(); | |
| 1564 | pub fn opt_item_ident(self, def_id: impl IntoQueryKey<DefId>) -> Option<Ident> { | |
| 1565 | let def_id = def_id.into_query_key(); | |
| 1564 | 1566 | let def = self.opt_item_name(def_id)?; |
| 1565 | 1567 | let span = self |
| 1566 | 1568 | .def_ident_span(def_id) |
| ... | ... | @@ -1571,8 +1573,8 @@ impl<'tcx> TyCtxt<'tcx> { |
| 1571 | 1573 | /// Look up the name and span of a definition. |
| 1572 | 1574 | /// |
| 1573 | 1575 | /// See [`item_name`][Self::item_name] for more information. |
| 1574 | pub fn item_ident(self, def_id: impl IntoQueryParam<DefId>) -> Ident { | |
| 1575 | let def_id = def_id.into_query_param(); | |
| 1576 | pub fn item_ident(self, def_id: impl IntoQueryKey<DefId>) -> Ident { | |
| 1577 | let def_id = def_id.into_query_key(); | |
| 1576 | 1578 | self.opt_item_ident(def_id).unwrap_or_else(|| { |
| 1577 | 1579 | bug!("item_ident: no name for {:?}", self.def_path(def_id)); |
| 1578 | 1580 | }) |
| ... | ... | @@ -1902,8 +1904,9 @@ impl<'tcx> TyCtxt<'tcx> { |
| 1902 | 1904 | } |
| 1903 | 1905 | |
| 1904 | 1906 | /// Returns the trait item that is implemented by the given item `DefId`. |
| 1905 | pub fn trait_item_of(self, def_id: impl IntoQueryParam<DefId>) -> Option<DefId> { | |
| 1906 | self.opt_associated_item(def_id.into_query_param())?.trait_item_def_id() | |
| 1907 | pub fn trait_item_of(self, def_id: impl IntoQueryKey<DefId>) -> Option<DefId> { | |
| 1908 | let def_id = def_id.into_query_key(); | |
| 1909 | self.opt_associated_item(def_id)?.trait_item_def_id() | |
| 1907 | 1910 | } |
| 1908 | 1911 | |
| 1909 | 1912 | /// If the given `DefId` is an associated item of a trait, |
| ... | ... | @@ -1915,8 +1918,8 @@ impl<'tcx> TyCtxt<'tcx> { |
| 1915 | 1918 | } |
| 1916 | 1919 | } |
| 1917 | 1920 | |
| 1918 | pub fn impl_is_of_trait(self, def_id: impl IntoQueryParam<DefId>) -> bool { | |
| 1919 | let def_id = def_id.into_query_param(); | |
| 1921 | pub fn impl_is_of_trait(self, def_id: impl IntoQueryKey<DefId>) -> bool { | |
| 1922 | let def_id = def_id.into_query_key(); | |
| 1920 | 1923 | let DefKind::Impl { of_trait } = self.def_kind(def_id) else { |
| 1921 | 1924 | panic!("expected Impl for {def_id:?}"); |
| 1922 | 1925 | }; |
| ... | ... | @@ -1950,15 +1953,17 @@ impl<'tcx> TyCtxt<'tcx> { |
| 1950 | 1953 | } |
| 1951 | 1954 | } |
| 1952 | 1955 | |
| 1953 | pub fn impl_polarity(self, def_id: impl IntoQueryParam<DefId>) -> ty::ImplPolarity { | |
| 1956 | pub fn impl_polarity(self, def_id: impl IntoQueryKey<DefId>) -> ty::ImplPolarity { | |
| 1957 | let def_id = def_id.into_query_key(); | |
| 1954 | 1958 | self.impl_trait_header(def_id).polarity |
| 1955 | 1959 | } |
| 1956 | 1960 | |
| 1957 | 1961 | /// Given an `impl_id`, return the trait it implements. |
| 1958 | 1962 | pub fn impl_trait_ref( |
| 1959 | 1963 | self, |
| 1960 | def_id: impl IntoQueryParam<DefId>, | |
| 1964 | def_id: impl IntoQueryKey<DefId>, | |
| 1961 | 1965 | ) -> ty::EarlyBinder<'tcx, ty::TraitRef<'tcx>> { |
| 1966 | let def_id = def_id.into_query_key(); | |
| 1962 | 1967 | self.impl_trait_header(def_id).trait_ref |
| 1963 | 1968 | } |
| 1964 | 1969 | |
| ... | ... | @@ -1966,21 +1971,22 @@ impl<'tcx> TyCtxt<'tcx> { |
| 1966 | 1971 | /// Returns `None` if it is an inherent impl. |
| 1967 | 1972 | pub fn impl_opt_trait_ref( |
| 1968 | 1973 | self, |
| 1969 | def_id: impl IntoQueryParam<DefId>, | |
| 1974 | def_id: impl IntoQueryKey<DefId>, | |
| 1970 | 1975 | ) -> Option<ty::EarlyBinder<'tcx, ty::TraitRef<'tcx>>> { |
| 1971 | let def_id = def_id.into_query_param(); | |
| 1976 | let def_id = def_id.into_query_key(); | |
| 1972 | 1977 | self.impl_is_of_trait(def_id).then(|| self.impl_trait_ref(def_id)) |
| 1973 | 1978 | } |
| 1974 | 1979 | |
| 1975 | 1980 | /// Given the `DefId` of an impl, returns the `DefId` of the trait it implements. |
| 1976 | pub fn impl_trait_id(self, def_id: impl IntoQueryParam<DefId>) -> DefId { | |
| 1981 | pub fn impl_trait_id(self, def_id: impl IntoQueryKey<DefId>) -> DefId { | |
| 1982 | let def_id = def_id.into_query_key(); | |
| 1977 | 1983 | self.impl_trait_ref(def_id).skip_binder().def_id |
| 1978 | 1984 | } |
| 1979 | 1985 | |
| 1980 | 1986 | /// Given the `DefId` of an impl, returns the `DefId` of the trait it implements. |
| 1981 | 1987 | /// Returns `None` if it is an inherent impl. |
| 1982 | pub fn impl_opt_trait_id(self, def_id: impl IntoQueryParam<DefId>) -> Option<DefId> { | |
| 1983 | let def_id = def_id.into_query_param(); | |
| 1988 | pub fn impl_opt_trait_id(self, def_id: impl IntoQueryKey<DefId>) -> Option<DefId> { | |
| 1989 | let def_id = def_id.into_query_key(); | |
| 1984 | 1990 | self.impl_is_of_trait(def_id).then(|| self.impl_trait_id(def_id)) |
| 1985 | 1991 | } |
| 1986 | 1992 |
compiler/rustc_middle/src/ty/print/pretty.rs+7-6| ... | ... | @@ -23,7 +23,7 @@ use smallvec::SmallVec; |
| 23 | 23 | // `pretty` is a separate module only for organization. |
| 24 | 24 | use super::*; |
| 25 | 25 | use crate::mir::interpret::{AllocRange, GlobalAlloc, Pointer, Provenance, Scalar}; |
| 26 | use crate::query::{IntoQueryParam, Providers}; | |
| 26 | use crate::query::{IntoQueryKey, Providers}; | |
| 27 | 27 | use crate::ty::{ |
| 28 | 28 | ConstInt, Expr, GenericArgKind, ParamConst, ScalarInt, Term, TermKind, TraitPredicate, |
| 29 | 29 | TypeFoldable, TypeSuperFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, |
| ... | ... | @@ -2180,17 +2180,18 @@ fn guess_def_namespace(tcx: TyCtxt<'_>, def_id: DefId) -> Namespace { |
| 2180 | 2180 | impl<'t> TyCtxt<'t> { |
| 2181 | 2181 | /// Returns a string identifying this `DefId`. This string is |
| 2182 | 2182 | /// suitable for user output. |
| 2183 | pub fn def_path_str(self, def_id: impl IntoQueryParam<DefId>) -> String { | |
| 2183 | pub fn def_path_str(self, def_id: impl IntoQueryKey<DefId>) -> String { | |
| 2184 | let def_id = def_id.into_query_key(); | |
| 2184 | 2185 | self.def_path_str_with_args(def_id, &[]) |
| 2185 | 2186 | } |
| 2186 | 2187 | |
| 2187 | 2188 | /// For this one we determine the appropriate namespace for the `def_id`. |
| 2188 | 2189 | pub fn def_path_str_with_args( |
| 2189 | 2190 | self, |
| 2190 | def_id: impl IntoQueryParam<DefId>, | |
| 2191 | def_id: impl IntoQueryKey<DefId>, | |
| 2191 | 2192 | args: &'t [GenericArg<'t>], |
| 2192 | 2193 | ) -> String { |
| 2193 | let def_id = def_id.into_query_param(); | |
| 2194 | let def_id = def_id.into_query_key(); | |
| 2194 | 2195 | let ns = guess_def_namespace(self, def_id); |
| 2195 | 2196 | debug!("def_path_str: def_id={:?}, ns={:?}", def_id, ns); |
| 2196 | 2197 | |
| ... | ... | @@ -2200,10 +2201,10 @@ impl<'t> TyCtxt<'t> { |
| 2200 | 2201 | /// For this one we always use value namespace. |
| 2201 | 2202 | pub fn value_path_str_with_args( |
| 2202 | 2203 | self, |
| 2203 | def_id: impl IntoQueryParam<DefId>, | |
| 2204 | def_id: impl IntoQueryKey<DefId>, | |
| 2204 | 2205 | args: &'t [GenericArg<'t>], |
| 2205 | 2206 | ) -> String { |
| 2206 | let def_id = def_id.into_query_param(); | |
| 2207 | let def_id = def_id.into_query_key(); | |
| 2207 | 2208 | let ns = Namespace::ValueNS; |
| 2208 | 2209 | debug!("value_path_str: def_id={:?}, ns={:?}", def_id, ns); |
| 2209 | 2210 |
compiler/rustc_session/src/cstore.rs+9-2| ... | ... | @@ -97,8 +97,15 @@ pub struct DllImport { |
| 97 | 97 | pub calling_convention: DllCallingConvention, |
| 98 | 98 | /// Span of import's "extern" declaration; used for diagnostics. |
| 99 | 99 | pub span: Span, |
| 100 | /// Is this for a function (rather than a static variable). | |
| 101 | pub is_fn: bool, | |
| 100 | pub symbol_type: DllImportSymbolType, | |
| 101 | pub size: rustc_abi::Size, | |
| 102 | } | |
| 103 | ||
| 104 | #[derive(Copy, Clone, Debug, Encodable, Decodable, HashStable_Generic, PartialEq)] | |
| 105 | pub enum DllImportSymbolType { | |
| 106 | Function, | |
| 107 | Static, | |
| 108 | ThreadLocal, | |
| 102 | 109 | } |
| 103 | 110 | |
| 104 | 111 | impl DllImport { |
tests/run-make/raw-dylib-elf/library.c+5| ... | ... | @@ -1,3 +1,8 @@ |
| 1 | int global_variable = 3; | |
| 2 | __thread int tls_variable = 33; | |
| 3 | const long const_array[] = {795, 906}; | |
| 4 | const char *const_string = "sums of three cubes"; | |
| 5 | ||
| 1 | 6 | int this_is_a_library_function() { |
| 2 | 7 | return 42; |
| 3 | 8 | } |
tests/run-make/raw-dylib-elf/main.rs+20-2| ... | ... | @@ -1,11 +1,29 @@ |
| 1 | 1 | #![feature(raw_dylib_elf)] |
| 2 | #![feature(thread_local)] | |
| 2 | 3 | #![allow(incomplete_features)] |
| 3 | 4 | |
| 5 | use std::ffi::{CStr, c_char, c_int, c_long}; | |
| 6 | ||
| 4 | 7 | #[link(name = "library", kind = "raw-dylib")] |
| 5 | 8 | unsafe extern "C" { |
| 6 | safe fn this_is_a_library_function() -> core::ffi::c_int; | |
| 9 | safe fn this_is_a_library_function() -> c_int; | |
| 10 | static mut global_variable: c_int; | |
| 11 | #[thread_local] | |
| 12 | static mut tls_variable: c_int; | |
| 13 | safe static const_array: [c_long; 2]; | |
| 14 | safe static const_string: *const c_char; | |
| 7 | 15 | } |
| 8 | 16 | |
| 9 | 17 | fn main() { |
| 10 | println!("{}", this_is_a_library_function()) | |
| 18 | unsafe { | |
| 19 | println!( | |
| 20 | "{} {} {} {} {} {}", | |
| 21 | this_is_a_library_function(), | |
| 22 | global_variable, | |
| 23 | tls_variable, | |
| 24 | const_array[0], | |
| 25 | const_array[1], | |
| 26 | CStr::from_ptr(const_string).to_str().unwrap(), | |
| 27 | ); | |
| 28 | } | |
| 11 | 29 | } |
tests/run-make/raw-dylib-elf/output.txt+1-1| ... | ... | @@ -1 +1 @@ |
| 1 | 42 | |
| 1 | 42 3 33 795 906 sums of three cubes |
tests/run-make/raw-dylib-elf/rmake.rs+19-11| ... | ... | @@ -11,19 +11,27 @@ |
| 11 | 11 | use run_make_support::{build_native_dynamic_lib, cwd, diff, run, rustc}; |
| 12 | 12 | |
| 13 | 13 | fn main() { |
| 14 | // We compile the binary without having the library present. | |
| 14 | // We compile the binaries without having the library present with different relocation | |
| 15 | // models. | |
| 15 | 16 | // We also set the rpath to the current directory so we can pick up the library at runtime. |
| 16 | rustc() | |
| 17 | .crate_type("bin") | |
| 18 | .input("main.rs") | |
| 19 | .arg(&format!("-Wl,-rpath={}", cwd().display())) | |
| 20 | .run(); | |
| 17 | let relocation_models = ["static", "pic", "pie"]; | |
| 18 | for relocation_model in relocation_models { | |
| 19 | rustc() | |
| 20 | .crate_type("bin") | |
| 21 | .input("main.rs") | |
| 22 | .arg(&format!("-Wl,-rpath={}", cwd().display())) | |
| 23 | .arg(&format!("-Crelocation-model={}", relocation_model)) | |
| 24 | .output(&format!("main-{}", relocation_model)) | |
| 25 | .run(); | |
| 26 | } | |
| 21 | 27 | |
| 22 | // Now, *after* building the binary, we build the library... | |
| 28 | // Now, *after* building the binaries, we build the library... | |
| 23 | 29 | build_native_dynamic_lib("library"); |
| 24 | 30 | |
| 25 | // ... and run with this library, ensuring it was linked correctly at runtime. | |
| 26 | let output = run("main").stdout_utf8(); | |
| 27 | ||
| 28 | diff().expected_file("output.txt").actual_text("actual", output).run(); | |
| 31 | for relocation_model in relocation_models { | |
| 32 | // ... and run with this library, ensuring it was linked correctly at runtime. | |
| 33 | // The output here should be the same regardless of the relocation model. | |
| 34 | let output = run(&format!("main-{}", relocation_model)).stdout_utf8(); | |
| 35 | diff().expected_file("output.txt").actual_text("actual", output).run(); | |
| 36 | } | |
| 29 | 37 | } |
tests/ui/issues/issue-23891.rs deleted-11| ... | ... | @@ -1,11 +0,0 @@ |
| 1 | //@ run-pass | |
| 2 | macro_rules! id { | |
| 3 | ($s: pat) => ($s); | |
| 4 | } | |
| 5 | ||
| 6 | fn main() { | |
| 7 | match (Some(123), Some(456)) { | |
| 8 | (id!(Some(a)), _) | (_, id!(Some(a))) => println!("{}", a), | |
| 9 | _ => (), | |
| 10 | } | |
| 11 | } |
tests/ui/macros/macro-in-or-pattern.rs created+14| ... | ... | @@ -0,0 +1,14 @@ |
| 1 | // Regression test for https://github.com/rust-lang/rust/issues/23891 | |
| 2 | // Tests that a macro expanding to a pattern works correctly inside of or patterns | |
| 3 | ||
| 4 | //@ run-pass | |
| 5 | macro_rules! id { | |
| 6 | ($s: pat) => ($s); | |
| 7 | } | |
| 8 | ||
| 9 | fn main() { | |
| 10 | match (Some(123), Some(456)) { | |
| 11 | (id!(Some(a)), _) | (_, id!(Some(a))) => println!("{}", a), | |
| 12 | _ => (), | |
| 13 | } | |
| 14 | } |