diff --git a/compiler/rustc_ast_lowering/src/delegation.rs b/compiler/rustc_ast_lowering/src/delegation.rs index 27f8a6eae02a9..d9dd0b3bca534 100644 --- a/compiler/rustc_ast_lowering/src/delegation.rs +++ b/compiler/rustc_ast_lowering/src/delegation.rs @@ -67,7 +67,9 @@ impl<'hir> LoweringContext<'_, 'hir> { return false; }; if let Some(local_sig_id) = sig_id.as_local() { - self.resolver.delegation_fn_sigs[&local_sig_id].has_self + // The value may be missing due to recursive delegation. + // Error will be emmited later during HIR ty lowering. + self.resolver.delegation_fn_sigs.get(&local_sig_id).map_or(false, |sig| sig.has_self) } else { match self.tcx.def_kind(sig_id) { DefKind::Fn => false, diff --git a/compiler/rustc_const_eval/src/interpret/cast.rs b/compiler/rustc_const_eval/src/interpret/cast.rs index 19414c72c6a42..0a45bbb3edb2f 100644 --- a/compiler/rustc_const_eval/src/interpret/cast.rs +++ b/compiler/rustc_const_eval/src/interpret/cast.rs @@ -274,9 +274,13 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { // Let's make sure v is sign-extended *if* it has a signed type. let signed = src_layout.abi.is_signed(); // Also asserts that abi is `Scalar`. - let v = scalar.to_bits(src_layout.size)?; - let v = if signed { self.sign_extend(v, src_layout) } else { v }; - trace!("cast_from_scalar: {}, {} -> {}", v, src_layout.ty, cast_ty); + let v = match src_layout.ty.kind() { + Uint(_) | RawPtr(..) | FnPtr(..) => scalar.to_uint(src_layout.size)?, + Int(_) => scalar.to_int(src_layout.size)? as u128, // we will cast back to `i128` below if the sign matters + Bool => scalar.to_bool()?.into(), + Char => scalar.to_char()?.into(), + _ => span_bug!(self.cur_span(), "invalid int-like cast from {}", src_layout.ty), + }; Ok(match *cast_ty.kind() { // int -> int diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics.rs b/compiler/rustc_const_eval/src/interpret/intrinsics.rs index dac5c10addc28..7f16d441606e9 100644 --- a/compiler/rustc_const_eval/src/interpret/intrinsics.rs +++ b/compiler/rustc_const_eval/src/interpret/intrinsics.rs @@ -197,7 +197,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { // rotate_right: (X << ((BW - S) % BW)) | (X >> (S % BW)) let layout_val = self.layout_of(instance_args.type_at(0))?; let val = self.read_scalar(&args[0])?; - let val_bits = val.to_bits(layout_val.size)?; + let val_bits = val.to_bits(layout_val.size)?; // sign is ignored here let layout_raw_shift = self.layout_of(self.tcx.types.u32)?; let raw_shift = self.read_scalar(&args[1])?; @@ -484,7 +484,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { ret_layout: TyAndLayout<'tcx>, ) -> InterpResult<'tcx, Scalar> { assert!(layout.ty.is_integral(), "invalid type for numeric intrinsic: {}", layout.ty); - let bits = val.to_bits(layout.size)?; + let bits = val.to_bits(layout.size)?; // these operations all ignore the sign let extra = 128 - u128::from(layout.size.bits()); let bits_out = match name { sym::ctpop => u128::from(bits.count_ones()), @@ -519,6 +519,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { // `x % y != 0` or `y == 0` or `x == T::MIN && y == -1`. // First, check x % y != 0 (or if that computation overflows). let rem = self.binary_op(BinOp::Rem, a, b)?; + // sign does not matter for 0 test, so `to_bits` is fine if rem.to_scalar().to_bits(a.layout.size)? != 0 { throw_ub_custom!( fluent::const_eval_exact_div_has_remainder, @@ -545,22 +546,19 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { self.binary_op(mir_op.wrapping_to_overflowing().unwrap(), l, r)?.to_scalar_pair(); Ok(if overflowed.to_bool()? { let size = l.layout.size; - let num_bits = size.bits(); if l.layout.abi.is_signed() { // For signed ints the saturated value depends on the sign of the first // term since the sign of the second term can be inferred from this and // the fact that the operation has overflowed (if either is 0 no // overflow can occur) - let first_term: u128 = l.to_scalar().to_bits(l.layout.size)?; - let first_term_positive = first_term & (1 << (num_bits - 1)) == 0; - if first_term_positive { + let first_term: i128 = l.to_scalar().to_int(l.layout.size)?; + if first_term >= 0 { // Negative overflow not possible since the positive first term // can only increase an (in range) negative term for addition - // or corresponding negated positive term for subtraction + // or corresponding negated positive term for subtraction. Scalar::from_int(size.signed_int_max(), size) } else { - // Positive overflow not possible for similar reason - // max negative + // Positive overflow not possible for similar reason. Scalar::from_int(size.signed_int_min(), size) } } else { diff --git a/compiler/rustc_const_eval/src/interpret/operator.rs b/compiler/rustc_const_eval/src/interpret/operator.rs index c821c98073d72..a6eef9f5662ca 100644 --- a/compiler/rustc_const_eval/src/interpret/operator.rs +++ b/compiler/rustc_const_eval/src/interpret/operator.rs @@ -437,23 +437,24 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { }; Ok(ImmTy::from_scalar(res, layout)) } - _ if layout.ty.is_integral() => { - let val = val.to_scalar(); - let val = val.to_bits(layout.size)?; + ty::Int(..) => { + let val = val.to_scalar().to_int(layout.size)?; let res = match un_op { - Not => self.truncate(!val, layout), // bitwise negation, then truncate - Neg => { - // arithmetic negation - assert!(layout.abi.is_signed()); - let val = self.sign_extend(val, layout) as i128; - let res = val.wrapping_neg(); - let res = res as u128; - // Truncate to target type. - self.truncate(res, layout) - } + Not => !val, + Neg => val.wrapping_neg(), _ => span_bug!(self.cur_span(), "Invalid integer op {:?}", un_op), }; - Ok(ImmTy::from_uint(res, layout)) + let res = ScalarInt::truncate_from_int(res, layout.size).0; + Ok(ImmTy::from_scalar(res.into(), layout)) + } + ty::Uint(..) => { + let val = val.to_scalar().to_uint(layout.size)?; + let res = match un_op { + Not => !val, + _ => span_bug!(self.cur_span(), "Invalid unsigned integer op {:?}", un_op), + }; + let res = ScalarInt::truncate_from_uint(res, layout.size).0; + Ok(ImmTy::from_scalar(res.into(), layout)) } ty::RawPtr(..) => { assert_eq!(un_op, PtrMetadata); diff --git a/compiler/rustc_middle/src/ty/consts/int.rs b/compiler/rustc_middle/src/ty/consts/int.rs index 52320dd141baf..13691b61941bd 100644 --- a/compiler/rustc_middle/src/ty/consts/int.rs +++ b/compiler/rustc_middle/src/ty/consts/int.rs @@ -209,8 +209,8 @@ impl ScalarInt { #[inline] pub fn try_from_uint(i: impl Into, size: Size) -> Option { - let data = i.into(); - if size.truncate(data) == data { Some(Self::raw(data, size)) } else { None } + let (r, overflow) = Self::truncate_from_uint(i, size); + if overflow { None } else { Some(r) } } /// Returns the truncated result, and whether truncation changed the value. @@ -223,20 +223,15 @@ impl ScalarInt { #[inline] pub fn try_from_int(i: impl Into, size: Size) -> Option { - let i = i.into(); - // `into` performed sign extension, we have to truncate - let truncated = size.truncate(i as u128); - if size.sign_extend(truncated) as i128 == i { - Some(Self::raw(truncated, size)) - } else { - None - } + let (r, overflow) = Self::truncate_from_int(i, size); + if overflow { None } else { Some(r) } } /// Returns the truncated result, and whether truncation changed the value. #[inline] pub fn truncate_from_int(i: impl Into, size: Size) -> (Self, bool) { let data = i.into(); + // `into` performed sign extension, we have to truncate let r = Self::raw(size.truncate(data as u128), size); (r, size.sign_extend(r.data) as i128 != data) } diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 4a935f4a64a0f..4306a8035241a 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -2563,7 +2563,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> { let InferOk { obligations, .. } = self .infcx .at(&cause, obligation.param_env) - .eq(DefineOpaqueTypes::Yes, placeholder_obligation_trait_ref, impl_trait_ref) + .eq(DefineOpaqueTypes::No, placeholder_obligation_trait_ref, impl_trait_ref) .map_err(|e| { debug!("match_impl: failed eq_trait_refs due to `{}`", e.to_string(self.tcx())) })?; diff --git a/src/tools/miri/tests/fail/validity/invalid_char_cast.rs b/src/tools/miri/tests/fail/validity/invalid_char_cast.rs new file mode 100644 index 0000000000000..6a590dc7ba10b --- /dev/null +++ b/src/tools/miri/tests/fail/validity/invalid_char_cast.rs @@ -0,0 +1,21 @@ +// Make sure we find these even with many checks disabled. +//@compile-flags: -Zmiri-disable-alignment-check -Zmiri-disable-stacked-borrows -Zmiri-disable-validation +#![feature(core_intrinsics)] +#![feature(custom_mir)] + +use std::intrinsics::mir::*; + +#[custom_mir(dialect = "runtime", phase = "optimized")] +fn cast(ptr: *const char) -> u32 { + mir! { + { + RET = *ptr as u32; //~ERROR: interpreting an invalid 32-bit value as a char + Return() + } + } +} + +pub fn main() { + let v = u32::MAX; + cast(&v as *const u32 as *const char); +} diff --git a/src/tools/miri/tests/fail/validity/invalid_char_cast.stderr b/src/tools/miri/tests/fail/validity/invalid_char_cast.stderr new file mode 100644 index 0000000000000..1b5c838cf463c --- /dev/null +++ b/src/tools/miri/tests/fail/validity/invalid_char_cast.stderr @@ -0,0 +1,20 @@ +error: Undefined Behavior: interpreting an invalid 32-bit value as a char: $HEX + --> $DIR/invalid_char_cast.rs:LL:CC + | +LL | RET = *ptr as u32; + | ^^^^^^^^^^^^^^^^^ interpreting an invalid 32-bit value as a char: $HEX + | + = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior + = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information + = note: BACKTRACE: + = note: inside `cast` at $DIR/invalid_char_cast.rs:LL:CC +note: inside `main` + --> $DIR/invalid_char_cast.rs:LL:CC + | +LL | cast(&v as *const u32 as *const char); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to 1 previous error + diff --git a/src/tools/miri/tests/fail/validity/invalid_char_match.rs b/src/tools/miri/tests/fail/validity/invalid_char_match.rs new file mode 100644 index 0000000000000..6c2e65b2bb744 --- /dev/null +++ b/src/tools/miri/tests/fail/validity/invalid_char_match.rs @@ -0,0 +1,26 @@ +// Make sure we find these even with many checks disabled. +//@compile-flags: -Zmiri-disable-alignment-check -Zmiri-disable-stacked-borrows -Zmiri-disable-validation +#![feature(core_intrinsics)] +#![feature(custom_mir)] + +use std::intrinsics::mir::*; + +#[custom_mir(dialect = "runtime", phase = "optimized")] +fn switch_int(ptr: *const char) { + mir! { + { + match *ptr { //~ERROR: interpreting an invalid 32-bit value as a char + '0' => ret, + _ => ret, + } + } + ret = { + Return() + } + } +} + +pub fn main() { + let v = u32::MAX; + switch_int(&v as *const u32 as *const char); +} diff --git a/src/tools/miri/tests/fail/validity/invalid_char_match.stderr b/src/tools/miri/tests/fail/validity/invalid_char_match.stderr new file mode 100644 index 0000000000000..7706ed97316ce --- /dev/null +++ b/src/tools/miri/tests/fail/validity/invalid_char_match.stderr @@ -0,0 +1,23 @@ +error: Undefined Behavior: interpreting an invalid 32-bit value as a char: $HEX + --> $DIR/invalid_char_match.rs:LL:CC + | +LL | / match *ptr { +LL | | '0' => ret, +LL | | _ => ret, +LL | | } + | |_____________^ interpreting an invalid 32-bit value as a char: $HEX + | + = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior + = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information + = note: BACKTRACE: + = note: inside `switch_int` at $DIR/invalid_char_match.rs:LL:CC +note: inside `main` + --> $DIR/invalid_char_match.rs:LL:CC + | +LL | switch_int(&v as *const u32 as *const char); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to 1 previous error + diff --git a/src/tools/miri/tests/fail/validity/invalid_enum_cast.rs b/src/tools/miri/tests/fail/validity/invalid_enum_cast.rs new file mode 100644 index 0000000000000..faf5fb699a6a1 --- /dev/null +++ b/src/tools/miri/tests/fail/validity/invalid_enum_cast.rs @@ -0,0 +1,15 @@ +// Make sure we find these even with many checks disabled. +//@compile-flags: -Zmiri-disable-alignment-check -Zmiri-disable-stacked-borrows -Zmiri-disable-validation + +#[derive(Copy, Clone)] +#[allow(unused)] +enum E {A, B, C } + +fn cast(ptr: *const E) { unsafe { + let _val = *ptr as u32; //~ERROR: enum value has invalid tag +}} + +pub fn main() { + let v = u32::MAX; + cast(&v as *const u32 as *const E); +} diff --git a/src/tools/miri/tests/fail/validity/invalid_enum_cast.stderr b/src/tools/miri/tests/fail/validity/invalid_enum_cast.stderr new file mode 100644 index 0000000000000..d898887604581 --- /dev/null +++ b/src/tools/miri/tests/fail/validity/invalid_enum_cast.stderr @@ -0,0 +1,20 @@ +error: Undefined Behavior: enum value has invalid tag: 0xff + --> $DIR/invalid_enum_cast.rs:LL:CC + | +LL | let _val = *ptr as u32; + | ^^^^^^^^^^^ enum value has invalid tag: 0xff + | + = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior + = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information + = note: BACKTRACE: + = note: inside `cast` at $DIR/invalid_enum_cast.rs:LL:CC +note: inside `main` + --> $DIR/invalid_enum_cast.rs:LL:CC + | +LL | cast(&v as *const u32 as *const E); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to 1 previous error + diff --git a/src/tools/run-make-support/src/lib.rs b/src/tools/run-make-support/src/lib.rs index bf74d94f91188..ee764b983d056 100644 --- a/src/tools/run-make-support/src/lib.rs +++ b/src/tools/run-make-support/src/lib.rs @@ -82,6 +82,11 @@ pub fn htmldocck() -> Command { python } +/// Returns the path for a local test file. +pub fn path>(p: P) -> PathBuf { + cwd().join(p.as_ref()) +} + /// Path to the root rust-lang/rust source checkout. pub fn source_root() -> PathBuf { env_var("SOURCE_ROOT").into() diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt index babf1abbe64ac..b07e012a1b8af 100644 --- a/src/tools/tidy/src/allowed_run_make_makefiles.txt +++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt @@ -144,7 +144,6 @@ run-make/mismatching-target-triples/Makefile run-make/missing-crate-dependency/Makefile run-make/mixing-libs/Makefile run-make/msvc-opt-minsize/Makefile -run-make/multiple-emits/Makefile run-make/native-link-modifier-bundle/Makefile run-make/native-link-modifier-verbatim-linker/Makefile run-make/native-link-modifier-verbatim-rustc/Makefile diff --git a/tests/crashes/124347.rs b/tests/crashes/124347.rs deleted file mode 100644 index d2bc555fe1c7b..0000000000000 --- a/tests/crashes/124347.rs +++ /dev/null @@ -1,4 +0,0 @@ -//@ known-bug: #124347 -trait Trait: ToReuse { - reuse Trait::lolno { &self.0 }; -} diff --git a/tests/run-make/multiple-emits/Makefile b/tests/run-make/multiple-emits/Makefile deleted file mode 100644 index d1f297644854f..0000000000000 --- a/tests/run-make/multiple-emits/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -include ../tools.mk - -all: - $(RUSTC) foo.rs --emit=asm,llvm-ir -o $(TMPDIR)/out 2>&1 - rm $(TMPDIR)/out.ll $(TMPDIR)/out.s - $(RUSTC) foo.rs --emit=asm,llvm-ir -o $(TMPDIR)/out2.ext 2>&1 - rm $(TMPDIR)/out2.ll $(TMPDIR)/out2.s diff --git a/tests/run-make/multiple-emits/rmake.rs b/tests/run-make/multiple-emits/rmake.rs new file mode 100644 index 0000000000000..67c0ebb9864a5 --- /dev/null +++ b/tests/run-make/multiple-emits/rmake.rs @@ -0,0 +1,13 @@ +use run_make_support::{cwd, path, rustc}; + +fn main() { + rustc().input("foo.rs").emit("asm,llvm-ir").output("out").run(); + + assert!(path("out.ll").is_file()); + assert!(path("out.s").is_file()); + + rustc().input("foo.rs").emit("asm,llvm-ir").output("out2.ext").run(); + + assert!(path("out2.ll").is_file()); + assert!(path("out2.s").is_file()); +} diff --git a/tests/ui/consts/const-eval/ub-invalid-values.rs b/tests/ui/consts/const-eval/ub-invalid-values.rs new file mode 100644 index 0000000000000..1724a88dd3d9a --- /dev/null +++ b/tests/ui/consts/const-eval/ub-invalid-values.rs @@ -0,0 +1,11 @@ +const fn bool_cast(ptr: *const bool) { unsafe { + let _val = *ptr as u32; //~ERROR: evaluation of constant value failed + //~^ interpreting an invalid 8-bit value as a bool +}} + +const _: () = { + let v = 3_u8; + bool_cast(&v as *const u8 as *const bool); +}; + +fn main() {} diff --git a/tests/ui/consts/const-eval/ub-invalid-values.stderr b/tests/ui/consts/const-eval/ub-invalid-values.stderr new file mode 100644 index 0000000000000..edf72f731e5a0 --- /dev/null +++ b/tests/ui/consts/const-eval/ub-invalid-values.stderr @@ -0,0 +1,20 @@ +error[E0080]: evaluation of constant value failed + --> $DIR/ub-invalid-values.rs:2:16 + | +LL | let _val = *ptr as u32; + | ^^^^^^^^^^^ interpreting an invalid 8-bit value as a bool: 0x03 + | +note: inside `bool_cast` + --> $DIR/ub-invalid-values.rs:2:16 + | +LL | let _val = *ptr as u32; + | ^^^^^^^^^^^ +note: inside `_` + --> $DIR/ub-invalid-values.rs:8:5 + | +LL | bool_cast(&v as *const u8 as *const bool); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0080`. diff --git a/tests/ui/delegation/ice-issue-124347.rs b/tests/ui/delegation/ice-issue-124347.rs new file mode 100644 index 0000000000000..82a96055099c7 --- /dev/null +++ b/tests/ui/delegation/ice-issue-124347.rs @@ -0,0 +1,12 @@ +#![feature(fn_delegation)] +#![allow(incomplete_features)] + +trait Trait { + reuse Trait::foo { &self.0 } + //~^ ERROR recursive delegation is not supported yet +} + +reuse foo; +//~^ ERROR recursive delegation is not supported yet + +fn main() {} diff --git a/tests/ui/delegation/ice-issue-124347.stderr b/tests/ui/delegation/ice-issue-124347.stderr new file mode 100644 index 0000000000000..5a3f4525d29e5 --- /dev/null +++ b/tests/ui/delegation/ice-issue-124347.stderr @@ -0,0 +1,14 @@ +error: recursive delegation is not supported yet + --> $DIR/ice-issue-124347.rs:5:18 + | +LL | reuse Trait::foo { &self.0 } + | ^^^ callee defined here + +error: recursive delegation is not supported yet + --> $DIR/ice-issue-124347.rs:9:7 + | +LL | reuse foo; + | ^^^ callee defined here + +error: aborting due to 2 previous errors + diff --git a/tests/ui/impl-trait/equality.rs b/tests/ui/impl-trait/equality.rs index 952f81f19784c..828b5aac896be 100644 --- a/tests/ui/impl-trait/equality.rs +++ b/tests/ui/impl-trait/equality.rs @@ -22,7 +22,7 @@ fn sum_to(n: u32) -> impl Foo { 0 } else { n + sum_to(n - 1) - //~^ ERROR cannot satisfy `>::Output == i32` + //~^ ERROR cannot add `impl Foo` to `u32` } } @@ -32,15 +32,12 @@ trait Leak: Sized { } impl Leak for T { default type T = (); - default fn leak(self) -> Self::T { - panic!() - } + default fn leak(self) -> Self::T { panic!() } } impl Leak for i32 { type T = i32; - fn leak(self) -> i32 { - self - } + fn leak(self) -> i32 { self } } -fn main() {} +fn main() { +} diff --git a/tests/ui/impl-trait/equality.stderr b/tests/ui/impl-trait/equality.stderr index c9ba1a5ba32d1..69f4cbbbf4294 100644 --- a/tests/ui/impl-trait/equality.stderr +++ b/tests/ui/impl-trait/equality.stderr @@ -22,13 +22,20 @@ help: change the type of the numeric literal from `u32` to `i32` LL | 0_i32 | ~~~ -error[E0284]: type annotations needed: cannot satisfy `>::Output == i32` +error[E0277]: cannot add `impl Foo` to `u32` --> $DIR/equality.rs:24:11 | LL | n + sum_to(n - 1) - | ^ cannot satisfy `>::Output == i32` + | ^ no implementation for `u32 + impl Foo` + | + = help: the trait `Add` is not implemented for `u32` + = help: the following other types implement trait `Add`: + <&'a u32 as Add> + <&u32 as Add<&u32>> + > + error: aborting due to 2 previous errors; 1 warning emitted -Some errors have detailed explanations: E0284, E0308. -For more information about an error, try `rustc --explain E0284`. +Some errors have detailed explanations: E0277, E0308. +For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui/impl-trait/nested_impl_trait.stderr b/tests/ui/impl-trait/nested_impl_trait.stderr index f7c708a1dfae8..1f9a2a5e9d600 100644 --- a/tests/ui/impl-trait/nested_impl_trait.stderr +++ b/tests/ui/impl-trait/nested_impl_trait.stderr @@ -46,23 +46,19 @@ error[E0277]: the trait bound `impl Into: Into` is not satisfie --> $DIR/nested_impl_trait.rs:6:46 | LL | fn bad_in_ret_position(x: impl Into) -> impl Into { x } - | ^^^^^^^^^^^^^^^^^^^^^ the trait `Debug` is not implemented for `impl Into` + | ^^^^^^^^^^^^^^^^^^^^^ the trait `From>` is not implemented for `impl Into`, which is required by `impl Into: Into` | -help: consider further restricting this bound - | -LL | fn bad_in_ret_position(x: impl Into + std::fmt::Debug) -> impl Into { x } - | +++++++++++++++++ + = help: the trait `Into` is implemented for `T` + = note: required for `impl Into` to implement `Into` error[E0277]: the trait bound `impl Into: Into` is not satisfied --> $DIR/nested_impl_trait.rs:19:34 | LL | fn bad(x: impl Into) -> impl Into { x } - | ^^^^^^^^^^^^^^^^^^^^^ the trait `Debug` is not implemented for `impl Into` - | -help: consider further restricting this bound + | ^^^^^^^^^^^^^^^^^^^^^ the trait `From>` is not implemented for `impl Into`, which is required by `impl Into: Into` | -LL | fn bad(x: impl Into + std::fmt::Debug) -> impl Into { x } - | +++++++++++++++++ + = help: the trait `Into` is implemented for `T` + = note: required for `impl Into` to implement `Into` error: aborting due to 7 previous errors diff --git a/tests/ui/impl-trait/recursive-bound-eval.next.stderr b/tests/ui/impl-trait/recursive-bound-eval.next.stderr new file mode 100644 index 0000000000000..4bab290d71c3c --- /dev/null +++ b/tests/ui/impl-trait/recursive-bound-eval.next.stderr @@ -0,0 +1,9 @@ +error[E0282]: type annotations needed + --> $DIR/recursive-bound-eval.rs:20:13 + | +LL | move || recursive_fn().parse() + | ^^^^^^^^^^^^^^ cannot infer type + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0282`. diff --git a/tests/ui/impl-trait/recursive-bound-eval.rs b/tests/ui/impl-trait/recursive-bound-eval.rs new file mode 100644 index 0000000000000..7859c8983fc89 --- /dev/null +++ b/tests/ui/impl-trait/recursive-bound-eval.rs @@ -0,0 +1,24 @@ +//! Test that we can evaluate nested obligations when invoking methods on recursive calls on +//! an RPIT. + +//@revisions: next current +//@[next] compile-flags: -Znext-solver + +//@[current] check-pass + +pub trait Parser { + fn parse(&self) -> E; +} + +impl E> Parser for T { + fn parse(&self) -> E { + self() + } +} + +pub fn recursive_fn() -> impl Parser { + move || recursive_fn().parse() + //[next]~^ ERROR: type annotations needed +} + +fn main() {} diff --git a/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration.rs b/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration.rs index 7874a21f3aec5..aab10be2de27a 100644 --- a/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration.rs +++ b/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration.rs @@ -11,7 +11,7 @@ impl PartialEq<(Bar, i32)> for Bar { } fn foo() -> Foo { - //~^ ERROR overflow evaluating the requirement `Bar: PartialEq<(Foo, i32)>` + //~^ ERROR can't compare `Bar` with `(Foo, i32)` Bar } diff --git a/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration.stderr b/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration.stderr index 2d4707f8a2799..bc810c0f88f3d 100644 --- a/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration.stderr +++ b/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration.stderr @@ -1,9 +1,15 @@ -error[E0275]: overflow evaluating the requirement `Bar: PartialEq<(Foo, i32)>` +error[E0277]: can't compare `Bar` with `(Foo, i32)` --> $DIR/recursive-type-alias-impl-trait-declaration.rs:13:13 | LL | fn foo() -> Foo { - | ^^^ + | ^^^ no implementation for `Bar == (Foo, i32)` +LL | +LL | Bar + | --- return type was inferred to be `Bar` here + | + = help: the trait `PartialEq<(Foo, i32)>` is not implemented for `Bar` + = help: the trait `PartialEq<(Bar, i32)>` is implemented for `Bar` error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0275`. +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/macros/proc_macro.rs b/tests/ui/macros/proc_macro.rs index ce2b041c26eba..8fea4ca282cf8 100644 --- a/tests/ui/macros/proc_macro.rs +++ b/tests/ui/macros/proc_macro.rs @@ -1,6 +1,5 @@ //@ run-pass //@ aux-build:proc_macro_def.rs -//@ ignore-cross-compile extern crate proc_macro_def; diff --git a/tests/ui/type-alias-impl-trait/constrain_in_projection.current.stderr b/tests/ui/type-alias-impl-trait/constrain_in_projection.current.stderr new file mode 100644 index 0000000000000..c215d197db436 --- /dev/null +++ b/tests/ui/type-alias-impl-trait/constrain_in_projection.current.stderr @@ -0,0 +1,11 @@ +error[E0277]: the trait bound `Foo: Trait` is not satisfied + --> $DIR/constrain_in_projection.rs:24:14 + | +LL | let x = >::Assoc::default(); + | ^^^ the trait `Trait` is not implemented for `Foo` + | + = help: the trait `Trait<()>` is implemented for `Foo` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/type-alias-impl-trait/constrain_in_projection.rs b/tests/ui/type-alias-impl-trait/constrain_in_projection.rs index 2a246900106cb..7d7d16361ae6d 100644 --- a/tests/ui/type-alias-impl-trait/constrain_in_projection.rs +++ b/tests/ui/type-alias-impl-trait/constrain_in_projection.rs @@ -4,7 +4,7 @@ //@ revisions: current next //@ ignore-compare-mode-next-solver (explicit revisions) //@[next] compile-flags: -Znext-solver -//@check-pass +//@[next]check-pass #![feature(type_alias_impl_trait)] @@ -22,6 +22,7 @@ impl Trait<()> for Foo { fn bop(_: Bar) { let x = >::Assoc::default(); + //[current]~^ `Foo: Trait` is not satisfied } fn main() {} diff --git a/tests/ui/type-alias-impl-trait/constrain_in_projection2.current.stderr b/tests/ui/type-alias-impl-trait/constrain_in_projection2.current.stderr index 0d6eac4216bae..69df5c77f9de9 100644 --- a/tests/ui/type-alias-impl-trait/constrain_in_projection2.current.stderr +++ b/tests/ui/type-alias-impl-trait/constrain_in_projection2.current.stderr @@ -1,19 +1,13 @@ -error[E0283]: type annotations needed: cannot satisfy `Foo: Trait` +error[E0277]: the trait bound `Foo: Trait` is not satisfied --> $DIR/constrain_in_projection2.rs:27:14 | LL | let x = >::Assoc::default(); - | ^^^ help: use the fully qualified path to an implementation: `::Assoc` + | ^^^ the trait `Trait` is not implemented for `Foo` | -note: multiple `impl`s satisfying `Foo: Trait` found - --> $DIR/constrain_in_projection2.rs:18:1 - | -LL | impl Trait<()> for Foo { - | ^^^^^^^^^^^^^^^^^^^^^^ -... -LL | impl Trait for Foo { - | ^^^^^^^^^^^^^^^^^^^^^^^ - = note: associated types cannot be accessed directly on a `trait`, they can only be accessed through a specific `impl` + = help: the following other types implement trait `Trait`: + > + > error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0283`. +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/type-alias-impl-trait/constrain_in_projection2.rs b/tests/ui/type-alias-impl-trait/constrain_in_projection2.rs index 0066131f0155f..af222f6c15347 100644 --- a/tests/ui/type-alias-impl-trait/constrain_in_projection2.rs +++ b/tests/ui/type-alias-impl-trait/constrain_in_projection2.rs @@ -25,7 +25,8 @@ impl Trait for Foo { fn bop(_: Bar) { let x = >::Assoc::default(); - //~^ ERROR: cannot satisfy `Foo: Trait` + //[next]~^ ERROR: cannot satisfy `Foo: Trait` + //[current]~^^ ERROR: `Foo: Trait` is not satisfied } fn main() {} diff --git a/tests/ui/type-alias-impl-trait/issue-84660-unsoundness.rs b/tests/ui/type-alias-impl-trait/issue-84660-unsoundness.rs index 99a5d36066b08..fd1f3c6353c6d 100644 --- a/tests/ui/type-alias-impl-trait/issue-84660-unsoundness.rs +++ b/tests/ui/type-alias-impl-trait/issue-84660-unsoundness.rs @@ -20,7 +20,7 @@ trait Trait { impl Trait for Out { type Out = Out; fn convert(_i: In) -> Self::Out { - //[next]~^ ERROR: type annotations needed + //[next]~^ ERROR: cannot satisfy `>::Out == ()` unreachable!(); } } diff --git a/tests/ui/type-alias-impl-trait/nested-tait-inference.stderr b/tests/ui/type-alias-impl-trait/nested-tait-inference.current.stderr similarity index 90% rename from tests/ui/type-alias-impl-trait/nested-tait-inference.stderr rename to tests/ui/type-alias-impl-trait/nested-tait-inference.current.stderr index 172ecded7a2f9..34532afcbbae4 100644 --- a/tests/ui/type-alias-impl-trait/nested-tait-inference.stderr +++ b/tests/ui/type-alias-impl-trait/nested-tait-inference.current.stderr @@ -1,5 +1,5 @@ error[E0277]: the trait bound `(): Foo` is not satisfied - --> $DIR/nested-tait-inference.rs:12:13 + --> $DIR/nested-tait-inference.rs:17:13 | LL | fn foo() -> impl Foo { | ^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `()` diff --git a/tests/ui/type-alias-impl-trait/nested-tait-inference.rs b/tests/ui/type-alias-impl-trait/nested-tait-inference.rs index 70495c44706a7..50d51c7faf91b 100644 --- a/tests/ui/type-alias-impl-trait/nested-tait-inference.rs +++ b/tests/ui/type-alias-impl-trait/nested-tait-inference.rs @@ -4,7 +4,7 @@ //@ revisions: current next //@ ignore-compare-mode-next-solver (explicit revisions) //@[next] compile-flags: -Znext-solver -//@check-pass +//@[next] check-pass use std::fmt::Debug; @@ -15,6 +15,8 @@ trait Foo {} impl Foo<()> for () {} fn foo() -> impl Foo { + //[current]~^ ERROR: the trait bound `(): Foo` is not satisfied + // FIXME(type-alias-impl-trait): We could probably make this work. () } diff --git a/tests/ui/type-alias-impl-trait/nested-tait-inference2.current.stderr b/tests/ui/type-alias-impl-trait/nested-tait-inference2.current.stderr index c7b7af152ab32..614bc09872f82 100644 --- a/tests/ui/type-alias-impl-trait/nested-tait-inference2.current.stderr +++ b/tests/ui/type-alias-impl-trait/nested-tait-inference2.current.stderr @@ -1,17 +1,16 @@ -error[E0283]: type annotations needed: cannot satisfy `(): Foo` +error[E0277]: the trait bound `(): Foo` is not satisfied --> $DIR/nested-tait-inference2.rs:17:13 | LL | fn foo() -> impl Foo { - | ^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `()` +LL | +LL | () + | -- return type was inferred to be `()` here | -note: multiple `impl`s satisfying `(): Foo` found - --> $DIR/nested-tait-inference2.rs:14:1 - | -LL | impl Foo<()> for () {} - | ^^^^^^^^^^^^^^^^^^^ -LL | impl Foo for () {} - | ^^^^^^^^^^^^^^^^^^^^ + = help: the following other types implement trait `Foo`: + <() as Foo<()>> + <() as Foo> error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0283`. +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/type-alias-impl-trait/nested-tait-inference2.rs b/tests/ui/type-alias-impl-trait/nested-tait-inference2.rs index fe2f76e552ad7..28d72b0cbeede 100644 --- a/tests/ui/type-alias-impl-trait/nested-tait-inference2.rs +++ b/tests/ui/type-alias-impl-trait/nested-tait-inference2.rs @@ -15,7 +15,7 @@ impl Foo<()> for () {} impl Foo for () {} fn foo() -> impl Foo { - //[current]~^ ERROR: cannot satisfy `(): Foo` + //[current]~^ ERROR: the trait bound `(): Foo` is not satisfied () //[next]~^ ERROR: cannot satisfy `impl Foo == ()` } diff --git a/tests/ui/type-alias-impl-trait/normalize-hidden-types.current.stderr b/tests/ui/type-alias-impl-trait/normalize-hidden-types.current.stderr index eff29303bf18e..a40dac06a01c3 100644 --- a/tests/ui/type-alias-impl-trait/normalize-hidden-types.current.stderr +++ b/tests/ui/type-alias-impl-trait/normalize-hidden-types.current.stderr @@ -22,17 +22,21 @@ note: previous use here LL | fn define_1() -> Opaque { dyn_hoops::<_>(0) } | ^^^^^^^^^^^^^^^^^ -error: concrete type differs from previous defining opaque type use +error[E0308]: mismatched types --> $DIR/normalize-hidden-types.rs:43:25 | +LL | type Opaque = impl Sized; + | ---------- the expected opaque type +... LL | let _: Opaque = dyn_hoops::(0); - | ^^^^^^^^^^^^^^^^^^ expected `*const (dyn FnOnce(()) + 'static)`, got `*const dyn for<'a> FnOnce(::Gat<'a>)` - | -note: previous use here - --> $DIR/normalize-hidden-types.rs:44:9 - | -LL | None - | ^^^^ + | ------ ^^^^^^^^^^^^^^^^^^ expected opaque type, found `*const dyn FnOnce(())` + | | + | expected due to this + | + = note: expected opaque type `typeck::Opaque` + found raw pointer `*const (dyn FnOnce(()) + 'static)` + = help: consider constraining the associated type `::Gat<'_>` to `()` or calling a method that returns `::Gat<'_>` + = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html error: concrete type differs from previous defining opaque type use --> $DIR/normalize-hidden-types.rs:52:25 @@ -48,3 +52,4 @@ LL | None error: aborting due to 4 previous errors +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/type-alias-impl-trait/self-referential-2.current.stderr b/tests/ui/type-alias-impl-trait/self-referential-2.current.stderr new file mode 100644 index 0000000000000..3ae3590ca7fe3 --- /dev/null +++ b/tests/ui/type-alias-impl-trait/self-referential-2.current.stderr @@ -0,0 +1,14 @@ +error[E0277]: can't compare `i32` with `Foo` + --> $DIR/self-referential-2.rs:10:13 + | +LL | fn bar() -> Bar { + | ^^^ no implementation for `i32 == Foo` +LL | 42_i32 + | ------ return type was inferred to be `i32` here + | + = help: the trait `PartialEq` is not implemented for `i32` + = help: the trait `PartialEq` is implemented for `i32` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/type-alias-impl-trait/self-referential-2.rs b/tests/ui/type-alias-impl-trait/self-referential-2.rs index f4102f2e2cb71..f96364ccfcddf 100644 --- a/tests/ui/type-alias-impl-trait/self-referential-2.rs +++ b/tests/ui/type-alias-impl-trait/self-referential-2.rs @@ -1,14 +1,14 @@ //@ revisions: current next //@ ignore-compare-mode-next-solver (explicit revisions) //@[next] compile-flags: -Znext-solver -//@ check-pass +//@[next] check-pass #![feature(type_alias_impl_trait)] type Foo = impl std::fmt::Debug; type Bar = impl PartialEq; fn bar() -> Bar { - 42_i32 + 42_i32 //[current]~^ ERROR can't compare `i32` with `Foo` } fn main() {} diff --git a/tests/ui/type-alias-impl-trait/self-referential-3.rs b/tests/ui/type-alias-impl-trait/self-referential-3.rs index 3b015ab322aca..b33051da2d779 100644 --- a/tests/ui/type-alias-impl-trait/self-referential-3.rs +++ b/tests/ui/type-alias-impl-trait/self-referential-3.rs @@ -5,7 +5,7 @@ type Bar<'a, 'b> = impl PartialEq> + std::fmt::Debug; fn bar<'a, 'b>(i: &'a i32) -> Bar<'a, 'b> { - //~^ ERROR overflow normalizing the type alias `Bar<'a, 'b>` + //~^ ERROR can't compare `&i32` with `Bar<'a, 'b>` i } diff --git a/tests/ui/type-alias-impl-trait/self-referential-3.stderr b/tests/ui/type-alias-impl-trait/self-referential-3.stderr index caa9f9691dda5..32eac622e5181 100644 --- a/tests/ui/type-alias-impl-trait/self-referential-3.stderr +++ b/tests/ui/type-alias-impl-trait/self-referential-3.stderr @@ -1,11 +1,15 @@ -error[E0275]: overflow normalizing the type alias `Bar<'a, 'b>` +error[E0277]: can't compare `&i32` with `Bar<'a, 'b>` --> $DIR/self-referential-3.rs:7:31 | LL | fn bar<'a, 'b>(i: &'a i32) -> Bar<'a, 'b> { - | ^^^^^^^^^^^ + | ^^^^^^^^^^^ no implementation for `&i32 == Bar<'a, 'b>` +LL | +LL | i + | - return type was inferred to be `&i32` here | - = note: in case this is a recursive type alias, consider using a struct, enum, or union instead + = help: the trait `PartialEq>` is not implemented for `&i32` + = help: the trait `PartialEq` is implemented for `i32` error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0275`. +For more information about this error, try `rustc --explain E0277`.