Skip to content

Commit 65d7296

Browse files
committed
Auto merge of rust-lang#135277 - matthiaskrgr:rollup-0k61sf8, r=matthiaskrgr
Rollup of 6 pull requests Successful merges: - rust-lang#128110 (Suggest Replacing Comma with Semicolon in Incorrect Repeat Expressions) - rust-lang#134609 (Add new `{x86_64,i686}-win7-windows-gnu` targets) - rust-lang#134875 (Implement `const Destruct` in old solver) - rust-lang#135221 (Include rustc and rustdoc book in replace-version-placeholder) - rust-lang#135231 (bootstrap: Add more comments to some of the test steps) - rust-lang#135256 (Move `mod cargo` below the import statements) Failed merges: - rust-lang#135195 (Make `lit_to_mir_constant` and `lit_to_const` infallible) r? `@ghost` `@rustbot` modify labels: rollup
2 parents e26ff2f + afbd735 commit 65d7296

35 files changed

+739
-159
lines changed

compiler/rustc_hir/src/hir.rs

+13-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use rustc_ast::token::CommentKind;
77
use rustc_ast::util::parser::{AssocOp, ExprPrecedence};
88
use rustc_ast::{
99
self as ast, AttrId, AttrStyle, DelimArgs, FloatTy, InlineAsmOptions, InlineAsmTemplatePiece,
10-
IntTy, Label, LitKind, MetaItemInner, MetaItemLit, TraitObjectSyntax, UintTy,
10+
IntTy, Label, LitIntType, LitKind, MetaItemInner, MetaItemLit, TraitObjectSyntax, UintTy,
1111
};
1212
pub use rustc_ast::{
1313
BinOp, BinOpKind, BindingMode, BorrowKind, BoundConstness, BoundPolarity, ByRef, CaptureBy,
@@ -2094,6 +2094,18 @@ impl Expr<'_> {
20942094
}
20952095
}
20962096

2097+
/// Check if expression is an integer literal that can be used
2098+
/// where `usize` is expected.
2099+
pub fn is_size_lit(&self) -> bool {
2100+
matches!(
2101+
self.kind,
2102+
ExprKind::Lit(Lit {
2103+
node: LitKind::Int(_, LitIntType::Unsuffixed | LitIntType::Unsigned(UintTy::Usize)),
2104+
..
2105+
})
2106+
)
2107+
}
2108+
20972109
/// If `Self.kind` is `ExprKind::DropTemps(expr)`, drill down until we get a non-`DropTemps`
20982110
/// `Expr`. This is used in suggestions to ignore this `ExprKind` as it is semantically
20992111
/// silent, only signaling the ownership system. By doing this, suggestions that check the

compiler/rustc_hir_typeck/messages.ftl

+2
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,8 @@ hir_typeck_remove_semi_for_coerce_ret = the `match` arms can conform to this ret
165165
hir_typeck_remove_semi_for_coerce_semi = the `match` is a statement because of this semicolon, consider removing it
166166
hir_typeck_remove_semi_for_coerce_suggestion = remove this semicolon
167167
168+
hir_typeck_replace_comma_with_semicolon = replace the comma with a semicolon to create {$descr}
169+
168170
hir_typeck_return_stmt_outside_of_fn_body =
169171
{$statement_kind} statement outside of function body
170172
.encl_body_label = the {$statement_kind} is part of this body...

compiler/rustc_hir_typeck/src/demand.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
3030
if expr_ty == expected {
3131
return;
3232
}
33-
3433
self.annotate_alternative_method_deref(err, expr, error);
3534
self.explain_self_literal(err, expr, expected, expr_ty);
3635

@@ -39,6 +38,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
3938
|| self.suggest_missing_unwrap_expect(err, expr, expected, expr_ty)
4039
|| self.suggest_remove_last_method_call(err, expr, expected)
4140
|| self.suggest_associated_const(err, expr, expected)
41+
|| self.suggest_semicolon_in_repeat_expr(err, expr, expr_ty)
4242
|| self.suggest_deref_ref_or_into(err, expr, expected, expr_ty, expected_ty_expr)
4343
|| self.suggest_option_to_bool(err, expr, expr_ty, expected)
4444
|| self.suggest_compatible_variants(err, expr, expected, expr_ty)

compiler/rustc_hir_typeck/src/errors.rs

