diff --git a/compiler/rustc_ast/src/token.rs b/compiler/rustc_ast/src/token.rs index 3189fcf7ff9bf..a7c6f8c5d8c26 100644 --- a/compiler/rustc_ast/src/token.rs +++ b/compiler/rustc_ast/src/token.rs @@ -756,6 +756,11 @@ impl Token { ) } + /// Returns `true` if the token is the integer literal. + pub fn is_integer_lit(&self) -> bool { + matches!(self.kind, Literal(Lit { kind: LitKind::Integer, .. })) + } + /// Returns `true` if the token is a non-raw identifier for which `pred` holds. pub fn is_non_raw_ident_where(&self, pred: impl FnOnce(Ident) -> bool) -> bool { match self.ident() { diff --git a/compiler/rustc_attr/src/builtin.rs b/compiler/rustc_attr/src/builtin.rs index 7e87d1c31301b..609d75733b2c8 100644 --- a/compiler/rustc_attr/src/builtin.rs +++ b/compiler/rustc_attr/src/builtin.rs @@ -985,7 +985,7 @@ pub fn parse_repr_attr(sess: &Session, attr: &Attribute) -> Vec { Ok(literal) => acc.push(ReprPacked(literal)), Err(message) => literal_error = Some(message), }; - } else if matches!(name, sym::C | sym::simd | sym::transparent) + } else if matches!(name, sym::Rust | sym::C | sym::simd | sym::transparent) || int_type_of_word(name).is_some() { recognised = true; @@ -1018,7 +1018,7 @@ pub fn parse_repr_attr(sess: &Session, attr: &Attribute) -> Vec { }); } else if matches!( meta_item.name_or_empty(), - sym::C | sym::simd | sym::transparent + sym::Rust | sym::C | sym::simd | sym::transparent ) || int_type_of_word(meta_item.name_or_empty()).is_some() { recognised = true; @@ -1043,7 +1043,7 @@ pub fn parse_repr_attr(sess: &Session, attr: &Attribute) -> Vec { ); } else if matches!( meta_item.name_or_empty(), - sym::C | sym::simd | sym::transparent + sym::Rust | sym::C | sym::simd | sym::transparent ) || int_type_of_word(meta_item.name_or_empty()).is_some() { recognised = true; diff --git a/compiler/rustc_hir_typeck/src/_match.rs b/compiler/rustc_hir_typeck/src/_match.rs index a29d9c95e5ea0..e7cbbc713353f 100644 --- a/compiler/rustc_hir_typeck/src/_match.rs +++ b/compiler/rustc_hir_typeck/src/_match.rs @@ -139,7 +139,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { &cause, Some(arm.body), arm_ty, - |err| self.suggest_removing_semicolon_for_coerce(err, expr, arm_ty, prior_arm), + |err| { + self.explain_never_type_coerced_to_unit(err, arm, arm_ty, prior_arm, expr); + }, false, ); @@ -177,6 +179,38 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { coercion.complete(self) } + fn explain_never_type_coerced_to_unit( + &self, + err: &mut Diagnostic, + arm: &hir::Arm<'tcx>, + arm_ty: Ty<'tcx>, + prior_arm: Option<(Option, Ty<'tcx>, Span)>, + expr: &hir::Expr<'tcx>, + ) { + if let hir::ExprKind::Block(block, _) = arm.body.kind + && let Some(expr) = block.expr + && let arm_tail_ty = self.node_ty(expr.hir_id) + && arm_tail_ty.is_never() + && !arm_ty.is_never() + { + err.span_label( + expr.span, + format!( + "this expression is of type `!`, but it is coerced to `{arm_ty}` due to its \ + surrounding expression", + ), + ); + self.suggest_mismatched_types_on_tail( + err, + expr, + arm_ty, + prior_arm.map_or(arm_tail_ty, |(_, ty, _)| ty), + expr.hir_id, + ); + } + self.suggest_removing_semicolon_for_coerce(err, expr, arm_ty, prior_arm) + } + fn suggest_removing_semicolon_for_coerce( &self, diag: &mut Diagnostic, diff --git a/compiler/rustc_hir_typeck/src/callee.rs b/compiler/rustc_hir_typeck/src/callee.rs index d40ac59baa416..365170a6bbf36 100644 --- a/compiler/rustc_hir_typeck/src/callee.rs +++ b/compiler/rustc_hir_typeck/src/callee.rs @@ -845,7 +845,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { expected, ); - self.write_method_call(call_expr.hir_id, method_callee); + self.write_method_call_and_enforce_effects(call_expr.hir_id, call_expr.span, method_callee); output_type } } @@ -895,7 +895,11 @@ impl<'a, 'tcx> DeferredCallResolution<'tcx> { adjustments.extend(autoref); fcx.apply_adjustments(self.callee_expr, adjustments); - fcx.write_method_call(self.call_expr.hir_id, method_callee); + fcx.write_method_call_and_enforce_effects( + self.call_expr.hir_id, + self.call_expr.span, + method_callee, + ); } None => { // This can happen if `#![no_core]` is used and the `fn/fn_mut/fn_once` diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs index ae2a4a9504ce3..587038d57bdfd 100644 --- a/compiler/rustc_hir_typeck/src/coercion.rs +++ b/compiler/rustc_hir_typeck/src/coercion.rs @@ -1715,6 +1715,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> { // label pointing out the cause for the type coercion will be wrong // as prior return coercions would not be relevant (#57664). let fn_decl = if let (Some(expr), Some(blk_id)) = (expression, blk_id) { + fcx.suggest_missing_semicolon(&mut err, expr, expected, false); let pointing_at_return_type = fcx.suggest_mismatched_types_on_tail(&mut err, expr, expected, found, blk_id); if let (Some(cond_expr), true, false) = ( diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index f16269795e985..ed5ac2cea3874 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -663,8 +663,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { coerce.coerce_forced_unit( self, &cause, - |err| { - self.suggest_mismatched_types_on_tail(err, expr, ty, e_ty, target_id); + |mut err| { + self.suggest_missing_semicolon(&mut err, expr, e_ty, false); + self.suggest_mismatched_types_on_tail( + &mut err, expr, ty, e_ty, target_id, + ); let error = Some(Sorts(ExpectedFound { expected: ty, found: e_ty })); self.annotate_loop_expected_due_to_inference(err, expr, error); if let Some(val) = ty_kind_suggestion(ty) { @@ -1312,9 +1315,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { Ok(method) => { // We could add a "consider `foo::`" suggestion here, but I wasn't able to // trigger this codepath causing `structurally_resolve_type` to emit an error. - - self.enforce_context_effects(expr.hir_id, expr.span, method.def_id, method.args); - self.write_method_call(expr.hir_id, method); + self.write_method_call_and_enforce_effects(expr.hir_id, expr.span, method); Ok(method) } Err(error) => { diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index c5b4acd7c86fa..fae192e230cac 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -159,7 +159,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } #[instrument(level = "debug", skip(self))] - pub fn write_method_call(&self, hir_id: hir::HirId, method: MethodCallee<'tcx>) { + pub fn write_method_call_and_enforce_effects( + &self, + hir_id: hir::HirId, + span: Span, + method: MethodCallee<'tcx>, + ) { + self.enforce_context_effects(hir_id, span, method.def_id, method.args); self.write_resolution(hir_id, Ok((DefKind::AssocFn, method.def_id))); self.write_args(hir_id, method.args); } diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs index 6660bea03d8b7..c74ef8f271338 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs @@ -72,7 +72,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { blk_id: hir::HirId, ) -> bool { let expr = expr.peel_drop_temps(); - self.suggest_missing_semicolon(err, expr, expected, false); let mut pointing_at_return_type = false; if let hir::ExprKind::Break(..) = expr.kind { // `break` type mismatches provide better context for tail `loop` expressions. diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs index b4591e7f4f71c..a22c95ac8ffac 100644 --- a/compiler/rustc_hir_typeck/src/lib.rs +++ b/compiler/rustc_hir_typeck/src/lib.rs @@ -438,9 +438,13 @@ fn fatally_break_rust(tcx: TyCtxt<'_>) { } } +/// `expected` here is the expected number of explicit generic arguments on the trait. fn has_expected_num_generic_args(tcx: TyCtxt<'_>, trait_did: DefId, expected: usize) -> bool { let generics = tcx.generics_of(trait_did); - generics.count() == expected + if generics.has_self { 1 } else { 0 } + generics.count() + == expected + + if generics.has_self { 1 } else { 0 } + + if generics.host_effect_index.is_some() { 1 } else { 0 } } pub fn provide(providers: &mut Providers) { diff --git a/compiler/rustc_hir_typeck/src/op.rs b/compiler/rustc_hir_typeck/src/op.rs index f40406c67265a..fcb3f8f47bd60 100644 --- a/compiler/rustc_hir_typeck/src/op.rs +++ b/compiler/rustc_hir_typeck/src/op.rs @@ -291,7 +291,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .push(autoref); } } - self.write_method_call(expr.hir_id, method); + self.write_method_call_and_enforce_effects(expr.hir_id, expr.span, method); method.sig.output() } @@ -781,7 +781,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { assert!(op.is_by_value()); match self.lookup_op_method(operand_ty, None, Op::Unary(op, ex.span), expected) { Ok(method) => { - self.write_method_call(ex.hir_id, method); + self.write_method_call_and_enforce_effects(ex.hir_id, ex.span, method); method.sig.output() } Err(errors) => { diff --git a/compiler/rustc_hir_typeck/src/place_op.rs b/compiler/rustc_hir_typeck/src/place_op.rs index f8ca3a4f3d7c0..79e41ef922759 100644 --- a/compiler/rustc_hir_typeck/src/place_op.rs +++ b/compiler/rustc_hir_typeck/src/place_op.rs @@ -38,7 +38,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { span_bug!(expr.span, "input to deref is not a ref?"); } let ty = self.make_overloaded_place_return_type(method).ty; - self.write_method_call(expr.hir_id, method); + self.write_method_call_and_enforce_effects(expr.hir_id, expr.span, method); Some(ty) } @@ -179,7 +179,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } self.apply_adjustments(base_expr, adjustments); - self.write_method_call(expr.hir_id, method); + self.write_method_call_and_enforce_effects(expr.hir_id, expr.span, method); return Some((input_ty, self.make_overloaded_place_return_type(method).ty)); } @@ -404,7 +404,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { None => return, }; debug!("convert_place_op_to_mutable: method={:?}", method); - self.write_method_call(expr.hir_id, method); + self.write_method_call_and_enforce_effects(expr.hir_id, expr.span, method); let ty::Ref(region, _, hir::Mutability::Mut) = method.sig.inputs()[0].kind() else { span_bug!(expr.span, "input to mutable place op is not a mut ref?"); diff --git a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs index 440767927d70c..c4bf2f2389957 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs @@ -263,13 +263,13 @@ impl<'tcx> ConstToPat<'tcx> { // (If there isn't, then we can safely issue a hard // error, because that's never worked, due to compiler // using `PartialEq::eq` in this scenario in the past.) - let partial_eq_trait_id = - self.tcx().require_lang_item(hir::LangItem::PartialEq, Some(self.span)); + let tcx = self.tcx(); + let partial_eq_trait_id = tcx.require_lang_item(hir::LangItem::PartialEq, Some(self.span)); let partial_eq_obligation = Obligation::new( - self.tcx(), + tcx, ObligationCause::dummy(), self.param_env, - ty::TraitRef::new(self.tcx(), partial_eq_trait_id, [ty, ty]), + ty::TraitRef::new(tcx, partial_eq_trait_id, [ty, ty]), ); // This *could* accept a type that isn't actually `PartialEq`, because region bounds get diff --git a/compiler/rustc_parse/src/parser/stmt.rs b/compiler/rustc_parse/src/parser/stmt.rs index 5316dde609605..620ba4a3cb363 100644 --- a/compiler/rustc_parse/src/parser/stmt.rs +++ b/compiler/rustc_parse/src/parser/stmt.rs @@ -567,20 +567,37 @@ impl<'a> Parser<'a> { snapshot.recover_diff_marker(); } if self.token == token::Colon { - // if next token is following a colon, it's likely a path - // and we can suggest a path separator - self.bump(); - if self.token.span.lo() == self.prev_token.span.hi() { + // if a previous and next token of the current one is + // integer literal (e.g. `1:42`), it's likely a range + // expression for Pythonistas and we can suggest so. + if self.prev_token.is_integer_lit() + && self.may_recover() + && self.look_ahead(1, |token| token.is_integer_lit()) + { + // FIXME(hkmatsumoto): Might be better to trigger + // this only when parsing an index expression. err.span_suggestion_verbose( - self.prev_token.span, - "maybe write a path separator here", - "::", + self.token.span, + "you might have meant a range expression", + "..", Applicability::MaybeIncorrect, ); - } - if self.sess.unstable_features.is_nightly_build() { - // FIXME(Nilstrieb): Remove this again after a few months. - err.note("type ascription syntax has been removed, see issue #101728 "); + } else { + // if next token is following a colon, it's likely a path + // and we can suggest a path separator + self.bump(); + if self.token.span.lo() == self.prev_token.span.hi() { + err.span_suggestion_verbose( + self.prev_token.span, + "maybe write a path separator here", + "::", + Applicability::MaybeIncorrect, + ); + } + if self.sess.unstable_features.is_nightly_build() { + // FIXME(Nilstrieb): Remove this again after a few months. + err.note("type ascription syntax has been removed, see issue #101728 "); + } } } diff --git a/src/tools/tidy/src/ui_tests.rs b/src/tools/tidy/src/ui_tests.rs index dfa386b49de7c..0fb57bf6f6c80 100644 --- a/src/tools/tidy/src/ui_tests.rs +++ b/src/tools/tidy/src/ui_tests.rs @@ -11,7 +11,7 @@ use std::path::{Path, PathBuf}; const ENTRY_LIMIT: usize = 900; // FIXME: The following limits should be reduced eventually. const ISSUES_ENTRY_LIMIT: usize = 1852; -const ROOT_ENTRY_LIMIT: usize = 867; +const ROOT_ENTRY_LIMIT: usize = 868; const EXPECTED_TEST_FILE_EXTENSIONS: &[&str] = &[ "rs", // test source files diff --git a/tests/ui/match/match-tail-expr-never-type-error.rs b/tests/ui/match/match-tail-expr-never-type-error.rs new file mode 100644 index 0000000000000..786ed3fa904be --- /dev/null +++ b/tests/ui/match/match-tail-expr-never-type-error.rs @@ -0,0 +1,16 @@ +fn never() -> ! { + loop {} +} + +fn bar(a: bool) { + match a { + true => 1, + false => { + never() //~ ERROR `match` arms have incompatible types + } + } +} +fn main() { + bar(true); + bar(false); +} diff --git a/tests/ui/match/match-tail-expr-never-type-error.stderr b/tests/ui/match/match-tail-expr-never-type-error.stderr new file mode 100644 index 0000000000000..226d33daeb254 --- /dev/null +++ b/tests/ui/match/match-tail-expr-never-type-error.stderr @@ -0,0 +1,21 @@ +error[E0308]: `match` arms have incompatible types + --> $DIR/match-tail-expr-never-type-error.rs:9:13 + | +LL | fn bar(a: bool) { + | - help: try adding a return type: `-> i32` +LL | / match a { +LL | | true => 1, + | | - this is found to be of type `{integer}` +LL | | false => { +LL | | never() + | | ^^^^^^^ + | | | + | | expected integer, found `()` + | | this expression is of type `!`, but it is coerced to `()` due to its surrounding expression +LL | | } +LL | | } + | |_____- `match` arms have incompatible types + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/repr/issue-83921-ice.rs b/tests/ui/repr/malformed-repr-hints.rs similarity index 76% rename from tests/ui/repr/issue-83921-ice.rs rename to tests/ui/repr/malformed-repr-hints.rs index 70583eb9bd332..27840b5f835d8 100644 --- a/tests/ui/repr/issue-83921-ice.rs +++ b/tests/ui/repr/malformed-repr-hints.rs @@ -19,6 +19,15 @@ struct S3; //~^ ERROR: incorrect `repr(align)` attribute format struct S4; +// Regression test for issue #118334: +#[repr(Rust(u8))] +//~^ ERROR: invalid representation hint +#[repr(Rust(0))] +//~^ ERROR: invalid representation hint +#[repr(Rust = 0)] +//~^ ERROR: invalid representation hint +struct S5; + #[repr(i8())] //~^ ERROR: invalid representation hint enum E1 { A, B } diff --git a/tests/ui/repr/issue-83921-ice.stderr b/tests/ui/repr/malformed-repr-hints.stderr similarity index 58% rename from tests/ui/repr/issue-83921-ice.stderr rename to tests/ui/repr/malformed-repr-hints.stderr index 32c450410eace..6fb927557619f 100644 --- a/tests/ui/repr/issue-83921-ice.stderr +++ b/tests/ui/repr/malformed-repr-hints.stderr @@ -1,46 +1,64 @@ error[E0552]: incorrect `repr(packed)` attribute format: `packed` takes exactly one parenthesized argument, or no parentheses at all - --> $DIR/issue-83921-ice.rs:6:8 + --> $DIR/malformed-repr-hints.rs:6:8 | LL | #[repr(packed())] | ^^^^^^^^ error[E0589]: invalid `repr(align)` attribute: `align` needs an argument - --> $DIR/issue-83921-ice.rs:10:8 + --> $DIR/malformed-repr-hints.rs:10:8 | LL | #[repr(align)] | ^^^^^ help: supply an argument here: `align(...)` error[E0693]: incorrect `repr(align)` attribute format: `align` takes exactly one argument in parentheses - --> $DIR/issue-83921-ice.rs:14:8 + --> $DIR/malformed-repr-hints.rs:14:8 | LL | #[repr(align(2, 4))] | ^^^^^^^^^^^ error[E0693]: incorrect `repr(align)` attribute format: `align` takes exactly one argument in parentheses - --> $DIR/issue-83921-ice.rs:18:8 + --> $DIR/malformed-repr-hints.rs:18:8 | LL | #[repr(align())] | ^^^^^^^ +error[E0552]: invalid representation hint: `Rust` does not take a parenthesized argument list + --> $DIR/malformed-repr-hints.rs:23:8 + | +LL | #[repr(Rust(u8))] + | ^^^^^^^^ + +error[E0552]: invalid representation hint: `Rust` does not take a parenthesized argument list + --> $DIR/malformed-repr-hints.rs:25:8 + | +LL | #[repr(Rust(0))] + | ^^^^^^^ + +error[E0552]: invalid representation hint: `Rust` does not take a value + --> $DIR/malformed-repr-hints.rs:27:8 + | +LL | #[repr(Rust = 0)] + | ^^^^^^^^ + error[E0552]: invalid representation hint: `i8` does not take a parenthesized argument list - --> $DIR/issue-83921-ice.rs:22:8 + --> $DIR/malformed-repr-hints.rs:31:8 | LL | #[repr(i8())] | ^^^^ error[E0552]: invalid representation hint: `u32` does not take a parenthesized argument list - --> $DIR/issue-83921-ice.rs:26:8 + --> $DIR/malformed-repr-hints.rs:35:8 | LL | #[repr(u32(42))] | ^^^^^^^ error[E0552]: invalid representation hint: `i64` does not take a value - --> $DIR/issue-83921-ice.rs:30:8 + --> $DIR/malformed-repr-hints.rs:39:8 | LL | #[repr(i64 = 2)] | ^^^^^^^ -error: aborting due to 7 previous errors +error: aborting due to 10 previous errors Some errors have detailed explanations: E0552, E0589, E0693. For more information about an error, try `rustc --explain E0552`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-nonconst.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-nonconst.rs index eada4ceafe92e..b9331caaf8efb 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-nonconst.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-nonconst.rs @@ -1,7 +1,4 @@ -// check-pass -// known-bug: #110395 - -#![feature(const_trait_impl)] +#![feature(const_trait_impl, effects)] struct S; @@ -24,6 +21,7 @@ const fn equals_self(t: &T) -> bool { // it not using the impl. pub const EQ: bool = equals_self(&S); -// FIXME(effects) ~^ ERROR +//~^ ERROR +// FIXME(effects) the diagnostics here isn't ideal, we shouldn't get `` fn main() {} diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-nonconst.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-nonconst.stderr new file mode 100644 index 0000000000000..4fe296d4d3fa9 --- /dev/null +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-nonconst.stderr @@ -0,0 +1,18 @@ +error[E0277]: the trait bound `S: ~const Foo` is not satisfied + --> $DIR/call-generic-method-nonconst.rs:23:34 + | +LL | pub const EQ: bool = equals_self(&S); + | ----------- ^^ the trait `Foo` is not implemented for `S` + | | + | required by a bound introduced by this call + | + = help: the trait `Foo` is implemented for `S` +note: required by a bound in `equals_self` + --> $DIR/call-generic-method-nonconst.rs:16:25 + | +LL | const fn equals_self(t: &T) -> bool { + | ^^^^^^^^^^ required by this bound in `equals_self` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/minicore.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/minicore.rs index c38b4b3f1a2ee..67da5f9533c6a 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/minicore.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/minicore.rs @@ -21,7 +21,7 @@ trait Add { fn add(self, rhs: Rhs) -> Self::Output; } -// FIXME we shouldn't need to have to specify `Rhs`. +// FIXME(effects) we shouldn't need to have to specify `Rhs`. impl const Add for i32 { type Output = i32; fn add(self, rhs: i32) -> i32 { @@ -336,7 +336,7 @@ fn from_str(s: &str) -> Result { } #[lang = "eq"] -#[const_trait] +// FIXME #[const_trait] trait PartialEq { fn eq(&self, other: &Rhs) -> bool; fn ne(&self, other: &Rhs) -> bool { diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/minicore.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/minicore.stderr index 0242937421890..19e6f6bffc6c8 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/minicore.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/minicore.stderr @@ -1,32 +1,61 @@ -error[E0369]: cannot add `i32` to `i32` - --> $DIR/minicore.rs:33:20 +warning: to use a constant of type `&str` in a pattern, the type must implement `PartialEq` + --> $DIR/minicore.rs:332:9 | -LL | let x = 42_i32 + 43_i32; - | ------ ^ ------ i32 - | | - | i32 +LL | "true" => Ok(true), + | ^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #116122 + = note: `#[warn(const_patterns_without_partial_eq)]` on by default + +warning: to use a constant of type `&str` in a pattern, the type must implement `PartialEq` + --> $DIR/minicore.rs:333:9 + | +LL | "false" => Ok(false), + | ^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #116122 -error[E0369]: cannot add `i32` to `i32` - --> $DIR/minicore.rs:37:20 +error[E0493]: destructor of `Self` cannot be evaluated at compile-time + --> $DIR/minicore.rs:494:9 | -LL | let x = 42_i32 + 43_i32; - | ------ ^ ------ i32 - | | - | i32 +LL | *self = source.clone() + | ^^^^^ + | | + | the destructor for this type cannot be evaluated in constant functions + | value is dropped here -error[E0600]: cannot apply unary operator `!` to type `bool` - --> $DIR/minicore.rs:343:9 +error[E0493]: destructor of `T` cannot be evaluated at compile-time + --> $DIR/minicore.rs:504:35 | -LL | !self.eq(other) - | ^^^^^^^^^^^^^^^ cannot apply unary operator `!` +LL | const fn drop(_: T) {} + | ^ - value is dropped here + | | + | the destructor for this type cannot be evaluated in constant functions -error[E0600]: cannot apply unary operator `!` to type `bool` - --> $DIR/minicore.rs:365:9 +error: aborting due to 2 previous errors; 2 warnings emitted + +For more information about this error, try `rustc --explain E0493`. +Future incompatibility report: Future breakage diagnostic: +warning: to use a constant of type `&str` in a pattern, the type must implement `PartialEq` + --> $DIR/minicore.rs:332:9 + | +LL | "true" => Ok(true), + | ^^^^^^ | -LL | !self - | ^^^^^ cannot apply unary operator `!` + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #116122 + = note: `#[warn(const_patterns_without_partial_eq)]` on by default -error: aborting due to 4 previous errors +Future breakage diagnostic: +warning: to use a constant of type `&str` in a pattern, the type must implement `PartialEq` + --> $DIR/minicore.rs:333:9 + | +LL | "false" => Ok(false), + | ^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #116122 + = note: `#[warn(const_patterns_without_partial_eq)]` on by default -Some errors have detailed explanations: E0369, E0600. -For more information about an error, try `rustc --explain E0369`. diff --git a/tests/ui/stable-mir-print/basic_function.rs b/tests/ui/stable-mir-print/basic_function.rs new file mode 100644 index 0000000000000..8b8a3154830ac --- /dev/null +++ b/tests/ui/stable-mir-print/basic_function.rs @@ -0,0 +1,14 @@ +// compile-flags: -Z unpretty=stable-mir +// check-pass + +fn foo(i:i32) -> i32 { + i + 1 +} + +fn bar(vec: &mut Vec) -> Vec { + let mut new_vec = vec.clone(); + new_vec.push(1); + new_vec +} + +fn main(){} diff --git a/tests/ui/stable-mir-print/basic_function.stdout b/tests/ui/stable-mir-print/basic_function.stdout new file mode 100644 index 0000000000000..e54ebe2b2c03f --- /dev/null +++ b/tests/ui/stable-mir-print/basic_function.stdout @@ -0,0 +1,226 @@ +// WARNING: This is highly experimental output it's intended for stable-mir developers only. +// If you find a bug or want to improve the output open a issue at https://github.com/rust-lang/project-stable-mir. +fn foo(_0: i32) -> i32 { + let mut _0: (i32, bool); +} + bb0: { + _2 = 1 Add const 1_i32 + } + bb1: { + _0 = move _2 + } +fn bar(_0: &mut Ty { + id: 10, + kind: RigidTy( + Adt( + AdtDef( + DefId { + id: 3, + name: "std::vec::Vec", + }, + ), + GenericArgs( + [ + Type( + Ty { + id: 11, + kind: Param( + ParamTy { + index: 0, + name: "T", + }, + ), + }, + ), + Type( + Ty { + id: 12, + kind: Param( + ParamTy { + index: 1, + name: "A", + }, + ), + }, + ), + ], + ), + ), + ), +}) -> Ty { + id: 10, + kind: RigidTy( + Adt( + AdtDef( + DefId { + id: 3, + name: "std::vec::Vec", + }, + ), + GenericArgs( + [ + Type( + Ty { + id: 11, + kind: Param( + ParamTy { + index: 0, + name: "T", + }, + ), + }, + ), + Type( + Ty { + id: 12, + kind: Param( + ParamTy { + index: 1, + name: "A", + }, + ), + }, + ), + ], + ), + ), + ), +} { + let mut _0: Ty { + id: 10, + kind: RigidTy( + Adt( + AdtDef( + DefId { + id: 3, + name: "std::vec::Vec", + }, + ), + GenericArgs( + [ + Type( + Ty { + id: 11, + kind: Param( + ParamTy { + index: 0, + name: "T", + }, + ), + }, + ), + Type( + Ty { + id: 12, + kind: Param( + ParamTy { + index: 1, + name: "A", + }, + ), + }, + ), + ], + ), + ), + ), +}; + let mut _1: &Ty { + id: 10, + kind: RigidTy( + Adt( + AdtDef( + DefId { + id: 3, + name: "std::vec::Vec", + }, + ), + GenericArgs( + [ + Type( + Ty { + id: 11, + kind: Param( + ParamTy { + index: 0, + name: "T", + }, + ), + }, + ), + Type( + Ty { + id: 12, + kind: Param( + ParamTy { + index: 1, + name: "A", + }, + ), + }, + ), + ], + ), + ), + ), +}; + let _2: (); + let mut _3: &mut Ty { + id: 10, + kind: RigidTy( + Adt( + AdtDef( + DefId { + id: 3, + name: "std::vec::Vec", + }, + ), + GenericArgs( + [ + Type( + Ty { + id: 11, + kind: Param( + ParamTy { + index: 0, + name: "T", + }, + ), + }, + ), + Type( + Ty { + id: 12, + kind: Param( + ParamTy { + index: 1, + name: "A", + }, + ), + }, + ), + ], + ), + ), + ), +}; +} + bb0: { + _3 = refShared1 + } + bb1: { + _5 = refMut { + kind: TwoPhaseBorrow, +}2 + } + bb2: { + _0 = move _2 + } + bb3: { + } + bb4: { + } +fn main() -> () { +} + bb0: { + } diff --git a/tests/ui/suggestions/range-index-instead-of-colon.rs b/tests/ui/suggestions/range-index-instead-of-colon.rs new file mode 100644 index 0000000000000..3267527ecf2a7 --- /dev/null +++ b/tests/ui/suggestions/range-index-instead-of-colon.rs @@ -0,0 +1,7 @@ +// edition:2021 + +fn main() { + &[1, 2, 3][1:2]; + //~^ ERROR: expected one of + //~| HELP: you might have meant a range expression +} diff --git a/tests/ui/suggestions/range-index-instead-of-colon.stderr b/tests/ui/suggestions/range-index-instead-of-colon.stderr new file mode 100644 index 0000000000000..df29356cc16b3 --- /dev/null +++ b/tests/ui/suggestions/range-index-instead-of-colon.stderr @@ -0,0 +1,13 @@ +error: expected one of `.`, `?`, `]`, or an operator, found `:` + --> $DIR/range-index-instead-of-colon.rs:4:17 + | +LL | &[1, 2, 3][1:2]; + | ^ expected one of `.`, `?`, `]`, or an operator + | +help: you might have meant a range expression + | +LL | &[1, 2, 3][1..2]; + | ~~ + +error: aborting due to 1 previous error + diff --git a/triagebot.toml b/triagebot.toml index 593386288b496..ed9d59b1bb9eb 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -18,6 +18,7 @@ allow-unauthenticated = [ "relnotes", "requires-*", "regression-*", + "rla-*", "perf-*", "AsyncAwait-OnDeck", "needs-triage",