Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 12 additions & 10 deletions compiler/rustc_codegen_llvm/src/intrinsic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
// <https://github.com/llvm/llvm-project/commit/56385af687c3a7a1f67716fb3f819336789a8cab>.
// 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()]),
Expand Down Expand Up @@ -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()]),
Expand Down
26 changes: 25 additions & 1 deletion compiler/rustc_const_eval/src/const_eval/machine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down Expand Up @@ -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;
Expand Down
63 changes: 5 additions & 58 deletions compiler/rustc_const_eval/src/const_eval/type_info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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) => {
Expand Down Expand Up @@ -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>,
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_error_codes/src/error_codes/E0117.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
2 changes: 1 addition & 1 deletion compiler/rustc_error_codes/src/error_codes/E0192.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
2 changes: 1 addition & 1 deletion compiler/rustc_error_codes/src/error_codes/E0207.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
2 changes: 1 addition & 1 deletion compiler/rustc_error_codes/src/error_codes/E0210.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
4 changes: 2 additions & 2 deletions compiler/rustc_error_codes/src/error_codes/E0228.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
2 changes: 1 addition & 1 deletion compiler/rustc_error_codes/src/error_codes/E0328.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,5 +30,5 @@ impl<T, U> CoerceUnsized<MyType<U>> for MyType<T>
where T: CoerceUnsized<U> {}
```

[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
2 changes: 1 addition & 1 deletion compiler/rustc_error_codes/src/error_codes/E0380.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
2 changes: 1 addition & 1 deletion compiler/rustc_error_codes/src/error_codes/E0398.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,4 @@ fn foo<'a>(arg: &'a Box<SomeTrait+'a>) { /* ... */ }
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
2 changes: 1 addition & 1 deletion compiler/rustc_error_codes/src/error_codes/E0517.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
2 changes: 1 addition & 1 deletion compiler/rustc_error_codes/src/error_codes/E0591.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
2 changes: 1 addition & 1 deletion compiler/rustc_error_codes/src/error_codes/E0737.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
2 changes: 1 addition & 1 deletion compiler/rustc_error_codes/src/error_codes/E0739.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
2 changes: 1 addition & 1 deletion compiler/rustc_error_codes/src/error_codes/E0787.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
2 changes: 1 addition & 1 deletion compiler/rustc_hir/src/hir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
4 changes: 4 additions & 0 deletions compiler/rustc_hir_analysis/src/check/intrinsic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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())
Expand Down
12 changes: 12 additions & 0 deletions compiler/rustc_hir_typeck/src/coercion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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`.
Expand Down
9 changes: 6 additions & 3 deletions compiler/rustc_hir_typeck/src/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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, .. },
Expand All @@ -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)
Expand Down
12 changes: 9 additions & 3 deletions compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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}`");
Expand Down Expand Up @@ -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",),
Expand Down Expand Up @@ -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<u32>` is expected, extracting `!` cannot produce
// an `Option<u32>`. Never-to-any coercion alone must not justify `.expect()` or `?`.
if is_ctor || !self.may_coerce_except_never(inner_ty, expected) {
return false;
}

Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_lint/src/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_lint/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -572,7 +572,7 @@ fn register_builtins(store: &mut LintStore) {
store.register_removed(
"unsupported_naked_functions",
"converted into hard error, see RFC 2972 \
<https://github.com/rust-lang/rfcs/blob/master/text/2972-constrained-naked.md> for more information",
<https://rust-lang.github.io/rfcs/2972-constrained-naked.html> for more information",
);
store.register_removed(
"mutable_borrow_reservation_conflict",
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_lint/src/non_ascii_idents.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
Loading
Loading