Skip to content

Commit 85abb27

Browse files
committed
Auto merge of rust-lang#137608 - fmease:rollup-h4siso6, r=fmease
Rollup of 8 pull requests Successful merges: - rust-lang#137370 (adjust_abi: make fallback logic for ABIs a bit easier to read) - rust-lang#137444 (Improve behavior of `IF_LET_RESCOPE` around temporaries and place expressions) - rust-lang#137464 (Fix invalid suggestion from type error for derive macro) - rust-lang#137539 ( Add rustdoc-gui regression test for rust-lang#137082 ) - rust-lang#137576 (Don't doc-comment BTreeMap<K, SetValZST, A>) - rust-lang#137595 (remove `simd_fpow` and `simd_fpowi`) - rust-lang#137600 (type_ir: remove redundant part of comment) - rust-lang#137602 (feature: fix typo in attribute description) r? `@ghost` `@rustbot` modify labels: rollup
2 parents 4ecd70d + 9fda3e6 commit 85abb27

File tree

26 files changed

+245
-385
lines changed

26 files changed

+245
-385
lines changed

compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs

-58
Original file line numberDiff line numberDiff line change
@@ -460,64 +460,6 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>(
460460
});
461461
}
462462

463-
sym::simd_fpow => {
464-
intrinsic_args!(fx, args => (a, b); intrinsic);
465-
466-
if !a.layout().ty.is_simd() {
467-
report_simd_type_validation_error(fx, intrinsic, span, a.layout().ty);
468-
return;
469-
}
470-
471-
simd_pair_for_each_lane(fx, a, b, ret, &|fx, lane_ty, _ret_lane_ty, a_lane, b_lane| {
472-
match lane_ty.kind() {
473-
ty::Float(FloatTy::F32) => fx.lib_call(
474-
"powf",
475-
vec![AbiParam::new(types::F32), AbiParam::new(types::F32)],
476-
vec![AbiParam::new(types::F32)],
477-
&[a_lane, b_lane],
478-
)[0],
479-
ty::Float(FloatTy::F64) => fx.lib_call(
480-
"pow",
481-
vec![AbiParam::new(types::F64), AbiParam::new(types::F64)],
482-
vec![AbiParam::new(types::F64)],
483-
&[a_lane, b_lane],
484-
)[0],
485-
_ => unreachable!("{:?}", lane_ty),
486-
}
487-
});
488-
}
489-
490-
sym::simd_fpowi => {
491-
intrinsic_args!(fx, args => (a, exp); intrinsic);
492-
let exp = exp.load_scalar(fx);
493-
494-
if !a.layout().ty.is_simd() {
495-
report_simd_type_validation_error(fx, intrinsic, span, a.layout().ty);
496-
return;
497-
}
498-
499-
simd_for_each_lane(
500-
fx,
501-
a,
502-
ret,
503-
&|fx, lane_ty, _ret_lane_ty, lane| match lane_ty.kind() {
504-
ty::Float(FloatTy::F32) => fx.lib_call(
505-
"__powisf2", // compiler-builtins
506-
vec![AbiParam::new(types::F32), AbiParam::new(types::I32)],
507-
vec![AbiParam::new(types::F32)],
508-
&[lane, exp],
509-
)[0],
510-
ty::Float(FloatTy::F64) => fx.lib_call(
511-
"__powidf2", // compiler-builtins
512-
vec![AbiParam::new(types::F64), AbiParam::new(types::I32)],
513-
vec![AbiParam::new(types::F64)],
514-
&[lane, exp],
515-
)[0],
516-
_ => unreachable!("{:?}", lane_ty),
517-
},
518-
);
519-
}
520-
521463
sym::simd_fsin
522464
| sym::simd_fcos
523465
| sym::simd_fexp

compiler/rustc_codegen_gcc/src/intrinsic/simd.rs