+13
Original file line numberDiff line numberDiff line change
@@ -846,3 +846,16 @@ pub(crate) struct PassFnItemToVariadicFunction {
846846
pub sugg_span: Span,
847847
pub replace: String,
848848
}
849+
850+
#[derive(Subdiagnostic)]
851+
#[suggestion(
852+
hir_typeck_replace_comma_with_semicolon,
853+
applicability = "machine-applicable",
854+
style = "verbose",
855+
code = "; "
856+
)]
857+
pub(crate) struct ReplaceCommaWithSemicolon {
858+
#[primary_span]
859+
pub comma_span: Span,
860+
pub descr: &'static str,
861+
}

compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs

+82-8
Original file line numberDiff line numberDiff line change
@@ -1320,14 +1320,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
13201320
let span = expr.span.shrink_to_hi();
13211321
let subdiag = if self.type_is_copy_modulo_regions(self.param_env, ty) {
13221322
errors::OptionResultRefMismatch::Copied { span, def_path }
1323-
} else if let Some(clone_did) = self.tcx.lang_items().clone_trait()
1324-
&& rustc_trait_selection::traits::type_known_to_meet_bound_modulo_regions(
1325-
self,
1326-
self.param_env,
1327-
ty,
1328-
clone_did,
1329-
)
1330-
{
1323+
} else if self.type_is_clone_modulo_regions(self.param_env, ty) {
13311324
errors::OptionResultRefMismatch::Cloned { span, def_path }
13321325
} else {
13331326
return false;
@@ -2182,6 +2175,87 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
21822175
}
21832176
}
21842177

2178+
/// Suggest replacing comma with semicolon in incorrect repeat expressions
2179+
/// like `["_", 10]` or `vec![String::new(), 10]`.
2180+
pub(crate) fn suggest_semicolon_in_repeat_expr(
2181+
&self,
2182+
err: &mut Diag<'_>,
2183+
expr: &hir::Expr<'_>,
2184+
expr_ty: Ty<'tcx>,
2185+
) -> bool {
2186+
// Check if `expr` is contained in array of two elements
2187+
if let hir::Node::Expr(array_expr) = self.tcx.parent_hir_node(expr.hir_id)
2188+
&& let hir::ExprKind::Array(elements) = array_expr.kind
2189+
&& let [first, second] = &elements[..]
2190+
&& second.hir_id == expr.hir_id
2191+
{
2192+
// Span between the two elements of the array
2193+
let comma_span = first.span.between(second.span);
2194+
2195+
// Check if `expr` is a constant value of type `usize`.
2196+
// This can only detect const variable declarations and
2197+
// calls to const functions.
2198+
2199+
// Checking this here instead of rustc_hir::hir because
2200+
// this check needs access to `self.tcx` but rustc_hir
2201+
// has no access to `TyCtxt`.
2202+
let expr_is_const_usize = expr_ty.is_usize()
2203+
&& match expr.kind {
2204+
ExprKind::Path(QPath::Resolved(
2205+
None,
2206+
Path { res: Res::Def(DefKind::Const, _), .. },
2207+
)) => true,
2208+
ExprKind::Call(
2209+
Expr {
2210+
kind:
2211+
ExprKind::Path(QPath::Resolved(
2212+
None,
2213+
Path { res: Res::Def(DefKind::Fn, fn_def_id), .. },
2214+
)),
2215+
..
2216+
},
2217+
_,
2218+
) => self.tcx.is_const_fn(*fn_def_id),
2219+
_ => false,
2220+
};
2221+
2222+
// Type of the first element is guaranteed to be checked
2223+
// when execution reaches here because `mismatched types`
2224+
// error occurs only when type of second element of array
2225+
// is not the same as type of first element.
2226+
let first_ty = self.typeck_results.borrow().expr_ty(first);
2227+
2228+
// `array_expr` is from a macro `vec!["a", 10]` if
2229+
// 1. array expression's span is imported from a macro
2230+
// 2. first element of array implements `Clone` trait
2231+
// 3. second element is an integer literal or is an expression of `usize` like type
2232+
if self.tcx.sess.source_map().is_imported(array_expr.span)
2233+
&& self.type_is_clone_modulo_regions(self.param_env, first_ty)
2234+
&& (expr.is_size_lit() || expr_ty.is_usize_like())
2235+
{
2236+
err.subdiagnostic(errors::ReplaceCommaWithSemicolon {
2237+
comma_span,
2238+
descr: "a vector",
2239+
});
2240+
return true;
2241+
}
2242+
2243+
// `array_expr` is from an array `["a", 10]` if
2244+
// 1. first element of array implements `Copy` trait
2245+
// 2. second element is an integer literal or is a const value of type `usize`
2246+
if self.type_is_copy_modulo_regions(self.param_env, first_ty)
2247+
&& (expr.is_size_lit() || expr_is_const_usize)
2248+
{
2249+
err.subdiagnostic(errors::ReplaceCommaWithSemicolon {
2250+
comma_span,
2251+
descr: "an array",
2252+
});
2253+
return true;
2254+
}
2255+
}
2256+
false
2257+
}
2258+
21852259
/// If the expected type is an enum (Issue #55250) with any variants whose
21862260
/// sole field is of the found type, suggest such variants. (Issue #42764)
21872261
pub(crate) fn suggest_compatible_variants(

compiler/rustc_middle/src/ty/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1417,8 +1417,8 @@ impl Hash for FieldDef {
14171417
impl<'tcx> FieldDef {
14181418
/// Returns the type of this field. The resulting type is not normalized. The `arg` is
14191419
/// typically obtained via the second field of [`TyKind::Adt`].
1420-
pub fn ty(&self, tcx: TyCtxt<'tcx>, arg: GenericArgsRef<'tcx>) -> Ty<'tcx> {
1421-
tcx.type_of(self.did).instantiate(tcx, arg)
1420+
pub fn ty(&self, tcx: TyCtxt<'tcx>, args: GenericArgsRef<'tcx>) -> Ty<'tcx> {
1421+
tcx.type_of(self.did).instantiate(tcx, args)
14221422
}
14231423

14241424
/// Computes the `Ident` of this variant by looking up the `Span`

compiler/rustc_middle/src/ty/sty.rs

+13-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ use crate::infer::canonical::Canonical;
2727
use crate::ty::InferTy::*;
2828
use crate::ty::{
2929
self, AdtDef, BoundRegionKind, Discr, GenericArg, GenericArgs, GenericArgsRef, List, ParamEnv,
30-
Region, Ty, TyCtxt, TypeFlags, TypeSuperVisitable, TypeVisitable, TypeVisitor,
30+
Region, Ty, TyCtxt, TypeFlags, TypeSuperVisitable, TypeVisitable, TypeVisitor, UintTy,
3131
};
3232

3333
// Re-export and re-parameterize some `I = TyCtxt<'tcx>` types here
@@ -1017,6 +1017,18 @@ impl<'tcx> Ty<'tcx> {
10171017
}
10181018
}
10191019

