Skip to content

Commit 9fc908f

Browse files
committed
Auto merge of rust-lang#138890 - matthiaskrgr:rollup-l7g1auw, r=matthiaskrgr
Rollup of 7 pull requests Successful merges: - rust-lang#138601 (add FCW to warn about wasm ABI transition) - rust-lang#138662 (Implement some basics in UEFI fs) - rust-lang#138800 (remove remnants of const_box feature) - rust-lang#138821 (match lowering cleanup: remove unused unsizing logic from `non_scalar_compare`) - rust-lang#138864 (Rework `--print` options documentation) - rust-lang#138868 (Add do_not_recommend typo help) - rust-lang#138882 (`with_scope` is only ever used for ast modules) r? `@ghost` `@rustbot` modify labels: rollup
2 parents 4510e86 + 79e42cf commit 9fc908f

File tree

25 files changed

+614
-207
lines changed

25 files changed

+614
-207
lines changed

compiler/rustc_codegen_ssa/src/mir/naked_asm.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -332,7 +332,7 @@ fn wasm_functype<'tcx>(tcx: TyCtxt<'tcx>, fn_abi: &FnAbi<'tcx, Ty<'tcx>>, def_id
332332
// please also add `wasm32-unknown-unknown` back in `tests/assembly/wasm32-naked-fn.rs`
333333
// basically the commit introducing this comment should be reverted
334334
if let PassMode::Pair { .. } = fn_abi.ret.mode {
335-
let _ = WasmCAbi::Legacy;
335+
let _ = WasmCAbi::Legacy { with_lint: true };
336336
span_bug!(
337337
tcx.def_span(def_id),
338338
"cannot return a pair (the wasm32-unknown-unknown ABI is broken, see https://github.com/rust-lang/rust/issues/115666"
@@ -384,7 +384,7 @@ fn wasm_type<'tcx>(
384384
BackendRepr::SimdVector { .. } => "v128",
385385
BackendRepr::Memory { .. } => {
386386
// FIXME: remove this branch once the wasm32-unknown-unknown ABI is fixed
387-
let _ = WasmCAbi::Legacy;
387+
let _ = WasmCAbi::Legacy { with_lint: true };
388388
span_bug!(
389389
tcx.def_span(def_id),
390390
"cannot use memory args (the wasm32-unknown-unknown ABI is broken, see https://github.com/rust-lang/rust/issues/115666"

compiler/rustc_lint_defs/src/builtin.rs

+46
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,7 @@ declare_lint_pass! {
143143
UNUSED_VARIABLES,
144144
USELESS_DEPRECATED,
145145
WARNINGS,
146+
WASM_C_ABI,
146147
// tidy-alphabetical-end
147148
]
148149
}
@@ -5082,6 +5083,8 @@ declare_lint! {
50825083
/// }
50835084
/// ```
50845085
///
5086+
/// This will produce:
5087+
///
50855088
/// ```text
50865089
/// warning: ABI error: this function call uses a avx vector type, which is not enabled in the caller
50875090
/// --> lint_example.rs:18:12
@@ -5125,3 +5128,46 @@ declare_lint! {
51255128
reference: "issue #116558 <https://github.com/rust-lang/rust/issues/116558>",
51265129
};
51275130
}
5131+
5132+
declare_lint! {
5133+
/// The `wasm_c_abi` lint detects usage of the `extern "C"` ABI of wasm that is affected
5134+
/// by a planned ABI change that has the goal of aligning Rust with the standard C ABI
5135+
/// of this target.
5136+
///
5137+
/// ### Example
5138+
///
5139+
/// ```rust,ignore (needs wasm32-unknown-unknown)
5140+
/// #[repr(C)]
5141+
/// struct MyType(i32, i32);
5142+
///
5143+
/// extern "C" my_fun(x: MyType) {}
5144+
/// ```
5145+
///
5146+
/// This will produce:
5147+
///
5148+
/// ```text
5149+
/// error: this function function definition is affected by the wasm ABI transition: it passes an argument of non-scalar type `MyType`
5150+
/// --> $DIR/wasm_c_abi_transition.rs:17:1
5151+
/// |
5152+
/// | pub extern "C" fn my_fun(_x: MyType) {}
5153+
/// | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
5154+
/// |
5155+
/// = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
5156+
/// = note: for more information, see issue #138762 <https://github.com/rust-lang/rust/issues/138762>
5157+
/// = help: the "C" ABI Rust uses on wasm32-unknown-unknown will change to align with the standard "C" ABI for this target
5158+
/// ```
5159+
///
5160+
/// ### Explanation
5161+
///
5162+
/// Rust has historically implemented a non-spec-compliant C ABI on wasm32-unknown-unknown. This
5163+
/// has caused incompatibilities with other compilers and Wasm targets. In a future version
5164+
/// of Rust, this will be fixed, and therefore code relying on the non-spec-compliant C ABI will
5165+
/// stop functioning.
5166+
pub WASM_C_ABI,
5167+
Warn,
5168+
"detects code relying on rustc's non-spec-compliant wasm C ABI",
5169+
@future_incompatible = FutureIncompatibleInfo {
5170+
reason: FutureIncompatibilityReason::FutureReleaseErrorReportInDeps,
5171+
reference: "issue #138762 <https://github.com/rust-lang/rust/issues/138762>",
5172+
};
5173+
}

compiler/rustc_middle/src/thir.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -800,9 +800,9 @@ pub enum PatKind<'tcx> {
800800
},
801801

802802
/// One of the following:
803-
/// * `&str`/`&[u8]` (represented as a valtree), which will be handled as a string/slice pattern
804-
/// and thus exhaustiveness checking will detect if you use the same string/slice twice in
805-
/// different patterns.
803+
/// * `&str` (represented as a valtree), which will be handled as a string pattern and thus
804+
/// exhaustiveness checking will detect if you use the same string twice in different
805+
/// patterns.
806806
/// * integer, bool, char or float (represented as a valtree), which will be handled by
807807
/// exhaustiveness to cover exactly its own value, similar to `&str`, but these values are
808808
/// much simpler.

compiler/rustc_mir_build/src/builder/matches/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1326,8 +1326,8 @@ enum TestKind<'tcx> {
13261326
Eq {
13271327
value: Const<'tcx>,
13281328
// Integer types are handled by `SwitchInt`, and constants with ADT
1329-
// types are converted back into patterns, so this can only be `&str`,
1330-
// `&[T]`, `f32` or `f64`.
1329+
// types and `&[T]` types are converted back into patterns, so this can
1330+
// only be `&str`, `f32` or `f64`.
13311331
ty: Ty<'tcx>,
13321332
},
13331333

compiler/rustc_mir_build/src/builder/matches/test.rs

+19-89
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ use std::sync::Arc;
1111
use rustc_data_structures::fx::FxIndexMap;
1212
use rustc_hir::{LangItem, RangeEnd};
1313
use rustc_middle::mir::*;
14-
use rustc_middle::ty::adjustment::PointerCoercion;
1514
use rustc_middle::ty::util::IntTypeExt;
1615
use rustc_middle::ty::{self, GenericArg, Ty, TyCtxt};
1716
use rustc_middle::{bug, span_bug};
@@ -178,21 +177,30 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
178177
_ => {}
179178
}
180179

180+
assert_eq!(expect_ty, ty);
181181
if !ty.is_scalar() {
182182
// Use `PartialEq::eq` instead of `BinOp::Eq`
183183
// (the binop can only handle primitives)
184-
self.non_scalar_compare(
184+
// Make sure that we do *not* call any user-defined code here.
185+
// The only type that can end up here is string literals, which have their
186+
// comparison defined in `core`.
187+
// (Interestingly this means that exhaustiveness analysis relies, for soundness,
188+
// on the `PartialEq` impl for `str` to b correct!)
189+
match *ty.kind() {
190+
ty::Ref(_, deref_ty, _) if deref_ty == self.tcx.types.str_ => {}
191+
_ => {
192+
span_bug!(source_info.span, "invalid type for non-scalar compare: {ty}")
193+
}
194+
};
195+
self.string_compare(
185196
block,
186197
success_block,
187198
fail_block,
188199
source_info,
189200
expect,
190-
expect_ty,
191201
Operand::Copy(place),
192-
ty,
193202
);
194203
} else {
195-
assert_eq!(expect_ty, ty);
196204
self.compare(
197205
block,
198206
success_block,
@@ -370,97 +378,19 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
370378
);
371379
}
372380

373-
/// Compare two values using `<T as std::compare::PartialEq>::eq`.
374-
/// If the values are already references, just call it directly, otherwise
375-
/// take a reference to the values first and then call it.
376-
fn non_scalar_compare(
381+
/// Compare two values of type `&str` using `<str as std::cmp::PartialEq>::eq`.
382+
fn string_compare(
377383
&mut self,
378384
block: BasicBlock,
379385
success_block: BasicBlock,
380386
fail_block: BasicBlock,
381387
source_info: SourceInfo,
382-
mut expect: Operand<'tcx>,
383-
expect_ty: Ty<'tcx>,
384-
mut val: Operand<'tcx>,
385-
mut ty: Ty<'tcx>,
388+
expect: Operand<'tcx>,
389+
val: Operand<'tcx>,
386390
) {
387-
// If we're using `b"..."` as a pattern, we need to insert an
388-
// unsizing coercion, as the byte string has the type `&[u8; N]`.
389-
//
390-
// We want to do this even when the scrutinee is a reference to an
391-
// array, so we can call `<[u8]>::eq` rather than having to find an
392-
// `<[u8; N]>::eq`.
393-
let unsize = |ty: Ty<'tcx>| match ty.kind() {
394-
ty::Ref(region, rty, _) => match rty.kind() {
395-
ty::Array(inner_ty, n) => Some((region, inner_ty, n)),
396-
_ => None,
397-
},
398-
_ => None,
399-
};
400-
let opt_ref_ty = unsize(ty);
401-
let opt_ref_test_ty = unsize(expect_ty);
402-
match (opt_ref_ty, opt_ref_test_ty) {
403-
// nothing to do, neither is an array
404-
(None, None) => {}
405-
(Some((region, elem_ty, _)), _) | (None, Some((region, elem_ty, _))) => {
406-
let tcx = self.tcx;
407-
// make both a slice
408-
ty = Ty::new_imm_ref(tcx, *region, Ty::new_slice(tcx, *elem_ty));
409-
if opt_ref_ty.is_some() {
410-
let temp = self.temp(ty, source_info.span);
411-
self.cfg.push_assign(
412-
block,
413-
source_info,
414-
temp,
415-
Rvalue::Cast(
416-
CastKind::PointerCoercion(
417-
PointerCoercion::Unsize,
418-
CoercionSource::Implicit,
419-
),
420-
val,
421-
ty,
422-
),
423-
);
424-
val = Operand::Copy(temp);
425-
}
426-
if opt_ref_test_ty.is_some() {
427-
let slice = self.temp(ty, source_info.span);
428-
self.cfg.push_assign(
429-
block,
430-
source_info,
431-
slice,
432-
Rvalue::Cast(
433-
CastKind::PointerCoercion(
434-
PointerCoercion::Unsize,
435-
CoercionSource::Implicit,
436-
),
437-
expect,
438-
ty,
439-
),
440-
);
441-
expect = Operand::Move(slice);
442-
}
443-
}
444-
}
445-
446-
// Figure out the type on which we are calling `PartialEq`. This involves an extra wrapping
447-
// reference: we can only compare two `&T`, and then compare_ty will be `T`.
448-
// Make sure that we do *not* call any user-defined code here.
449-
// The only types that can end up here are string and byte literals,
450-
// which have their comparison defined in `core`.
451-
// (Interestingly this means that exhaustiveness analysis relies, for soundness,
452-
// on the `PartialEq` impls for `str` and `[u8]` to b correct!)
453-
let compare_ty = match *ty.kind() {
454-
ty::Ref(_, deref_ty, _)
455-
if deref_ty == self.tcx.types.str_ || deref_ty != self.tcx.types.u8 =>
456-
{
457-
deref_ty
458-
}
459-
_ => span_bug!(source_info.span, "invalid type for non-scalar compare: {}", ty),
460-
};
461-
391+
let str_ty = self.tcx.types.str_;
462392
let eq_def_id = self.tcx.require_lang_item(LangItem::PartialEq, Some(source_info.span));
463-
let method = trait_method(self.tcx, eq_def_id, sym::eq, [compare_ty, compare_ty]);
393+
let method = trait_method(self.tcx, eq_def_id, sym::eq, [str_ty, str_ty]);
464394

465395
let bool_ty = self.tcx.types.bool;
466396
let eq_result = self.temp(bool_ty, source_info.span);

compiler/rustc_monomorphize/messages.ftl

+7
Original file line numberDiff line numberDiff line change
@@ -63,4 +63,11 @@ monomorphize_symbol_already_defined = symbol `{$symbol}` is already defined
6363
monomorphize_unknown_cgu_collection_mode =
6464
unknown codegen-item collection mode '{$mode}', falling back to 'lazy' mode
6565
66+
monomorphize_wasm_c_abi_transition =
67+
this function {$is_call ->
68+
[true] call
69+
*[false] definition
70+
} involves an argument of type `{$ty}` which is affected by the wasm ABI transition
71+
.help = the "C" ABI Rust uses on wasm32-unknown-unknown will change to align with the standard "C" ABI for this target
72+
6673
monomorphize_written_to_path = the full type name has been written to '{$path}'

compiler/rustc_monomorphize/src/errors.rs

+9
Original file line numberDiff line numberDiff line change
@@ -103,3 +103,12 @@ pub(crate) struct AbiRequiredTargetFeature<'a> {
103103
/// Whether this is a problem at a call site or at a declaration.
104104
pub is_call: bool,
105105
}
106+
107+
#[derive(LintDiagnostic)]
108+
#[diag(monomorphize_wasm_c_abi_transition)]
109+
#[help]
110+
pub(crate) struct WasmCAbiTransition<'a> {
111+
pub ty: Ty<'a>,
112+
/// Whether this is a problem at a call site or at a declaration.
113+
pub is_call: bool,
114+
}

0 commit comments

Comments
 (0)