diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs index c4ff1eee56750..c4255652146ad 100644 --- a/compiler/rustc_codegen_llvm/src/intrinsic.rs +++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs @@ -55,6 +55,12 @@ fn call_simple_intrinsic<'ll, 'tcx>( name: Symbol, args: &[OperandRef<'tcx, &'ll Value>], ) -> Option<&'ll Value> { + let llvm_version = crate::llvm_util::get_version(); + // minimum/maximum were broken for f64/f128 before + // . + // We use the fallback body there. + let fixed_minmax = llvm_version >= (23, 0, 0); + let (base_name, type_params): (&'static str, &[&'ll Type]) = match name { sym::sqrtf16 => ("llvm.sqrt", &[bx.type_f16()]), sym::sqrtf32 => ("llvm.sqrt", &[bx.type_f32()]), @@ -83,18 +89,14 @@ fn call_simple_intrinsic<'ll, 'tcx>( sym::minimumf16 => ("llvm.minimum", &[bx.type_f16()]), sym::minimumf32 => ("llvm.minimum", &[bx.type_f32()]), - // FIXME: LLVM currently mis-compile those intrinsics, re-enable them - // when llvm/llvm-project#{139380,139381,140445} are fixed. - //sym::minimumf64 => ("llvm.minimum", &[bx.type_f64()]), - //sym::minimumf128 => ("llvm.minimum", &[cx.type_f128()]), - // + sym::minimumf64 if fixed_minmax => ("llvm.minimum", &[bx.type_f64()]), + sym::minimumf128 if fixed_minmax => ("llvm.minimum", &[bx.type_f128()]), + sym::maximumf16 => ("llvm.maximum", &[bx.type_f16()]), sym::maximumf32 => ("llvm.maximum", &[bx.type_f32()]), - // FIXME: LLVM currently mis-compile those intrinsics, re-enable them - // when llvm/llvm-project#{139380,139381,140445} are fixed. - //sym::maximumf64 => ("llvm.maximum", &[bx.type_f64()]), - //sym::maximumf128 => ("llvm.maximum", &[cx.type_f128()]), - // + sym::maximumf64 if fixed_minmax => ("llvm.maximum", &[bx.type_f64()]), + sym::maximumf128 if fixed_minmax => ("llvm.maximum", &[bx.type_f128()]), + sym::copysignf16 => ("llvm.copysign", &[bx.type_f16()]), sym::copysignf32 => ("llvm.copysign", &[bx.type_f32()]), sym::copysignf64 => ("llvm.copysign", &[bx.type_f64()]), diff --git a/compiler/rustc_const_eval/src/const_eval/machine.rs b/compiler/rustc_const_eval/src/const_eval/machine.rs index ce4c8497463c8..4251c74eb1ffb 100644 --- a/compiler/rustc_const_eval/src/const_eval/machine.rs +++ b/compiler/rustc_const_eval/src/const_eval/machine.rs @@ -12,7 +12,7 @@ use rustc_lint_defs::builtin::LONG_RUNNING_CONST_EVAL; use rustc_middle::mir::AssertMessage; use rustc_middle::mir::interpret::ReportedErrorInfo; use rustc_middle::query::TyCtxtAt; -use rustc_middle::ty::layout::{HasTypingEnv, TyAndLayout, ValidityRequirement}; +use rustc_middle::ty::layout::{HasTyCtxt, HasTypingEnv, TyAndLayout, ValidityRequirement}; use rustc_middle::ty::{self, FieldInfo, ScalarInt, Ty, TyCtxt}; use rustc_middle::{bug, mir, span_bug}; use rustc_span::{Span, Symbol, sym}; @@ -638,6 +638,30 @@ impl<'tcx> interpret::Machine<'tcx> for CompileTimeMachine<'tcx> { ecx.write_discriminant(variant_index, dest)?; } + sym::type_id_element_ty => { + let ty = ecx.read_type_id(&args[0])?; + let variant_index = if let ty::Array(ty, _) | ty::Slice(ty) = ty.kind() { + let (variant_idx, variant_place) = + ecx.project_downcast_named(dest, sym::Some)?; + let type_id_field_place = ecx.project_field(&variant_place, FieldIdx::ZERO)?; + ecx.write_type_id(*ty, &type_id_field_place)?; + variant_idx + } else { + ecx.project_downcast_named(dest, sym::None)?.0 + }; + ecx.write_discriminant(variant_index, dest)?; + } + + sym::type_id_array_len => { + let ty = ecx.read_type_id(&args[0])?; + let len = if let ty::Array(_, len) = ty.kind() { + len.to_leaf().to_target_usize(ecx.tcx.tcx()) + } else { + 0 + }; + ecx.write_scalar(Scalar::from_target_usize(len, ecx), dest)?; + } + sym::type_id_fields => { let ty = ecx.read_type_id(&args[0])?; let variant_idx = ecx.read_target_usize(&args[1])? as usize; diff --git a/compiler/rustc_const_eval/src/const_eval/type_info.rs b/compiler/rustc_const_eval/src/const_eval/type_info.rs index 8d93aee57a518..f9bd6ec1b4aad 100644 --- a/compiler/rustc_const_eval/src/const_eval/type_info.rs +++ b/compiler/rustc_const_eval/src/const_eval/type_info.rs @@ -6,7 +6,7 @@ use rustc_abi::{ExternAbi, FieldIdx}; use rustc_hir::attrs::lang_items::LangItem; use rustc_middle::span_bug; use rustc_middle::ty::layout::TyAndLayout; -use rustc_middle::ty::{self, Const, FnHeader, FnSigKind, FnSigTys, ScalarInt, Ty, TyCtxt}; +use rustc_middle::ty::{self, FnHeader, FnSigKind, FnSigTys, ScalarInt, Ty, TyCtxt}; use rustc_span::{Symbol, sym}; use crate::const_eval::CompileTimeMachine; @@ -82,22 +82,14 @@ impl<'tcx> InterpCx<'tcx, CompileTimeMachine<'tcx>> { self.write_tuple_type_info(tuple_place, fields, ty)?; variant } - ty::Array(ty, len) => { - let (variant, variant_place) = + ty::Array(_, _) => { + let (variant, _variant_place) = self.project_downcast_named(&field_dest, sym::Array)?; - let array_place = self.project_field(&variant_place, FieldIdx::ZERO)?; - - self.write_array_type_info(array_place, *ty, *len)?; - variant } - ty::Slice(ty) => { - let (variant, variant_place) = + ty::Slice(_) => { + let (variant, _variant_place) = self.project_downcast_named(&field_dest, sym::Slice)?; - let slice_place = self.project_field(&variant_place, FieldIdx::ZERO)?; - - self.write_slice_type_info(slice_place, *ty)?; - variant } ty::Adt(adt_def, generics) => { @@ -239,51 +231,6 @@ impl<'tcx> InterpCx<'tcx, CompileTimeMachine<'tcx>> { ) } - pub(crate) fn write_array_type_info( - &mut self, - place: impl Writeable<'tcx, CtfeProvenance>, - ty: Ty<'tcx>, - len: Const<'tcx>, - ) -> InterpResult<'tcx> { - // Iterate over all fields of `type_info::Array`. - for (field_idx, field) in - place.layout().ty.ty_adt_def().unwrap().non_enum_variant().fields.iter_enumerated() - { - let field_place = self.project_field(&place, field_idx)?; - - match field.name { - // Write the `TypeId` of the array's elements to the `element_ty` field. - sym::element_ty => self.write_type_id(ty, &field_place)?, - // Write the length of the array to the `len` field. - sym::len => self.write_scalar(len.to_leaf(), &field_place)?, - other => span_bug!(self.tcx.def_span(field.did), "unimplemented field {other}"), - } - } - - interp_ok(()) - } - - pub(crate) fn write_slice_type_info( - &mut self, - place: impl Writeable<'tcx, CtfeProvenance>, - ty: Ty<'tcx>, - ) -> InterpResult<'tcx> { - // Iterate over all fields of `type_info::Slice`. - for (field_idx, field) in - place.layout().ty.ty_adt_def().unwrap().non_enum_variant().fields.iter_enumerated() - { - let field_place = self.project_field(&place, field_idx)?; - - match field.name { - // Write the `TypeId` of the slice's elements to the `element_ty` field. - sym::element_ty => self.write_type_id(ty, &field_place)?, - other => span_bug!(self.tcx.def_span(field.did), "unimplemented field {other}"), - } - } - - interp_ok(()) - } - pub(crate) fn write_type_id_generics( &mut self, place: &impl Writeable<'tcx, CtfeProvenance>, diff --git a/compiler/rustc_error_codes/src/error_codes/E0117.md b/compiler/rustc_error_codes/src/error_codes/E0117.md index 0544667cccaea..ddd3f57366d73 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0117.md +++ b/compiler/rustc_error_codes/src/error_codes/E0117.md @@ -47,4 +47,4 @@ impl Bar for u32 { For information on the design of the orphan rules, see [RFC 1023]. -[RFC 1023]: https://github.com/rust-lang/rfcs/blob/master/text/1023-rebalancing-coherence.md +[RFC 1023]: https://rust-lang.github.io/rfcs/1023-rebalancing-coherence.html diff --git a/compiler/rustc_error_codes/src/error_codes/E0192.md b/compiler/rustc_error_codes/src/error_codes/E0192.md index deca042a91a50..995829ed403ce 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0192.md +++ b/compiler/rustc_error_codes/src/error_codes/E0192.md @@ -19,4 +19,4 @@ fn main() {} Negative impls are only allowed for auto traits. For more information see the [opt-in builtin traits RFC][RFC 19]. -[RFC 19]: https://github.com/rust-lang/rfcs/blob/master/text/0019-opt-in-builtin-traits.md +[RFC 19]: https://rust-lang.github.io/rfcs/0019-opt-in-builtin-traits.html diff --git a/compiler/rustc_error_codes/src/error_codes/E0207.md b/compiler/rustc_error_codes/src/error_codes/E0207.md index f80b0093ecc53..95526d8baac2d 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0207.md +++ b/compiler/rustc_error_codes/src/error_codes/E0207.md @@ -223,4 +223,4 @@ impl<'a> Contents for &'a Foo { For more information, please see [RFC 447]. -[RFC 447]: https://github.com/rust-lang/rfcs/blob/master/text/0447-no-unused-impl-parameters.md +[RFC 447]: https://rust-lang.github.io/rfcs/0447-no-unused-impl-parameters.html diff --git a/compiler/rustc_error_codes/src/error_codes/E0210.md b/compiler/rustc_error_codes/src/error_codes/E0210.md index 41263e5e3f5ac..32a8c106d23fa 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0210.md +++ b/compiler/rustc_error_codes/src/error_codes/E0210.md @@ -77,4 +77,4 @@ For information on the design of the orphan rules, see [RFC 2451] and [RFC 1023]. [RFC 2451]: https://rust-lang.github.io/rfcs/2451-re-rebalancing-coherence.html -[RFC 1023]: https://github.com/rust-lang/rfcs/blob/master/text/1023-rebalancing-coherence.md +[RFC 1023]: https://rust-lang.github.io/rfcs/1023-rebalancing-coherence.html diff --git a/compiler/rustc_error_codes/src/error_codes/E0228.md b/compiler/rustc_error_codes/src/error_codes/E0228.md index 3443a5ae8638c..c1155dbbe1b30 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0228.md +++ b/compiler/rustc_error_codes/src/error_codes/E0228.md @@ -36,5 +36,5 @@ type Foo<'a, 'b> = TwoBounds<'a, 'b, dyn Trait + 'b>; For more information, see [RFC 599] and its amendment [RFC 1156]. -[RFC 599]: https://github.com/rust-lang/rfcs/blob/master/text/0599-default-object-bound.md -[RFC 1156]: https://github.com/rust-lang/rfcs/blob/master/text/1156-adjust-default-object-bounds.md +[RFC 599]: https://rust-lang.github.io/rfcs/0599-default-object-bound.html +[RFC 1156]: https://rust-lang.github.io/rfcs/1156-adjust-default-object-bounds.html diff --git a/compiler/rustc_error_codes/src/error_codes/E0328.md b/compiler/rustc_error_codes/src/error_codes/E0328.md index 8390923545565..084c4ad1cac3e 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0328.md +++ b/compiler/rustc_error_codes/src/error_codes/E0328.md @@ -30,5 +30,5 @@ impl CoerceUnsized> for MyType where T: CoerceUnsized {} ``` -[RFC 982]: https://github.com/rust-lang/rfcs/blob/master/text/0982-dst-coercion.md +[RFC 982]: https://rust-lang.github.io/rfcs/0982-dst-coercion.html [`CoerceUnsized`]: https://doc.rust-lang.org/std/ops/trait.CoerceUnsized.html diff --git a/compiler/rustc_error_codes/src/error_codes/E0380.md b/compiler/rustc_error_codes/src/error_codes/E0380.md index 638f0c8ecc65f..e9fbf86e2c5c5 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0380.md +++ b/compiler/rustc_error_codes/src/error_codes/E0380.md @@ -11,4 +11,4 @@ unsafe auto trait Trait { Auto traits cannot have methods or associated items. For more information see the [opt-in builtin traits RFC][RFC 19]. -[RFC 19]: https://github.com/rust-lang/rfcs/blob/master/text/0019-opt-in-builtin-traits.md +[RFC 19]: https://rust-lang.github.io/rfcs/0019-opt-in-builtin-traits.html diff --git a/compiler/rustc_error_codes/src/error_codes/E0398.md b/compiler/rustc_error_codes/src/error_codes/E0398.md index 75d86979e3c87..fddcd4e5c4072 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0398.md +++ b/compiler/rustc_error_codes/src/error_codes/E0398.md @@ -32,4 +32,4 @@ fn foo<'a>(arg: &'a Box) { /* ... */ } This explicitly states that you expect the trait object `SomeTrait` to contain references (with a maximum lifetime of `'a`). -[RFC 1156]: https://github.com/rust-lang/rfcs/blob/master/text/1156-adjust-default-object-bounds.md +[RFC 1156]: https://rust-lang.github.io/rfcs/1156-adjust-default-object-bounds.html diff --git a/compiler/rustc_error_codes/src/error_codes/E0517.md b/compiler/rustc_error_codes/src/error_codes/E0517.md index 1655904722fbc..cfad2a58b727f 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0517.md +++ b/compiler/rustc_error_codes/src/error_codes/E0517.md @@ -50,4 +50,4 @@ types (i.e., `u8`, `i32`, etc) a representation that permits vectorization via SIMD. This doesn't make much sense for enums since they don't consist of a single list of data. -[rfc2195]: https://github.com/rust-lang/rfcs/blob/master/text/2195-really-tagged-unions.md +[rfc2195]: https://rust-lang.github.io/rfcs/2195-really-tagged-unions.html diff --git a/compiler/rustc_error_codes/src/error_codes/E0591.md b/compiler/rustc_error_codes/src/error_codes/E0591.md index c32aa95a3bfdd..27c605b8a34f8 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0591.md +++ b/compiler/rustc_error_codes/src/error_codes/E0591.md @@ -78,4 +78,4 @@ alone suffices for that. `*mut fn()` is a pointer to a fn pointer. (Since these values are typically just passed to C code, however, this rarely makes a difference in practice.) -[rfc401]: https://github.com/rust-lang/rfcs/blob/master/text/0401-coercions.md +[rfc401]: https://rust-lang.github.io/rfcs/0401-coercions.html diff --git a/compiler/rustc_error_codes/src/error_codes/E0737.md b/compiler/rustc_error_codes/src/error_codes/E0737.md index ab5e60692b4da..50c6849b49ce3 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0737.md +++ b/compiler/rustc_error_codes/src/error_codes/E0737.md @@ -9,4 +9,4 @@ Erroneous code example: extern "C" fn foo() {} ``` -[RFC 2091]: https://github.com/rust-lang/rfcs/blob/master/text/2091-inline-semantic.md +[RFC 2091]: https://rust-lang.github.io/rfcs/2091-inline-semantic.html diff --git a/compiler/rustc_error_codes/src/error_codes/E0739.md b/compiler/rustc_error_codes/src/error_codes/E0739.md index 5403405ca9dc1..cc2073f07798b 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0739.md +++ b/compiler/rustc_error_codes/src/error_codes/E0739.md @@ -11,4 +11,4 @@ struct Bar { } ``` -[RFC 2091]: https://github.com/rust-lang/rfcs/blob/master/text/2091-inline-semantic.md +[RFC 2091]: https://rust-lang.github.io/rfcs/2091-inline-semantic.html diff --git a/compiler/rustc_error_codes/src/error_codes/E0787.md b/compiler/rustc_error_codes/src/error_codes/E0787.md index b7f92c8feb587..758d30b78ea23 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0787.md +++ b/compiler/rustc_error_codes/src/error_codes/E0787.md @@ -22,4 +22,4 @@ The asm block must not contain any operands other than `const` and For more information, please see [RFC 2972]. -[RFC 2972]: https://github.com/rust-lang/rfcs/blob/master/text/2972-constrained-naked.md +[RFC 2972]: https://rust-lang.github.io/rfcs/2972-constrained-naked.html diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index e23128c1a491f..3d27276093aa5 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -2293,7 +2293,7 @@ impl Expr<'_> { // Type ascription inherits its place expression kind from its // operand. See: - // https://github.com/rust-lang/rfcs/blob/master/text/0803-type-ascription.md#type-ascription-and-temporaries + // https://rust-lang.github.io/rfcs/0803-type-ascription.html#type-ascription-and-temporaries ExprKind::Type(ref e, _) => e.is_place_expr(allow_projections_from), // Unsafe binder cast preserves place-ness of the sub-expression. diff --git a/compiler/rustc_hir_analysis/src/check/intrinsic.rs b/compiler/rustc_hir_analysis/src/check/intrinsic.rs index 61f72ee4b5de1..cca93e8aef0ec 100644 --- a/compiler/rustc_hir_analysis/src/check/intrinsic.rs +++ b/compiler/rustc_hir_analysis/src/check/intrinsic.rs @@ -199,6 +199,8 @@ fn intrinsic_operation_unsafety(tcx: TyCtxt<'_>, intrinsic_id: LocalDefId) -> hi | sym::truncf64 | sym::truncf128 | sym::type_id + | sym::type_id_array_len + | sym::type_id_element_ty | sym::type_id_eq | sym::type_id_field_representing_type | sym::type_id_fields @@ -315,6 +317,8 @@ pub(crate) fn check_intrinsic_type( sym::type_name => (1, 0, vec![], Ty::new_static_str(tcx)), sym::type_id => (1, 0, vec![], type_id_ty()), + sym::type_id_array_len => (0, 0, vec![type_id_ty()], tcx.types.usize), + sym::type_id_element_ty => (0, 0, vec![type_id_ty()], Ty::new_option(tcx, type_id_ty())), sym::type_id_eq => (0, 0, vec![type_id_ty(), type_id_ty()], tcx.types.bool), sym::type_id_field_representing_type => { (0, 0, vec![type_id_ty(), tcx.types.usize, tcx.types.usize], type_id_ty()) diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs index 6aa88ee627e83..a54fe8032bc45 100644 --- a/compiler/rustc_hir_typeck/src/coercion.rs +++ b/compiler/rustc_hir_typeck/src/coercion.rs @@ -1186,6 +1186,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }) } + /// Like [`Self::may_coerce`], but for suggestions whose replacement must complete with a + /// value of the target type. A coercion from `!` to another type does not provide such a + /// value, so it should not by itself justify these suggestions. + /// + /// This should only be used for suggestions. + pub(crate) fn may_coerce_except_never(&self, expr_ty: Ty<'tcx>, target_ty: Ty<'tcx>) -> bool { + if expr_ty.is_never() && !target_ty.is_never() { + return false; + } + self.may_coerce(expr_ty, target_ty) + } + /// Given a type and a target type, this function will calculate and return /// how many dereference steps needed to coerce `expr_ty` to `target`. If /// it's not possible, return `None`. diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index 548177a150b9a..cc2be9d392b36 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -1337,7 +1337,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let rhs = Ty::new_imm_ref(self.tcx, self.tcx.lifetimes.re_erased, rhs.peel_refs()); self.may_coerce(rhs, lhs) }; - let (applicability, eq) = if self.may_coerce(rhs_ty, lhs_ty) { + // Never-to-any coercions do not imply that the operands can be compared, e.g. `String == !`. + let (applicability, eq) = if self.may_coerce_except_never(rhs_ty, lhs_ty) { (Applicability::MachineApplicable, true) } else if refs_can_coerce(rhs_ty, lhs_ty) { // The lhs and rhs are likely missing some references in either side. Subsequent @@ -1352,7 +1353,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // if x == 1 && y == 2 { .. } // + let actual_lhs = self.check_expr(rhs_expr); - let may_eq = self.may_coerce(rhs_ty, actual_lhs) || refs_can_coerce(rhs_ty, actual_lhs); + let may_eq = self.may_coerce_except_never(rhs_ty, actual_lhs) + || refs_can_coerce(rhs_ty, actual_lhs); (Applicability::MaybeIncorrect, may_eq) } else if let ExprKind::Binary( Spanned { node: hir::BinOpKind::And | hir::BinOpKind::Or, .. }, @@ -1363,7 +1365,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // if x == 1 && y == 2 { .. } // + let actual_rhs = self.check_expr(lhs_expr); - let may_eq = self.may_coerce(actual_rhs, lhs_ty) || refs_can_coerce(actual_rhs, lhs_ty); + let may_eq = self.may_coerce_except_never(actual_rhs, lhs_ty) + || refs_can_coerce(actual_rhs, lhs_ty); (Applicability::MaybeIncorrect, may_eq) } else { (Applicability::MaybeIncorrect, false) diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs index 573c08895255b..3e2c2e8cc3944 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs @@ -1761,7 +1761,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { provided_ty }; - if !self.may_coerce(expected_ty, dummy_ty) { + if !self.may_coerce_except_never(expected_ty, dummy_ty) { return; } let msg = format!("use `{adt_name}::map_or` to deref inner value of `{adt_name}`"); @@ -2003,7 +2003,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if item_ty.has_param() { return false; } - if self.may_coerce(item_ty, expected_ty) { + // An unused associated const of type `!` may not have been evaluated yet. Do not + // suggest referring to it just because `!` can coerce to the expected type. + if self.may_coerce_except_never(item_ty, expected_ty) { err.span_suggestion_verbose( segment.ident.span, format!("try referring to the associated const `{capitalized_name}` instead",), @@ -2367,7 +2369,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } else { return false; }; - if is_ctor || !self.may_coerce(args.type_at(0), expected) { + let inner_ty = args.type_at(0); + + // For `Option` where `Option` is expected, extracting `!` cannot produce + // an `Option`. Never-to-any coercion alone must not justify `.expect()` or `?`. + if is_ctor || !self.may_coerce_except_never(inner_ty, expected) { return false; } diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index 930a74d8022a7..f85a14852d6cd 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -1401,7 +1401,7 @@ declare_lint! { /// See [RFC 2056] for more details. This feature is currently only /// available on the nightly channel, see [tracking issue #48214]. /// - /// [RFC 2056]: https://github.com/rust-lang/rfcs/blob/master/text/2056-allow-trivial-where-clause-constraints.md + /// [RFC 2056]: https://rust-lang.github.io/rfcs/2056-allow-trivial-where-clause-constraints.html /// [tracking issue #48214]: https://github.com/rust-lang/rust/issues/48214 TRIVIAL_BOUNDS, Warn, diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs index a8f4f06aaa4f7..95033707cf110 100644 --- a/compiler/rustc_lint/src/lib.rs +++ b/compiler/rustc_lint/src/lib.rs @@ -572,7 +572,7 @@ fn register_builtins(store: &mut LintStore) { store.register_removed( "unsupported_naked_functions", "converted into hard error, see RFC 2972 \ - for more information", + for more information", ); store.register_removed( "mutable_borrow_reservation_conflict", diff --git a/compiler/rustc_lint/src/non_ascii_idents.rs b/compiler/rustc_lint/src/non_ascii_idents.rs index 80e8a98cf267a..416b8717a7dc3 100644 --- a/compiler/rustc_lint/src/non_ascii_idents.rs +++ b/compiler/rustc_lint/src/non_ascii_idents.rs @@ -33,7 +33,7 @@ declare_lint! { /// collaboration or for security reasons). /// See [RFC 2457] for more details. /// - /// [RFC 2457]: https://github.com/rust-lang/rfcs/blob/master/text/2457-non-ascii-idents.md + /// [RFC 2457]: https://rust-lang.github.io/rfcs/2457-non-ascii-idents.html pub NON_ASCII_IDENTS, Allow, "detects non-ASCII identifiers", diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index a51c66f746ad7..9caba9c1b5fdb 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -1266,9 +1266,9 @@ declare_lint! { /// See [RFC 401 (coercions)][rfc-401], [RFC 803 (type ascription)][rfc-803] and /// [RFC 3307 (remove type ascription)][rfc-3307] for historical context. /// - /// [rfc-401]: https://github.com/rust-lang/rfcs/blob/master/text/0401-coercions.md - /// [rfc-803]: https://github.com/rust-lang/rfcs/blob/master/text/0803-type-ascription.md - /// [rfc-3307]: https://github.com/rust-lang/rfcs/blob/master/text/3307-de-rfc-type-ascription.md + /// [rfc-401]: https://rust-lang.github.io/rfcs/0401-coercions.html + /// [rfc-803]: https://rust-lang.github.io/rfcs/0803-type-ascription.html + /// [rfc-3307]: https://rust-lang.github.io/rfcs/3307-de-rfc-type-ascription.html pub TRIVIAL_CASTS, Allow, "detects trivial casts which could be removed" @@ -1301,9 +1301,9 @@ declare_lint! { /// See [RFC 401 (coercions)][rfc-401], [RFC 803 (type ascription)][rfc-803] and /// [RFC 3307 (remove type ascription)][rfc-3307] for historical context. /// - /// [rfc-401]: https://github.com/rust-lang/rfcs/blob/master/text/0401-coercions.md - /// [rfc-803]: https://github.com/rust-lang/rfcs/blob/master/text/0803-type-ascription.md - /// [rfc-3307]: https://github.com/rust-lang/rfcs/blob/master/text/3307-de-rfc-type-ascription.md + /// [rfc-401]: https://rust-lang.github.io/rfcs/0401-coercions.html + /// [rfc-803]: https://rust-lang.github.io/rfcs/0803-type-ascription.html + /// [rfc-3307]: https://rust-lang.github.io/rfcs/3307-de-rfc-type-ascription.html pub TRIVIAL_NUMERIC_CASTS, Allow, "detects trivial casts of numeric types which could be removed" @@ -1348,7 +1348,7 @@ declare_lint! { /// Note that support for this is only available on the nightly channel. /// See [RFC 1977] for more details, as well as the [Cargo documentation]. /// - /// [RFC 1977]: https://github.com/rust-lang/rfcs/blob/master/text/1977-public-private-dependencies.md + /// [RFC 1977]: https://rust-lang.github.io/rfcs/1977-public-private-dependencies.html /// [Cargo documentation]: https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#public-dependency pub EXPORTED_PRIVATE_DEPENDENCIES, Warn, @@ -1791,7 +1791,7 @@ declare_lint! { /// that it produces. See [RFC 2115] for historical context, and [issue /// #44752] for more details. /// - /// [RFC 2115]: https://github.com/rust-lang/rfcs/blob/master/text/2115-argument-lifetimes.md + /// [RFC 2115]: https://rust-lang.github.io/rfcs/2115-argument-lifetimes.html /// [issue #44752]: https://github.com/rust-lang/rust/issues/44752 pub SINGLE_USE_LIFETIMES, Allow, @@ -2092,7 +2092,7 @@ declare_lint! { /// [`while let`]: https://doc.rust-lang.org/reference/expressions/loop-expr.html#predicate-pattern-loops /// [`let`]: https://doc.rust-lang.org/reference/statements.html#let-statements /// [`loop`]: https://doc.rust-lang.org/reference/expressions/loop-expr.html#infinite-loops - /// [RFC 2086]: https://github.com/rust-lang/rfcs/blob/master/text/2086-allow-if-let-irrefutables.md + /// [RFC 2086]: https://rust-lang.github.io/rfcs/2086-allow-if-let-irrefutables.html pub IRREFUTABLE_LET_PATTERNS, Warn, "detects irrefutable patterns in `if let` and `while let` statements" @@ -2362,7 +2362,7 @@ declare_lint! { /// > fn render<'r>(_: Ref<'r, dyn std::fmt::Display + 'static>) {} /// > ``` /// - /// [RFC 2093]: https://github.com/rust-lang/rfcs/blob/master/text/2093-infer-outlives.md + /// [RFC 2093]: https://rust-lang.github.io/rfcs/2093-infer-outlives.html /// [TOLD]: https://doc.rust-lang.org/reference/lifetime-elision.html#default-trait-object-lifetimes pub EXPLICIT_OUTLIVES_REQUIREMENTS, Allow, @@ -2432,7 +2432,7 @@ declare_lint! { /// /// [issue #57644]: https://github.com/rust-lang/rust/issues/57644 /// [type aliases]: https://doc.rust-lang.org/reference/items/type-aliases.html#type-aliases - /// [RFC 2338]: https://github.com/rust-lang/rfcs/blob/master/text/2338-type-alias-enum-variants.md + /// [RFC 2338]: https://rust-lang.github.io/rfcs/2338-type-alias-enum-variants.html /// [qualified path]: https://doc.rust-lang.org/reference/paths.html#qualified-paths /// [future-incompatible]: ../index.md#future-incompatible-lints pub AMBIGUOUS_ASSOCIATED_ITEMS, @@ -2641,7 +2641,7 @@ declare_lint! { /// [`unsafe fn`]: https://doc.rust-lang.org/reference/unsafe-functions.html /// [`unsafe` block]: https://doc.rust-lang.org/reference/expressions/block-expr.html#unsafe-blocks /// [unsafe]: https://doc.rust-lang.org/reference/unsafety.html - /// [RFC #2585]: https://github.com/rust-lang/rfcs/blob/master/text/2585-unsafe-block-in-unsafe-fn.md + /// [RFC #2585]: https://rust-lang.github.io/rfcs/2585-unsafe-block-in-unsafe-fn.html /// [issue #71668]: https://github.com/rust-lang/rust/issues/71668 pub UNSAFE_OP_IN_UNSAFE_FN, Allow, diff --git a/compiler/rustc_middle/src/ty/typeck_results.rs b/compiler/rustc_middle/src/ty/typeck_results.rs index ff7cef3613437..45fe03499ed6f 100644 --- a/compiler/rustc_middle/src/ty/typeck_results.rs +++ b/compiler/rustc_middle/src/ty/typeck_results.rs @@ -101,7 +101,7 @@ pub struct TypeckResults<'tcx> { /// leads to a `vec![&Box>, Box>]`. Empty vectors are not stored. /// /// See: - /// + /// pat_adjustments: ItemLocalMap>>, /// Set of reference patterns that match against a match-ergonomics inserted reference diff --git a/compiler/rustc_pattern_analysis/src/constructor.rs b/compiler/rustc_pattern_analysis/src/constructor.rs index 2159a8533508f..6deec10071a16 100644 --- a/compiler/rustc_pattern_analysis/src/constructor.rs +++ b/compiler/rustc_pattern_analysis/src/constructor.rs @@ -880,7 +880,7 @@ impl Constructor { (Opaque(..), _) | (_, Opaque(..)) => false, _ => { - return Err(cx.bug(format_args!( + return Err(cx.delayed_bug(format_args!( "trying to compare incompatible constructors {self:?} and {other:?}" ))); } diff --git a/compiler/rustc_pattern_analysis/src/lib.rs b/compiler/rustc_pattern_analysis/src/lib.rs index 324ce0a4025e7..f17375ea47c5f 100644 --- a/compiler/rustc_pattern_analysis/src/lib.rs +++ b/compiler/rustc_pattern_analysis/src/lib.rs @@ -82,6 +82,11 @@ pub trait PatCx: Sized + fmt::Debug { /// Raise a bug. fn bug(&self, fmt: fmt::Arguments<'_>) -> Self::Error; + /// Raise a delayed bug. + fn delayed_bug(&self, fmt: fmt::Arguments<'_>) -> Self::Error { + self.bug(fmt) + } + /// Lint that the range `pat` overlapped with all the ranges in `overlaps_with`, where the range /// they overlapped over is `overlaps_on`. We only detect singleton overlaps. /// The default implementation does nothing. diff --git a/compiler/rustc_pattern_analysis/src/rustc.rs b/compiler/rustc_pattern_analysis/src/rustc.rs index d030756cfa954..df0ff7c22cd9d 100644 --- a/compiler/rustc_pattern_analysis/src/rustc.rs +++ b/compiler/rustc_pattern_analysis/src/rustc.rs @@ -932,6 +932,10 @@ impl<'p, 'tcx: 'p> PatCx for RustcPatCtxt<'p, 'tcx> { span_bug!(self.scrut_span, "{}", fmt) } + fn delayed_bug(&self, fmt: fmt::Arguments<'_>) -> Self::Error { + self.tcx.dcx().span_delayed_bug(self.scrut_span, format!("{fmt}")) + } + fn lint_overlapping_range_endpoints( &self, pat: &crate::pat::DeconstructedPat, diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs index 590cf99d1d272..9f1ff3fa6bc6b 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -56,7 +56,7 @@ impl<'tcx> fmt::Display for LazyDefPathStr<'tcx> { /// Implemented to visit all `DefId`s in a type. /// Visiting `DefId`s is useful because visibilities and reachabilities are attached to them. /// The idea is to visit "all components of a type", as documented in -/// . +/// . /// The default type visitor (`TypeVisitor`) does most of the job, but it has some shortcomings. /// First, it doesn't have overridable `fn visit_trait_ref`, so we have to catch trait `DefId`s /// manually. Second, it doesn't visit some type components like signatures of fn types, or traits diff --git a/compiler/rustc_span/src/edition.rs b/compiler/rustc_span/src/edition.rs index e24e05df113b4..38165f511b417 100644 --- a/compiler/rustc_span/src/edition.rs +++ b/compiler/rustc_span/src/edition.rs @@ -3,7 +3,7 @@ use std::str::FromStr; use rustc_macros::{BlobDecodable, Encodable, StableHash}; -/// The edition of the compiler. (See [RFC 2052](https://github.com/rust-lang/rfcs/blob/master/text/2052-epochs.md).) +/// The edition of the compiler. (See [RFC 2052](https://rust-lang.github.io/rfcs/2052-epochs.html).) #[derive(Clone, Copy, Hash, PartialEq, PartialOrd, Debug, Encodable, BlobDecodable, Eq)] #[derive(StableHash)] pub enum Edition { diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 68d28f9227dbe..c8fa04e08f768 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -2168,6 +2168,8 @@ symbols! { type_ascription, type_changing_struct_update, type_id, + type_id_array_len, + type_id_element_ty, type_id_eq, type_id_field_representing_type, type_id_fields, diff --git a/library/core/src/ffi/c_void.md b/library/core/src/ffi/c_void.md index 1c3ae6333d827..84def0777e9e7 100644 --- a/library/core/src/ffi/c_void.md +++ b/library/core/src/ffi/c_void.md @@ -13,4 +13,4 @@ compilers down to 1.1.0. After Rust 1.30.0, it was re-exported by this definition. For more information, please read [RFC 2521]. [Nomicon]: https://doc.rust-lang.org/nomicon/ffi.html#representing-opaque-structs -[RFC 2521]: https://github.com/rust-lang/rfcs/blob/master/text/2521-c_void-reunification.md +[RFC 2521]: https://rust-lang.github.io/rfcs/2521-c_void-reunification.html diff --git a/library/core/src/intrinsics/mod.rs b/library/core/src/intrinsics/mod.rs index f8cc81228b27b..9b55d70fecb9a 100644 --- a/library/core/src/intrinsics/mod.rs +++ b/library/core/src/intrinsics/mod.rs @@ -3009,6 +3009,22 @@ pub const fn type_id_eq(a: crate::any::TypeId, b: crate::any::TypeId) -> bool { #[rustc_comptime] pub fn type_id_is_signed(_id: crate::any::TypeId) -> bool; +/// Gets the length of the array represented by this `TypeId`. +/// +/// The more user-friendly version of this intrinsic is [`core::any::TypeId::array_len`]. +#[rustc_intrinsic] +#[unstable(feature = "core_intrinsics", issue = "none")] +#[rustc_comptime] +pub fn type_id_array_len(_id: crate::any::TypeId) -> usize; + +/// Gets the type of each element of the array or slice represented by this `TypeId`. +/// +/// The more user-friendly version of this intrinsic is [`core::any::TypeId::element_ty`]. +#[rustc_intrinsic] +#[unstable(feature = "core_intrinsics", issue = "none")] +#[rustc_comptime] +pub fn type_id_element_ty(_id: crate::any::TypeId) -> Option; + /// Gets the size of the type represented by this `TypeId`. /// /// The more user-friendly version of this intrinsic is [`core::any::TypeId::size`]. diff --git a/library/core/src/keyword_docs.rs b/library/core/src/keyword_docs.rs index 38f48d29ff272..2ea028ef8439d 100644 --- a/library/core/src/keyword_docs.rs +++ b/library/core/src/keyword_docs.rs @@ -2506,7 +2506,7 @@ const _: () = (); /// } /// ``` /// -/// [RFC]: https://github.com/rust-lang/rfcs/blob/master/text/0135-where.md +/// [RFC]: https://rust-lang.github.io/rfcs/0135-where.html const _: () = (); #[doc(keyword = "while")] diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs index e499955df9479..bb90dbb834497 100644 --- a/library/core/src/marker.rs +++ b/library/core/src/marker.rs @@ -225,7 +225,7 @@ pub trait PointeeSized { /// /// [`ops::CoerceUnsized`]: crate::ops::CoerceUnsized /// [`Rc`]: ../../std/rc/struct.Rc.html -/// [RFC982]: https://github.com/rust-lang/rfcs/blob/master/text/0982-dst-coercion.md +/// [RFC982]: https://rust-lang.github.io/rfcs/0982-dst-coercion.html /// [nomicon-coerce]: ../../nomicon/coercions.html /// [^1]: Formerly known as *object safe*. #[unstable(feature = "unsize", issue = "18598")] diff --git a/library/core/src/mem/type_info.rs b/library/core/src/mem/type_info.rs index 1f38339a7421b..a11d1f1d0dc18 100644 --- a/library/core/src/mem/type_info.rs +++ b/library/core/src/mem/type_info.rs @@ -78,9 +78,9 @@ pub enum TypeKind { /// Tuples. Tuple, /// Arrays. - Array(Array), + Array, /// Slices. - Slice(Slice), + Slice, /// Dynamic Traits. DynTrait(DynTrait), /// Structs. @@ -111,26 +111,6 @@ pub enum TypeKind { Other, } -/// Compile-time type information about arrays. -#[derive(Debug)] -#[non_exhaustive] -#[unstable(feature = "type_info", issue = "146922")] -pub struct Array { - /// The type of each element in the array. - pub element_ty: TypeId, - /// The length of the array. - pub len: usize, -} - -/// Compile-time type information about slices. -#[derive(Debug)] -#[non_exhaustive] -#[unstable(feature = "type_info", issue = "146922")] -pub struct Slice { - /// The type of each element in the slice. - pub element_ty: TypeId, -} - /// Compile-time type information about dynamic traits. /// FIXME(#146922): Add super traits and generics #[derive(Debug)] @@ -295,6 +275,44 @@ impl TypeId { intrinsics::type_id_is_signed(self) } + /// When called on a `TypeId` representing an array or slice this returns the type of each + /// element otherwise this returns `None`. + /// + /// # Examples + /// + /// ``` + /// #![feature(type_info)] + /// use std::any::TypeId; + /// + /// assert_eq!(const { TypeId::of::<[u32; 16]>().element_ty() }, Some(TypeId::of::())); + /// assert_eq!(const { TypeId::of::().element_ty() }, None); // not an array or slice + /// ``` + #[unstable(feature = "type_info", issue = "146922")] + #[rustc_const_unstable(feature = "type_info", issue = "146922")] + #[rustc_comptime] + pub fn element_ty(self) -> Option { + intrinsics::type_id_element_ty(self) + } + + /// When called on a `TypeId` representing an array this returns the length of the array in + /// all other cases this returns zero. + /// + /// # Examples + /// + /// ``` + /// #![feature(type_info)] + /// use std::any::TypeId; + /// + /// assert_eq!(const { TypeId::of::<[u32; 16]>().array_len() }, 16); + /// assert_eq!(const { TypeId::of::().array_len() }, 0); // not an array + /// ``` + #[unstable(feature = "type_info", issue = "146922")] + #[rustc_const_unstable(feature = "type_info", issue = "146922")] + #[rustc_comptime] + pub fn array_len(self) -> usize { + intrinsics::type_id_array_len(self) + } + /// Returns the size of the type represented by this `TypeId`. `None` if it is unsized. /// /// # Examples diff --git a/library/core/src/ops/unsize.rs b/library/core/src/ops/unsize.rs index aade68df2b6ce..979b5f1737407 100644 --- a/library/core/src/ops/unsize.rs +++ b/library/core/src/ops/unsize.rs @@ -28,7 +28,7 @@ use crate::marker::{PointeeSized, Unsize}; /// [`Unsize`][unsize] is used to mark types which can be coerced to DSTs if behind /// pointers. It is implemented automatically by the compiler. /// -/// [dst-coerce]: https://github.com/rust-lang/rfcs/blob/master/text/0982-dst-coercion.md +/// [dst-coerce]: https://rust-lang.github.io/rfcs/0982-dst-coercion.html /// [unsize]: crate::marker::Unsize /// [nomicon-coerce]: ../../nomicon/coercions.html #[unstable(feature = "coerce_unsized", issue = "18598")] diff --git a/library/core/src/panic/unwind_safe.rs b/library/core/src/panic/unwind_safe.rs index bf2e61dc541c6..60c833db33e15 100644 --- a/library/core/src/panic/unwind_safe.rs +++ b/library/core/src/panic/unwind_safe.rs @@ -42,7 +42,7 @@ use crate::task::{Context, Poll}; /// That was a bit of a whirlwind tour of unwind safety, but for more information /// about unwind safety and how it applies to Rust, see an [associated RFC][rfc]. /// -/// [rfc]: https://github.com/rust-lang/rfcs/blob/master/text/1236-stabilize-catch-panic.md +/// [rfc]: https://rust-lang.github.io/rfcs/1236-stabilize-catch-panic.html /// /// ## What is `UnwindSafe`? /// diff --git a/library/core/src/ptr/unique.rs b/library/core/src/ptr/unique.rs index dedabf7043cd6..5e3fe666ac9ba 100644 --- a/library/core/src/ptr/unique.rs +++ b/library/core/src/ptr/unique.rs @@ -38,7 +38,7 @@ pub struct Unique { // for dropck to understand that we logically own a `T`. // // For details, see: - // https://github.com/rust-lang/rfcs/blob/master/text/0769-sound-generic-drop.md#phantom-data + // https://rust-lang.github.io/rfcs/0769-sound-generic-drop.html#phantom-data _marker: PhantomData, } diff --git a/library/coretests/tests/mem/type_info.rs b/library/coretests/tests/mem/type_info.rs index 7fe592496f1a7..865b6a269afff 100644 --- a/library/coretests/tests/mem/type_info.rs +++ b/library/coretests/tests/mem/type_info.rs @@ -7,29 +7,27 @@ use std::mem::type_info::{Const, Generic, GenericType, Type, TypeKind}; #[test] fn test_arrays() { // Normal array. - match const { Type::of::<[u16; 4]>() }.kind { - TypeKind::Array(array) => { - assert_eq!(array.element_ty, TypeId::of::()); - assert_eq!(array.len, 4); - } - _ => unreachable!(), + assert!(matches!(Type::of::<[u16; 4]>().kind, TypeKind::Array)); + const { + let ty_id = TypeId::of::<[u16; 4]>(); + assert!(ty_id.element_ty() == Some(TypeId::of::())); + assert!(ty_id.array_len() == 4); } // Zero-length array. - match const { Type::of::<[bool; 0]>() }.kind { - TypeKind::Array(array) => { - assert_eq!(array.element_ty, TypeId::of::()); - assert_eq!(array.len, 0); - } - _ => unreachable!(), + assert!(matches!(Type::of::<[bool; 0]>().kind, TypeKind::Array)); + const { + let ty_id = TypeId::of::<[bool; 0]>(); + assert!(ty_id.element_ty() == Some(TypeId::of::())); + assert!(ty_id.array_len() == 0); } } #[test] fn test_slices() { - match const { Type::of::<[usize]>() }.kind { - TypeKind::Slice(slice) => assert_eq!(slice.element_ty, TypeId::of::()), - _ => unreachable!(), + assert!(matches!(Type::of::<[usize]>().kind, TypeKind::Slice)); + const { + assert!(TypeId::of::<[usize]>().element_ty() == Some(TypeId::of::())); } } diff --git a/library/std/src/panic.rs b/library/std/src/panic.rs index a07a5fb6290ca..3ef786c294187 100644 --- a/library/std/src/panic.rs +++ b/library/std/src/panic.rs @@ -313,7 +313,7 @@ pub use core::panic::abort_on_unwind; /// it becomes a problem the [`AssertUnwindSafe`] wrapper struct can be used to /// quickly assert that the usage here is indeed unwind safe. /// -/// [rfc]: https://github.com/rust-lang/rfcs/blob/master/text/1236-stabilize-catch-panic.md +/// [rfc]: https://rust-lang.github.io/rfcs/1236-stabilize-catch-panic.html /// /// # Notes /// diff --git a/src/doc/rustc/src/lints/index.md b/src/doc/rustc/src/lints/index.md index 029c9edc1b5fe..e2499b204b458 100644 --- a/src/doc/rustc/src/lints/index.md +++ b/src/doc/rustc/src/lints/index.md @@ -57,4 +57,4 @@ warning: borrow of packed field is unsafe and requires unsafe function or block For more information about the process and policy of future-incompatible changes, see [RFC 1589]. -[RFC 1589]: https://github.com/rust-lang/rfcs/blob/master/text/1589-rustc-bug-fix-procedure.md +[RFC 1589]: https://rust-lang.github.io/rfcs/1589-rustc-bug-fix-procedure.html diff --git a/src/doc/unstable-book/src/language-features/default-field-values.md b/src/doc/unstable-book/src/language-features/default-field-values.md index 6da6c4e6c57e4..9060e52481ca4 100644 --- a/src/doc/unstable-book/src/language-features/default-field-values.md +++ b/src/doc/unstable-book/src/language-features/default-field-values.md @@ -6,7 +6,7 @@ The tracking issue for this feature is: [#132162] The RFC for this feature is: [#3681] -[#3681]: https://github.com/rust-lang/rfcs/blob/master/text/3681-default-field-values.md +[#3681]: https://rust-lang.github.io/rfcs/3681-default-field-values.html ------------------------ diff --git a/src/doc/unstable-book/src/language-features/type-changing-struct-update.md b/src/doc/unstable-book/src/language-features/type-changing-struct-update.md index 9909cf35b5b51..5d71bcd3ac3f0 100644 --- a/src/doc/unstable-book/src/language-features/type-changing-struct-update.md +++ b/src/doc/unstable-book/src/language-features/type-changing-struct-update.md @@ -9,7 +9,7 @@ The tracking issue for this feature is: [#86555] This implements [RFC2528]. When turned on, you can create instances of the same struct that have different generic type or lifetime parameters. -[RFC2528]: https://github.com/rust-lang/rfcs/blob/master/text/2528-type-changing-struct-update-syntax.md +[RFC2528]: https://rust-lang.github.io/rfcs/2528-type-changing-struct-update-syntax.html ```rust #![allow(unused_variables, dead_code)] diff --git a/src/rustdoc-json-types/lib.rs b/src/rustdoc-json-types/lib.rs index 3c20d392aab91..29ac079b6cc44 100644 --- a/src/rustdoc-json-types/lib.rs +++ b/src/rustdoc-json-types/lib.rs @@ -278,7 +278,7 @@ pub struct Item { /// The full markdown docstring of this item. Absent if there is no documentation at all, /// Some("") if there is some documentation but it is empty (EG `#[doc = ""]`). pub docs: Option, - /// This mapping resolves [intra-doc links](https://github.com/rust-lang/rfcs/blob/master/text/1946-intra-rustdoc-links.md) from the docstring to their IDs + /// This mapping resolves [intra-doc links](https://rust-lang.github.io/rfcs/1946-intra-rustdoc-links.html) from the docstring to their IDs pub links: HashMap, /// Attributes on this item. /// diff --git a/tests/run-make/raw-dylib-alt-calling-convention/rmake.rs b/tests/run-make/raw-dylib-alt-calling-convention/rmake.rs index 0843c6beae823..89e22fd6bfaba 100644 --- a/tests/run-make/raw-dylib-alt-calling-convention/rmake.rs +++ b/tests/run-make/raw-dylib-alt-calling-convention/rmake.rs @@ -1,7 +1,7 @@ // `raw-dylib` is a Windows-specific attribute which emits idata sections for the items in the // attached extern block, // so they may be linked against without linking against an import library. -// To learn more, read https://github.com/rust-lang/rfcs/blob/master/text/2627-raw-dylib-kind.md +// To learn more, read https://rust-lang.github.io/rfcs/2627-raw-dylib-kind.html // This test uses this feature alongside alternative calling conventions, checking that both // features are compatible and result in the expected output upon execution of the binary. // See https://github.com/rust-lang/rust/pull/84171 diff --git a/tests/run-make/raw-dylib-c/rmake.rs b/tests/run-make/raw-dylib-c/rmake.rs index 3cfd8cb400bbf..8ee7018536fc8 100644 --- a/tests/run-make/raw-dylib-c/rmake.rs +++ b/tests/run-make/raw-dylib-c/rmake.rs @@ -1,7 +1,7 @@ // `raw-dylib` is a Windows-specific attribute which emits idata sections for the items in the // attached extern block, // so they may be linked against without linking against an import library. -// To learn more, read https://github.com/rust-lang/rfcs/blob/master/text/2627-raw-dylib-kind.md +// To learn more, read https://rust-lang.github.io/rfcs/2627-raw-dylib-kind.html // This test is the simplest of the raw-dylib tests, simply smoke-testing that the feature // can be used to build an executable binary with an expected output with native C files // compiling into dynamic libraries. diff --git a/tests/run-make/raw-dylib-import-name-type/rmake.rs b/tests/run-make/raw-dylib-import-name-type/rmake.rs index 71f255ab39f06..d1a1ea75064c5 100644 --- a/tests/run-make/raw-dylib-import-name-type/rmake.rs +++ b/tests/run-make/raw-dylib-import-name-type/rmake.rs @@ -1,7 +1,7 @@ // `raw-dylib` is a Windows-specific attribute which emits idata sections for the items in the // attached extern block, // so they may be linked against without linking against an import library. -// To learn more, read https://github.com/rust-lang/rfcs/blob/master/text/2627-raw-dylib-kind.md +// To learn more, read https://rust-lang.github.io/rfcs/2627-raw-dylib-kind.html // This test uses this feature alongside `import_name_type`, which allows for customization // of how Windows symbols will be named. A sanity check of this feature is done by comparison // with expected output. diff --git a/tests/run-make/raw-dylib-link-ordinal/rmake.rs b/tests/run-make/raw-dylib-link-ordinal/rmake.rs index b9254b167534b..2c30114e0c3bf 100644 --- a/tests/run-make/raw-dylib-link-ordinal/rmake.rs +++ b/tests/run-make/raw-dylib-link-ordinal/rmake.rs @@ -1,7 +1,7 @@ // `raw-dylib` is a Windows-specific attribute which emits idata sections for the items in the // attached extern block, // so they may be linked against without linking against an import library. -// To learn more, read https://github.com/rust-lang/rfcs/blob/master/text/2627-raw-dylib-kind.md +// To learn more, read https://rust-lang.github.io/rfcs/2627-raw-dylib-kind.html // `#[link_ordinal(n)]` allows Rust to link against DLLs that export symbols by ordinal rather // than by name. As long as the ordinal matches, the name of the function in Rust is not // required to match the name of the corresponding function in the exporting DLL. diff --git a/tests/run-make/raw-dylib-stdcall-ordinal/rmake.rs b/tests/run-make/raw-dylib-stdcall-ordinal/rmake.rs index f898cc0f8c8d4..b6b4263487f95 100644 --- a/tests/run-make/raw-dylib-stdcall-ordinal/rmake.rs +++ b/tests/run-make/raw-dylib-stdcall-ordinal/rmake.rs @@ -1,7 +1,7 @@ // `raw-dylib` is a Windows-specific attribute which emits idata sections for the items in the // attached extern block, // so they may be linked against without linking against an import library. -// To learn more, read https://github.com/rust-lang/rfcs/blob/master/text/2627-raw-dylib-kind.md +// To learn more, read https://rust-lang.github.io/rfcs/2627-raw-dylib-kind.html // Almost identical to `raw-dylib-link-ordinal`, but with the addition of calling conventions, // such as stdcall. // See https://github.com/rust-lang/rust/pull/90782 diff --git a/tests/ui/README.md b/tests/ui/README.md index b80c8215c1cf8..8df2769996f41 100644 --- a/tests/ui/README.md +++ b/tests/ui/README.md @@ -88,7 +88,7 @@ These tests exercise associated constants in traits and impls, on aspects such a These tests cover associated types defined directly within inherent impls (not in traits). -See [RFC 0195 Associated items - Inherent associated items](https://github.com/rust-lang/rfcs/blob/master/text/0195-associated-items.md#inherent-associated-items). +See [RFC 0195 Associated items - Inherent associated items](https://rust-lang.github.io/rfcs/0195-associated-items.html#inherent-associated-items). ## `tests/ui/associated-item`: Associated Items @@ -429,7 +429,7 @@ Tests for built-in derive macros (`Debug`, `Clone`, etc.) when used in conjuncti ## `tests/ui/destructuring-assignment/` -Exercises destructuring assignments. See [RFC 2909 Destructuring assignment](https://github.com/rust-lang/rfcs/blob/master/text/2909-destructuring-assignment.md). +Exercises destructuring assignments. See [RFC 2909 Destructuring assignment](https://rust-lang.github.io/rfcs/2909-destructuring-assignment.html). ## `tests/ui/diagnostic-flags/` @@ -443,7 +443,7 @@ Everything to do with `--diagnostic-width`. ## `tests/ui/diagnostic_namespace/` -Exercises `#[diagnostic::*]` namespaced attributes. See [RFC 3368 Diagnostic attribute namespace](https://github.com/rust-lang/rfcs/blob/master/text/3368-diagnostic-attribute-namespace.md). +Exercises `#[diagnostic::*]` namespaced attributes. See [RFC 3368 Diagnostic attribute namespace](https://rust-lang.github.io/rfcs/3368-diagnostic-attribute-namespace.html). ## `tests/ui/did_you_mean/` @@ -653,7 +653,7 @@ See: Functional Struct Update is the name for the idiom by which one can write `..` at the end of a struct literal expression to fill in all remaining fields of the struct literal by using `` as the source for them. -See [RFC 0736 Privacy-respecting Functional Struct Update](https://github.com/rust-lang/rfcs/blob/master/text/0736-privacy-respecting-fru.md). +See [RFC 0736 Privacy-respecting Functional Struct Update](https://rust-lang.github.io/rfcs/0736-privacy-respecting-fru.html). ## `tests/ui/functions-closures/` @@ -959,7 +959,7 @@ See [Tracking issue for promoting `!` to a type (RFC 1216) #35121](https://githu ## `tests/ui/new-range/` -See [RFC 3550 New Range](https://github.com/rust-lang/rfcs/blob/master/text/3550-new-range.md). +See [RFC 3550 New Range](https://rust-lang.github.io/rfcs/3550-new-range.html). ## `tests/ui/nll/`: Non-lexical lifetimes @@ -1038,7 +1038,7 @@ See [panic handler | Nomicon](https://doc.rust-lang.org/nomicon/panic-handler.ht Exercises `#![panic_runtime]`, `-C panic`, panic runtimes and panic unwind strategy. -See [RFC 1513 Less unwinding](https://github.com/rust-lang/rfcs/blob/master/text/1513-less-unwinding.md). +See [RFC 1513 Less unwinding](https://rust-lang.github.io/rfcs/1513-less-unwinding.html). ## `tests/ui/panics/` @@ -1134,7 +1134,7 @@ Broad category of tests ranges, both in their `..` or `..=` form, as well as the ## `tests/ui/raw-ref-op/`: Using operators on `&raw` values -Exercises `&raw mut ` and `&raw const `. See [RFC 2582 Raw reference MIR operator](https://github.com/rust-lang/rfcs/blob/master/text/2582-raw-reference-mir-operator.md). +Exercises `&raw mut ` and `&raw const `. See [RFC 2582 Raw reference MIR operator](https://rust-lang.github.io/rfcs/2582-raw-reference-mir-operator.html). ## `tests/ui/reachable` @@ -1444,7 +1444,7 @@ Tests for the `#[doc(hidden)]` items. ## `tests/ui/trivial-bounds/` -`#![feature(trivial_bounds)]`. See [RFC 2056 Allow trivial where clause constraints](https://github.com/rust-lang/rfcs/blob/master/text/2056-allow-trivial-where-clause-constraints.md). +`#![feature(trivial_bounds)]`. See [RFC 2056 Allow trivial where clause constraints](https://rust-lang.github.io/rfcs/2056-allow-trivial-where-clause-constraints.html). ## `tests/ui/try-block/` @@ -1452,7 +1452,7 @@ Tests for the `#[doc(hidden)]` items. ## `tests/ui/try-trait/` -`#![feature(try_trait_v2)]`. See [RFC 3058 Try Trait v2](https://github.com/rust-lang/rfcs/blob/master/text/3058-try-trait-v2.md). +`#![feature(try_trait_v2)]`. See [RFC 3058 Try Trait v2](https://rust-lang.github.io/rfcs/3058-try-trait-v2.html). ## `tests/ui/tuple/` @@ -1486,7 +1486,7 @@ General collection of type checking related tests. ## `tests/ui/ufcs/` -See [RFC 0132 Unified Function Call Syntax](https://github.com/rust-lang/rfcs/blob/master/text/0132-ufcs.md). +See [RFC 0132 Unified Function Call Syntax](https://rust-lang.github.io/rfcs/0132-ufcs.html). ## `tests/ui/unboxed-closures/` @@ -1550,7 +1550,7 @@ See [Tracking issue for RFC 3458: Unsafe fields #132922](https://github.com/rust See: -- [RFC 1909 Unsized rvalues](https://github.com/rust-lang/rfcs/blob/master/text/1909-unsized-rvalues.md) +- [RFC 1909 Unsized rvalues](https://rust-lang.github.io/rfcs/1909-unsized-rvalues.html) - [de-RFC 3829: Remove unsized_locals](https://github.com/rust-lang/rfcs/pull/3829) - [Tracking issue for RFC #1909: Unsized Rvalues (`unsized_locals`, `unsized_fn_params`)](https://github.com/rust-lang/rust/issues/48055) diff --git a/tests/ui/const-generics/gca/const-pattern-field-type-mismatch-162394.rs b/tests/ui/const-generics/gca/const-pattern-field-type-mismatch-162394.rs new file mode 100644 index 0000000000000..9557c9da80702 --- /dev/null +++ b/tests/ui/const-generics/gca/const-pattern-field-type-mismatch-162394.rs @@ -0,0 +1,25 @@ +//@ compile-flags: -Znext-solver=globally + +#![allow(incomplete_features)] +#![feature(macroless_generic_const_args)] +#![feature(generic_const_args, min_generic_const_args)] +#![feature(min_adt_const_params)] + +use std::marker::ConstParamTy; + +#[derive(PartialEq, Eq, ConstParamTy)] +pub enum Foo { + FooA(()), +} + +impl Foo { + const A2: Foo = Self::FooA("foo"); //~ ERROR the constant `"foo"` is not of type `()` +} + +fn main() { + let foo = Foo::FooA(()); + match foo { + Foo::A2 => {} + _ => {} + } +} diff --git a/tests/ui/const-generics/gca/const-pattern-field-type-mismatch-162394.stderr b/tests/ui/const-generics/gca/const-pattern-field-type-mismatch-162394.stderr new file mode 100644 index 0000000000000..afa00eaeed7e7 --- /dev/null +++ b/tests/ui/const-generics/gca/const-pattern-field-type-mismatch-162394.stderr @@ -0,0 +1,8 @@ +error: the constant `"foo"` is not of type `()` + --> $DIR/const-pattern-field-type-mismatch-162394.rs:16:5 + | +LL | const A2: Foo = Self::FooA("foo"); + | ^^^^^^^^^^^^^ expected `()`, found `&'static str` + +error: aborting due to 1 previous error + diff --git a/tests/ui/explain/basic.stdout b/tests/ui/explain/basic.stdout index 6377768d4785d..c87295f008df3 100644 --- a/tests/ui/explain/basic.stdout +++ b/tests/ui/explain/basic.stdout @@ -68,4 +68,4 @@ alone suffices for that. `*mut fn()` is a pointer to a fn pointer. (Since these values are typically just passed to C code, however, this rarely makes a difference in practice.) -[rfc401]: https://github.com/rust-lang/rfcs/blob/master/text/0401-coercions.md +[rfc401]: https://rust-lang.github.io/rfcs/0401-coercions.html diff --git a/tests/ui/explain/ensure-color-always-works.stdout b/tests/ui/explain/ensure-color-always-works.stdout index 7e5358bcfb7ec..3ab869f7ebfbb 100644 --- a/tests/ui/explain/ensure-color-always-works.stdout +++ b/tests/ui/explain/ensure-color-always-works.stdout @@ -1,4 +1,4 @@ -Per ]8;;https://github.com/rust-lang/rfcs/blob/master/text/0401-coercions.md\RFC 401]8;;\, if you have a function declaration foo: +Per ]8;;https://rust-lang.github.io/rfcs/0401-coercions.html\RFC 401]8;;\, if you have a function declaration foo: struct S; diff --git a/tests/ui/mismatched_types/never-option-unwrap-suggestion-issue-162241.rs b/tests/ui/mismatched_types/never-option-unwrap-suggestion-issue-162241.rs new file mode 100644 index 0000000000000..82a8fe45e0454 --- /dev/null +++ b/tests/ui/mismatched_types/never-option-unwrap-suggestion-issue-162241.rs @@ -0,0 +1,22 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/162241. + +fn main() { + let never: Option = None; + let _: Option = never; + //~^ ERROR mismatched types + + let x: Option = None; + let _: ! = x; + //~^ ERROR mismatched types + + let never: Option = loop {}; + let number: Option = never; + //~^ ERROR mismatched types +} + +fn question_mark() -> Option { + let never: Option = None; + let _: u32 = never; + //~^ ERROR mismatched types + Some(0) +} diff --git a/tests/ui/mismatched_types/never-option-unwrap-suggestion-issue-162241.stderr b/tests/ui/mismatched_types/never-option-unwrap-suggestion-issue-162241.stderr new file mode 100644 index 0000000000000..a9787accf9d24 --- /dev/null +++ b/tests/ui/mismatched_types/never-option-unwrap-suggestion-issue-162241.stderr @@ -0,0 +1,51 @@ +error[E0308]: mismatched types + --> $DIR/never-option-unwrap-suggestion-issue-162241.rs:5:26 + | +LL | let _: Option = never; + | ----------- ^^^^^ expected `Option`, found `Option` + | | + | expected due to this + | + = note: expected enum `Option` + found enum `Option` + +error[E0308]: mismatched types + --> $DIR/never-option-unwrap-suggestion-issue-162241.rs:9:16 + | +LL | let _: ! = x; + | - ^ expected `!`, found `Option` + | | + | expected due to this + | + = note: expected type `!` + found enum `Option` +help: consider using `Option::expect` to unwrap the `Option` value, panicking if the value is an `Option::None` + | +LL | let _: ! = x.expect("REASON"); + | +++++++++++++++++ + +error[E0308]: mismatched types + --> $DIR/never-option-unwrap-suggestion-issue-162241.rs:13:31 + | +LL | let number: Option = never; + | ----------- ^^^^^ expected `Option`, found `Option` + | | + | expected due to this + | + = note: expected enum `Option` + found enum `Option` + +error[E0308]: mismatched types + --> $DIR/never-option-unwrap-suggestion-issue-162241.rs:19:18 + | +LL | let _: u32 = never; + | --- ^^^^^ expected `u32`, found `Option` + | | + | expected due to this + | + = note: expected type `u32` + found enum `Option` + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/rfcs/rfc-1238-nonparametric-dropck/must-work-ex1.rs b/tests/ui/rfcs/rfc-1238-nonparametric-dropck/must-work-ex1.rs index 9afd7ddbd88a9..b7dd767eddfc5 100644 --- a/tests/ui/rfcs/rfc-1238-nonparametric-dropck/must-work-ex1.rs +++ b/tests/ui/rfcs/rfc-1238-nonparametric-dropck/must-work-ex1.rs @@ -1,6 +1,6 @@ //! Test for . //! Example taken from RFC 1238 text -//! . +//! . //@ run-pass use std::cell::Cell; diff --git a/tests/ui/rfcs/rfc-1238-nonparametric-dropck/must-work-ex2.rs b/tests/ui/rfcs/rfc-1238-nonparametric-dropck/must-work-ex2.rs index 4e8d403672641..06d84d5d4e911 100644 --- a/tests/ui/rfcs/rfc-1238-nonparametric-dropck/must-work-ex2.rs +++ b/tests/ui/rfcs/rfc-1238-nonparametric-dropck/must-work-ex2.rs @@ -1,6 +1,6 @@ //! Test for . //! Example taken from RFC 1238 text -//! . +//! . //@ run-pass use std::cell::Cell; diff --git a/tests/ui/rfcs/rfc-1238-nonparametric-dropck/reject-ex1.rs b/tests/ui/rfcs/rfc-1238-nonparametric-dropck/reject-ex1.rs index 3209a17041f67..1866376448dc2 100644 --- a/tests/ui/rfcs/rfc-1238-nonparametric-dropck/reject-ex1.rs +++ b/tests/ui/rfcs/rfc-1238-nonparametric-dropck/reject-ex1.rs @@ -1,6 +1,6 @@ //! Test for . //! Example taken from RFC 1238 text -//! . +//! . //! Compare against tests/ui/rfcs/rfc-1238-nonparametric-dropck/must-work-ex2.rs. use std::cell::Cell; diff --git a/tests/ui/rfcs/rfc-1238-nonparametric-dropck/ugeh-ex1.rs b/tests/ui/rfcs/rfc-1238-nonparametric-dropck/ugeh-ex1.rs index 722523c094329..61136f224a542 100644 --- a/tests/ui/rfcs/rfc-1238-nonparametric-dropck/ugeh-ex1.rs +++ b/tests/ui/rfcs/rfc-1238-nonparametric-dropck/ugeh-ex1.rs @@ -1,6 +1,6 @@ //! Test for . //! Example taken from RFC 1238 text -//! . +//! . //@ run-pass #![feature(dropck_eyepatch)] diff --git a/tests/ui/suggestions/never-coercion-equality-suggestion.rs b/tests/ui/suggestions/never-coercion-equality-suggestion.rs new file mode 100644 index 0000000000000..f5ec7393b0cf6 --- /dev/null +++ b/tests/ui/suggestions/never-coercion-equality-suggestion.rs @@ -0,0 +1,48 @@ +//! Never-to-any coercions should not justify suggesting equality in place of assignment. + +#![allow(unreachable_code, unused_mut)] + +fn diverging() -> ! { + panic!() +} + +fn direct(value: String) { + if value = diverging() {} + //~^ ERROR mismatched types +} + +fn inferred_integer() { + let mut value = 0; + if value = diverging() {} + //~^ ERROR mismatched types +} + +fn logical_lhs(flag: bool) { + if flag && flag = diverging() {} + //~^ ERROR mismatched types + + if flag || flag = diverging() {} + //~^ ERROR mismatched types +} + +fn logical_rhs(value: String, flag: bool) { + if value = diverging() && flag {} + //~^ ERROR mismatched types + + if value = diverging() || flag {} + //~^ ERROR mismatched types +} + +fn ordinary_comparison(value: String) { + // Keep suggesting equality when the types match without never-to-any coercion. + if value = String::new() {} + //~^ ERROR mismatched types +} + +fn never_comparison(left: !, right: !) { + // Comparing two never values does not require a never-to-any coercion either. + if left = right {} + //~^ ERROR mismatched types +} + +fn main() {} diff --git a/tests/ui/suggestions/never-coercion-equality-suggestion.stderr b/tests/ui/suggestions/never-coercion-equality-suggestion.stderr new file mode 100644 index 0000000000000..87f89273b93fe --- /dev/null +++ b/tests/ui/suggestions/never-coercion-equality-suggestion.stderr @@ -0,0 +1,61 @@ +error[E0308]: mismatched types + --> $DIR/never-coercion-equality-suggestion.rs:10:8 + | +LL | if value = diverging() {} + | ^^^^^^^^^^^^^^^^^^^ expected `bool`, found `()` + +error[E0308]: mismatched types + --> $DIR/never-coercion-equality-suggestion.rs:16:8 + | +LL | if value = diverging() {} + | ^^^^^^^^^^^^^^^^^^^ expected `bool`, found `()` + +error[E0308]: mismatched types + --> $DIR/never-coercion-equality-suggestion.rs:21:8 + | +LL | if flag && flag = diverging() {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `bool`, found `()` + +error[E0308]: mismatched types + --> $DIR/never-coercion-equality-suggestion.rs:24:8 + | +LL | if flag || flag = diverging() {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `bool`, found `()` + +error[E0308]: mismatched types + --> $DIR/never-coercion-equality-suggestion.rs:29:8 + | +LL | if value = diverging() && flag {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `bool`, found `()` + +error[E0308]: mismatched types + --> $DIR/never-coercion-equality-suggestion.rs:32:8 + | +LL | if value = diverging() || flag {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `bool`, found `()` + +error[E0308]: mismatched types + --> $DIR/never-coercion-equality-suggestion.rs:38:8 + | +LL | if value = String::new() {} + | ^^^^^^^^^^^^^^^^^^^^^ expected `bool`, found `()` + | +help: you might have meant to compare for equality + | +LL | if value == String::new() {} + | + + +error[E0308]: mismatched types + --> $DIR/never-coercion-equality-suggestion.rs:44:8 + | +LL | if left = right {} + | ^^^^^^^^^^^^ expected `bool`, found `()` + | +help: you might have meant to compare for equality + | +LL | if left == right {} + | + + +error: aborting due to 8 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/suggestions/never-coercion-suggestion-candidates.rs b/tests/ui/suggestions/never-coercion-suggestion-candidates.rs new file mode 100644 index 0000000000000..cfb92e76581a1 --- /dev/null +++ b/tests/ui/suggestions/never-coercion-suggestion-candidates.rs @@ -0,0 +1,39 @@ +//! Reject candidates justified only by never coercions, but retain useful suggestions for +//! calling diverging functions and using lazy fallbacks. + +fn diverging() -> ! { + panic!() +} + +fn call_diverging_function() { + // Keep the suggestion to call `diverging`: a missing call is still plausible even when + // the function never returns. + let _: u32 = diverging; + //~^ ERROR mismatched types +} + +struct Inherent; + +impl Inherent { + fn item() {} + const ITEM: ! = panic!(); +} + +fn associated_const() { + let _: u32 = Inherent::item; + //~^ ERROR mismatched types +} + +fn lazy_fallback() { + // Keep `unwrap_or_else` as a hint to use a lazy fallback. The explicit `-> !` also needs + // to be removed for the suggested code to compile; this suggestion does not handle that. + let _: u32 = None::.unwrap_or(|| -> ! { panic!() }); + //~^ ERROR mismatched types +} + +fn map_or_never(value: Option) -> ! { + value.unwrap_or(&[]) + //~^ ERROR mismatched types +} + +fn main() {} diff --git a/tests/ui/suggestions/never-coercion-suggestion-candidates.stderr b/tests/ui/suggestions/never-coercion-suggestion-candidates.stderr new file mode 100644 index 0000000000000..6eb18897cb3cc --- /dev/null +++ b/tests/ui/suggestions/never-coercion-suggestion-candidates.stderr @@ -0,0 +1,78 @@ +error[E0308]: mismatched types + --> $DIR/never-coercion-suggestion-candidates.rs:11:18 + | +LL | fn diverging() -> ! { + | ------------------- function `diverging` defined here +... +LL | let _: u32 = diverging; + | --- ^^^^^^^^^ expected `u32`, found fn item + | | + | expected due to this + | + = note: expected type `u32` + found fn item `fn() -> ! {diverging}` +help: use parentheses to call this function + | +LL | let _: u32 = diverging(); + | ++ + +error[E0308]: mismatched types + --> $DIR/never-coercion-suggestion-candidates.rs:23:18 + | +LL | let _: u32 = Inherent::item; + | --- ^^^^^^^^^^^^^^ expected `u32`, found fn item + | | + | expected due to this + | + = note: expected type `u32` + found fn item `fn() {Inherent::item}` + +error[E0308]: mismatched types + --> $DIR/never-coercion-suggestion-candidates.rs:30:40 + | +LL | let _: u32 = None::.unwrap_or(|| -> ! { panic!() }); + | --------- ^^^^^^^^^^^^^^^^^^^^ expected `u32`, found closure + | | + | arguments to this method are incorrect + | + = note: expected type `u32` + found closure `{closure@$DIR/never-coercion-suggestion-candidates.rs:30:40: 30:47}` +help: the return type of this call is `{closure@$DIR/never-coercion-suggestion-candidates.rs:30:40: 30:47}` due to the type of the argument passed + --> $DIR/never-coercion-suggestion-candidates.rs:30:18 + | +LL | let _: u32 = None::.unwrap_or(|| -> ! { panic!() }); + | ^^^^^^^^^^^^^^^^^^^^^^--------------------^ + | | + | this argument influences the return type of `unwrap_or` +note: method defined here + --> $SRC_DIR/core/src/option.rs:LL:COL +help: try calling `unwrap_or_else` instead + | +LL | let _: u32 = None::.unwrap_or_else(|| -> ! { panic!() }); + | +++++ + +error[E0308]: mismatched types + --> $DIR/never-coercion-suggestion-candidates.rs:35:21 + | +LL | fn map_or_never(value: Option) -> ! { + | - this return type influences the call expression's return type +LL | value.unwrap_or(&[]) + | --------- ^^^ expected `!`, found `&[_; 0]` + | | + | arguments to this method are incorrect + | + = note: expected type `!` + found reference `&[_; 0]` +help: the return type of this call is `&[_; 0]` due to the type of the argument passed + --> $DIR/never-coercion-suggestion-candidates.rs:35:5 + | +LL | value.unwrap_or(&[]) + | ^^^^^^^^^^^^^^^^---^ + | | + | this argument influences the return type of `unwrap_or` +note: method defined here + --> $SRC_DIR/core/src/option.rs:LL:COL + +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/issue-65679-inst-opaque-ty-from-val-twice.rs b/tests/ui/type-alias-impl-trait/issue-65679-inst-opaque-ty-from-val-twice.rs index 6fc3aa8ce7e68..905975cbd4c7f 100644 --- a/tests/ui/type-alias-impl-trait/issue-65679-inst-opaque-ty-from-val-twice.rs +++ b/tests/ui/type-alias-impl-trait/issue-65679-inst-opaque-ty-from-val-twice.rs @@ -7,7 +7,7 @@ pub type T = impl Sized; // to be the same as where it occurs, whereas `impl Trait`'s instance is location sensitive; // so difference assertion should not be declared on impl-trait-type-alias's instances. // for details, check RFC-2515: -// https://github.com/rust-lang/rfcs/blob/master/text/2515-type_alias_impl_trait.md +// https://rust-lang.github.io/rfcs/2515-type_alias_impl_trait.html #[define_opaque(T)] fn bop() {