Skip to content

Rollup of 4 pull requests #135438

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

Merged
merged 8 commits into from
Jan 14, 2025
59 changes: 25 additions & 34 deletions compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ use rustc_middle::bug;
use rustc_middle::hir::nested_filter::OnlyBodies;
use rustc_middle::mir::tcx::PlaceTy;
use rustc_middle::mir::{
self, AggregateKind, BindingForm, BorrowKind, CallSource, ClearCrossCrate, ConstraintCategory,
self, AggregateKind, BindingForm, BorrowKind, ClearCrossCrate, ConstraintCategory,
FakeBorrowKind, FakeReadCause, LocalDecl, LocalInfo, LocalKind, Location, MutBorrowKind,
Operand, Place, PlaceRef, ProjectionElem, Rvalue, Statement, StatementKind, Terminator,
TerminatorKind, VarBindingForm, VarDebugInfoContents,
Expand All @@ -30,13 +30,13 @@ use rustc_middle::ty::{
self, PredicateKind, Ty, TyCtxt, TypeSuperVisitable, TypeVisitor, Upcast,
suggest_constraining_type_params,
};
use rustc_middle::util::CallKind;
use rustc_mir_dataflow::move_paths::{InitKind, MoveOutIndex, MovePathIndex};
use rustc_span::def_id::{DefId, LocalDefId};
use rustc_span::hygiene::DesugaringKind;
use rustc_span::{BytePos, Ident, Span, Symbol, kw, sym};
use rustc_trait_selection::error_reporting::InferCtxtErrorExt;
use rustc_trait_selection::error_reporting::traits::FindExprBySpan;
use rustc_trait_selection::error_reporting::traits::call_kind::CallKind;
use rustc_trait_selection::infer::InferCtxtExt;
use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt as _;
use rustc_trait_selection::traits::{Obligation, ObligationCause, ObligationCtxt};
Expand All @@ -46,7 +46,7 @@ use super::explain_borrow::{BorrowExplanation, LaterUseKind};
use super::{DescribePlaceOpt, RegionName, RegionNameSource, UseSpans};
use crate::borrow_set::{BorrowData, TwoPhaseActivation};
use crate::diagnostics::conflict_errors::StorageDeadOrDrop::LocalStorageDead;
use crate::diagnostics::{CapturedMessageOpt, Instance, find_all_local_uses};
use crate::diagnostics::{CapturedMessageOpt, call_kind, find_all_local_uses};
use crate::prefixes::IsPrefixOf;
use crate::{InitializationRequiringAction, MirBorrowckCtxt, WriteKind, borrowck_errors};

Expand Down Expand Up @@ -305,7 +305,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
}

if let UseSpans::FnSelfUse {
kind: CallKind::DerefCoercion { deref_target, deref_target_ty, .. },
kind: CallKind::DerefCoercion { deref_target_span, deref_target_ty, .. },
..
} = use_spans
{
Expand All @@ -315,8 +315,10 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
));

// Check first whether the source is accessible (issue #87060)
if self.infcx.tcx.sess.source_map().is_span_accessible(deref_target) {
err.span_note(deref_target, "deref defined here");
if let Some(deref_target_span) = deref_target_span
&& self.infcx.tcx.sess.source_map().is_span_accessible(deref_target_span)
{
err.span_note(deref_target_span, "deref defined here");
}
}

