Skip to content

Commit 002da76

Browse files
committed
Auto merge of rust-lang#137838 - matthiaskrgr:rollup-5brlcyr, r=matthiaskrgr
Rollup of 9 pull requests Successful merges: - rust-lang#137045 (Defer repeat expr `Copy` checks to end of type checking) - rust-lang#137171 (Suggest swapping equality on E0277) - rust-lang#137686 (Handle asm const similar to inline const) - rust-lang#137689 (Use `Binder<Vec<Ty>>` instead of `Vec<Binder<Ty>>` in both solvers for sized/auto traits/etc.) - rust-lang#137718 (Use original command for showing sccache stats) - rust-lang#137730 (checked_ilog tests: deal with a bit of float imprecision) - rust-lang#137735 (Update E0133 docs for 2024 edition) - rust-lang#137742 (unconditionally lower match arm even if it's unneeded for never pattern in match) - rust-lang#137771 (Tweak incorrect ABI suggestion and make suggestion verbose) Failed merges: - rust-lang#137723 (Make `rust.description` more general-purpose and pass `CFG_VER_DESCRIPTION`) r? `@ghost` `@rustbot` modify labels: rollup
2 parents 30508fa + e5a639d commit 002da76

File tree

57 files changed

+749
-321
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

57 files changed

+749
-321
lines changed

compiler/rustc_ast_lowering/messages.ftl

+1-1
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ ast_lowering_invalid_abi_clobber_abi =
8888
invalid ABI for `clobber_abi`
8989
.note = the following ABIs are supported on this target: {$supported_abis}
9090
91-
ast_lowering_invalid_abi_suggestion = did you mean
91+
ast_lowering_invalid_abi_suggestion = there's a similarly named valid ABI `{$suggestion}`
9292
9393
ast_lowering_invalid_asm_template_modifier_const =
9494
asm template modifiers are not allowed for `const` arguments