+8-20
Original file line numberDiff line numberDiff line change
@@ -772,8 +772,6 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
772772
sym::simd_floor => "floor",
773773
sym::simd_fma => "fma",
774774
sym::simd_relaxed_fma => "fma", // FIXME: this should relax to non-fused multiply-add when necessary
775-
sym::simd_fpowi => "__builtin_powi",
776-
sym::simd_fpow => "pow",
777775
sym::simd_fsin => "sin",
778776
sym::simd_fsqrt => "sqrt",
779777
sym::simd_round => "round",
@@ -788,24 +786,16 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
788786
let mut vector_elements = vec![];
789787
for i in 0..in_len {
790788
let index = bx.context.new_rvalue_from_long(bx.ulong_type, i as i64);
791-
// we have to treat fpowi specially, since fpowi's second argument is always an i32
792789
let mut arguments = vec![];
793-
if name == sym::simd_fpowi {
794-
arguments = vec![
795-
bx.extract_element(args[0].immediate(), index).to_rvalue(),
796-
args[1].immediate(),
797-
];
798-
} else {
799-
for arg in args {
800-
let mut element = bx.extract_element(arg.immediate(), index).to_rvalue();
801-
// FIXME: it would probably be better to not have casts here and use the proper
802-
// instructions.
803-
if let Some(typ) = cast_type {
804-
element = bx.context.new_cast(None, element, typ);
805-
}
806-
arguments.push(element);
790+
for arg in args {
791+
let mut element = bx.extract_element(arg.immediate(), index).to_rvalue();
792+
// FIXME: it would probably be better to not have casts here and use the proper
793+
// instructions.
794+
if let Some(typ) = cast_type {
795+
element = bx.context.new_cast(None, element, typ);
807796
}
808-
};
797+
arguments.push(element);
798+
}
809799
let mut result = bx.context.new_call(None, function, &arguments);
810800
if cast_type.is_some() {
811801
result = bx.context.new_cast(None, result, elem_ty);
@@ -829,8 +819,6 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
829819
| sym::simd_floor
830820
| sym::simd_fma
831821
| sym::simd_relaxed_fma
832-
| sym::simd_fpow
833-
| sym::simd_fpowi
834822
| sym::simd_fsin
835823
| sym::simd_fsqrt
836824
| sym::simd_round

compiler/rustc_codegen_llvm/src/intrinsic.rs

-4
Original file line numberDiff line numberDiff line change
@@ -1581,8 +1581,6 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
15811581
sym::simd_floor => ("floor", bx.type_func(&[vec_ty], vec_ty)),
15821582
sym::simd_fma => ("fma", bx.type_func(&[vec_ty, vec_ty, vec_ty], vec_ty)),
15831583
sym::simd_relaxed_fma => ("fmuladd", bx.type_func(&[vec_ty, vec_ty, vec_ty], vec_ty)),
1584-
sym::simd_fpowi => ("powi", bx.type_func(&[vec_ty, bx.type_i32()], vec_ty)),
1585-
sym::simd_fpow => ("pow", bx.type_func(&[vec_ty, vec_ty], vec_ty)),
15861584
sym::simd_fsin => ("sin", bx.type_func(&[vec_ty], vec_ty)),
15871585
sym::simd_fsqrt => ("sqrt", bx.type_func(&[vec_ty], vec_ty)),
15881586
sym::simd_round => ("round", bx.type_func(&[vec_ty], vec_ty)),
@@ -1615,8 +1613,6 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
16151613
| sym::simd_flog
16161614
| sym::simd_floor
16171615
| sym::simd_fma
1618-
| sym::simd_fpow
1619-
| sym::simd_fpowi
16201616
| sym::simd_fsin
16211617
| sym::simd_fsqrt
16221618
| sym::simd_relaxed_fma

compiler/rustc_feature/src/builtin_attrs.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1011,7 +1011,7 @@ pub static BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
10111011
),
10121012
rustc_attr!(
10131013
rustc_force_inline, Normal, template!(Word, NameValueStr: "reason"), WarnFollowing, EncodeCrossCrate::Yes,
1014-
"#![rustc_force_inline] forces a free function to be inlined"
1014+
"#[rustc_force_inline] forces a free function to be inlined"
10151015
),
10161016

10171017
// ==========================================================================

compiler/rustc_hir_analysis/src/check/intrinsic.rs

-2
Original file line numberDiff line numberDiff line change
@@ -645,7 +645,6 @@ pub fn check_intrinsic_type(
645645
| sym::simd_xor
646646
| sym::simd_fmin
647647
| sym::simd_fmax
648-
| sym::simd_fpow
649648
| sym::simd_saturating_add
650649
| sym::simd_saturating_sub => (1, 0, vec![param(0), param(0)], param(0)),
651650
sym::simd_arith_offset => (2, 0, vec![param(0), param(1)], param(0)),
@@ -668,7 +667,6 @@ pub fn check_intrinsic_type(
668667
| sym::simd_floor
669668
| sym::simd_round
670669
| sym::simd_trunc => (1, 0, vec![param(0)], param(0)),
671-
sym::simd_fpowi => (1, 0, vec![param(0), tcx.types.i32], param(0)),
672670
sym::simd_fma | sym::simd_relaxed_fma => {
673671
(1, 0, vec![param(0), param(0), param(0)], param(0))
674672
}

compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs

+9-5
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ use rustc_middle::ty::{
2323
};
2424
use rustc_session::errors::ExprParenthesesNeeded;
2525
use rustc_span::source_map::Spanned;
26-
use rustc_span::{Ident, Span, Symbol, sym};
26+
use rustc_span::{ExpnKind, Ident, MacroKind, Span, Symbol, sym};
2727
use rustc_trait_selection::error_reporting::InferCtxtErrorExt;
2828
use rustc_trait_selection::error_reporting::traits::DefIdOrName;
2929
use rustc_trait_selection::infer::InferCtxtExt;
@@ -1365,6 +1365,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
13651365
self.param_env,
13661366
ty::TraitRef::new(self.tcx, into_def_id, [expr_ty, expected_ty]),
13671367
))
1368+
&& !expr
1369+
.span
1370+
.macro_backtrace()
1371+
.any(|x| matches!(x.kind, ExpnKind::Macro(MacroKind::Attr | MacroKind::Derive, ..)))
13681372
{
13691373
let span = expr.span.find_oldest_ancestor_in_same_ctxt();
13701374

@@ -1380,10 +1384,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
13801384
sugg.insert(0, (expr.span.shrink_to_lo(), format!("{}: ", name)));
13811385
}
13821386
diag.multipart_suggestion(
1383-
format!("call `Into::into` on this expression to convert `{expr_ty}` into `{expected_ty}`"),
1384-
sugg,
1385-
Applicability::MaybeIncorrect
1386-
);
1387+
format!("call `Into::into` on this expression to convert `{expr_ty}` into `{expected_ty}`"),
1388+
sugg,
1389+
Applicability::MaybeIncorrect
1390+
);
13871391
return true;
13881392
}
13891393