Expand Down Expand Up @@ -3765,38 +3767,27 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {

fn explain_deref_coercion(&mut self, loan: &BorrowData<'tcx>, err: &mut Diag<'_>) {
let tcx = self.infcx.tcx;
if let (
Some(Terminator {
kind: TerminatorKind::Call { call_source: CallSource::OverloadedOperator, .. },
..
}),
Some((method_did, method_args)),
) = (
&self.body[loan.reserve_location.block].terminator,
rustc_middle::util::find_self_call(
if let Some(Terminator { kind: TerminatorKind::Call { call_source, fn_span, .. }, .. }) =
&self.body[loan.reserve_location.block].terminator
&& let Some((method_did, method_args)) = rustc_middle::util::find_self_call(
tcx,
self.body,
loan.assigned_place.local,
loan.reserve_location.block,
),
) {
if tcx.is_diagnostic_item(sym::deref_method, method_did) {
let deref_target =
tcx.get_diagnostic_item(sym::deref_target).and_then(|deref_target| {
Instance::try_resolve(
tcx,
self.infcx.typing_env(self.infcx.param_env),
deref_target,
method_args,
)
.transpose()
});
if let Some(Ok(instance)) = deref_target {
let deref_target_ty =
instance.ty(tcx, self.infcx.typing_env(self.infcx.param_env));
err.note(format!("borrow occurs due to deref coercion to `{deref_target_ty}`"));
err.span_note(tcx.def_span(instance.def_id()), "deref defined here");
}
)
&& let CallKind::DerefCoercion { deref_target_span, deref_target_ty, .. } = call_kind(
self.infcx.tcx,
self.infcx.typing_env(self.infcx.param_env),
method_did,
method_args,
*fn_span,
call_source.from_hir_call(),
Some(self.infcx.tcx.fn_arg_names(method_did)[0]),
)
{
err.note(format!("borrow occurs due to deref coercion to `{deref_target_ty}`"));
if let Some(deref_target_span) = deref_target_span {
err.span_note(deref_target_span, "deref defined here");
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@ use rustc_middle::mir::{
};
use rustc_middle::ty::adjustment::PointerCoercion;
use rustc_middle::ty::{self, RegionVid, Ty, TyCtxt};
use rustc_middle::util::CallKind;
use rustc_span::{DesugaringKind, Span, kw, sym};
use rustc_trait_selection::error_reporting::traits::FindExprBySpan;
use rustc_trait_selection::error_reporting::traits::call_kind::CallKind;
use tracing::{debug, instrument};

use super::{RegionName, UseSpans, find_use};
Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_borrowck/src/diagnostics/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,13 @@ use rustc_middle::mir::{
StatementKind, Terminator, TerminatorKind,
};
use rustc_middle::ty::print::Print;
use rustc_middle::ty::{self, Instance, Ty, TyCtxt};
use rustc_middle::util::{CallDesugaringKind, call_kind};
use rustc_middle::ty::{self, Ty, TyCtxt};
use rustc_mir_dataflow::move_paths::{InitLocation, LookupResult, MoveOutIndex};
use rustc_span::def_id::LocalDefId;
use rustc_span::source_map::Spanned;
use rustc_span::{DUMMY_SP, ErrorGuaranteed, Span, Symbol, sym};
use rustc_trait_selection::error_reporting::InferCtxtErrorExt;
use rustc_trait_selection::error_reporting::traits::call_kind::{CallDesugaringKind, call_kind};
use rustc_trait_selection::infer::InferCtxtExt;
use rustc_trait_selection::traits::{
FulfillmentErrorCode, type_known_to_meet_bound_modulo_regions,
Expand Down Expand Up @@ -63,7 +63,7 @@ pub(crate) use mutability_errors::AccessKind;
pub(crate) use outlives_suggestion::OutlivesSuggestionBuilder;
pub(crate) use region_errors::{ErrorConstraintInfo, RegionErrorKind, RegionErrors};
pub(crate) use region_name::{RegionName, RegionNameSource};
pub(crate) use rustc_middle::util::CallKind;
pub(crate) use rustc_trait_selection::error_reporting::traits::call_kind::CallKind;

pub(super) struct DescribePlaceOpt {
including_downcast: bool,
Expand Down
10 changes: 3 additions & 7 deletions compiler/rustc_codegen_llvm/src/back/lto.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
use std::collections::BTreeMap;
use std::ffi::{CStr, CString};
use std::fs::File;
use std::mem::ManuallyDrop;
use std::path::Path;
use std::sync::Arc;
use std::{io, iter, slice};

use object::read::archive::ArchiveFile;
use rustc_codegen_ssa::back::lto::{LtoModuleCodegen, SerializedModule, ThinModule, ThinShared};
use rustc_codegen_ssa::back::symbol_export;
use rustc_codegen_ssa::back::write::{CodegenContext, FatLtoInput, TargetMachineFactoryConfig};
use rustc_codegen_ssa::back::write::{CodegenContext, FatLtoInput};
use rustc_codegen_ssa::traits::*;
use rustc_codegen_ssa::{ModuleCodegen, ModuleKind, looks_like_rust_object_file};
use rustc_data_structures::fx::FxHashMap;
Expand Down Expand Up @@ -706,18 +705,15 @@ pub(crate) unsafe fn optimize_thin_module(
let dcx = dcx.handle();

let module_name = &thin_module.shared.module_names[thin_module.idx];
let tm_factory_config = TargetMachineFactoryConfig::new(cgcx, module_name.to_str().unwrap());
let tm = (cgcx.tm_factory)(tm_factory_config).map_err(|e| write::llvm_err(dcx, e))?;

// Right now the implementation we've got only works over serialized
// modules, so we create a fresh new LLVM context and parse the module
// into that context. One day, however, we may do this for upstream
// crates but for locally codegened modules we may be able to reuse
// that LLVM Context and Module.
let llcx = unsafe { llvm::LLVMRustContextCreate(cgcx.fewer_names) };
let llmod_raw = parse_module(llcx, module_name, thin_module.data(), dcx)? as *const _;
let module_llvm = ModuleLlvm::parse(cgcx, module_name, thin_module.data(), dcx)?;
let mut module = ModuleCodegen {
module_llvm: ModuleLlvm { llmod_raw, llcx, tm: ManuallyDrop::new(tm) },
module_llvm,
name: thin_module.name().to_string(),
kind: ModuleKind::Regular,
};
Expand Down
12 changes: 8 additions & 4 deletions compiler/rustc_const_eval/src/check_consts/ops.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,11 @@ use rustc_middle::ty::{
self, Closure, FnDef, FnPtr, GenericArgKind, GenericArgsRef, Param, TraitRef, Ty,
suggest_constraining_type_param,
};
use rustc_middle::util::{CallDesugaringKind, CallKind, call_kind};
use rustc_session::parse::add_feature_diagnostics;
use rustc_span::{BytePos, Pos, Span, Symbol, sym};
use rustc_trait_selection::error_reporting::traits::call_kind::{
CallDesugaringKind, CallKind, call_kind,
};
use rustc_trait_selection::traits::SelectionContext;
use tracing::debug;

Expand Down Expand Up @@ -324,10 +326,12 @@ fn build_error_for_const_call<'tcx>(
note_trait_if_possible(&mut err, self_ty, trait_id);
err
}
CallKind::DerefCoercion { deref_target, deref_target_ty, self_ty } => {
CallKind::DerefCoercion { deref_target_span, deref_target_ty, self_ty } => {
// Check first whether the source is accessible (issue #87060)
let target = if tcx.sess.source_map().is_span_accessible(deref_target) {
Some(deref_target)
let target = if let Some(deref_target_span) = deref_target_span
&& tcx.sess.source_map().is_span_accessible(deref_target_span)
{
Some(deref_target_span)
} else {
None
};
Expand Down
12 changes: 11 additions & 1 deletion compiler/rustc_feature/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,14 +68,24 @@ impl UnstableFeatures {
/// If `krate` is [`Some`], then setting `RUSTC_BOOTSTRAP=krate` will enable the nightly
/// features. Otherwise, only `RUSTC_BOOTSTRAP=1` will work.
pub fn from_environment(krate: Option<&str>) -> Self {
Self::from_environment_value(krate, std::env::var("RUSTC_BOOTSTRAP"))
}

/// Avoid unsafe `std::env::set_var()` by allowing tests to inject
/// `std::env::var("RUSTC_BOOTSTRAP")` with the `env_var_rustc_bootstrap`
/// arg.
fn from_environment_value(
krate: Option<&str>,
env_var_rustc_bootstrap: Result<String, std::env::VarError>,
) -> Self {
// `true` if this is a feature-staged build, i.e., on the beta or stable channel.
let disable_unstable_features =
option_env!("CFG_DISABLE_UNSTABLE_FEATURES").is_some_and(|s| s != "0");
// Returns whether `krate` should be counted as unstable
let is_unstable_crate =
|var: &str| krate.is_some_and(|name| var.split(',').any(|new_krate| new_krate == name));

let bootstrap = std::env::var("RUSTC_BOOTSTRAP").ok();
let bootstrap = env_var_rustc_bootstrap.ok();
if let Some(val) = bootstrap.as_deref() {
match val {
val if val == "1" || is_unstable_crate(val) => return UnstableFeatures::Cheat,
Expand Down
16 changes: 10 additions & 6 deletions compiler/rustc_feature/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@ use super::UnstableFeatures;

#[test]
fn rustc_bootstrap_parsing() {
let is_bootstrap = |env, krate| {
std::env::set_var("RUSTC_BOOTSTRAP", env);
matches!(UnstableFeatures::from_environment(krate), UnstableFeatures::Cheat)
let is_bootstrap = |env: &str, krate: Option<&str>| {
matches!(
UnstableFeatures::from_environment_value(krate, Ok(env.to_string())),
UnstableFeatures::Cheat
)
};
assert!(is_bootstrap("1", None));
assert!(is_bootstrap("1", Some("x")));
Expand All @@ -22,9 +24,11 @@ fn rustc_bootstrap_parsing() {
assert!(!is_bootstrap("0", None));

// `RUSTC_BOOTSTRAP=-1` is force-stable, no unstable features allowed.
let is_force_stable = |krate| {
std::env::set_var("RUSTC_BOOTSTRAP", "-1");
matches!(UnstableFeatures::from_environment(krate), UnstableFeatures::Disallow)
let is_force_stable = |krate: Option<&str>| {
matches!(
UnstableFeatures::from_environment_value(krate, Ok("-1".to_string())),
UnstableFeatures::Disallow
)
};
assert!(is_force_stable(None));
// Does not support specifying any crate.
Expand Down
22 changes: 20 additions & 2 deletions compiler/rustc_middle/src/ty/instance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use std::path::PathBuf;
use rustc_data_structures::fx::FxHashMap;
use rustc_errors::ErrorGuaranteed;
use rustc_hir as hir;
use rustc_hir::def::Namespace;
use rustc_hir::def::{CtorKind, DefKind, Namespace};
use rustc_hir::def_id::{CrateNum, DefId};
use rustc_hir::lang_items::LangItem;
use rustc_index::bit_set::FiniteBitSet;
Expand Down Expand Up @@ -498,7 +498,8 @@ impl<'tcx> Instance<'tcx> {

/// Resolves a `(def_id, args)` pair to an (optional) instance -- most commonly,
/// this is used to find the precise code that will run for a trait method invocation,
/// if known.
/// if known. This should only be used for functions and consts. If you want to
/// resolve an associated type, use [`TyCtxt::try_normalize_erasing_regions`].
///
/// Returns `Ok(None)` if we cannot resolve `Instance` to a specific instance.
/// For example, in a context like this,
Expand Down Expand Up @@ -527,6 +528,23 @@ impl<'tcx> Instance<'tcx> {
def_id: DefId,
args: GenericArgsRef<'tcx>,
) -> Result<Option<Instance<'tcx>>, ErrorGuaranteed> {
assert_matches!(
tcx.def_kind(def_id),
DefKind::Fn
| DefKind::AssocFn
| DefKind::Const
| DefKind::AssocConst
| DefKind::AnonConst
| DefKind::InlineConst
| DefKind::Static { .. }
| DefKind::Ctor(_, CtorKind::Fn)
| DefKind::Closure
| DefKind::SyntheticCoroutineBody,
"`Instance::try_resolve` should only be used to resolve instances of \
functions, statics, and consts; to resolve associated types, use \
`try_normalize_erasing_regions`."
);

// Rust code can easily create exponentially-long types using only a
// polynomial recursion depth. Even with the default recursion
// depth, you can easily get cases that take >2^60 steps to run,
Expand Down
2 changes: 0 additions & 2 deletions compiler/rustc_middle/src/util/mod.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
pub mod bug;
pub mod call_kind;
pub mod common;
pub mod find_self_call;

pub use call_kind::{CallDesugaringKind, CallKind, call_kind};
pub use find_self_call::find_self_call;

#[derive(Default, Copy, Clone)]
Expand Down
Loading
Loading