Skip to content

Commit ba824a2

Browse files
committed
Auto merge of rust-lang#121227 - Nadrieril:rollup-n6qky3z, r=Nadrieril
Rollup of 8 pull requests Successful merges: - rust-lang#119032 (Use a hardcoded constant instead of calling OpenProcessToken.) - rust-lang#120932 (const_mut_refs: allow mutable pointers to statics) - rust-lang#121059 (Add and use a simple extension trait derive macro in the compiler) - rust-lang#121135 (coverage: Discard spans that fill the entire function body) - rust-lang#121187 (Add examples to document the return type of quickselect functions) - rust-lang#121191 (Add myself to review rotation (and a rustbot ping)) - rust-lang#121192 (Give some intrinsics fallback bodies) - rust-lang#121197 (Ensure `./configure` works when `configure.py` path contains spaces) r? `@ghost` `@rustbot` modify labels: rollup
2 parents dfdbe30 + e266a12 commit ba824a2

File tree

65 files changed

+720
-1151
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

65 files changed

+720
-1151
lines changed

compiler/rustc_ast_lowering/src/lib.rs

+3-10
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ use rustc_hir::def::{DefKind, LifetimeRes, Namespace, PartialRes, PerNS, Res};
5757
use rustc_hir::def_id::{LocalDefId, LocalDefIdMap, CRATE_DEF_ID, LOCAL_CRATE};
5858
use rustc_hir::{ConstArg, GenericArg, ItemLocalMap, ParamName, TraitCandidate};
5959
use rustc_index::{Idx, IndexSlice, IndexVec};
60+
use rustc_macros::extension;
6061
use rustc_middle::span_bug;
6162
use rustc_middle::ty::{ResolverAstLowering, TyCtxt};
6263
use rustc_session::parse::{add_feature_diagnostics, feature_err};
@@ -190,16 +191,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
190191
}
191192
}
192193

193-
trait ResolverAstLoweringExt {
194-
fn legacy_const_generic_args(&self, expr: &Expr) -> Option<Vec<usize>>;
195-
fn get_partial_res(&self, id: NodeId) -> Option<PartialRes>;
196-
fn get_import_res(&self, id: NodeId) -> PerNS<Option<Res<NodeId>>>;
197-
fn get_label_res(&self, id: NodeId) -> Option<NodeId>;
198-
fn get_lifetime_res(&self, id: NodeId) -> Option<LifetimeRes>;
199-
fn take_extra_lifetime_params(&mut self, id: NodeId) -> Vec<(Ident, NodeId, LifetimeRes)>;
200-
}
201-
202-
impl ResolverAstLoweringExt for ResolverAstLowering {
194+
#[extension(trait ResolverAstLoweringExt)]
195+
impl ResolverAstLowering {
203196
fn legacy_const_generic_args(&self, expr: &Expr) -> Option<Vec<usize>> {
204197
if let ExprKind::Path(None, path) = &expr.kind {
205198
// Don't perform legacy const generics rewriting if the path already

compiler/rustc_borrowck/src/facts.rs

+3-12
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use crate::location::{LocationIndex, LocationTable};
22
use crate::BorrowIndex;
33
use polonius_engine::AllFacts as PoloniusFacts;
44
use polonius_engine::Atom;
5+
use rustc_macros::extension;
56
use rustc_middle::mir::Local;
67
use rustc_middle::ty::{RegionVid, TyCtxt};
78
use rustc_mir_dataflow::move_paths::MovePathIndex;
@@ -24,20 +25,10 @@ impl polonius_engine::FactTypes for RustcFacts {
2425

2526
pub type AllFacts = PoloniusFacts<RustcFacts>;
2627

27-
pub(crate) trait AllFactsExt {
28+
#[extension(pub(crate) trait AllFactsExt)]
29+
impl AllFacts {
2830
/// Returns `true` if there is a need to gather `AllFacts` given the
2931
/// current `-Z` flags.
30-
fn enabled(tcx: TyCtxt<'_>) -> bool;
31-
32-
fn write_to_dir(
33-
&self,
34-
dir: impl AsRef<Path>,
35-
location_table: &LocationTable,
36-
) -> Result<(), Box<dyn Error>>;
37-
}
38-
39-
impl AllFactsExt for AllFacts {
40-
/// Return
4132
fn enabled(tcx: TyCtxt<'_>) -> bool {
4233
tcx.sess.opts.unstable_opts.nll_facts
4334
|| tcx.sess.opts.unstable_opts.polonius.is_legacy_enabled()

compiler/rustc_borrowck/src/place_ext.rs

+3-11
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,16 @@
11
use crate::borrow_set::LocalsStateAtExit;
22
use rustc_hir as hir;
3+
use rustc_macros::extension;
34
use rustc_middle::mir::ProjectionElem;
45
use rustc_middle::mir::{Body, Mutability, Place};
56
use rustc_middle::ty::{self, TyCtxt};
67

7-
/// Extension methods for the `Place` type.
8-
pub trait PlaceExt<'tcx> {
8+
#[extension(pub trait PlaceExt<'tcx>)]
9+
impl<'tcx> Place<'tcx> {
910
/// Returns `true` if we can safely ignore borrows of this place.
1011
/// This is true whenever there is no action that the user can do
1112
/// to the place `self` that would invalidate the borrow. This is true
1213
/// for borrows of raw pointer dereferents as well as shared references.
13-
fn ignore_borrow(
14-
&self,
15-
tcx: TyCtxt<'tcx>,
16-
body: &Body<'tcx>,
17-
locals_state_at_exit: &LocalsStateAtExit,
18-
) -> bool;
19-
}
20-
21-
impl<'tcx> PlaceExt<'tcx> for Place<'tcx> {
2214
fn ignore_borrow(
2315
&self,
2416
tcx: TyCtxt<'tcx>,

compiler/rustc_borrowck/src/region_infer/opaque_types.rs

+3-9
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use rustc_hir::OpaqueTyOrigin;
66
use rustc_infer::infer::InferCtxt;
77
use rustc_infer::infer::TyCtxtInferExt as _;
88
use rustc_infer::traits::{Obligation, ObligationCause};
9+
use rustc_macros::extension;
910
use rustc_middle::traits::DefiningAnchor;
1011
use rustc_middle::ty::visit::TypeVisitableExt;
1112
use rustc_middle::ty::{self, OpaqueHiddenType, OpaqueTypeKey, Ty, TyCtxt, TypeFoldable};
@@ -225,15 +226,8 @@ impl<'tcx> RegionInferenceContext<'tcx> {
225226
}
226227
}
227228

228-
pub trait InferCtxtExt<'tcx> {
229-
fn infer_opaque_definition_from_instantiation(
230-
&self,
231-
opaque_type_key: OpaqueTypeKey<'tcx>,
232-
instantiated_ty: OpaqueHiddenType<'tcx>,
233-
) -> Ty<'tcx>;
234-
}
235-
236-
impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
229+
#[extension(pub trait InferCtxtExt<'tcx>)]
230+
impl<'tcx> InferCtxt<'tcx> {
237231
/// Given the fully resolved, instantiated type for an opaque
238232
/// type, i.e., the value of an inference variable like C1 or C2
239233
/// (*), computes the "definition type" for an opaque type

compiler/rustc_borrowck/src/universal_regions.rs

+3-21
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ use rustc_hir::lang_items::LangItem;
2222
use rustc_hir::BodyOwnerKind;
2323
use rustc_index::IndexVec;
2424
use rustc_infer::infer::NllRegionVariableOrigin;
25+
use rustc_macros::extension;
2526
use rustc_middle::ty::fold::TypeFoldable;
2627
use rustc_middle::ty::print::with_no_trimmed_paths;
2728
use rustc_middle::ty::{self, InlineConstArgs, InlineConstArgsParts, RegionVid, Ty, TyCtxt};
@@ -793,27 +794,8 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
793794
}
794795
}
795796

796-
trait InferCtxtExt<'tcx> {
797-
fn replace_free_regions_with_nll_infer_vars<T>(
798-
&self,
799-
origin: NllRegionVariableOrigin,
800-
value: T,
801-
) -> T
802-
where
803-
T: TypeFoldable<TyCtxt<'tcx>>;
804-
805-
fn replace_bound_regions_with_nll_infer_vars<T>(
806-
&self,
807-
origin: NllRegionVariableOrigin,
808-
all_outlive_scope: LocalDefId,
809-
value: ty::Binder<'tcx, T>,
810-
indices: &mut UniversalRegionIndices<'tcx>,
811-
) -> T
812-
where
813-
T: TypeFoldable<TyCtxt<'tcx>>;
814-
}
815-
816-
impl<'cx, 'tcx> InferCtxtExt<'tcx> for BorrowckInferCtxt<'cx, 'tcx> {
797+
#[extension(trait InferCtxtExt<'tcx>)]
798+
impl<'cx, 'tcx> BorrowckInferCtxt<'cx, 'tcx> {
817799
#[instrument(skip(self), level = "debug")]
818800
fn replace_free_regions_with_nll_infer_vars<T>(
819801
&self,

compiler/rustc_const_eval/src/transform/check_consts/check.rs

+33-4
Original file line numberDiff line numberDiff line change
@@ -344,7 +344,7 @@ impl<'mir, 'tcx> Checker<'mir, 'tcx> {
344344
visitor.visit_ty(ty);
345345
}
346346

347-
fn check_mut_borrow(&mut self, local: Local, kind: hir::BorrowKind) {
347+
fn check_mut_borrow(&mut self, place: &Place<'_>, kind: hir::BorrowKind) {
348348
match self.const_kind() {
349349
// In a const fn all borrows are transient or point to the places given via
350350
// references in the arguments (so we already checked them with
@@ -355,10 +355,19 @@ impl<'mir, 'tcx> Checker<'mir, 'tcx> {
355355
// to mutable memory.
356356
hir::ConstContext::ConstFn => self.check_op(ops::TransientMutBorrow(kind)),
357357
_ => {
358+
// For indirect places, we are not creating a new permanent borrow, it's just as
359+
// transient as the already existing one. For reborrowing references this is handled
360+
// at the top of `visit_rvalue`, but for raw pointers we handle it here.
361+
// Pointers/references to `static mut` and cases where the `*` is not the first
362+
// projection also end up here.
358363
// Locals with StorageDead do not live beyond the evaluation and can
359364
// thus safely be borrowed without being able to be leaked to the final
360365
// value of the constant.
361-
if self.local_has_storage_dead(local) {
366+
// Note: This is only sound if every local that has a `StorageDead` has a
367+
// `StorageDead` in every control flow path leading to a `return` terminator.
368+
// The good news is that interning will detect if any unexpected mutable
369+
// pointer slips through.
370+
if place.is_indirect() || self.local_has_storage_dead(place.local) {
362371
self.check_op(ops::TransientMutBorrow(kind));
363372
} else {
364373
self.check_op(ops::MutBorrow(kind));
@@ -390,6 +399,11 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
390399
trace!("visit_rvalue: rvalue={:?} location={:?}", rvalue, location);
391400

392401
// Special-case reborrows to be more like a copy of a reference.
402+
// FIXME: this does not actually handle all reborrows. It only detects cases where `*` is the outermost
403+
// projection of the borrowed place, it skips deref'ing raw pointers and it skips `static`.
404+
// All those cases are handled below with shared/mutable borrows.
405+
// Once `const_mut_refs` is stable, we should be able to entirely remove this special case.
406+
// (`const_refs_to_cell` is not needed, we already allow all borrows of indirect places anyway.)
393407
match *rvalue {
394408
Rvalue::Ref(_, kind, place) => {
395409
if let Some(reborrowed_place_ref) = place_as_reborrow(self.tcx, self.body, place) {
@@ -460,7 +474,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
460474

461475
if !is_allowed {
462476
self.check_mut_borrow(
463-
place.local,
477+
place,
464478
if matches!(rvalue, Rvalue::Ref(..)) {
465479
hir::BorrowKind::Ref
466480
} else {
@@ -478,7 +492,14 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
478492
place.as_ref(),
479493
);
480494

481-
if borrowed_place_has_mut_interior {
495+
// If the place is indirect, this is basically a reborrow. We have a reborrow
496+
// special case above, but for raw pointers and pointers/references to `static` and
497+
// when the `*` is not the first projection, `place_as_reborrow` does not recognize
498+
// them as such, so we end up here. This should probably be considered a
499+
// `TransientCellBorrow` (we consider the equivalent mutable case a
500+
// `TransientMutBorrow`), but such reborrows got accidentally stabilized already and
501+
// it is too much of a breaking change to take back.
502+
if borrowed_place_has_mut_interior && !place.is_indirect() {
482503
match self.const_kind() {
483504
// In a const fn all borrows are transient or point to the places given via
484505
// references in the arguments (so we already checked them with
@@ -495,6 +516,8 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
495516
// final value.
496517
// Note: This is only sound if every local that has a `StorageDead` has a
497518
// `StorageDead` in every control flow path leading to a `return` terminator.
519+
// The good news is that interning will detect if any unexpected mutable
520+
// pointer slips through.
498521
if self.local_has_storage_dead(place.local) {
499522
self.check_op(ops::TransientCellBorrow);
500523
} else {
@@ -948,6 +971,12 @@ fn place_as_reborrow<'tcx>(
948971
) -> Option<PlaceRef<'tcx>> {
949972
match place.as_ref().last_projection() {
950973
Some((place_base, ProjectionElem::Deref)) => {
974+
// FIXME: why do statics and raw pointers get excluded here? This makes
975+
// some code involving mutable pointers unstable, but it is unclear
976+
// why that code is treated differently from mutable references.
977+
// Once TransientMutBorrow and TransientCellBorrow are stable,
978+
// this can probably be cleaned up without any behavioral changes.
979+
951980
// A borrow of a `static` also looks like `&(*_1)` in the MIR, but `_1` is a `const`
952981
// that points to the allocation for the static. Don't treat these as reborrows.
953982
if body.local_decls[place_base.local].is_ref_to_static() {

compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs

+24
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,13 @@ pub trait Qualif {
7474
adt: AdtDef<'tcx>,
7575
args: GenericArgsRef<'tcx>,
7676
) -> bool;
77+
78+
/// Returns `true` if this `Qualif` behaves sructurally for pointers and references:
79+
/// the pointer/reference qualifies if and only if the pointee qualifies.
80+
///
81+
/// (This is currently `false` for all our instances, but that may change in the future. Also,
82+
/// by keeping it abstract, the handling of `Deref` in `in_place` becomes more clear.)
83+
fn deref_structural<'tcx>(cx: &ConstCx<'_, 'tcx>) -> bool;
7784
}
7885

7986
/// Constant containing interior mutability (`UnsafeCell<T>`).
@@ -103,6 +110,10 @@ impl Qualif for HasMutInterior {
103110
// It arises structurally for all other types.
104111
adt.is_unsafe_cell()
105112
}
113+
114+
fn deref_structural<'tcx>(_cx: &ConstCx<'_, 'tcx>) -> bool {
115+
false
116+
}
106117
}
107118

108119
/// Constant containing an ADT that implements `Drop`.
@@ -131,6 +142,10 @@ impl Qualif for NeedsDrop {
131142
) -> bool {
132143
adt.has_dtor(cx.tcx)
133144
}
145+
146+
fn deref_structural<'tcx>(_cx: &ConstCx<'_, 'tcx>) -> bool {
147+
false
148+
}
134149
}
135150

136151
/// Constant containing an ADT that implements non-const `Drop`.
@@ -210,6 +225,10 @@ impl Qualif for NeedsNonConstDrop {
210225
) -> bool {
211226
adt.has_non_const_dtor(cx.tcx)
212227
}
228+
229+
fn deref_structural<'tcx>(_cx: &ConstCx<'_, 'tcx>) -> bool {
230+
false
231+
}
213232
}
214233

215234
// FIXME: Use `mir::visit::Visitor` for the `in_*` functions if/when it supports early return.
@@ -303,6 +322,11 @@ where
303322
return false;
304323
}
305324

325+
if matches!(elem, ProjectionElem::Deref) && !Q::deref_structural(cx) {
326+
// We have to assume that this qualifies.
327+
return true;
328+
}
329+
306330
place = place_base;
307331
}
308332

compiler/rustc_hir_analysis/src/check/intrinsic.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -407,9 +407,9 @@ pub fn check_intrinsic_type(
407407
}
408408
sym::float_to_int_unchecked => (2, 0, vec![param(0)], param(1)),
409409

410-
sym::assume => (0, 0, vec![tcx.types.bool], Ty::new_unit(tcx)),
411-
sym::likely => (0, 0, vec![tcx.types.bool], tcx.types.bool),
412-
sym::unlikely => (0, 0, vec![tcx.types.bool], tcx.types.bool),
410+
sym::assume => (0, 1, vec![tcx.types.bool], Ty::new_unit(tcx)),
411+
sym::likely => (0, 1, vec![tcx.types.bool], tcx.types.bool),
412+
sym::unlikely => (0, 1, vec![tcx.types.bool], tcx.types.bool),
413413

414414
sym::read_via_copy => (1, 0, vec![Ty::new_imm_ptr(tcx, param(0))], param(0)),
415415
sym::write_via_move => {

compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs

+3-11
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ use rustc_hir::def::{DefKind, Res};
1414
use rustc_hir::def_id::LocalDefId;
1515
use rustc_hir::intravisit::{self, Visitor};
1616
use rustc_hir::{GenericArg, GenericParam, GenericParamKind, HirIdMap, LifetimeName, Node};
17+
use rustc_macros::extension;
1718
use rustc_middle::bug;
1819
use rustc_middle::hir::nested_filter;
1920
use rustc_middle::middle::resolve_bound_vars::*;
@@ -27,17 +28,8 @@ use std::fmt;
2728

2829
use crate::errors;
2930

30-
trait RegionExt {
31-
fn early(param: &GenericParam<'_>) -> (LocalDefId, ResolvedArg);
32-
33-
fn late(index: u32, param: &GenericParam<'_>) -> (LocalDefId, ResolvedArg);
34-
35-
fn id(&self) -> Option<DefId>;
36-
37-
fn shifted(self, amount: u32) -> ResolvedArg;
38-
}
39-
40-
impl RegionExt for ResolvedArg {
31+
#[extension(trait RegionExt)]
32+
impl ResolvedArg {
4133
fn early(param: &GenericParam<'_>) -> (LocalDefId, ResolvedArg) {
4234
debug!("ResolvedArg::early: def_id={:?}", param.def_id);
4335
(param.def_id, ResolvedArg::EarlyBound(param.def_id.to_def_id()))

compiler/rustc_infer/src/infer/canonical/instantiate.rs

+6-20
Original file line numberDiff line numberDiff line change
@@ -13,37 +13,23 @@ use rustc_middle::ty::{self, TyCtxt};
1313

1414
/// FIXME(-Znext-solver): This or public because it is shared with the
1515
/// new trait solver implementation. We should deduplicate canonicalization.
16-
pub trait CanonicalExt<'tcx, V> {
16+
#[extension(pub trait CanonicalExt<'tcx, V>)]
17+
impl<'tcx, V> Canonical<'tcx, V> {
1718
/// Instantiate the wrapped value, replacing each canonical value
1819
/// with the value given in `var_values`.
1920
fn instantiate(&self, tcx: TyCtxt<'tcx>, var_values: &CanonicalVarValues<'tcx>) -> V
2021
where
21-
V: TypeFoldable<TyCtxt<'tcx>>;
22+
V: TypeFoldable<TyCtxt<'tcx>>,
23+
{
24+
self.instantiate_projected(tcx, var_values, |value| value.clone())
25+
}
2226

2327
/// Allows one to apply a instantiation to some subset of
2428
/// `self.value`. Invoke `projection_fn` with `self.value` to get
2529
/// a value V that is expressed in terms of the same canonical
2630
/// variables bound in `self` (usually this extracts from subset
2731
/// of `self`). Apply the instantiation `var_values` to this value
2832
/// V, replacing each of the canonical variables.
29-
fn instantiate_projected<T>(
30-
&self,
31-
tcx: TyCtxt<'tcx>,
32-
var_values: &CanonicalVarValues<'tcx>,
33-
projection_fn: impl FnOnce(&V) -> T,
34-
) -> T
35-
where
36-
T: TypeFoldable<TyCtxt<'tcx>>;
37-
}
38-
39-
impl<'tcx, V> CanonicalExt<'tcx, V> for Canonical<'tcx, V> {
40-
fn instantiate(&self, tcx: TyCtxt<'tcx>, var_values: &CanonicalVarValues<'tcx>) -> V
41-
where
42-
V: TypeFoldable<TyCtxt<'tcx>>,
43-
{
44-
self.instantiate_projected(tcx, var_values, |value| value.clone())
45-
}
46-
4733
fn instantiate_projected<T>(
4834
&self,
4935
tcx: TyCtxt<'tcx>,

0 commit comments

Comments
 (0)