compiler/rustc_lint/src/if_let_rescope.rs

+79-77
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
use std::iter::repeat;
22
use std::ops::ControlFlow;
33

4-
use hir::intravisit::Visitor;
4+
use hir::intravisit::{self, Visitor};
55
use rustc_ast::Recovered;
66
use rustc_errors::{
77
Applicability, Diag, EmissionGuarantee, SubdiagMessageOp, Subdiagnostic, SuggestionStyle,
88
};
99
use rustc_hir::{self as hir, HirIdSet};
1010
use rustc_macros::LintDiagnostic;
1111
use rustc_middle::ty::TyCtxt;
12+
use rustc_middle::ty::adjustment::Adjust;
1213
use rustc_session::lint::{FutureIncompatibilityReason, LintId};
1314
use rustc_session::{declare_lint, impl_lint_pass};
1415
use rustc_span::Span;
@@ -160,7 +161,7 @@ impl IfLetRescope {
160161
let lifetime_end = source_map.end_point(conseq.span);
161162

162163
if let ControlFlow::Break(significant_dropper) =
163-
(FindSignificantDropper { cx }).visit_expr(init)
164+
(FindSignificantDropper { cx }).check_if_let_scrutinee(init)
164165
{
165166
first_if_to_lint = first_if_to_lint.or_else(|| Some((span, expr.hir_id)));
166167
significant_droppers.push(significant_dropper);
@@ -363,96 +364,97 @@ enum SingleArmMatchBegin {
363364
WithoutOpenBracket(Span),
364365
}
365366

366-
struct FindSignificantDropper<'tcx, 'a> {
367+
struct FindSignificantDropper<'a, 'tcx> {
367368
cx: &'a LateContext<'tcx>,
368369
}
369370

370-
impl<'tcx, 'a> Visitor<'tcx> for FindSignificantDropper<'tcx, 'a> {
371-
type Result = ControlFlow<Span>;
371+
impl<'tcx> FindSignificantDropper<'_, 'tcx> {
372+
/// Check the scrutinee of an `if let` to see if it promotes any temporary values
373+
/// that would change drop order in edition 2024. Specifically, it checks the value
374+
/// of the scrutinee itself, and also recurses into the expression to find any ref
375+
/// exprs (or autoref) which would promote temporaries that would be scoped to the
376+
/// end of this `if`.
377+
fn check_if_let_scrutinee(&mut self, init: &'tcx hir::Expr<'tcx>) -> ControlFlow<Span> {
378+
self.check_promoted_temp_with_drop(init)?;
379+
self.visit_expr(init)
380+
}
372381

373-
fn visit_expr(&mut self, expr: &'tcx hir::Expr<'tcx>) -> Self::Result {
374-
if self
382+
/// Check that an expression is not a promoted temporary with a significant
383+
/// drop impl.
384+
///
385+
/// An expression is a promoted temporary if it has an addr taken (i.e. `&expr` or autoref)
386+
/// or is the scrutinee of the `if let`, *and* the expression is not a place
387+
/// expr, and it has a significant drop.
388+
fn check_promoted_temp_with_drop(&self, expr: &'tcx hir::Expr<'tcx>) -> ControlFlow<Span> {
389+
if !expr.is_place_expr(|base| {
390+
self.cx
391+
.typeck_results()
392+
.adjustments()
393+
.get(base.hir_id)
394+
.is_some_and(|x| x.iter().any(|adj| matches!(adj.kind, Adjust::Deref(_))))
395+
}) && self
375396
.cx
376397
.typeck_results()
377398
.expr_ty(expr)
378399
.has_significant_drop(self.cx.tcx, self.cx.typing_env())
379400
{
380-
return ControlFlow::Break(expr.span);
401+
ControlFlow::Break(expr.span)
402+
} else {
403+
ControlFlow::Continue(())
381404
}
382-
match expr.kind {
383-
hir::ExprKind::ConstBlock(_)
384-
| hir::ExprKind::Lit(_)
385-
| hir::ExprKind::Path(_)
386-
| hir::ExprKind::Assign(_, _, _)
387-
| hir::ExprKind::AssignOp(_, _, _)
388-
| hir::ExprKind::Break(_, _)
389-
| hir::ExprKind::Continue(_)
390-
| hir::ExprKind::Ret(_)
391-
| hir::ExprKind::Become(_)
392-
| hir::ExprKind::InlineAsm(_)
393-
| hir::ExprKind::OffsetOf(_, _)
394-
| hir::ExprKind::Repeat(_, _)
395-
| hir::ExprKind::Err(_)
396-
| hir::ExprKind::Struct(_, _, _)
397-
| hir::ExprKind::Closure(_)
398-
| hir::ExprKind::Block(_, _)
399-
| hir::ExprKind::DropTemps(_)
400-
| hir::ExprKind::Loop(_, _, _, _) => ControlFlow::Continue(()),
405+
}
406+
}
401407

402-
hir::ExprKind::Tup(exprs) | hir::ExprKind::Array(exprs) => {
403-
for expr in exprs {
404-
self.visit_expr(expr)?;
405-
}
406-
ControlFlow::Continue(())
407-
}
408-
hir::ExprKind::Call(callee, args) => {
409-
self.visit_expr(callee)?;
410-
for expr in args {
411-
self.visit_expr(expr)?;
412-
}
413-
ControlFlow::Continue(())
414-
}
415-
hir::ExprKind::MethodCall(_, receiver, args, _) => {
416-
self.visit_expr(receiver)?;
417-
for expr in args {
418-
self.visit_expr(expr)?;
408+
impl<'tcx> Visitor<'tcx> for FindSignificantDropper<'_, 'tcx> {
409+
type Result = ControlFlow<Span>;
410+
411+
fn visit_block(&mut self, b: &'tcx hir::Block<'tcx>) -> Self::Result {
412+
// Blocks introduce temporary terminating scope for all of its
413+
// statements, so just visit the tail expr, skipping over any
414+
// statements. This prevents false positives like `{ let x = &Drop; }`.
415+
if let Some(expr) = b.expr { self.visit_expr(expr) } else { ControlFlow::Continue(()) }
416+
}
417+
418+
fn visit_expr(&mut self, expr: &'tcx hir::Expr<'tcx>) -> Self::Result {
419+
// Check for promoted temporaries from autoref, e.g.
420+
// `if let None = TypeWithDrop.as_ref() {} else {}`
421+
// where `fn as_ref(&self) -> Option<...>`.
422+
for adj in self.cx.typeck_results().expr_adjustments(expr) {
423+
match adj.kind {
424+
// Skip when we hit the first deref expr.
425+
Adjust::Deref(_) => break,
426+
Adjust::Borrow(_) => {
427+
self.check_promoted_temp_with_drop(expr)?;
419428
}
420-
ControlFlow::Continue(())
421-
}
422-
hir::ExprKind::Index(left, right, _) | hir::ExprKind::Binary(_, left, right) => {
423-
self.visit_expr(left)?;
424-
self.visit_expr(right)
429+
_ => {}
425430
}
426-
hir::ExprKind::Unary(_, expr)
427-
| hir::ExprKind::Cast(expr, _)
428-
| hir::ExprKind::Type(expr, _)
429-
| hir::ExprKind::UnsafeBinderCast(_, expr, _)
430-
| hir::ExprKind::Yield(expr, _)
431-
| hir::ExprKind::AddrOf(_, _, expr)
432-
| hir::ExprKind::Match(expr, _, _)
433-
| hir::ExprKind::Field(expr, _)
434-
| hir::ExprKind::Let(&hir::LetExpr {
435-
init: expr,
436-
span: _,
437-
pat: _,
438-
ty: _,
439-
recovered: Recovered::No,
440-
}) => self.visit_expr(expr),
441-
hir::ExprKind::Let(_) => ControlFlow::Continue(()),
431+
}
442432

443-
hir::ExprKind::If(cond, _, _) => {
444-
if let hir::ExprKind::Let(hir::LetExpr {
445-
init,
446-
span: _,
447-
pat: _,
448-
ty: _,
449-
recovered: Recovered::No,
450-
}) = cond.kind
451-
{
452-
self.visit_expr(init)?;
453-
}
454-
ControlFlow::Continue(())
433+
match expr.kind {
434+
// Account for cases like `if let None = Some(&Drop) {} else {}`.
435+
hir::ExprKind::AddrOf(_, _, expr) => {
436+
self.check_promoted_temp_with_drop(expr)?;
437+
intravisit::walk_expr(self, expr)
438+
}
439+
// `(Drop, ()).1` introduces a temporary and then moves out of
440+
// part of it, therefore we should check it for temporaries.
441+
// FIXME: This may have false positives if we move the part
442+
// that actually has drop, but oh well.
443+
hir::ExprKind::Index(expr, _, _) | hir::ExprKind::Field(expr, _) => {
444+
self.check_promoted_temp_with_drop(expr)?;
445+
intravisit::walk_expr(self, expr)
455446
}
447+
// If always introduces a temporary terminating scope for its cond and arms,
448+
// so don't visit them.
449+
hir::ExprKind::If(..) => ControlFlow::Continue(()),
450+
// Match introduces temporary terminating scopes for arms, so don't visit
451+
// them, and only visit the scrutinee to account for cases like:
452+
// `if let None = match &Drop { _ => Some(1) } {} else {}`.
453+
hir::ExprKind::Match(scrut, _, _) => self.visit_expr(scrut),
454+
// Self explanatory.
455+
hir::ExprKind::DropTemps(_) => ControlFlow::Continue(()),
456+
// Otherwise, walk into the expr's parts.
457+
_ => intravisit::walk_expr(self, expr),
456458
}
457459
}
458460
}

0 commit comments

Comments
 (0)