compiler/rustc_ast_lowering/src/asm.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
195195
}
196196
}
197197
InlineAsmOperand::Const { anon_const } => hir::InlineAsmOperand::Const {
198-
anon_const: self.lower_anon_const_to_anon_const(anon_const),
198+
anon_const: self.lower_const_block(anon_const),
199199
},
200200
InlineAsmOperand::Sym { sym } => {
201201
let static_def_id = self

compiler/rustc_ast_lowering/src/errors.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,9 @@ pub(crate) struct TupleStructWithDefault {
4646
#[derive(Subdiagnostic)]
4747
#[suggestion(
4848
ast_lowering_invalid_abi_suggestion,
49-
code = "{suggestion}",
50-
applicability = "maybe-incorrect"
49+
code = "\"{suggestion}\"",
50+
applicability = "maybe-incorrect",
51+
style = "verbose"
5152
)]
5253
pub(crate) struct InvalidAbiSuggestion {
5354
#[primary_span]

compiler/rustc_ast_lowering/src/expr.rs

+5-2
Original file line numberDiff line numberDiff line change
@@ -671,10 +671,13 @@ impl<'hir> LoweringContext<'_, 'hir> {
671671
let span = self.lower_span(arm.span);
672672
self.lower_attrs(hir_id, &arm.attrs, arm.span);
673673
let is_never_pattern = pat.is_never_pattern();
674-
let body = if let Some(body) = &arm.body
674+
// We need to lower the body even if it's unneeded for never pattern in match,
675+
// ensure that we can get HirId for DefId if need (issue #137708).
676+
let body = arm.body.as_ref().map(|x| self.lower_expr(x));
677+
let body = if let Some(body) = body
675678
&& !is_never_pattern
676679
{
677-
self.lower_expr(body)
680+
body
678681
} else {
679682
// Either `body.is_none()` or `is_never_pattern` here.
680683
if !is_never_pattern {

compiler/rustc_ast_lowering/src/item.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1510,7 +1510,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
15101510
span: abi.span,
15111511
suggestion: suggested_name.map(|suggested_name| InvalidAbiSuggestion {
15121512
span: abi.span,
1513-
suggestion: format!("\"{suggested_name}\""),
1513+
suggestion: suggested_name.to_string(),
15141514
}),
15151515
command: "rustc --print=calling-conventions".to_string(),
15161516
});

compiler/rustc_error_codes/src/error_codes/E0133.md

+2-1
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ unsafe fn g() {
4545
```
4646

4747
Linting against this is controlled via the `unsafe_op_in_unsafe_fn` lint, which
48-
is `allow` by default but will be upgraded to `warn` in a future edition.
48+
is `warn` by default in the 2024 edition and `allow` by default in earlier
49+
editions.
4950

5051
[unsafe-section]: https://doc.rust-lang.org/book/ch19-01-unsafe-rust.html

compiler/rustc_hir/src/hir.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -3512,7 +3512,7 @@ pub enum InlineAsmOperand<'hir> {
35123512
out_expr: Option<&'hir Expr<'hir>>,
35133513
},
35143514
Const {
3515-
anon_const: &'hir AnonConst,
3515+
anon_const: ConstBlock,
35163516
},
35173517
SymFn {
35183518
expr: &'hir Expr<'hir>,

compiler/rustc_hir/src/intravisit.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1447,7 +1447,7 @@ pub fn walk_inline_asm<'v, V: Visitor<'v>>(
14471447
visit_opt!(visitor, visit_expr, out_expr);
14481448
}
14491449
InlineAsmOperand::Const { anon_const, .. } => {
1450-
try_visit!(visitor.visit_anon_const(anon_const));
1450+
try_visit!(visitor.visit_inline_const(anon_const));
14511451
}
14521452
InlineAsmOperand::SymFn { expr, .. } => {
14531453
try_visit!(visitor.visit_expr(expr));

compiler/rustc_hir_analysis/src/check/intrinsicck.rs

+25-9
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
use std::assert_matches::debug_assert_matches;
2-
31
use rustc_abi::FieldIdx;
42
use rustc_ast::InlineAsmTemplatePiece;
53
use rustc_data_structures::fx::FxIndexSet;
@@ -21,6 +19,7 @@ pub struct InlineAsmCtxt<'a, 'tcx: 'a> {
2119
typing_env: ty::TypingEnv<'tcx>,
2220
target_features: &'tcx FxIndexSet<Symbol>,
2321
expr_ty: Box<dyn Fn(&hir::Expr<'tcx>) -> Ty<'tcx> + 'a>,
22+
node_ty: Box<dyn Fn(hir::HirId) -> Ty<'tcx> + 'a>,
2423
}
2524

2625
enum NonAsmTypeReason<'tcx> {
@@ -35,20 +34,26 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
3534
tcx: TyCtxt<'tcx>,
3635
def_id: LocalDefId,
3736
typing_env: ty::TypingEnv<'tcx>,
38-
get_operand_ty: impl Fn(&hir::Expr<'tcx>) -> Ty<'tcx> + 'a,
37+
expr_ty: impl Fn(&hir::Expr<'tcx>) -> Ty<'tcx> + 'a,
38+
node_ty: impl Fn(hir::HirId) -> Ty<'tcx> + 'a,
3939
) -> Self {
4040
InlineAsmCtxt {
4141
tcx,
4242
typing_env,
4343
target_features: tcx.asm_target_features(def_id),
44-
expr_ty: Box::new(get_operand_ty),
44+
expr_ty: Box::new(expr_ty),
45+
node_ty: Box::new(node_ty),
4546
}
4647
}
4748

4849
fn expr_ty(&self, expr: &hir::Expr<'tcx>) -> Ty<'tcx> {
4950
(self.expr_ty)(expr)
5051
}
5152

53+
fn node_ty(&self, hir_id: hir::HirId) -> Ty<'tcx> {
54+
(self.node_ty)(hir_id)
55+
}
56+
5257
// FIXME(compiler-errors): This could use `<$ty as Pointee>::Metadata == ()`
5358
fn is_thin_ptr_ty(&self, ty: Ty<'tcx>) -> bool {
5459
// Type still may have region variables, but `Sized` does not depend
@@ -487,12 +492,23 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
487492
);
488493
}
489494
}
490-
// Typeck has checked that Const operands are integers.
491495
hir::InlineAsmOperand::Const { anon_const } => {
492-
debug_assert_matches!(
493-
self.tcx.type_of(anon_const.def_id).instantiate_identity().kind(),
494-
ty::Error(_) | ty::Int(_) | ty::Uint(_)
495-
);
496+
let ty = self.node_ty(anon_const.hir_id);
497+
match ty.kind() {
498+
ty::Error(_) => {}
499+
_ if ty.is_integral() => {}
500+
_ => {
501+
self.tcx
502+
.dcx()
503+
.struct_span_err(op_sp, "invalid type for `const` operand")
504+
.with_span_label(
505+
self.tcx.def_span(anon_const.def_id),
506+
format!("is {} `{}`", ty.kind().article(), ty),
507+
)
508+
.with_help("`const` operands must be of an integer type")
509+
.emit();
510+
}
511+
}
496512
}
497513
// Typeck has checked that SymFn refers to a function.
498514
hir::InlineAsmOperand::SymFn { expr } => {

compiler/rustc_hir_analysis/src/collect/generics_of.rs

-11
Original file line numberDiff line numberDiff line change
@@ -186,17 +186,6 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
186186
{
187187
Some(parent_did)
188188
}
189-
// Exclude `GlobalAsm` here which cannot have generics.
190-
Node::Expr(&Expr { kind: ExprKind::InlineAsm(asm), .. })
191-
if asm.operands.iter().any(|(op, _op_sp)| match op {
192-
hir::InlineAsmOperand::Const { anon_const } => {
193-
anon_const.hir_id == hir_id
194-
}
195-
_ => false,
196-
}) =>
197-
{
198-
Some(parent_did)
199-
}
200189
Node::TyPat(_) => Some(parent_did),
201190
_ => None,
202191
}

compiler/rustc_hir_analysis/src/collect/type_of.rs

+1-33
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use rustc_middle::query::plumbing::CyclePlaceholder;
88
use rustc_middle::ty::fold::fold_regions;
99
use rustc_middle::ty::print::with_forced_trimmed_paths;
1010
use rustc_middle::ty::util::IntTypeExt;
11-
use rustc_middle::ty::{self, Article, IsSuggestable, Ty, TyCtxt, TypeVisitableExt};
11+
use rustc_middle::ty::{self, IsSuggestable, Ty, TyCtxt, TypeVisitableExt};
1212
use rustc_middle::{bug, span_bug};
1313
use rustc_span::{DUMMY_SP, Ident, Span};
1414

@@ -35,13 +35,6 @@ fn anon_const_type_of<'tcx>(icx: &ItemCtxt<'tcx>, def_id: LocalDefId) -> Ty<'tcx
3535
let parent_node_id = tcx.parent_hir_id(hir_id);
3636
let parent_node = tcx.hir_node(parent_node_id);
3737

38-
let find_const = |&(op, op_sp)| match op {
39-
hir::InlineAsmOperand::Const { anon_const } if anon_const.hir_id == hir_id => {
40-
Some((anon_const, op_sp))
41-
}
42-
_ => None,
43-
};
44-
4538
match parent_node {
4639
// Anon consts "inside" the type system.
4740
Node::ConstArg(&ConstArg {
@@ -50,31 +43,6 @@ fn anon_const_type_of<'tcx>(icx: &ItemCtxt<'tcx>, def_id: LocalDefId) -> Ty<'tcx
5043
..
5144
}) if anon_hir_id == hir_id => const_arg_anon_type_of(icx, arg_hir_id, span),
5245

53-
// Anon consts outside the type system.
54-
Node::Expr(&Expr { kind: ExprKind::InlineAsm(asm), .. })
55-
| Node::Item(&Item { kind: ItemKind::GlobalAsm { asm, .. }, .. })
56-
if let Some((anon_const, op_sp)) = asm.operands.iter().find_map(find_const) =>
57-
{
58-
let ty = tcx.typeck(def_id).node_type(hir_id);
59-
60-
match ty.kind() {
61-
ty::Error(_) => ty,
62-
ty::Int(_) | ty::Uint(_) => ty,
63-
_ => {
64-
let guar = tcx
65-
.dcx()
66-
.struct_span_err(op_sp, "invalid type for `const` operand")
67-
.with_span_label(
68-
tcx.def_span(anon_const.def_id),
69-
format!("is {} `{}`", ty.kind().article(), ty),
70-
)
71-
.with_help("`const` operands must be of an integer type")
72-
.emit();
73-
74-
Ty::new_error(tcx, guar)
75-
}
76-
}
77-
}
7846
Node::Variant(Variant { disr_expr: Some(e), .. }) if e.hir_id == hir_id => {
7947
tcx.adt_def(tcx.hir_get_parent_item(hir_id)).repr().discr_type().to_ty(tcx)
8048
}

compiler/rustc_hir_pretty/src/lib.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -1413,7 +1413,8 @@ impl<'a> State<'a> {
14131413
hir::InlineAsmOperand::Const { ref anon_const } => {
14141414
s.word("const");
14151415
s.space();
1416-
s.print_anon_const(anon_const);
1416+
// Not using `print_inline_const` to avoid additional `const { ... }`
1417+
s.ann.nested(s, Nested::Body(anon_const.body))
14171418
}
14181419
hir::InlineAsmOperand::SymFn { ref expr } => {
14191420
s.word("sym_fn");

compiler/rustc_hir_typeck/src/expr.rs

+10-8
Original file line numberDiff line numberDiff line change
@@ -1853,12 +1853,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
18531853
return Ty::new_error(tcx, guar);
18541854
}
18551855

1856+
// We defer checking whether the element type is `Copy` as it is possible to have
1857+
// an inference variable as a repeat count and it seems unlikely that `Copy` would
1858+
// have inference side effects required for type checking to succeed.
1859+
if tcx.features().generic_arg_infer() {
1860+
self.deferred_repeat_expr_checks.borrow_mut().push((element, element_ty, count));
18561861
// If the length is 0, we don't create any elements, so we don't copy any.
18571862
// If the length is 1, we don't copy that one element, we move it. Only check
18581863
// for `Copy` if the length is larger, or unevaluated.
1859-
// FIXME(min_const_generic_exprs): We could perhaps defer this check so that
1860-
// we don't require `<?0t as Tr>::CONST` doesn't unnecessarily require `Copy`.
1861-
if count.try_to_target_usize(tcx).is_none_or(|x| x > 1) {
1864+
} else if count.try_to_target_usize(self.tcx).is_none_or(|x| x > 1) {
18621865
self.enforce_repeat_element_needs_copy_bound(element, element_ty);
18631866
}
18641867

@@ -1868,7 +1871,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
18681871
}
18691872

18701873
/// Requires that `element_ty` is `Copy` (unless it's a const expression itself).
1871-
fn enforce_repeat_element_needs_copy_bound(
1874+
pub(super) fn enforce_repeat_element_needs_copy_bound(
18721875
&self,
18731876
element: &hir::Expr<'_>,
18741877
element_ty: Ty<'tcx>,
@@ -3771,13 +3774,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
37713774
self.check_expr_asm_operand(out_expr, false);
37723775
}
37733776
}
3777+
hir::InlineAsmOperand::Const { ref anon_const } => {
3778+
self.check_expr_const_block(anon_const, Expectation::NoExpectation);
3779+
}
37743780
hir::InlineAsmOperand::SymFn { expr } => {
37753781
self.check_expr(expr);
37763782
}
3777-
// `AnonConst`s have their own body and is type-checked separately.
3778-
// As they don't flow into the type system we don't need them to
3779-
// be well-formed.
3780-
hir::InlineAsmOperand::Const { .. } => {}
37813783
hir::InlineAsmOperand::SymStatic { .. } => {}
37823784
hir::InlineAsmOperand::Label { block } => {
37833785
let previous_diverges = self.diverges.get();

compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs

+40-11
Original file line numberDiff line numberDiff line change
@@ -85,33 +85,36 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
8585
})
8686
}
8787

88-
/// Resolves type and const variables in `ty` if possible. Unlike the infcx
88+
/// Resolves type and const variables in `t` if possible. Unlike the infcx
8989
/// version (resolve_vars_if_possible), this version will
9090
/// also select obligations if it seems useful, in an effort
9191
/// to get more type information.
9292
// FIXME(-Znext-solver): A lot of the calls to this method should
9393
// probably be `try_structurally_resolve_type` or `structurally_resolve_type` instead.
9494
#[instrument(skip(self), level = "debug", ret)]
95-
pub(crate) fn resolve_vars_with_obligations(&self, mut ty: Ty<'tcx>) -> Ty<'tcx> {
95+
pub(crate) fn resolve_vars_with_obligations<T: TypeFoldable<TyCtxt<'tcx>>>(
96+
&self,
97+
mut t: T,
98+
) -> T {
9699
// No Infer()? Nothing needs doing.
97-
if !ty.has_non_region_infer() {
100+
if !t.has_non_region_infer() {
98101
debug!("no inference var, nothing needs doing");
99-
return ty;
102+
return t;
100103
}
101104

102-
// If `ty` is a type variable, see whether we already know what it is.
103-
ty = self.resolve_vars_if_possible(ty);
104-
if !ty.has_non_region_infer() {
105-
debug!(?ty);
106-
return ty;
105+
// If `t` is a type variable, see whether we already know what it is.
106+
t = self.resolve_vars_if_possible(t);
107+
if !t.has_non_region_infer() {
108+
debug!(?t);
109+
return t;
107110
}
108111

109112
// If not, try resolving pending obligations as much as
110113
// possible. This can help substantially when there are
111114
// indirect dependencies that don't seem worth tracking
112115
// precisely.
113116
self.select_obligations_where_possible(|_| {});
114-
self.resolve_vars_if_possible(ty)
117+
self.resolve_vars_if_possible(t)
115118
}
116119

117120
pub(crate) fn record_deferred_call_resolution(
@@ -1454,7 +1457,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
14541457
sp: Span,
14551458
ct: ty::Const<'tcx>,
14561459
) -> ty::Const<'tcx> {
1457-
// FIXME(min_const_generic_exprs): We could process obligations here if `ct` is a var.
1460+
let ct = self.resolve_vars_with_obligations(ct);
14581461

14591462
if self.next_trait_solver()
14601463
&& let ty::ConstKind::Unevaluated(..) = ct.kind()
@@ -1510,6 +1513,32 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
15101513
}
15111514
}
15121515

1516+
pub(crate) fn structurally_resolve_const(
1517+
&self,
1518+
sp: Span,
1519+
ct: ty::Const<'tcx>,
1520+
) -> ty::Const<'tcx> {
1521+
let ct = self.try_structurally_resolve_const(sp, ct);
1522+
1523+
if !ct.is_ct_infer() {
1524+
ct
1525+
} else {
1526+
let e = self.tainted_by_errors().unwrap_or_else(|| {
1527+
self.err_ctxt()
1528+
.emit_inference_failure_err(
1529+
self.body_id,
1530+
sp,
1531+
ct.into(),
1532+
TypeAnnotationNeeded::E0282,
1533+
true,
1534+
)
1535+
.emit()
1536+
});
1537+
// FIXME: Infer `?ct = {const error}`?
1538+
ty::Const::new_error(self.tcx, e)
1539+
}
1540+
}
1541+
15131542
pub(crate) fn with_breakable_ctxt<F: FnOnce() -> R, R>(
15141543
&self,
15151544
id: HirId,

0 commit comments

Comments
 (0)