Auto merge of #150351 - JonathanBrouwer:rollup-knpqs9d, r=JonathanBrouwer
Rollup of 3 pull requests Successful merges: - rust-lang/rust#150141 (Misc cleanups from reading some borrowck code) - rust-lang/rust#150297 (Fix compile issue in Vita libstd) - rust-lang/rust#150341 (Fix some divergences with the cg_clif subtree) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
e7d44143a1
6 changed files with 101 additions and 128 deletions
|
|
@ -1,4 +1,4 @@
|
|||
//! This query borrow-checks the MIR to (further) ensure it is not broken.
|
||||
//! This crate implemens MIR typeck and MIR borrowck.
|
||||
|
||||
// tidy-alphabetical-start
|
||||
#![allow(internal_features)]
|
||||
|
|
@ -111,9 +111,9 @@ pub fn provide(providers: &mut Providers) {
|
|||
*providers = Providers { mir_borrowck, ..*providers };
|
||||
}
|
||||
|
||||
/// Provider for `query mir_borrowck`. Similar to `typeck`, this must
|
||||
/// only be called for typeck roots which will then borrowck all
|
||||
/// nested bodies as well.
|
||||
/// Provider for `query mir_borrowck`. Unlike `typeck`, this must
|
||||
/// only be called for typeck roots which *similar* to `typeck` will
|
||||
/// then borrowck all nested bodies as well.
|
||||
fn mir_borrowck(
|
||||
tcx: TyCtxt<'_>,
|
||||
def: LocalDefId,
|
||||
|
|
|
|||
|
|
@ -255,7 +255,7 @@ impl<'tcx> BorrowCheckRootCtxt<'tcx> {
|
|||
}
|
||||
|
||||
// We now apply the closure requirements of nested bodies modulo
|
||||
// regions. In case a body does not depend on opaque types, we
|
||||
// opaques. In case a body does not depend on opaque types, we
|
||||
// eagerly check its region constraints and use the final closure
|
||||
// requirements.
|
||||
//
|
||||
|
|
|
|||
|
|
@ -1,13 +1,12 @@
|
|||
//! Code to extract the universally quantified regions declared on a
|
||||
//! function and the relationships between them. For example:
|
||||
//! function. For example:
|
||||
//!
|
||||
//! ```
|
||||
//! fn foo<'a, 'b, 'c: 'b>() { }
|
||||
//! ```
|
||||
//!
|
||||
//! here we would return a map assigning each of `{'a, 'b, 'c}`
|
||||
//! to an index, as well as the `FreeRegionMap` which can compute
|
||||
//! relationships between them.
|
||||
//! to an index.
|
||||
//!
|
||||
//! The code in this file doesn't *do anything* with those results; it
|
||||
//! just returns them for other code to use.
|
||||
|
|
@ -271,8 +270,7 @@ impl<'tcx> UniversalRegions<'tcx> {
|
|||
/// Creates a new and fully initialized `UniversalRegions` that
|
||||
/// contains indices for all the free regions found in the given
|
||||
/// MIR -- that is, all the regions that appear in the function's
|
||||
/// signature. This will also compute the relationships that are
|
||||
/// known between those regions.
|
||||
/// signature.
|
||||
pub(crate) fn new(infcx: &BorrowckInferCtxt<'tcx>, mir_def: LocalDefId) -> Self {
|
||||
UniversalRegionsBuilder { infcx, mir_def }.build()
|
||||
}
|
||||
|
|
@ -648,17 +646,14 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
|
|||
|
||||
BodyOwnerKind::Const { .. } | BodyOwnerKind::Static(..) => {
|
||||
let identity_args = GenericArgs::identity_for_item(tcx, typeck_root_def_id);
|
||||
if self.mir_def.to_def_id() == typeck_root_def_id
|
||||
// Do not ICE when checking default_field_values consts with lifetimes (#135649)
|
||||
&& DefKind::Field != tcx.def_kind(tcx.parent(typeck_root_def_id))
|
||||
{
|
||||
if self.mir_def.to_def_id() == typeck_root_def_id {
|
||||
let args = self.infcx.replace_free_regions_with_nll_infer_vars(
|
||||
NllRegionVariableOrigin::FreeRegion,
|
||||
identity_args,
|
||||
);
|
||||
DefiningTy::Const(self.mir_def.to_def_id(), args)
|
||||
} else {
|
||||
// FIXME this line creates a dependency between borrowck and typeck.
|
||||
// FIXME: this line creates a query dependency between borrowck and typeck.
|
||||
//
|
||||
// This is required for `AscribeUserType` canonical query, which will call
|
||||
// `type_of(inline_const_def_id)`. That `type_of` would inject erased lifetimes
|
||||
|
|
@ -699,30 +694,14 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
|
|||
let tcx = self.infcx.tcx;
|
||||
let typeck_root_def_id = tcx.typeck_root_def_id(self.mir_def.to_def_id());
|
||||
let identity_args = GenericArgs::identity_for_item(tcx, typeck_root_def_id);
|
||||
let fr_args = match defining_ty {
|
||||
DefiningTy::Closure(_, args)
|
||||
| DefiningTy::CoroutineClosure(_, args)
|
||||
| DefiningTy::Coroutine(_, args)
|
||||
| DefiningTy::InlineConst(_, args) => {
|
||||
// In the case of closures, we rely on the fact that
|
||||
// the first N elements in the ClosureArgs are
|
||||
// inherited from the `typeck_root_def_id`.
|
||||
// Therefore, when we zip together (below) with
|
||||
// `identity_args`, we will get only those regions
|
||||
// that correspond to early-bound regions declared on
|
||||
// the `typeck_root_def_id`.
|
||||
assert!(args.len() >= identity_args.len());
|
||||
assert_eq!(args.regions().count(), identity_args.regions().count());
|
||||
args
|
||||
}
|
||||
|
||||
DefiningTy::FnDef(_, args) | DefiningTy::Const(_, args) => args,
|
||||
|
||||
DefiningTy::GlobalAsm(_) => ty::List::empty(),
|
||||
};
|
||||
let renumbered_args = defining_ty.args();
|
||||
|
||||
let global_mapping = iter::once((tcx.lifetimes.re_static, fr_static));
|
||||
let arg_mapping = iter::zip(identity_args.regions(), fr_args.regions().map(|r| r.as_var()));
|
||||
// This relies on typeck roots being generics_of parents with their
|
||||
// parameters at the start of nested bodies' generics.
|
||||
assert!(renumbered_args.len() >= identity_args.len());
|
||||
let arg_mapping =
|
||||
iter::zip(identity_args.regions(), renumbered_args.regions().map(|r| r.as_var()));
|
||||
|
||||
UniversalRegionIndices {
|
||||
indices: global_mapping.chain(arg_mapping).collect(),
|
||||
|
|
@ -862,8 +841,8 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
|
|||
};
|
||||
|
||||
// FIXME(#129952): We probably want a more principled approach here.
|
||||
if let Err(terr) = inputs_and_output.skip_binder().error_reported() {
|
||||
self.infcx.set_tainted_by_errors(terr);
|
||||
if let Err(e) = inputs_and_output.error_reported() {
|
||||
self.infcx.set_tainted_by_errors(e);
|
||||
}
|
||||
|
||||
inputs_and_output
|
||||
|
|
|
|||
|
|
@ -1005,14 +1005,6 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>(
|
|||
let lane_clif_ty = fx.clif_type(val_lane_ty).unwrap();
|
||||
let ret_lane_layout = fx.layout_of(ret_lane_ty);
|
||||
|
||||
let alignment =
|
||||
generic_args[3].expect_const().to_branch()[0].to_leaf().to_simd_alignment();
|
||||
|
||||
let memflags = match alignment {
|
||||
SimdAlign::Unaligned => MemFlags::new().with_notrap(),
|
||||
_ => MemFlags::trusted(),
|
||||
};
|
||||
|
||||
for lane_idx in 0..ptr_lane_count {
|
||||
let val_lane = val.value_lane(fx, lane_idx).load_scalar(fx);
|
||||
let ptr_lane = ptr.value_lane(fx, lane_idx).load_scalar(fx);
|
||||
|
|
@ -1028,7 +1020,7 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>(
|
|||
fx.bcx.seal_block(if_disabled);
|
||||
|
||||
fx.bcx.switch_to_block(if_enabled);
|
||||
let res = fx.bcx.ins().load(lane_clif_ty, memflags, ptr_lane, 0);
|
||||
let res = fx.bcx.ins().load(lane_clif_ty, MemFlags::trusted(), ptr_lane, 0);
|
||||
fx.bcx.ins().jump(next, &[res.into()]);
|
||||
|
||||
fx.bcx.switch_to_block(if_disabled);
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ use rustc_middle::ty::util::IntTypeExt;
|
|||
use rustc_middle::ty::{self, DefiningScopeKind, IsSuggestable, Ty, TyCtxt, TypeVisitableExt};
|
||||
use rustc_middle::{bug, span_bug};
|
||||
use rustc_span::{DUMMY_SP, Ident, Span};
|
||||
use tracing::instrument;
|
||||
|
||||
use super::{HirPlaceholderCollector, ItemCtxt, bad_placeholder};
|
||||
use crate::check::wfcheck::check_static_item;
|
||||
|
|
@ -17,85 +18,7 @@ use crate::hir_ty_lowering::HirTyLowerer;
|
|||
|
||||
mod opaque;
|
||||
|
||||
fn anon_const_type_of<'tcx>(icx: &ItemCtxt<'tcx>, def_id: LocalDefId) -> Ty<'tcx> {
|
||||
use hir::*;
|
||||
use rustc_middle::ty::Ty;
|
||||
let tcx = icx.tcx;
|
||||
let hir_id = tcx.local_def_id_to_hir_id(def_id);
|
||||
|
||||
let node = tcx.hir_node(hir_id);
|
||||
let Node::AnonConst(&AnonConst { span, .. }) = node else {
|
||||
span_bug!(
|
||||
tcx.def_span(def_id),
|
||||
"expected anon const in `anon_const_type_of`, got {node:?}"
|
||||
);
|
||||
};
|
||||
|
||||
let parent_node_id = tcx.parent_hir_id(hir_id);
|
||||
let parent_node = tcx.hir_node(parent_node_id);
|
||||
|
||||
match parent_node {
|
||||
// Anon consts "inside" the type system.
|
||||
Node::ConstArg(&ConstArg {
|
||||
hir_id: arg_hir_id,
|
||||
kind: ConstArgKind::Anon(&AnonConst { hir_id: anon_hir_id, .. }),
|
||||
..
|
||||
}) if anon_hir_id == hir_id => const_arg_anon_type_of(icx, arg_hir_id, span),
|
||||
|
||||
Node::Variant(Variant { disr_expr: Some(e), .. }) if e.hir_id == hir_id => {
|
||||
tcx.adt_def(tcx.hir_get_parent_item(hir_id)).repr().discr_type().to_ty(tcx)
|
||||
}
|
||||
|
||||
Node::Field(&hir::FieldDef { default: Some(c), def_id: field_def_id, .. })
|
||||
if c.hir_id == hir_id =>
|
||||
{
|
||||
tcx.type_of(field_def_id).instantiate_identity()
|
||||
}
|
||||
|
||||
_ => Ty::new_error_with_message(
|
||||
tcx,
|
||||
span,
|
||||
format!("unexpected anon const parent in type_of(): {parent_node:?}"),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
fn const_arg_anon_type_of<'tcx>(icx: &ItemCtxt<'tcx>, arg_hir_id: HirId, span: Span) -> Ty<'tcx> {
|
||||
use hir::*;
|
||||
use rustc_middle::ty::Ty;
|
||||
|
||||
let tcx = icx.tcx;
|
||||
|
||||
match tcx.parent_hir_node(arg_hir_id) {
|
||||
// Array length const arguments do not have `type_of` fed as there is never a corresponding
|
||||
// generic parameter definition.
|
||||
Node::Ty(&hir::Ty { kind: TyKind::Array(_, ref constant), .. })
|
||||
| Node::Expr(&Expr { kind: ExprKind::Repeat(_, ref constant), .. })
|
||||
if constant.hir_id == arg_hir_id =>
|
||||
{
|
||||
tcx.types.usize
|
||||
}
|
||||
|
||||
Node::TyPat(pat) => {
|
||||
let node = match tcx.parent_hir_node(pat.hir_id) {
|
||||
// Or patterns can be nested one level deep
|
||||
Node::TyPat(p) => tcx.parent_hir_node(p.hir_id),
|
||||
other => other,
|
||||
};
|
||||
let hir::TyKind::Pat(ty, _) = node.expect_ty().kind else { bug!() };
|
||||
icx.lower_ty(ty)
|
||||
}
|
||||
|
||||
// This is not a `bug!` as const arguments in path segments that did not resolve to anything
|
||||
// will result in `type_of` never being fed.
|
||||
_ => Ty::new_error_with_message(
|
||||
tcx,
|
||||
span,
|
||||
"`type_of` called on const argument's anon const before the const argument was lowered",
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
#[instrument(level = "debug", skip(tcx), ret)]
|
||||
pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<'_, Ty<'_>> {
|
||||
use rustc_hir::*;
|
||||
use rustc_middle::ty::Ty;
|
||||
|
|
@ -408,6 +331,85 @@ pub(super) fn type_of_opaque_hir_typeck(
|
|||
}
|
||||
}
|
||||
|
||||
fn anon_const_type_of<'tcx>(icx: &ItemCtxt<'tcx>, def_id: LocalDefId) -> Ty<'tcx> {
|
||||
use hir::*;
|
||||
use rustc_middle::ty::Ty;
|
||||
let tcx = icx.tcx;
|
||||
let hir_id = tcx.local_def_id_to_hir_id(def_id);
|
||||
|
||||
let node = tcx.hir_node(hir_id);
|
||||
let Node::AnonConst(&AnonConst { span, .. }) = node else {
|
||||
span_bug!(
|
||||
tcx.def_span(def_id),
|
||||
"expected anon const in `anon_const_type_of`, got {node:?}"
|
||||
);
|
||||
};
|
||||
|
||||
let parent_node_id = tcx.parent_hir_id(hir_id);
|
||||
let parent_node = tcx.hir_node(parent_node_id);
|
||||
|
||||
match parent_node {
|
||||
// Anon consts "inside" the type system.
|
||||
Node::ConstArg(&ConstArg {
|
||||
hir_id: arg_hir_id,
|
||||
kind: ConstArgKind::Anon(&AnonConst { hir_id: anon_hir_id, .. }),
|
||||
..
|
||||
}) if anon_hir_id == hir_id => const_arg_anon_type_of(icx, arg_hir_id, span),
|
||||
|
||||
Node::Variant(Variant { disr_expr: Some(e), .. }) if e.hir_id == hir_id => {
|
||||
tcx.adt_def(tcx.hir_get_parent_item(hir_id)).repr().discr_type().to_ty(tcx)
|
||||
}
|
||||
|
||||
Node::Field(&hir::FieldDef { default: Some(c), def_id: field_def_id, .. })
|
||||
if c.hir_id == hir_id =>
|
||||
{
|
||||
tcx.type_of(field_def_id).instantiate_identity()
|
||||
}
|
||||
|
||||
_ => Ty::new_error_with_message(
|
||||
tcx,
|
||||
span,
|
||||
format!("unexpected anon const parent in type_of(): {parent_node:?}"),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
fn const_arg_anon_type_of<'tcx>(icx: &ItemCtxt<'tcx>, arg_hir_id: HirId, span: Span) -> Ty<'tcx> {
|
||||
use hir::*;
|
||||
use rustc_middle::ty::Ty;
|
||||
|
||||
let tcx = icx.tcx;
|
||||
|
||||
match tcx.parent_hir_node(arg_hir_id) {
|
||||
// Array length const arguments do not have `type_of` fed as there is never a corresponding
|
||||
// generic parameter definition.
|
||||
Node::Ty(&hir::Ty { kind: TyKind::Array(_, ref constant), .. })
|
||||
| Node::Expr(&Expr { kind: ExprKind::Repeat(_, ref constant), .. })
|
||||
if constant.hir_id == arg_hir_id =>
|
||||
{
|
||||
tcx.types.usize
|
||||
}
|
||||
|
||||
Node::TyPat(pat) => {
|
||||
let node = match tcx.parent_hir_node(pat.hir_id) {
|
||||
// Or patterns can be nested one level deep
|
||||
Node::TyPat(p) => tcx.parent_hir_node(p.hir_id),
|
||||
other => other,
|
||||
};
|
||||
let hir::TyKind::Pat(ty, _) = node.expect_ty().kind else { bug!() };
|
||||
icx.lower_ty(ty)
|
||||
}
|
||||
|
||||
// This is not a `bug!` as const arguments in path segments that did not resolve to anything
|
||||
// will result in `type_of` never being fed.
|
||||
_ => Ty::new_error_with_message(
|
||||
tcx,
|
||||
span,
|
||||
"`type_of` called on const argument's anon const before the const argument was lowered",
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
fn infer_placeholder_type<'tcx>(
|
||||
cx: &dyn HirTyLowerer<'tcx>,
|
||||
def_id: LocalDefId,
|
||||
|
|
|
|||
|
|
@ -2166,7 +2166,7 @@ fn open_from(from: &Path) -> io::Result<(crate::fs::File, crate::fs::Metadata)>
|
|||
|
||||
fn set_times_impl(p: &CStr, times: FileTimes, follow_symlinks: bool) -> io::Result<()> {
|
||||
cfg_select! {
|
||||
any(target_os = "redox", target_os = "espidf", target_os = "horizon", target_os = "nuttx") => {
|
||||
any(target_os = "redox", target_os = "espidf", target_os = "horizon", target_os = "nuttx", target_os = "vita") => {
|
||||
let _ = (p, times, follow_symlinks);
|
||||
Err(io::const_error!(
|
||||
io::ErrorKind::Unsupported,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue