Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
60 changes: 60 additions & 0 deletions compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1198,6 +1198,12 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
);
return;
}

// Do not suggest changing type if that is not under user control.
if self.is_closure_arg_with_non_locally_decided_type(local) {
return;
}

let decl_span = local_decl.source_info.span;

let (amp_mut_sugg, local_var_ty_info) = match *local_decl.local_info() {
Expand Down Expand Up @@ -1500,6 +1506,60 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
Applicability::HasPlaceholders,
);
}

/// Returns `true` if `local` is an argument in a closure passed to a
/// function defined in another crate.
///
/// For example, in the following code this function returns `true` for `x`
/// since `Option::inspect()` is not defined in the current crate:
///
/// ```text
/// some_option.as_mut().inspect(|x| {
/// ```
fn is_closure_arg_with_non_locally_decided_type(&self, local: Local) -> bool {
// We don't care about regular local variables, only args.
if self.body.local_kind(local) != LocalKind::Arg {
return false;
}

// Make sure we are inside a closure.
let InstanceKind::Item(body_def_id) = self.body.source.instance else {
return false;
};
let Some(Node::Expr(hir::Expr { hir_id: body_hir_id, kind, .. })) =
self.infcx.tcx.hir_get_if_local(body_def_id)
else {
return false;
};
let ExprKind::Closure(hir::Closure { kind: hir::ClosureKind::Closure, .. }) = kind else {
return false;
};

// Check if the method/function that our closure is passed to is defined
// in another crate.
let Node::Expr(closure_parent) = self.infcx.tcx.parent_hir_node(*body_hir_id) else {
return false;
};
match closure_parent.kind {
ExprKind::MethodCall(method, _, _, _) => self
.infcx
.tcx
.typeck(method.hir_id.owner.def_id)
.type_dependent_def_id(closure_parent.hir_id)
.is_some_and(|def_id| !def_id.is_local()),
ExprKind::Call(func, _) => self
.infcx
.tcx
.typeck(func.hir_id.owner.def_id)
.node_type_opt(func.hir_id)
.and_then(|ty| match ty.kind() {
ty::FnDef(def_id, _) => Some(def_id),
_ => None,
})
.is_some_and(|def_id| !def_id.is_local()),
_ => false,
}
}
}

struct BindingFinder {
Expand Down
7 changes: 5 additions & 2 deletions compiler/rustc_builtin_macros/src/cfg_select.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,21 @@ use crate::errors::{CfgSelectNoMatches, CfgSelectUnreachable};

/// Selects the first arm whose predicate evaluates to true.
fn select_arm(ecx: &ExtCtxt<'_>, branches: CfgSelectBranches) -> Option<(TokenStream, Span)> {
let mut result = None;
for (cfg, tt, arm_span) in branches.reachable {
if let EvalConfigResult::True = attr::eval_config_entry(
&ecx.sess,
&cfg,
ecx.current_expansion.lint_node_id,
ShouldEmit::ErrorsAndLints,
) {
return Some((tt, arm_span));
// FIXME(#149215) Ideally we should short-circuit here, but `eval_config_entry` currently emits lints so we cannot do this yet.
result.get_or_insert((tt, arm_span));
}
}

branches.wildcard.map(|(_, tt, span)| (tt, span))
let wildcard = branches.wildcard.map(|(_, tt, span)| (tt, span));
result.or(wildcard)
}

pub(super) fn expand_cfg_select<'cx>(
Expand Down
5 changes: 3 additions & 2 deletions compiler/rustc_interface/src/interface.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ use rustc_session::parse::ParseSess;
use rustc_session::{CompilerIO, EarlyDiagCtxt, Session, lint};
use rustc_span::source_map::{FileLoader, RealFileLoader, SourceMapInputs};
use rustc_span::{FileName, sym};
use rustc_target::spec::Target;
use tracing::trace;

use crate::util;
Expand Down Expand Up @@ -385,7 +386,7 @@ pub struct Config {
/// custom driver where the custom codegen backend has arbitrary data."
/// (See #102759.)
pub make_codegen_backend:
Option<Box<dyn FnOnce(&config::Options) -> Box<dyn CodegenBackend> + Send>>,
Option<Box<dyn FnOnce(&config::Options, &Target) -> Box<dyn CodegenBackend> + Send>>,

/// Registry of diagnostics codes.
pub registry: Registry,
Expand Down Expand Up @@ -453,7 +454,7 @@ pub fn run_compiler<R: Send>(config: Config, f: impl FnOnce(&Compiler) -> R + Se
Some(make_codegen_backend) => {
// N.B. `make_codegen_backend` takes precedence over
// `target.default_codegen_backend`, which is ignored in this case.
make_codegen_backend(&config.opts)
make_codegen_backend(&config.opts, &target)
}
};

Expand Down
10 changes: 8 additions & 2 deletions compiler/rustc_interface/src/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -339,7 +339,7 @@ pub fn get_codegen_backend(
filename if filename.contains('.') => {
load_backend_from_dylib(early_dcx, filename.as_ref())
}
"dummy" => || Box::new(DummyCodegenBackend),
"dummy" => || Box::new(DummyCodegenBackend { target_config_override: None }),
#[cfg(feature = "llvm")]
"llvm" => rustc_codegen_llvm::LlvmCodegenBackend::new,
backend_name => get_codegen_sysroot(early_dcx, sysroot, backend_name),
Expand All @@ -352,7 +352,9 @@ pub fn get_codegen_backend(
unsafe { load() }
}

struct DummyCodegenBackend;
pub struct DummyCodegenBackend {
pub target_config_override: Option<Box<dyn Fn(&Session) -> TargetConfig>>,
}

impl CodegenBackend for DummyCodegenBackend {
fn locale_resource(&self) -> &'static str {
Expand All @@ -364,6 +366,10 @@ impl CodegenBackend for DummyCodegenBackend {
}

fn target_config(&self, sess: &Session) -> TargetConfig {
if let Some(target_config_override) = &self.target_config_override {
return target_config_override(sess);
}

let abi_required_features = sess.target.abi_required_features();
let (target_features, unstable_target_features) = cfg_target_feature::<0>(
sess,
Expand Down
2 changes: 0 additions & 2 deletions library/core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -126,8 +126,6 @@
#![feature(str_split_inclusive_remainder)]
#![feature(str_split_remainder)]
#![feature(ub_checks)]
#![feature(unchecked_neg)]
#![feature(unchecked_shifts)]
#![feature(unsafe_pinned)]
#![feature(utf16_extra)]
#![feature(variant_count)]
Expand Down
21 changes: 6 additions & 15 deletions library/core/src/num/int_macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1275,11 +1275,8 @@ macro_rules! int_impl {
/// i.e. when [`checked_neg`] would return `None`.
///
#[doc = concat!("[`checked_neg`]: ", stringify!($SelfT), "::checked_neg")]
#[unstable(
feature = "unchecked_neg",
reason = "niche optimization path",
issue = "85122",
)]
#[stable(feature = "unchecked_neg", since = "CURRENT_RUSTC_VERSION")]
#[rustc_const_stable(feature = "unchecked_neg", since = "CURRENT_RUSTC_VERSION")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline(always)]
Expand Down Expand Up @@ -1395,11 +1392,8 @@ macro_rules! int_impl {
/// i.e. when [`checked_shl`] would return `None`.
///
#[doc = concat!("[`checked_shl`]: ", stringify!($SelfT), "::checked_shl")]
#[unstable(
feature = "unchecked_shifts",
reason = "niche optimization path",
issue = "85122",
)]
#[stable(feature = "unchecked_shifts", since = "CURRENT_RUSTC_VERSION")]
#[rustc_const_stable(feature = "unchecked_shifts", since = "CURRENT_RUSTC_VERSION")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline(always)]
Expand Down Expand Up @@ -1570,11 +1564,8 @@ macro_rules! int_impl {
/// i.e. when [`checked_shr`] would return `None`.
///
#[doc = concat!("[`checked_shr`]: ", stringify!($SelfT), "::checked_shr")]
#[unstable(
feature = "unchecked_shifts",
reason = "niche optimization path",
issue = "85122",
)]
#[stable(feature = "unchecked_shifts", since = "CURRENT_RUSTC_VERSION")]
#[rustc_const_stable(feature = "unchecked_shifts", since = "CURRENT_RUSTC_VERSION")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline(always)]
Expand Down
14 changes: 4 additions & 10 deletions library/core/src/num/uint_macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1851,11 +1851,8 @@ macro_rules! uint_impl {
/// i.e. when [`checked_shl`] would return `None`.
///
#[doc = concat!("[`checked_shl`]: ", stringify!($SelfT), "::checked_shl")]
#[unstable(
feature = "unchecked_shifts",
reason = "niche optimization path",
issue = "85122",
)]
#[stable(feature = "unchecked_shifts", since = "CURRENT_RUSTC_VERSION")]
#[rustc_const_stable(feature = "unchecked_shifts", since = "CURRENT_RUSTC_VERSION")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline(always)]
Expand Down Expand Up @@ -2023,11 +2020,8 @@ macro_rules! uint_impl {
/// i.e. when [`checked_shr`] would return `None`.
///
#[doc = concat!("[`checked_shr`]: ", stringify!($SelfT), "::checked_shr")]
#[unstable(
feature = "unchecked_shifts",
reason = "niche optimization path",
issue = "85122",
)]
#[stable(feature = "unchecked_shifts", since = "CURRENT_RUSTC_VERSION")]
#[rustc_const_stable(feature = "unchecked_shifts", since = "CURRENT_RUSTC_VERSION")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline(always)]
Expand Down
Loading
Loading