1020+
/// Check if type is an `usize`.
1021+
#[inline]
1022+
pub fn is_usize(self) -> bool {
1023+
matches!(self.kind(), Uint(UintTy::Usize))
1024+
}
1025+
1026+
/// Check if type is an `usize` or an integral type variable.
1027+
#[inline]
1028+
pub fn is_usize_like(self) -> bool {
1029+
matches!(self.kind(), Uint(UintTy::Usize) | Infer(IntVar(_)))
1030+
}
1031+
10201032
#[inline]
10211033
pub fn is_never(self) -> bool {
10221034
matches!(self.kind(), Never)

compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs

+2
Original file line numberDiff line numberDiff line change
@@ -712,6 +712,8 @@ pub(in crate::solve) fn extract_fn_def_from_const_callable<I: Interner>(
712712
}
713713
}
714714

715+
// NOTE: Keep this in sync with `evaluate_host_effect_for_destruct_goal` in
716+
// the old solver, for as long as that exists.
715717
pub(in crate::solve) fn const_conditions_for_destruct<I: Interner>(
716718
cx: I,
717719
self_ty: I::Ty,

compiler/rustc_target/src/spec/mod.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -1812,9 +1812,11 @@ supported_targets! {
18121812
("aarch64-unknown-illumos", aarch64_unknown_illumos),
18131813

18141814
("x86_64-pc-windows-gnu", x86_64_pc_windows_gnu),
1815+
("x86_64-uwp-windows-gnu", x86_64_uwp_windows_gnu),
1816+
("x86_64-win7-windows-gnu", x86_64_win7_windows_gnu),
18151817
("i686-pc-windows-gnu", i686_pc_windows_gnu),
18161818
("i686-uwp-windows-gnu", i686_uwp_windows_gnu),
1817-
("x86_64-uwp-windows-gnu", x86_64_uwp_windows_gnu),
1819+
("i686-win7-windows-gnu", i686_win7_windows_gnu),
18181820

18191821
("aarch64-pc-windows-gnullvm", aarch64_pc_windows_gnullvm),
18201822
("i686-pc-windows-gnullvm", i686_pc_windows_gnullvm),
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
use crate::spec::{Cc, FramePointer, LinkerFlavor, Lld, Target, base};
2+
3+
pub(crate) fn target() -> Target {
4+
let mut base = base::windows_gnu::opts();
5+
base.vendor = "win7".into();
6+
base.cpu = "pentium4".into();
7+
base.max_atomic_width = Some(64);
8+
base.frame_pointer = FramePointer::Always; // Required for backtraces
9+
base.linker = Some("i686-w64-mingw32-gcc".into());
10+
11+
// Mark all dynamic libraries and executables as compatible with the larger 4GiB address
12+
// space available to x86 Windows binaries on x86_64.
13+
base.add_pre_link_args(LinkerFlavor::Gnu(Cc::No, Lld::No), &[
14+
"-m",
15+
"i386pe",
16+
"--large-address-aware",
17+
]);
18+
base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-Wl,--large-address-aware"]);
19+
20+
Target {
21+
llvm_target: "i686-pc-windows-gnu".into(),
22+
metadata: crate::spec::TargetMetadata {
23+
description: Some("32-bit MinGW (Windows 7+)".into()),
24+
tier: Some(3),
25+
host_tools: Some(false),
26+
std: Some(true),
27+
},
28+
pointer_width: 32,
29+
data_layout: "e-m:x-p:32:32-p270:32:32-p271:32:32-p272:64:64-\
30+
i64:64-i128:128-f80:32-n8:16:32-a:0:32-S32"
31+
.into(),
32+
arch: "x86".into(),
33+
options: base,
34+
}
35+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
use crate::spec::{Cc, LinkerFlavor, Lld, Target, base};
2+
3+
pub(crate) fn target() -> Target {
4+
let mut base = base::windows_gnu::opts();
5+
base.vendor = "win7".into();
6+
base.cpu = "x86-64".into();
7+
base.plt_by_default = false;
8+
// Use high-entropy 64 bit address space for ASLR
9+
base.add_pre_link_args(LinkerFlavor::Gnu(Cc::No, Lld::No), &[
10+
"-m",
11+
"i386pep",
12+
"--high-entropy-va",
13+
]);
14+
base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m64", "-Wl,--high-entropy-va"]);
15+
base.max_atomic_width = Some(64);
16+
base.linker = Some("x86_64-w64-mingw32-gcc".into());
17+
18+
Target {
19+
llvm_target: "x86_64-pc-windows-gnu".into(),
20+
metadata: crate::spec::TargetMetadata {
21+
description: Some("64-bit MinGW (Windows 7+)".into()),
22+
tier: Some(3),
23+
host_tools: Some(false),
24+
std: Some(true),
25+
},
26+
pointer_width: 64,
27+
data_layout:
28+
"e-m:w-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128".into(),
29+
arch: "x86_64".into(),
30+
options: base,
31+
}
32+
}

compiler/rustc_trait_selection/src/infer.rs

+6
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,12 @@ impl<'tcx> InferCtxt<'tcx> {
4747
traits::type_known_to_meet_bound_modulo_regions(self, param_env, ty, copy_def_id)
4848
}
4949

50+
fn type_is_clone_modulo_regions(&self, param_env: ty::ParamEnv<'tcx>, ty: Ty<'tcx>) -> bool {
51+
let ty = self.resolve_vars_if_possible(ty);
52+
let clone_def_id = self.tcx.require_lang_item(LangItem::Clone, None);
53+
traits::type_known_to_meet_bound_modulo_regions(self, param_env, ty, clone_def_id)
54+
}
55+
5056
fn type_is_sized_modulo_regions(&self, param_env: ty::ParamEnv<'tcx>, ty: Ty<'tcx>) -> bool {
5157
let lang_item = self.tcx.require_lang_item(LangItem::Sized, None);
5258
traits::type_known_to_meet_bound_modulo_regions(self, param_env, ty, lang_item)

0 commit comments

Comments
 (0)