diff --git a/compiler/rustc_codegen_llvm/src/context.rs b/compiler/rustc_codegen_llvm/src/context.rs index dd3f39eceadb6..1fd9f9e811671 100644 --- a/compiler/rustc_codegen_llvm/src/context.rs +++ b/compiler/rustc_codegen_llvm/src/context.rs @@ -1000,8 +1000,10 @@ impl<'ll> CodegenCx<'ll, '_> { ifn!("llvm.is.constant.i64", fn(t_i64) -> i1); ifn!("llvm.is.constant.i128", fn(t_i128) -> i1); ifn!("llvm.is.constant.isize", fn(t_isize) -> i1); + ifn!("llvm.is.constant.f16", fn(t_f16) -> i1); ifn!("llvm.is.constant.f32", fn(t_f32) -> i1); ifn!("llvm.is.constant.f64", fn(t_f64) -> i1); + ifn!("llvm.is.constant.f128", fn(t_f128) -> i1); ifn!("llvm.is.constant.ptr", fn(ptr) -> i1); ifn!("llvm.expect.i1", fn(i1, i1) -> i1); diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs index f5558723d11bf..abfe38d4c0cc6 100644 --- a/compiler/rustc_codegen_llvm/src/intrinsic.rs +++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs @@ -192,14 +192,22 @@ impl<'ll, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'_, 'll, 'tcx> { } sym::is_val_statically_known => { let intrinsic_type = args[0].layout.immediate_llvm_type(self.cx); - match self.type_kind(intrinsic_type) { - TypeKind::Pointer | TypeKind::Integer | TypeKind::Float | TypeKind::Double => { - self.call_intrinsic( - &format!("llvm.is.constant.{:?}", intrinsic_type), - &[args[0].immediate()], - ) + let kind = self.type_kind(intrinsic_type); + let intrinsic_name = match kind { + TypeKind::Pointer | TypeKind::Integer => { + Some(format!("llvm.is.constant.{intrinsic_type:?}")) } - _ => self.const_bool(false), + // LLVM float types' intrinsic names differ from their type names. + TypeKind::Half => Some(format!("llvm.is.constant.f16")), + TypeKind::Float => Some(format!("llvm.is.constant.f32")), + TypeKind::Double => Some(format!("llvm.is.constant.f64")), + TypeKind::FP128 => Some(format!("llvm.is.constant.f128")), + _ => None, + }; + if let Some(intrinsic_name) = intrinsic_name { + self.call_intrinsic(&intrinsic_name, &[args[0].immediate()]) + } else { + self.const_bool(false) } } sym::unlikely => self diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index 3b71e2f19b168..b3cf73bac1aa6 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -3448,6 +3448,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { trait_missing_method: bool, ) { let mut alt_rcvr_sugg = false; + let mut trait_in_other_version_found = false; if let (SelfSource::MethodCall(rcvr), false) = (source, unsatisfied_bounds) { debug!( "suggest_traits_to_import: span={:?}, item_name={:?}, rcvr_ty={:?}, rcvr={:?}", @@ -3489,8 +3490,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // self types and rely on the suggestion to `use` the trait from // `suggest_valid_traits`. let did = Some(pick.item.container_id(self.tcx)); - let skip = skippable.contains(&did); - if pick.autoderefs == 0 && !skip { + if skippable.contains(&did) { + continue; + } + trait_in_other_version_found = self + .detect_and_explain_multiple_crate_versions( + err, + pick.item.def_id, + rcvr.hir_id, + *rcvr_ty, + ); + if pick.autoderefs == 0 && !trait_in_other_version_found { err.span_label( pick.item.ident(self.tcx).span, format!("the method is available for `{rcvr_ty}` here"), @@ -3675,7 +3685,32 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } } - if self.suggest_valid_traits(err, item_name, valid_out_of_scope_traits, true) { + + if let SelfSource::QPath(ty) = source + && !valid_out_of_scope_traits.is_empty() + && let hir::TyKind::Path(path) = ty.kind + && let hir::QPath::Resolved(_, path) = path + && let Some(def_id) = path.res.opt_def_id() + && let Some(assoc) = self + .tcx + .associated_items(valid_out_of_scope_traits[0]) + .filter_by_name_unhygienic(item_name.name) + .next() + { + // See if the `Type::function(val)` where `function` wasn't found corresponds to a + // `Trait` that is imported directly, but `Type` came from a different version of the + // same crate. + let rcvr_ty = self.tcx.type_of(def_id).instantiate_identity(); + trait_in_other_version_found = self.detect_and_explain_multiple_crate_versions( + err, + assoc.def_id, + ty.hir_id, + rcvr_ty, + ); + } + if !trait_in_other_version_found + && self.suggest_valid_traits(err, item_name, valid_out_of_scope_traits, true) + { return; } @@ -4040,6 +4075,62 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } + fn detect_and_explain_multiple_crate_versions( + &self, + err: &mut Diag<'_>, + item_def_id: DefId, + hir_id: hir::HirId, + rcvr_ty: Ty<'_>, + ) -> bool { + let hir_id = self.tcx.parent_hir_id(hir_id); + let Some(traits) = self.tcx.in_scope_traits(hir_id) else { return false }; + if traits.is_empty() { + return false; + } + let trait_def_id = self.tcx.parent(item_def_id); + let krate = self.tcx.crate_name(trait_def_id.krate); + let name = self.tcx.item_name(trait_def_id); + let candidates: Vec<_> = traits + .iter() + .filter(|c| { + c.def_id.krate != trait_def_id.krate + && self.tcx.crate_name(c.def_id.krate) == krate + && self.tcx.item_name(c.def_id) == name + }) + .map(|c| (c.def_id, c.import_ids.get(0).cloned())) + .collect(); + if candidates.is_empty() { + return false; + } + let item_span = self.tcx.def_span(item_def_id); + let msg = format!( + "there are multiple different versions of crate `{krate}` in the dependency graph", + ); + let trait_span = self.tcx.def_span(trait_def_id); + let mut multi_span: MultiSpan = trait_span.into(); + multi_span.push_span_label(trait_span, format!("this is the trait that is needed")); + let descr = self.tcx.associated_item(item_def_id).descr(); + multi_span + .push_span_label(item_span, format!("the {descr} is available for `{rcvr_ty}` here")); + for (def_id, import_def_id) in candidates { + if let Some(import_def_id) = import_def_id { + multi_span.push_span_label( + self.tcx.def_span(import_def_id), + format!( + "`{name}` imported here doesn't correspond to the right version of crate \ + `{krate}`", + ), + ); + } + multi_span.push_span_label( + self.tcx.def_span(def_id), + format!("this is the trait that was imported"), + ); + } + err.span_note(multi_span, msg); + true + } + /// issue #102320, for `unwrap_or` with closure as argument, suggest `unwrap_or_else` /// FIXME: currently not working for suggesting `map_or_else`, see #102408 pub(crate) fn suggest_else_fn_with_closure( diff --git a/compiler/rustc_middle/src/mir/pretty.rs b/compiler/rustc_middle/src/mir/pretty.rs index f2d8781413096..5dd0e69cf1fe6 100644 --- a/compiler/rustc_middle/src/mir/pretty.rs +++ b/compiler/rustc_middle/src/mir/pretty.rs @@ -1418,21 +1418,19 @@ pub fn write_allocations<'tcx>( alloc.inner().provenance().ptrs().values().map(|p| p.alloc_id()) } - fn alloc_ids_from_const_val(val: ConstValue<'_>) -> impl Iterator + '_ { + fn alloc_id_from_const_val(val: ConstValue<'_>) -> Option { match val { - ConstValue::Scalar(interpret::Scalar::Ptr(ptr, _)) => { - Either::Left(std::iter::once(ptr.provenance.alloc_id())) - } - ConstValue::Scalar(interpret::Scalar::Int { .. }) => Either::Right(std::iter::empty()), - ConstValue::ZeroSized => Either::Right(std::iter::empty()), + ConstValue::Scalar(interpret::Scalar::Ptr(ptr, _)) => Some(ptr.provenance.alloc_id()), + ConstValue::Scalar(interpret::Scalar::Int { .. }) => None, + ConstValue::ZeroSized => None, ConstValue::Slice { .. } => { // `u8`/`str` slices, shouldn't contain pointers that we want to print. - Either::Right(std::iter::empty()) + None } ConstValue::Indirect { alloc_id, .. } => { // FIXME: we don't actually want to print all of these, since some are printed nicely directly as values inline in MIR. // Really we'd want `pretty_print_const_value` to decide which allocations to print, instead of having a separate visitor. - Either::Left(std::iter::once(alloc_id)) + Some(alloc_id) } } } @@ -1443,7 +1441,9 @@ pub fn write_allocations<'tcx>( match c.const_ { Const::Ty(_, _) | Const::Unevaluated(..) => {} Const::Val(val, _) => { - self.0.extend(alloc_ids_from_const_val(val)); + if let Some(id) = alloc_id_from_const_val(val) { + self.0.insert(id); + } } } } diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs index 326a0e4e35ce8..04769bf79c9b5 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs @@ -1689,11 +1689,11 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { err.highlighted_span_help( span, vec![ - StringPart::normal("you have ".to_string()), + StringPart::normal("there are ".to_string()), StringPart::highlighted("multiple different versions".to_string()), StringPart::normal(" of crate `".to_string()), StringPart::highlighted(format!("{name}")), - StringPart::normal("` in your dependency graph".to_string()), + StringPart::normal("` the your dependency graph".to_string()), ], ); let candidates = if impl_candidates.is_empty() { diff --git a/tests/codegen/is_val_statically_known.rs b/tests/codegen/is_val_statically_known.rs index 6af4f353a481c..fe432d3bcc4de 100644 --- a/tests/codegen/is_val_statically_known.rs +++ b/tests/codegen/is_val_statically_known.rs @@ -1,6 +1,7 @@ //@ compile-flags: --crate-type=lib -Zmerge-functions=disabled -O #![feature(core_intrinsics)] +#![feature(f16, f128)] use std::intrinsics::is_val_statically_known; @@ -49,7 +50,7 @@ pub fn _bool_false(b: bool) -> i32 { #[inline] pub fn _iref(a: &u8) -> i32 { - if unsafe { is_val_statically_known(a) } { 5 } else { 4 } + if is_val_statically_known(a) { 5 } else { 4 } } // CHECK-LABEL: @_iref_borrow( @@ -68,7 +69,7 @@ pub fn _iref_arg(a: &u8) -> i32 { #[inline] pub fn _slice_ref(a: &[u8]) -> i32 { - if unsafe { is_val_statically_known(a) } { 7 } else { 6 } + if is_val_statically_known(a) { 7 } else { 6 } } // CHECK-LABEL: @_slice_ref_borrow( @@ -84,3 +85,79 @@ pub fn _slice_ref_arg(a: &[u8]) -> i32 { // CHECK: ret i32 6 _slice_ref(a) } + +#[inline] +pub fn _f16(a: f16) -> i32 { + if is_val_statically_known(a) { 1 } else { 0 } +} + +// CHECK-LABEL: @_f16_true( +#[no_mangle] +pub fn _f16_true() -> i32 { + // CHECK: ret i32 1 + _f16(1.0) +} + +// CHECK-LABEL: @_f16_false( +#[no_mangle] +pub fn _f16_false(a: f16) -> i32 { + // CHECK: ret i32 0 + _f16(a) +} + +#[inline] +pub fn _f32(a: f32) -> i32 { + if is_val_statically_known(a) { 1 } else { 0 } +} + +// CHECK-LABEL: @_f32_true( +#[no_mangle] +pub fn _f32_true() -> i32 { + // CHECK: ret i32 1 + _f32(1.0) +} + +// CHECK-LABEL: @_f32_false( +#[no_mangle] +pub fn _f32_false(a: f32) -> i32 { + // CHECK: ret i32 0 + _f32(a) +} + +#[inline] +pub fn _f64(a: f64) -> i32 { + if is_val_statically_known(a) { 1 } else { 0 } +} + +// CHECK-LABEL: @_f64_true( +#[no_mangle] +pub fn _f64_true() -> i32 { + // CHECK: ret i32 1 + _f64(1.0) +} + +// CHECK-LABEL: @_f64_false( +#[no_mangle] +pub fn _f64_false(a: f64) -> i32 { + // CHECK: ret i32 0 + _f64(a) +} + +#[inline] +pub fn _f128(a: f128) -> i32 { + if is_val_statically_known(a) { 1 } else { 0 } +} + +// CHECK-LABEL: @_f128_true( +#[no_mangle] +pub fn _f128_true() -> i32 { + // CHECK: ret i32 1 + _f128(1.0) +} + +// CHECK-LABEL: @_f128_false( +#[no_mangle] +pub fn _f128_false(a: f128) -> i32 { + // CHECK: ret i32 0 + _f128(a) +} diff --git a/tests/debuginfo/drop-locations.rs b/tests/debuginfo/drop-locations.rs index 0777313d19804..2db087dda7967 100644 --- a/tests/debuginfo/drop-locations.rs +++ b/tests/debuginfo/drop-locations.rs @@ -1,4 +1,3 @@ -//@ ignore-windows //@ ignore-android //@ min-lldb-version: 310 //@ ignore-test: #128971 diff --git a/tests/debuginfo/embedded-visualizer.rs b/tests/debuginfo/embedded-visualizer.rs index 69afd273f7735..959dbba7fd73c 100644 --- a/tests/debuginfo/embedded-visualizer.rs +++ b/tests/debuginfo/embedded-visualizer.rs @@ -1,7 +1,7 @@ //@ compile-flags:-g //@ min-gdb-version: 8.1 //@ ignore-lldb -//@ ignore-windows-gnu // emit_debug_gdb_scripts is disabled on Windows +//@ ignore-windows-gnu: #128981 // === CDB TESTS ================================================================================== diff --git a/tests/debuginfo/empty-string.rs b/tests/debuginfo/empty-string.rs index 35b68ed91c0fc..eac3448bfd510 100644 --- a/tests/debuginfo/empty-string.rs +++ b/tests/debuginfo/empty-string.rs @@ -1,4 +1,4 @@ -//@ ignore-windows failing on win32 bot +//@ ignore-windows-gnu: #128981 //@ ignore-android: FIXME(#10381) //@ compile-flags:-g //@ min-gdb-version: 8.1 diff --git a/tests/debuginfo/issue-12886.rs b/tests/debuginfo/issue-12886.rs index c6cf0dd4e05e3..48250e885374d 100644 --- a/tests/debuginfo/issue-12886.rs +++ b/tests/debuginfo/issue-12886.rs @@ -1,4 +1,3 @@ -//@ ignore-windows failing on 64-bit bots FIXME #17638 //@ ignore-lldb //@ ignore-aarch64 @@ -6,7 +5,7 @@ // gdb-command:run // gdb-command:next -// gdb-check:[...]24[...]let s = Some(5).unwrap(); // #break +// gdb-check:[...]23[...]let s = Some(5).unwrap(); // #break // gdb-command:continue #![feature(omit_gdb_pretty_printer_section)] diff --git a/tests/debuginfo/macro-stepping.rs b/tests/debuginfo/macro-stepping.rs index 3edac3c7832f9..35bb6de4fef38 100644 --- a/tests/debuginfo/macro-stepping.rs +++ b/tests/debuginfo/macro-stepping.rs @@ -1,4 +1,3 @@ -//@ ignore-windows //@ ignore-android //@ ignore-aarch64 //@ min-lldb-version: 1800 diff --git a/tests/debuginfo/numeric-types.rs b/tests/debuginfo/numeric-types.rs index 98bc31e88557a..6f45b69e5e34c 100644 --- a/tests/debuginfo/numeric-types.rs +++ b/tests/debuginfo/numeric-types.rs @@ -1,7 +1,7 @@ //@ compile-flags:-g //@ min-gdb-version: 8.1 -//@ ignore-windows-gnu // emit_debug_gdb_scripts is disabled on Windows +//@ ignore-windows-gnu: #128981 // Tests the visualizations for `NonZero`, `Wrapping` and // `Atomic{Bool,I8,I16,I32,I64,Isize,U8,U16,U32,U64,Usize}` located in `libcore.natvis`. diff --git a/tests/debuginfo/pretty-huge-vec.rs b/tests/debuginfo/pretty-huge-vec.rs index dcf3521175d4c..b88e5db1acb8c 100644 --- a/tests/debuginfo/pretty-huge-vec.rs +++ b/tests/debuginfo/pretty-huge-vec.rs @@ -1,4 +1,4 @@ -//@ ignore-windows failing on win32 bot +//@ ignore-windows-gnu: #128981 //@ ignore-android: FIXME(#10381) //@ compile-flags:-g //@ min-gdb-version: 8.1 diff --git a/tests/debuginfo/pretty-slices.rs b/tests/debuginfo/pretty-slices.rs index 9defa344be03e..44335f5c83b3f 100644 --- a/tests/debuginfo/pretty-slices.rs +++ b/tests/debuginfo/pretty-slices.rs @@ -1,5 +1,5 @@ //@ ignore-android: FIXME(#10381) -//@ ignore-windows +//@ ignore-windows-gnu: #128981 //@ compile-flags:-g // gdb-command: run diff --git a/tests/debuginfo/pretty-std-collections.rs b/tests/debuginfo/pretty-std-collections.rs index 3d5a30d19a9ce..3ec00886e2f40 100644 --- a/tests/debuginfo/pretty-std-collections.rs +++ b/tests/debuginfo/pretty-std-collections.rs @@ -1,4 +1,3 @@ -//@ ignore-windows failing on win32 bot //@ ignore-android: FIXME(#10381) //@ ignore-windows-gnu: #128981 //@ compile-flags:-g diff --git a/tests/debuginfo/pretty-uninitialized-vec.rs b/tests/debuginfo/pretty-uninitialized-vec.rs index 5206ff23fd5ba..ddb751161d8ce 100644 --- a/tests/debuginfo/pretty-uninitialized-vec.rs +++ b/tests/debuginfo/pretty-uninitialized-vec.rs @@ -1,4 +1,4 @@ -//@ ignore-windows failing on win32 bot +//@ ignore-windows-gnu: #128981 //@ ignore-android: FIXME(#10381) //@ compile-flags:-g //@ min-gdb-version: 8.1 diff --git a/tests/debuginfo/thread-names.rs b/tests/debuginfo/thread-names.rs index 6b3b0c7f4b231..265b9271cf306 100644 --- a/tests/debuginfo/thread-names.rs +++ b/tests/debuginfo/thread-names.rs @@ -4,7 +4,7 @@ //@[macos] only-macos //@[win] only-windows //@ ignore-sgx -//@ ignore-windows-gnu +//@ ignore-windows-gnu: gdb on windows-gnu does not print thread names // === GDB TESTS ================================================================================== // diff --git a/tests/run-make/crate-loading/multiple-dep-versions-1.rs b/tests/run-make/crate-loading/multiple-dep-versions-1.rs index 2d35163382916..d81462504dd57 100644 --- a/tests/run-make/crate-loading/multiple-dep-versions-1.rs +++ b/tests/run-make/crate-loading/multiple-dep-versions-1.rs @@ -1,6 +1,12 @@ #![crate_name = "dependency"] #![crate_type = "rlib"] -pub struct Type; -pub trait Trait {} -impl Trait for Type {} +pub struct Type(pub i32); +pub trait Trait { + fn foo(&self); + fn bar(); +} +impl Trait for Type { + fn foo(&self) {} + fn bar() {} +} pub fn do_something(_: X) {} diff --git a/tests/run-make/crate-loading/multiple-dep-versions-2.rs b/tests/run-make/crate-loading/multiple-dep-versions-2.rs index a5df3dc61eda5..0a566fe2c6051 100644 --- a/tests/run-make/crate-loading/multiple-dep-versions-2.rs +++ b/tests/run-make/crate-loading/multiple-dep-versions-2.rs @@ -1,6 +1,12 @@ #![crate_name = "dependency"] #![crate_type = "rlib"] -pub struct Type(pub i32); -pub trait Trait {} -impl Trait for Type {} +pub struct Type; +pub trait Trait { + fn foo(&self); + fn bar(); +} +impl Trait for Type { + fn foo(&self) {} + fn bar() {} +} pub fn do_something(_: X) {} diff --git a/tests/run-make/crate-loading/multiple-dep-versions-3.rs b/tests/run-make/crate-loading/multiple-dep-versions-3.rs new file mode 100644 index 0000000000000..07d888e9f1034 --- /dev/null +++ b/tests/run-make/crate-loading/multiple-dep-versions-3.rs @@ -0,0 +1,5 @@ +#![crate_name = "foo"] +#![crate_type = "rlib"] + +extern crate dependency; +pub use dependency::Type; diff --git a/tests/run-make/crate-loading/multiple-dep-versions.rs b/tests/run-make/crate-loading/multiple-dep-versions.rs index 5a6cb03aaa4a7..8ef042bf41842 100644 --- a/tests/run-make/crate-loading/multiple-dep-versions.rs +++ b/tests/run-make/crate-loading/multiple-dep-versions.rs @@ -1,8 +1,10 @@ extern crate dep_2_reexport; extern crate dependency; -use dep_2_reexport::do_something; -use dependency::Type; +use dep_2_reexport::Type; +use dependency::{do_something, Trait}; fn main() { do_something(Type); + Type.foo(); + Type::bar(); } diff --git a/tests/run-make/crate-loading/rmake.rs b/tests/run-make/crate-loading/rmake.rs index d7abd5872c94a..13585edf6ccbe 100644 --- a/tests/run-make/crate-loading/rmake.rs +++ b/tests/run-make/crate-loading/rmake.rs @@ -1,26 +1,100 @@ //@ only-linux //@ ignore-wasm32 //@ ignore-wasm64 +// ignore-tidy-linelength use run_make_support::{rust_lib_name, rustc}; fn main() { rustc().input("multiple-dep-versions-1.rs").run(); rustc().input("multiple-dep-versions-2.rs").extra_filename("2").metadata("2").run(); + rustc() + .input("multiple-dep-versions-3.rs") + .extern_("dependency", rust_lib_name("dependency2")) + .run(); rustc() .input("multiple-dep-versions.rs") .extern_("dependency", rust_lib_name("dependency")) - .extern_("dep_2_reexport", rust_lib_name("dependency2")) + .extern_("dep_2_reexport", rust_lib_name("foo")) .run_fail() .assert_stderr_contains( - "you have multiple different versions of crate `dependency` in your dependency graph", + r#"error[E0277]: the trait bound `dep_2_reexport::Type: Trait` is not satisfied + --> multiple-dep-versions.rs:7:18 + | +7 | do_something(Type); + | ------------ ^^^^ the trait `Trait` is not implemented for `dep_2_reexport::Type` + | | + | required by a bound introduced by this call + | +help: there are multiple different versions of crate `dependency` the your dependency graph + --> multiple-dep-versions.rs:1:1 + | +1 | extern crate dep_2_reexport; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one version of crate `dependency` is used here, as a dependency of crate `foo` +2 | extern crate dependency; + | ^^^^^^^^^^^^^^^^^^^^^^^^ one version of crate `dependency` is used here, as a direct dependency of the current crate"#, + ) + .assert_stderr_contains( + r#" +3 | pub struct Type(pub i32); + | ^^^^^^^^^^^^^^^ this type implements the required trait +4 | pub trait Trait { + | --------------- this is the required trait"#, + ) + .assert_stderr_contains( + r#" +3 | pub struct Type; + | ^^^^^^^^^^^^^^^ this type doesn't implement the required trait"#, + ) + .assert_stderr_contains( + r#" +error[E0599]: no method named `foo` found for struct `dep_2_reexport::Type` in the current scope + --> multiple-dep-versions.rs:8:10 + | +8 | Type.foo(); + | ^^^ method not found in `Type` + | +note: there are multiple different versions of crate `dependency` in the dependency graph"#, + ) + .assert_stderr_contains( + r#" +4 | pub trait Trait { + | ^^^^^^^^^^^^^^^ this is the trait that is needed +5 | fn foo(&self); + | -------------- the method is available for `dep_2_reexport::Type` here + | + ::: multiple-dep-versions.rs:4:32 + | +4 | use dependency::{do_something, Trait}; + | ----- `Trait` imported here doesn't correspond to the right version of crate `dependency`"#, ) .assert_stderr_contains( - "two types coming from two different versions of the same crate are different types \ - even if they look the same", + r#" +4 | pub trait Trait { + | --------------- this is the trait that was imported"#, ) - .assert_stderr_contains("this type doesn't implement the required trait") - .assert_stderr_contains("this type implements the required trait") - .assert_stderr_contains("this is the required trait"); + .assert_stderr_contains( + r#" +error[E0599]: no function or associated item named `bar` found for struct `dep_2_reexport::Type` in the current scope + --> multiple-dep-versions.rs:9:11 + | +9 | Type::bar(); + | ^^^ function or associated item not found in `Type` + | +note: there are multiple different versions of crate `dependency` in the dependency graph"#, + ) + .assert_stderr_contains( + r#" +4 | pub trait Trait { + | ^^^^^^^^^^^^^^^ this is the trait that is needed +5 | fn foo(&self); +6 | fn bar(); + | --------- the associated function is available for `dep_2_reexport::Type` here + | + ::: multiple-dep-versions.rs:4:32 + | +4 | use dependency::{do_something, Trait}; + | ----- `Trait` imported here doesn't correspond to the right version of crate `dependency`"#, + ); } diff --git a/tests/run-make/dump-ice-to-disk/rmake.rs b/tests/run-make/dump-ice-to-disk/rmake.rs index 48b4071e06541..08767246b90d0 100644 --- a/tests/run-make/dump-ice-to-disk/rmake.rs +++ b/tests/run-make/dump-ice-to-disk/rmake.rs @@ -14,11 +14,14 @@ //! that `RUSTC_ICE_PATH` takes precedence and no ICE dump is emitted under `METRICS_PATH`. //! //! See . - -//@ ignore-windows -// FIXME(#128911): @jieyouxu: This test is sometimes for whatever forsaken reason flakey in -// `i686-mingw`, and I cannot reproduce it locally. The error messages upon assertion failure in -// this test is intentionally extremely verbose to aid debugging that issue. +//! +//! # Test history +//! +//! - The previous rmake.rs iteration of this test was flakey for unknown reason on `i686-mingw` +//! *specifically*, so assertion failures in this test was made extremely verbose to help +//! diagnose why the ICE messages was different *specifically* on `i686-mingw`. +//! - An attempt is made to re-enable this test on `i686-mingw` (by removing `ignore-windows`). If +//! this test is still flakey, please restore the `ignore-windows` directive. use std::cell::OnceCell; use std::path::{Path, PathBuf}; diff --git a/tests/run-make/libtest-json/rmake.rs b/tests/run-make/libtest-json/rmake.rs index acbd88dc46cb9..c31f4a79b641f 100644 --- a/tests/run-make/libtest-json/rmake.rs +++ b/tests/run-make/libtest-json/rmake.rs @@ -3,7 +3,7 @@ //@ ignore-cross-compile //@ needs-unwind (test file contains #[should_panic] test) -use run_make_support::{cmd, diff, python_command, rustc}; +use run_make_support::{cmd, diff, rustc, serde_json}; fn main() { rustc().arg("--test").input("f.rs").run(); @@ -21,7 +21,18 @@ fn run_tests(extra_args: &[&str], expected_file: &str) { .run_fail(); let test_stdout = &cmd_out.stdout_utf8(); - python_command().arg("validate_json.py").stdin(test_stdout).run(); + // Verify that the test process output is JSON Lines, i.e. each line is valid JSON. + for (line, n) in test_stdout.lines().zip(1..) { + if let Err(e) = serde_json::from_str::(line) { + panic!( + "could not parse JSON on line {n}: {e}\n\ + \n\ + === STDOUT ===\n\ + {test_stdout}\ + ==============" + ); + } + } diff() .expected_file(expected_file) diff --git a/tests/run-make/libtest-json/validate_json.py b/tests/run-make/libtest-json/validate_json.py deleted file mode 100755 index 657f732f2bffd..0000000000000 --- a/tests/run-make/libtest-json/validate_json.py +++ /dev/null @@ -1,8 +0,0 @@ -#!/usr/bin/env python - -import sys -import json - -# Try to decode line in order to ensure it is a valid JSON document -for line in sys.stdin: - json.loads(line)