diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/librustdoc/html/render/write_shared.rs | 18 | ||||
| -rw-r--r-- | src/librustdoc/html/render/write_shared/tests.rs | 6 | ||||
| -rw-r--r-- | src/tools/miri/src/machine.rs | 46 | ||||
| -rw-r--r-- | src/tools/miri/tests/panic/target_feature_wasm.rs (renamed from src/tools/miri/tests/pass/function_calls/target_feature_wasm.rs) | 4 |
4 files changed, 59 insertions, 15 deletions
diff --git a/src/librustdoc/html/render/write_shared.rs b/src/librustdoc/html/render/write_shared.rs index a18b7a252a4..60dc142b9ff 100644 --- a/src/librustdoc/html/render/write_shared.rs +++ b/src/librustdoc/html/render/write_shared.rs @@ -75,11 +75,11 @@ pub(crate) fn write_shared( let crate_name = krate.name(cx.tcx()); let crate_name = crate_name.as_str(); // rand let crate_name_json = OrderedJson::serialize(crate_name).unwrap(); // "rand" - let external_crates = hack_get_external_crate_names(&cx.dst)?; + let external_crates = hack_get_external_crate_names(&cx.dst, &cx.shared.resource_suffix)?; let info = CrateInfo { src_files_js: SourcesPart::get(cx, &crate_name_json)?, search_index_js: SearchIndexPart::get(index, &cx.shared.resource_suffix)?, - all_crates: AllCratesPart::get(crate_name_json.clone())?, + all_crates: AllCratesPart::get(crate_name_json.clone(), &cx.shared.resource_suffix)?, crates_index: CratesIndexPart::get(&crate_name, &external_crates)?, trait_impl: TraitAliasPart::get(cx, &crate_name_json)?, type_impl: TypeAliasPart::get(cx, krate, &crate_name_json)?, @@ -291,10 +291,13 @@ impl AllCratesPart { SortedTemplate::from_before_after("window.ALL_CRATES = [", "];") } - fn get(crate_name_json: OrderedJson) -> Result<PartsAndLocations<Self>, Error> { + fn get( + crate_name_json: OrderedJson, + resource_suffix: &str, + ) -> Result<PartsAndLocations<Self>, Error> { // external hack_get_external_crate_names not needed here, because // there's no way that we write the search index but not crates.js - let path = PathBuf::from("crates.js"); + let path = suffix_path("crates.js", resource_suffix); Ok(PartsAndLocations::with(path, crate_name_json)) } } @@ -305,8 +308,11 @@ impl AllCratesPart { /// /// This is to match the current behavior of rustdoc, which allows you to get all crates /// on the index page, even if --enable-index-page is only passed to the last crate. -fn hack_get_external_crate_names(doc_root: &Path) -> Result<Vec<String>, Error> { - let path = doc_root.join("crates.js"); +fn hack_get_external_crate_names( + doc_root: &Path, + resource_suffix: &str, +) -> Result<Vec<String>, Error> { + let path = doc_root.join(suffix_path("crates.js", resource_suffix)); let Ok(content) = fs::read_to_string(&path) else { // they didn't emit invocation specific, so we just say there were no crates return Ok(Vec::default()); diff --git a/src/librustdoc/html/render/write_shared/tests.rs b/src/librustdoc/html/render/write_shared/tests.rs index 4d1874b7df5..e282cd99e43 100644 --- a/src/librustdoc/html/render/write_shared/tests.rs +++ b/src/librustdoc/html/render/write_shared/tests.rs @@ -6,10 +6,10 @@ use crate::html::render::write_shared::*; fn hack_external_crate_names() { let path = tempfile::TempDir::new().unwrap(); let path = path.path(); - let crates = hack_get_external_crate_names(&path).unwrap(); + let crates = hack_get_external_crate_names(&path, "").unwrap(); assert!(crates.is_empty()); fs::write(path.join("crates.js"), r#"window.ALL_CRATES = ["a","b","c"];"#).unwrap(); - let crates = hack_get_external_crate_names(&path).unwrap(); + let crates = hack_get_external_crate_names(&path, "").unwrap(); assert_eq!(crates, ["a".to_string(), "b".to_string(), "c".to_string()]); } @@ -60,7 +60,7 @@ fn all_crates_template() { #[test] fn all_crates_parts() { - let parts = AllCratesPart::get(OrderedJson::serialize("crate").unwrap()).unwrap(); + let parts = AllCratesPart::get(OrderedJson::serialize("crate").unwrap(), "").unwrap(); assert_eq!(&parts.parts[0].0, Path::new("crates.js")); assert_eq!(&parts.parts[0].1.to_string(), r#""crate""#); } diff --git a/src/tools/miri/src/machine.rs b/src/tools/miri/src/machine.rs index a7493d48d6a..264b7b269de 100644 --- a/src/tools/miri/src/machine.rs +++ b/src/tools/miri/src/machine.rs @@ -947,15 +947,47 @@ impl<'tcx> Machine<'tcx> for MiriMachine<'tcx> { } #[inline(always)] - fn enforce_abi(_ecx: &MiriInterpCx<'tcx>) -> bool { - true - } - - #[inline(always)] fn ignore_optional_overflow_checks(ecx: &MiriInterpCx<'tcx>) -> bool { !ecx.tcx.sess.overflow_checks() } + fn check_fn_target_features( + ecx: &MiriInterpCx<'tcx>, + instance: ty::Instance<'tcx>, + ) -> InterpResult<'tcx> { + let attrs = ecx.tcx.codegen_fn_attrs(instance.def_id()); + if attrs + .target_features + .iter() + .any(|feature| !ecx.tcx.sess.target_features.contains(&feature.name)) + { + let unavailable = attrs + .target_features + .iter() + .filter(|&feature| { + !feature.implied && !ecx.tcx.sess.target_features.contains(&feature.name) + }) + .fold(String::new(), |mut s, feature| { + if !s.is_empty() { + s.push_str(", "); + } + s.push_str(feature.name.as_str()); + s + }); + let msg = format!( + "calling a function that requires unavailable target features: {unavailable}" + ); + // On WASM, this is not UB, but instead gets rejected during validation of the module + // (see #84988). + if ecx.tcx.sess.target.is_like_wasm { + throw_machine_stop!(TerminationInfo::Abort(msg)); + } else { + throw_ub_format!("{msg}"); + } + } + Ok(()) + } + #[inline(always)] fn find_mir_or_eval_fn( ecx: &mut MiriInterpCx<'tcx>, @@ -1060,6 +1092,10 @@ impl<'tcx> Machine<'tcx> for MiriMachine<'tcx> { ecx.generate_nan(inputs) } + fn ub_checks(ecx: &InterpCx<'tcx, Self>) -> InterpResult<'tcx, bool> { + Ok(ecx.tcx.sess.ub_checks()) + } + fn thread_local_static_pointer( ecx: &mut MiriInterpCx<'tcx>, def_id: DefId, diff --git a/src/tools/miri/tests/pass/function_calls/target_feature_wasm.rs b/src/tools/miri/tests/panic/target_feature_wasm.rs index 5056f32de44..c67d2983f78 100644 --- a/src/tools/miri/tests/pass/function_calls/target_feature_wasm.rs +++ b/src/tools/miri/tests/panic/target_feature_wasm.rs @@ -2,7 +2,9 @@ //@compile-flags: -C target-feature=-simd128 fn main() { - // Calling functions with `#[target_feature]` is not unsound on WASM, see #84988 + // Calling functions with `#[target_feature]` is not unsound on WASM, see #84988. + // But if the compiler actually uses the target feature, it will lead to an error when the module is loaded. + // We emulate this with an "unsupported" error. assert!(!cfg!(target_feature = "simd128")); simd128_fn(); } |
