Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rollup of 10 pull requests #133340

Closed
wants to merge 24 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
0a619dd
Rename `parse_no_flag` to `parse_no_value`
Zalathar Nov 18, 2024
660246b
Don't allow `-Zunstable-options` to take a value
Zalathar Nov 18, 2024
16550d9
Fix missing submodule in `./x vendor`
ehuss Nov 19, 2024
030ddee
don't require const stability for const impls
fee1-dead Nov 20, 2024
2487765
Detect const in pattern with typo
estebank Nov 5, 2024
666bcbd
aarch64 softfloat target: always pass floats in int registers
RalfJung Nov 16, 2024
0465f71
Stop being so bail-y in candidate assembly
compiler-errors Nov 21, 2024
9dfc682
generate-copyright: Now generates a library file too.
jonathanpallant Nov 19, 2024
5d30436
Re-delay a resolve `bug`
jieyouxu Nov 21, 2024
514ef18
constify `Add`
fee1-dead Nov 20, 2024
f74fdd2
Add code example for `wrapping_neg` method for signed integers
GuillaumeGomez Nov 21, 2024
02f51ec
Change to pass "strip" options in an array of string slices and add o…
xingxue-ibm Nov 19, 2024
d8e8fc5
Keep list of submodules close to list of vendored workspaces
ehuss Nov 21, 2024
2932833
generate-copyright: Fixup comment for get_metadata_and_notices.
jonathanpallant Nov 22, 2024
89aa101
Rollup merge of #132090 - compiler-errors:baily, r=lcnr
jieyouxu Nov 22, 2024
db521ab
Rollup merge of #132658 - estebank:const-in-pattern-typo, r=Nadrieril
jieyouxu Nov 22, 2024
9975b65
Rollup merge of #133102 - RalfJung:aarch64-softfloat, r=davidtwco,wes…
jieyouxu Nov 22, 2024
6acd34d
Rollup merge of #133159 - Zalathar:unstable-options-no-value, r=jieyouxu
jieyouxu Nov 22, 2024
53559c2
Rollup merge of #133208 - ferrocene:split-copyright-html, r=Kobzol
jieyouxu Nov 22, 2024
ff307b9
Rollup merge of #133215 - ehuss:fix-vendor-rustc-perf, r=kobzol
jieyouxu Nov 22, 2024
1a06e44
Rollup merge of #133217 - xingxue-ibm:fix-strip, r=compiler-errors
jieyouxu Nov 22, 2024
15d66c3
Rollup merge of #133237 - fee1-dead-contrib:constadd, r=compiler-errors
jieyouxu Nov 22, 2024
2228a9c
Rollup merge of #133286 - jieyouxu:bug-ourselves, r=compiler-errors
jieyouxu Nov 22, 2024
3248214
Rollup merge of #133301 - GuillaumeGomez:add-example-wrapping-neg, r=…
jieyouxu Nov 22, 2024
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_ssa/src/back/link.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1117,14 +1117,14 @@ fn link_natively(
let stripcmd = "rust-objcopy";
match (strip, crate_type) {
(Strip::Debuginfo, _) => {
strip_symbols_with_external_utility(sess, stripcmd, out_filename, Some("-S"))
strip_symbols_with_external_utility(sess, stripcmd, out_filename, &["-S"])
}
// Per the manpage, `-x` is the maximum safe strip level for dynamic libraries. (#93988)
(Strip::Symbols, CrateType::Dylib | CrateType::Cdylib | CrateType::ProcMacro) => {
strip_symbols_with_external_utility(sess, stripcmd, out_filename, Some("-x"))
strip_symbols_with_external_utility(sess, stripcmd, out_filename, &["-x"])
}
(Strip::Symbols, _) => {
strip_symbols_with_external_utility(sess, stripcmd, out_filename, None)
strip_symbols_with_external_utility(sess, stripcmd, out_filename, &[])
}
(Strip::None, _) => {}
}
Expand All @@ -1141,7 +1141,7 @@ fn link_natively(
match strip {
// Always preserve the symbol table (-x).
Strip::Debuginfo => {
strip_symbols_with_external_utility(sess, stripcmd, out_filename, Some("-x"))
strip_symbols_with_external_utility(sess, stripcmd, out_filename, &["-x"])
}
// Strip::Symbols is handled via the --strip-all linker option.
Strip::Symbols => {}
Expand All @@ -1158,11 +1158,15 @@ fn link_natively(
match strip {
Strip::Debuginfo => {
// FIXME: AIX's strip utility only offers option to strip line number information.
strip_symbols_with_external_utility(sess, stripcmd, out_filename, Some("-l"))
strip_symbols_with_external_utility(sess, stripcmd, out_filename, &[
"-X32_64", "-l",
])
}
Strip::Symbols => {
// Must be noted this option might remove symbol __aix_rust_metadata and thus removes .info section which contains metadata.
strip_symbols_with_external_utility(sess, stripcmd, out_filename, Some("-r"))
strip_symbols_with_external_utility(sess, stripcmd, out_filename, &[
"-X32_64", "-r",
])
}
Strip::None => {}
}
Expand All @@ -1181,12 +1185,10 @@ fn strip_symbols_with_external_utility(
sess: &Session,
util: &str,
out_filename: &Path,
option: Option<&str>,
options: &[&str],
) {
let mut cmd = Command::new(util);
if let Some(option) = option {
cmd.arg(option);
}
cmd.args(options);

let mut new_path = sess.get_tools_search_paths(false);
if let Some(path) = env::var_os("PATH") {
Expand Down
7 changes: 7 additions & 0 deletions compiler/rustc_mir_build/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -338,6 +338,13 @@ mir_build_unreachable_pattern = unreachable pattern
.unreachable_covered_by_catchall = matches any value
.unreachable_covered_by_one = matches all the relevant values
.unreachable_covered_by_many = multiple earlier patterns match some of the same values
.unreachable_pattern_const_reexport_accessible = there is a constant of the same name imported in another scope, which could have been used to pattern match against its value instead of introducing a new catch-all binding, but it needs to be imported in the pattern's scope
.unreachable_pattern_wanted_const = you might have meant to pattern match against the value of {$is_typo ->
[true] similarly named constant
*[false] constant
} `{$const_name}` instead of introducing a new catch-all binding
.unreachable_pattern_const_inaccessible = there is a constant of the same name, which could have been used to pattern match against its value instead of introducing a new catch-all binding, but it is not accessible from this scope
.unreachable_pattern_let_binding = there is a binding of the same name; if you meant to pattern match against the value of that binding, that is a feature of constants that is not available for `let` bindings
.suggestion = remove the match arm

mir_build_unsafe_fn_safe_body = an unsafe function restricts its caller, but its body is safe by default
Expand Down
22 changes: 22 additions & 0 deletions compiler/rustc_mir_build/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -593,6 +593,14 @@ pub(crate) struct UnreachablePattern<'tcx> {
pub(crate) uninhabited_note: Option<()>,
#[label(mir_build_unreachable_covered_by_catchall)]
pub(crate) covered_by_catchall: Option<Span>,
#[subdiagnostic]
pub(crate) wanted_constant: Option<WantedConstant>,
#[note(mir_build_unreachable_pattern_const_reexport_accessible)]
pub(crate) accessible_constant: Option<Span>,
#[note(mir_build_unreachable_pattern_const_inaccessible)]
pub(crate) inaccessible_constant: Option<Span>,
#[note(mir_build_unreachable_pattern_let_binding)]
pub(crate) pattern_let_binding: Option<Span>,
#[label(mir_build_unreachable_covered_by_one)]
pub(crate) covered_by_one: Option<Span>,
#[note(mir_build_unreachable_covered_by_many)]
Expand All @@ -602,6 +610,20 @@ pub(crate) struct UnreachablePattern<'tcx> {
pub(crate) suggest_remove: Option<Span>,
}

#[derive(Subdiagnostic)]
#[suggestion(
mir_build_unreachable_pattern_wanted_const,
code = "{const_path}",
applicability = "machine-applicable"
)]
pub(crate) struct WantedConstant {
#[primary_span]
pub(crate) span: Span,
pub(crate) is_typo: bool,
pub(crate) const_name: String,
pub(crate) const_path: String,
}

#[derive(Diagnostic)]
#[diag(mir_build_const_pattern_depends_on_generic_parameter, code = E0158)]
pub(crate) struct ConstPatternDependsOnGenericParameter {
Expand Down
164 changes: 163 additions & 1 deletion compiler/rustc_mir_build/src/thir/pattern/check_match.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ use rustc_errors::{Applicability, ErrorGuaranteed, MultiSpan, struct_span_code_e
use rustc_hir::def::*;
use rustc_hir::def_id::LocalDefId;
use rustc_hir::{self as hir, BindingMode, ByRef, HirId};
use rustc_infer::infer::TyCtxtInferExt;
use rustc_infer::traits::Reveal;
use rustc_lint::Level;
use rustc_middle::bug;
use rustc_middle::middle::limits::get_limit_size;
use rustc_middle::thir::visit::Visitor;
Expand All @@ -22,8 +24,10 @@ use rustc_pattern_analysis::rustc::{
use rustc_session::lint::builtin::{
BINDINGS_WITH_VARIANT_NAME, IRREFUTABLE_LET_PATTERNS, UNREACHABLE_PATTERNS,
};
use rustc_span::edit_distance::find_best_match_for_name;
use rustc_span::hygiene::DesugaringKind;
use rustc_span::{Span, sym};
use rustc_trait_selection::infer::InferCtxtExt;
use tracing::instrument;

use crate::errors::*;
Expand Down Expand Up @@ -969,6 +973,10 @@ fn report_unreachable_pattern<'p, 'tcx>(
covered_by_one: None,
covered_by_many: None,
covered_by_many_n_more_count: 0,
wanted_constant: None,
accessible_constant: None,
inaccessible_constant: None,
pattern_let_binding: None,
suggest_remove: None,
};
match explanation.covered_by.as_slice() {
Expand All @@ -991,7 +999,10 @@ fn report_unreachable_pattern<'p, 'tcx>(
});
}
[covering_pat] if pat_is_catchall(covering_pat) => {
lint.covered_by_catchall = Some(covering_pat.data().span);
// A binding pattern that matches all, a single binding name.
let pat = covering_pat.data();
lint.covered_by_catchall = Some(pat.span);
find_fallback_pattern_typo(cx, hir_id, pat, &mut lint);
}
[covering_pat] => {
lint.covered_by_one = Some(covering_pat.data().span);
Expand Down Expand Up @@ -1024,6 +1035,157 @@ fn report_unreachable_pattern<'p, 'tcx>(
cx.tcx.emit_node_span_lint(UNREACHABLE_PATTERNS, hir_id, pat_span, lint);
}

/// Detect typos that were meant to be a `const` but were interpreted as a new pattern binding.
fn find_fallback_pattern_typo<'tcx>(
cx: &PatCtxt<'_, 'tcx>,
hir_id: HirId,
pat: &Pat<'tcx>,
lint: &mut UnreachablePattern<'_>,
) {
if let (Level::Allow, _) = cx.tcx.lint_level_at_node(UNREACHABLE_PATTERNS, hir_id) {
// This is because we use `with_no_trimmed_paths` later, so if we never emit the lint we'd
// ICE. At the same time, we don't really need to do all of this if we won't emit anything.
return;
}
if let PatKind::Binding { name, subpattern: None, ty, .. } = pat.kind {
// See if the binding might have been a `const` that was mistyped or out of scope.
let mut accessible = vec![];
let mut accessible_path = vec![];
let mut inaccessible = vec![];
let mut imported = vec![];
let mut imported_spans = vec![];
let infcx = cx.tcx.infer_ctxt().build(ty::TypingMode::non_body_analysis());
let parent = cx.tcx.hir().get_parent_item(hir_id);

for item in cx.tcx.hir_crate_items(()).free_items() {
if let DefKind::Use = cx.tcx.def_kind(item.owner_id) {
// Look for consts being re-exported.
let item = cx.tcx.hir().expect_item(item.owner_id.def_id);
let use_name = item.ident.name;
let hir::ItemKind::Use(path, _) = item.kind else {
continue;
};
for res in &path.res {
if let Res::Def(DefKind::Const, id) = res
&& infcx.can_eq(cx.param_env, ty, cx.tcx.type_of(id).instantiate_identity())
{
if cx.tcx.visibility(id).is_accessible_from(parent, cx.tcx) {
// The original const is accessible, suggest using it directly.
let item_name = cx.tcx.item_name(*id);
accessible.push(item_name);
accessible_path.push(with_no_trimmed_paths!(cx.tcx.def_path_str(id)));
} else if cx
.tcx
.visibility(item.owner_id)
.is_accessible_from(parent, cx.tcx)
{
// The const is accessible only through the re-export, point at
// the `use`.
imported.push(use_name);
imported_spans.push(item.ident.span);
}
}
}
}
if let DefKind::Const = cx.tcx.def_kind(item.owner_id)
&& infcx.can_eq(
cx.param_env,
ty,
cx.tcx.type_of(item.owner_id).instantiate_identity(),
)
{
// Look for local consts.
let item_name = cx.tcx.item_name(item.owner_id.into());
let vis = cx.tcx.visibility(item.owner_id);
if vis.is_accessible_from(parent, cx.tcx) {
accessible.push(item_name);
let path = if item_name == name {
// We know that the const wasn't in scope because it has the exact
// same name, so we suggest the full path.
with_no_trimmed_paths!(cx.tcx.def_path_str(item.owner_id))
} else {
// The const is likely just typoed, and nothing else.
cx.tcx.def_path_str(item.owner_id)
};
accessible_path.push(path);
} else if name == item_name {
// The const exists somewhere in this crate, but it can't be imported
// from this pattern's scope. We'll just point at its definition.
inaccessible.push(cx.tcx.def_span(item.owner_id));
}
}
}
if let Some((i, &const_name)) =
accessible.iter().enumerate().find(|(_, &const_name)| const_name == name)
{
// The pattern name is an exact match, so the pattern needed to be imported.
lint.wanted_constant = Some(WantedConstant {
span: pat.span,
is_typo: false,
const_name: const_name.to_string(),
const_path: accessible_path[i].clone(),
});
} else if let Some(name) = find_best_match_for_name(&accessible, name, None) {
// The pattern name is likely a typo.
lint.wanted_constant = Some(WantedConstant {
span: pat.span,
is_typo: true,
const_name: name.to_string(),
const_path: name.to_string(),
});
} else if let Some(i) =
imported.iter().enumerate().find(|(_, &const_name)| const_name == name).map(|(i, _)| i)
{
// The const with the exact name wasn't re-exported from an import in this
// crate, we point at the import.
lint.accessible_constant = Some(imported_spans[i]);
} else if let Some(name) = find_best_match_for_name(&imported, name, None) {
// The typoed const wasn't re-exported by an import in this crate, we suggest
// the right name (which will likely require another follow up suggestion).
lint.wanted_constant = Some(WantedConstant {
span: pat.span,
is_typo: true,
const_path: name.to_string(),
const_name: name.to_string(),
});
} else if !inaccessible.is_empty() {
for span in inaccessible {
// The const with the exact name match isn't accessible, we just point at it.
lint.inaccessible_constant = Some(span);
}
} else {
// Look for local bindings for people that might have gotten confused with how
// `let` and `const` works.
for (_, node) in cx.tcx.hir().parent_iter(hir_id) {
match node {
hir::Node::Stmt(hir::Stmt { kind: hir::StmtKind::Let(let_stmt), .. }) => {
if let hir::PatKind::Binding(_, _, binding_name, _) = let_stmt.pat.kind {
if name == binding_name.name {
lint.pattern_let_binding = Some(binding_name.span);
}
}
}
hir::Node::Block(hir::Block { stmts, .. }) => {
for stmt in *stmts {
if let hir::StmtKind::Let(let_stmt) = stmt.kind {
if let hir::PatKind::Binding(_, _, binding_name, _) =
let_stmt.pat.kind
{
if name == binding_name.name {
lint.pattern_let_binding = Some(binding_name.span);
}
}
}
}
}
hir::Node::Item(_) => break,
_ => {}
}
}
}
}
}

/// Report unreachable arms, if any.
fn report_arm_reachability<'p, 'tcx>(
cx: &PatCtxt<'p, 'tcx>,
Expand Down
11 changes: 1 addition & 10 deletions compiler/rustc_passes/src/stability.rs
Original file line number Diff line number Diff line change
Expand Up @@ -590,16 +590,7 @@ impl<'tcx> MissingStabilityAnnotations<'tcx> {
}

fn check_missing_const_stability(&self, def_id: LocalDefId, span: Span) {
// if the const impl is derived using the `derive_const` attribute,
// then it would be "stable" at least for the impl.
// We gate usages of it using `feature(const_trait_impl)` anyways
// so there is no unstable leakage
if self.tcx.is_automatically_derived(def_id.to_def_id()) {
return;
}

let is_const = self.tcx.is_const_fn(def_id.to_def_id())
|| self.tcx.is_const_trait_impl(def_id.to_def_id());
let is_const = self.tcx.is_const_fn(def_id.to_def_id());

// Reachable const fn must have a stability attribute.
if is_const
Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_resolve/src/late.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3940,12 +3940,12 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
}
Res::SelfCtor(_) => {
// We resolve `Self` in pattern position as an ident sometimes during recovery,
// so delay a bug instead of ICEing. (Note: is this no longer true? We now ICE. If
// this triggers, please convert to a delayed bug and add a test.)
self.r.dcx().span_bug(
// so delay a bug instead of ICEing.
self.r.dcx().span_delayed_bug(
ident.span,
"unexpected `SelfCtor` in pattern, expected identifier"
);
None
}
_ => span_bug!(
ident.span,
Expand Down
Loading
Loading