mirror of
https://github.com/rust-lang/rust.git
synced 2025-06-04 19:29:07 +00:00
Accept TyCtxt
instead of TyCtxtAt
in Ty::is_*
functions
Functions in answer: - `Ty::is_freeze` - `Ty::is_sized` - `Ty::is_unpin` - `Ty::is_copy_modulo_regions`
This commit is contained in:
parent
44fcfb0a96
commit
a17ccfa621
@ -1776,7 +1776,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
|||||||
// `Sized` bound in no way depends on precise regions, so this
|
// `Sized` bound in no way depends on precise regions, so this
|
||||||
// shouldn't affect `is_sized`.
|
// shouldn't affect `is_sized`.
|
||||||
let erased_ty = tcx.erase_regions(ty);
|
let erased_ty = tcx.erase_regions(ty);
|
||||||
if !erased_ty.is_sized(tcx.at(span), self.param_env) {
|
if !erased_ty.is_sized(tcx, self.param_env) {
|
||||||
// in current MIR construction, all non-control-flow rvalue
|
// in current MIR construction, all non-control-flow rvalue
|
||||||
// expressions evaluate through `as_temp` or `into` a return
|
// expressions evaluate through `as_temp` or `into` a return
|
||||||
// slot or local, so to find all unsized rvalues it is enough
|
// slot or local, so to find all unsized rvalues it is enough
|
||||||
|
@ -5,7 +5,6 @@ use crate::common::TypeKind;
|
|||||||
use crate::mir::place::PlaceRef;
|
use crate::mir::place::PlaceRef;
|
||||||
use rustc_middle::ty::layout::TyAndLayout;
|
use rustc_middle::ty::layout::TyAndLayout;
|
||||||
use rustc_middle::ty::{self, Ty};
|
use rustc_middle::ty::{self, Ty};
|
||||||
use rustc_span::DUMMY_SP;
|
|
||||||
use rustc_target::abi::call::{ArgAbi, CastTarget, FnAbi, Reg};
|
use rustc_target::abi::call::{ArgAbi, CastTarget, FnAbi, Reg};
|
||||||
use rustc_target::abi::{AddressSpace, Integer};
|
use rustc_target::abi::{AddressSpace, Integer};
|
||||||
|
|
||||||
@ -75,16 +74,16 @@ pub trait DerivedTypeMethods<'tcx>: BaseTypeMethods<'tcx> + MiscMethods<'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn type_is_sized(&self, ty: Ty<'tcx>) -> bool {
|
fn type_is_sized(&self, ty: Ty<'tcx>) -> bool {
|
||||||
ty.is_sized(self.tcx().at(DUMMY_SP), ty::ParamEnv::reveal_all())
|
ty.is_sized(self.tcx(), ty::ParamEnv::reveal_all())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn type_is_freeze(&self, ty: Ty<'tcx>) -> bool {
|
fn type_is_freeze(&self, ty: Ty<'tcx>) -> bool {
|
||||||
ty.is_freeze(self.tcx().at(DUMMY_SP), ty::ParamEnv::reveal_all())
|
ty.is_freeze(self.tcx(), ty::ParamEnv::reveal_all())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn type_has_metadata(&self, ty: Ty<'tcx>) -> bool {
|
fn type_has_metadata(&self, ty: Ty<'tcx>) -> bool {
|
||||||
let param_env = ty::ParamEnv::reveal_all();
|
let param_env = ty::ParamEnv::reveal_all();
|
||||||
if ty.is_sized(self.tcx().at(DUMMY_SP), param_env) {
|
if ty.is_sized(self.tcx(), param_env) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -212,7 +212,7 @@ fn create_pointee_place<'tcx>(
|
|||||||
) -> MPlaceTy<'tcx> {
|
) -> MPlaceTy<'tcx> {
|
||||||
let tcx = ecx.tcx.tcx;
|
let tcx = ecx.tcx.tcx;
|
||||||
|
|
||||||
if !ty.is_sized(ecx.tcx, ty::ParamEnv::empty()) {
|
if !ty.is_sized(*ecx.tcx, ty::ParamEnv::empty()) {
|
||||||
// We need to create `Allocation`s for custom DSTs
|
// We need to create `Allocation`s for custom DSTs
|
||||||
|
|
||||||
let (unsized_inner_ty, num_elems) = get_info_on_unsized_field(ty, valtree, tcx);
|
let (unsized_inner_ty, num_elems) = get_info_on_unsized_field(ty, valtree, tcx);
|
||||||
@ -398,7 +398,7 @@ fn valtree_into_mplace<'tcx>(
|
|||||||
|
|
||||||
let mut place_inner = match ty.kind() {
|
let mut place_inner = match ty.kind() {
|
||||||
ty::Str | ty::Slice(_) => ecx.mplace_index(&place, i as u64).unwrap(),
|
ty::Str | ty::Slice(_) => ecx.mplace_index(&place, i as u64).unwrap(),
|
||||||
_ if !ty.is_sized(ecx.tcx, ty::ParamEnv::empty())
|
_ if !ty.is_sized(*ecx.tcx, ty::ParamEnv::empty())
|
||||||
&& i == branches.len() - 1 =>
|
&& i == branches.len() - 1 =>
|
||||||
{
|
{
|
||||||
// Note: For custom DSTs we need to manually process the last unsized field.
|
// Note: For custom DSTs we need to manually process the last unsized field.
|
||||||
|
@ -468,7 +468,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
|||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn type_is_freeze(&self, ty: Ty<'tcx>) -> bool {
|
pub fn type_is_freeze(&self, ty: Ty<'tcx>) -> bool {
|
||||||
ty.is_freeze(self.tcx, self.param_env)
|
ty.is_freeze(*self.tcx, self.param_env)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn load_mir(
|
pub fn load_mir(
|
||||||
|
@ -114,7 +114,7 @@ fn intern_shallow<'rt, 'mir, 'tcx, M: CompileTimeMachine<'mir, 'tcx, const_eval:
|
|||||||
if let InternMode::Static(mutability) = mode {
|
if let InternMode::Static(mutability) = mode {
|
||||||
// For this, we need to take into account `UnsafeCell`. When `ty` is `None`, we assume
|
// For this, we need to take into account `UnsafeCell`. When `ty` is `None`, we assume
|
||||||
// no interior mutability.
|
// no interior mutability.
|
||||||
let frozen = ty.map_or(true, |ty| ty.is_freeze(ecx.tcx, ecx.param_env));
|
let frozen = ty.map_or(true, |ty| ty.is_freeze(*ecx.tcx, ecx.param_env));
|
||||||
// For statics, allocation mutability is the combination of place mutability and
|
// For statics, allocation mutability is the combination of place mutability and
|
||||||
// type mutability.
|
// type mutability.
|
||||||
// The entire allocation needs to be mutable if it contains an `UnsafeCell` anywhere.
|
// The entire allocation needs to be mutable if it contains an `UnsafeCell` anywhere.
|
||||||
|
@ -15,7 +15,6 @@ use rustc_middle::mir::interpret::InterpError;
|
|||||||
use rustc_middle::ty;
|
use rustc_middle::ty;
|
||||||
use rustc_middle::ty::layout::{LayoutOf, TyAndLayout};
|
use rustc_middle::ty::layout::{LayoutOf, TyAndLayout};
|
||||||
use rustc_span::symbol::{sym, Symbol};
|
use rustc_span::symbol::{sym, Symbol};
|
||||||
use rustc_span::DUMMY_SP;
|
|
||||||
use rustc_target::abi::{Abi, Scalar as ScalarAbi, Size, VariantIdx, Variants, WrappingRange};
|
use rustc_target::abi::{Abi, Scalar as ScalarAbi, Size, VariantIdx, Variants, WrappingRange};
|
||||||
|
|
||||||
use std::hash::Hash;
|
use std::hash::Hash;
|
||||||
@ -726,7 +725,7 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M>
|
|||||||
) -> InterpResult<'tcx> {
|
) -> InterpResult<'tcx> {
|
||||||
// Special check preventing `UnsafeCell` inside unions in the inner part of constants.
|
// Special check preventing `UnsafeCell` inside unions in the inner part of constants.
|
||||||
if matches!(self.ctfe_mode, Some(CtfeValidationMode::Const { inner: true, .. })) {
|
if matches!(self.ctfe_mode, Some(CtfeValidationMode::Const { inner: true, .. })) {
|
||||||
if !op.layout.ty.is_freeze(self.ecx.tcx.at(DUMMY_SP), self.ecx.param_env) {
|
if !op.layout.ty.is_freeze(*self.ecx.tcx, self.ecx.param_env) {
|
||||||
throw_validation_failure!(self.path, { "`UnsafeCell` in a `const`" });
|
throw_validation_failure!(self.path, { "`UnsafeCell` in a `const`" });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,6 @@ use rustc_infer::infer::TyCtxtInferExt;
|
|||||||
use rustc_middle::mir;
|
use rustc_middle::mir;
|
||||||
use rustc_middle::mir::*;
|
use rustc_middle::mir::*;
|
||||||
use rustc_middle::ty::{self, subst::SubstsRef, AdtDef, Ty};
|
use rustc_middle::ty::{self, subst::SubstsRef, AdtDef, Ty};
|
||||||
use rustc_span::DUMMY_SP;
|
|
||||||
use rustc_trait_selection::traits::{
|
use rustc_trait_selection::traits::{
|
||||||
self, ImplSource, Obligation, ObligationCause, SelectionContext,
|
self, ImplSource, Obligation, ObligationCause, SelectionContext,
|
||||||
};
|
};
|
||||||
@ -92,7 +91,7 @@ impl Qualif for HasMutInterior {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn in_any_value_of_ty<'tcx>(cx: &ConstCx<'_, 'tcx>, ty: Ty<'tcx>) -> bool {
|
fn in_any_value_of_ty<'tcx>(cx: &ConstCx<'_, 'tcx>, ty: Ty<'tcx>) -> bool {
|
||||||
!ty.is_freeze(cx.tcx.at(DUMMY_SP), cx.param_env)
|
!ty.is_freeze(cx.tcx, cx.param_env)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn in_adt_inherently<'tcx>(
|
fn in_adt_inherently<'tcx>(
|
||||||
|
@ -8,7 +8,6 @@ use rustc_middle::mir::{self, BasicBlock, Local, Location, Statement, StatementK
|
|||||||
use rustc_mir_dataflow::fmt::DebugWithContext;
|
use rustc_mir_dataflow::fmt::DebugWithContext;
|
||||||
use rustc_mir_dataflow::JoinSemiLattice;
|
use rustc_mir_dataflow::JoinSemiLattice;
|
||||||
use rustc_mir_dataflow::{Analysis, AnalysisDomain, CallReturnPlaces};
|
use rustc_mir_dataflow::{Analysis, AnalysisDomain, CallReturnPlaces};
|
||||||
use rustc_span::DUMMY_SP;
|
|
||||||
|
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
@ -120,10 +119,7 @@ where
|
|||||||
///
|
///
|
||||||
/// [rust-lang/unsafe-code-guidelines#134]: https://github.com/rust-lang/unsafe-code-guidelines/issues/134
|
/// [rust-lang/unsafe-code-guidelines#134]: https://github.com/rust-lang/unsafe-code-guidelines/issues/134
|
||||||
fn shared_borrow_allows_mutation(&self, place: mir::Place<'tcx>) -> bool {
|
fn shared_borrow_allows_mutation(&self, place: mir::Place<'tcx>) -> bool {
|
||||||
!place
|
!place.ty(self.ccx.body, self.ccx.tcx).ty.is_freeze(self.ccx.tcx, self.ccx.param_env)
|
||||||
.ty(self.ccx.body, self.ccx.tcx)
|
|
||||||
.ty
|
|
||||||
.is_freeze(self.ccx.tcx.at(DUMMY_SP), self.ccx.param_env)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -235,9 +235,8 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
|
|||||||
// `Operand::Copy` is only supposed to be used with `Copy` types.
|
// `Operand::Copy` is only supposed to be used with `Copy` types.
|
||||||
if let Operand::Copy(place) = operand {
|
if let Operand::Copy(place) = operand {
|
||||||
let ty = place.ty(&self.body.local_decls, self.tcx).ty;
|
let ty = place.ty(&self.body.local_decls, self.tcx).ty;
|
||||||
let span = self.body.source_info(location).span;
|
|
||||||
|
|
||||||
if !ty.is_copy_modulo_regions(self.tcx.at(span), self.param_env) {
|
if !ty.is_copy_modulo_regions(self.tcx, self.param_env) {
|
||||||
self.fail(location, format!("`Operand::Copy` with non-`Copy` type {}", ty));
|
self.fail(location, format!("`Operand::Copy` with non-`Copy` type {}", ty));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -114,7 +114,7 @@ fn check_union_fields(tcx: TyCtxt<'_>, span: Span, item_def_id: LocalDefId) -> b
|
|||||||
_ => {
|
_ => {
|
||||||
// Fallback case: allow `ManuallyDrop` and things that are `Copy`.
|
// Fallback case: allow `ManuallyDrop` and things that are `Copy`.
|
||||||
ty.ty_adt_def().is_some_and(|adt_def| adt_def.is_manually_drop())
|
ty.ty_adt_def().is_some_and(|adt_def| adt_def.is_manually_drop())
|
||||||
|| ty.is_copy_modulo_regions(tcx.at(span), param_env)
|
|| ty.is_copy_modulo_regions(tcx, param_env)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -33,7 +33,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
|
|||||||
fn is_thin_ptr_ty(&self, ty: Ty<'tcx>) -> bool {
|
fn is_thin_ptr_ty(&self, ty: Ty<'tcx>) -> bool {
|
||||||
// Type still may have region variables, but `Sized` does not depend
|
// Type still may have region variables, but `Sized` does not depend
|
||||||
// on those, so just erase them before querying.
|
// on those, so just erase them before querying.
|
||||||
if ty.is_sized(self.tcx.at(DUMMY_SP), self.param_env) {
|
if ty.is_sized(self.tcx, self.param_env) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if let ty::Foreign(..) = ty.kind() {
|
if let ty::Foreign(..) = ty.kind() {
|
||||||
@ -128,7 +128,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
|
|||||||
|
|
||||||
// Check that the type implements Copy. The only case where this can
|
// Check that the type implements Copy. The only case where this can
|
||||||
// possibly fail is for SIMD types which don't #[derive(Copy)].
|
// possibly fail is for SIMD types which don't #[derive(Copy)].
|
||||||
if !ty.is_copy_modulo_regions(self.tcx.at(expr.span), self.param_env) {
|
if !ty.is_copy_modulo_regions(self.tcx, self.param_env) {
|
||||||
let msg = "arguments for inline assembly must be copyable";
|
let msg = "arguments for inline assembly must be copyable";
|
||||||
let mut err = self.tcx.sess.struct_span_err(expr.span, msg);
|
let mut err = self.tcx.sess.struct_span_err(expr.span, msg);
|
||||||
err.note(&format!("`{ty}` does not implement the Copy trait"));
|
err.note(&format!("`{ty}` does not implement the Copy trait"));
|
||||||
|
@ -752,7 +752,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingCopyImplementations {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let param_env = ty::ParamEnv::empty();
|
let param_env = ty::ParamEnv::empty();
|
||||||
if ty.is_copy_modulo_regions(cx.tcx.at(item.span), param_env) {
|
if ty.is_copy_modulo_regions(cx.tcx, param_env) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if can_type_implement_copy(
|
if can_type_implement_copy(
|
||||||
|
@ -11,7 +11,7 @@ use rustc_middle::ty::subst::SubstsRef;
|
|||||||
use rustc_middle::ty::{self, AdtKind, DefIdTree, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable};
|
use rustc_middle::ty::{self, AdtKind, DefIdTree, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable};
|
||||||
use rustc_span::source_map;
|
use rustc_span::source_map;
|
||||||
use rustc_span::symbol::sym;
|
use rustc_span::symbol::sym;
|
||||||
use rustc_span::{Span, Symbol, DUMMY_SP};
|
use rustc_span::{Span, Symbol};
|
||||||
use rustc_target::abi::{Abi, WrappingRange};
|
use rustc_target::abi::{Abi, WrappingRange};
|
||||||
use rustc_target::abi::{Integer, TagEncoding, Variants};
|
use rustc_target::abi::{Integer, TagEncoding, Variants};
|
||||||
use rustc_target::spec::abi::Abi as SpecAbi;
|
use rustc_target::spec::abi::Abi as SpecAbi;
|
||||||
@ -931,7 +931,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
|
|||||||
match *ty.kind() {
|
match *ty.kind() {
|
||||||
ty::Adt(def, substs) => {
|
ty::Adt(def, substs) => {
|
||||||
if def.is_box() && matches!(self.mode, CItemKind::Definition) {
|
if def.is_box() && matches!(self.mode, CItemKind::Definition) {
|
||||||
if ty.boxed_ty().is_sized(tcx.at(DUMMY_SP), self.cx.param_env) {
|
if ty.boxed_ty().is_sized(tcx, self.cx.param_env) {
|
||||||
return FfiSafe;
|
return FfiSafe;
|
||||||
} else {
|
} else {
|
||||||
return FfiUnsafe {
|
return FfiUnsafe {
|
||||||
@ -1082,7 +1082,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
|
|||||||
ty::RawPtr(ty::TypeAndMut { ty, .. }) | ty::Ref(_, ty, _)
|
ty::RawPtr(ty::TypeAndMut { ty, .. }) | ty::Ref(_, ty, _)
|
||||||
if {
|
if {
|
||||||
matches!(self.mode, CItemKind::Definition)
|
matches!(self.mode, CItemKind::Definition)
|
||||||
&& ty.is_sized(self.cx.tcx.at(DUMMY_SP), self.cx.param_env)
|
&& ty.is_sized(self.cx.tcx, self.cx.param_env)
|
||||||
} =>
|
} =>
|
||||||
{
|
{
|
||||||
FfiSafe
|
FfiSafe
|
||||||
|
@ -830,7 +830,7 @@ where
|
|||||||
} else {
|
} else {
|
||||||
match mt {
|
match mt {
|
||||||
hir::Mutability::Not => {
|
hir::Mutability::Not => {
|
||||||
if ty.is_freeze(tcx.at(DUMMY_SP), cx.param_env()) {
|
if ty.is_freeze(tcx, cx.param_env()) {
|
||||||
PointerKind::Frozen
|
PointerKind::Frozen
|
||||||
} else {
|
} else {
|
||||||
PointerKind::SharedMutable
|
PointerKind::SharedMutable
|
||||||
@ -841,7 +841,7 @@ where
|
|||||||
// noalias, as another pointer to the structure can be obtained, that
|
// noalias, as another pointer to the structure can be obtained, that
|
||||||
// is not based-on the original reference. We consider all !Unpin
|
// is not based-on the original reference. We consider all !Unpin
|
||||||
// types to be potentially self-referential here.
|
// types to be potentially self-referential here.
|
||||||
if ty.is_unpin(tcx.at(DUMMY_SP), cx.param_env()) {
|
if ty.is_unpin(tcx, cx.param_env()) {
|
||||||
PointerKind::UniqueBorrowed
|
PointerKind::UniqueBorrowed
|
||||||
} else {
|
} else {
|
||||||
PointerKind::UniqueBorrowedPinned
|
PointerKind::UniqueBorrowedPinned
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
|
|
||||||
use crate::middle::codegen_fn_attrs::CodegenFnAttrFlags;
|
use crate::middle::codegen_fn_attrs::CodegenFnAttrFlags;
|
||||||
use crate::ty::layout::IntegerExt;
|
use crate::ty::layout::IntegerExt;
|
||||||
use crate::ty::query::TyCtxtAt;
|
|
||||||
use crate::ty::{
|
use crate::ty::{
|
||||||
self, DefIdTree, FallibleTypeFolder, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable,
|
self, DefIdTree, FallibleTypeFolder, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable,
|
||||||
TypeVisitable,
|
TypeVisitable,
|
||||||
@ -821,12 +820,8 @@ impl<'tcx> Ty<'tcx> {
|
|||||||
/// does copies even when the type actually doesn't satisfy the
|
/// does copies even when the type actually doesn't satisfy the
|
||||||
/// full requirements for the `Copy` trait (cc #29149) -- this
|
/// full requirements for the `Copy` trait (cc #29149) -- this
|
||||||
/// winds up being reported as an error during NLL borrow check.
|
/// winds up being reported as an error during NLL borrow check.
|
||||||
pub fn is_copy_modulo_regions(
|
pub fn is_copy_modulo_regions(self, tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>) -> bool {
|
||||||
self,
|
self.is_trivially_pure_clone_copy() || tcx.is_copy_raw(param_env.and(self))
|
||||||
tcx_at: TyCtxtAt<'tcx>,
|
|
||||||
param_env: ty::ParamEnv<'tcx>,
|
|
||||||
) -> bool {
|
|
||||||
self.is_trivially_pure_clone_copy() || tcx_at.is_copy_raw(param_env.and(self))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Checks whether values of this type `T` have a size known at
|
/// Checks whether values of this type `T` have a size known at
|
||||||
@ -835,8 +830,8 @@ impl<'tcx> Ty<'tcx> {
|
|||||||
/// over-approximation in generic contexts, where one can have
|
/// over-approximation in generic contexts, where one can have
|
||||||
/// strange rules like `<T as Foo<'static>>::Bar: Sized` that
|
/// strange rules like `<T as Foo<'static>>::Bar: Sized` that
|
||||||
/// actually carry lifetime requirements.
|
/// actually carry lifetime requirements.
|
||||||
pub fn is_sized(self, tcx_at: TyCtxtAt<'tcx>, param_env: ty::ParamEnv<'tcx>) -> bool {
|
pub fn is_sized(self, tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>) -> bool {
|
||||||
self.is_trivially_sized(tcx_at.tcx) || tcx_at.is_sized_raw(param_env.and(self))
|
self.is_trivially_sized(tcx) || tcx.is_sized_raw(param_env.and(self))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Checks whether values of this type `T` implement the `Freeze`
|
/// Checks whether values of this type `T` implement the `Freeze`
|
||||||
@ -846,8 +841,8 @@ impl<'tcx> Ty<'tcx> {
|
|||||||
/// optimization as well as the rules around static values. Note
|
/// optimization as well as the rules around static values. Note
|
||||||
/// that the `Freeze` trait is not exposed to end users and is
|
/// that the `Freeze` trait is not exposed to end users and is
|
||||||
/// effectively an implementation detail.
|
/// effectively an implementation detail.
|
||||||
pub fn is_freeze(self, tcx_at: TyCtxtAt<'tcx>, param_env: ty::ParamEnv<'tcx>) -> bool {
|
pub fn is_freeze(self, tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>) -> bool {
|
||||||
self.is_trivially_freeze() || tcx_at.is_freeze_raw(param_env.and(self))
|
self.is_trivially_freeze() || tcx.is_freeze_raw(param_env.and(self))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Fast path helper for testing if a type is `Freeze`.
|
/// Fast path helper for testing if a type is `Freeze`.
|
||||||
@ -886,8 +881,8 @@ impl<'tcx> Ty<'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Checks whether values of this type `T` implement the `Unpin` trait.
|
/// Checks whether values of this type `T` implement the `Unpin` trait.
|
||||||
pub fn is_unpin(self, tcx_at: TyCtxtAt<'tcx>, param_env: ty::ParamEnv<'tcx>) -> bool {
|
pub fn is_unpin(self, tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>) -> bool {
|
||||||
self.is_trivially_unpin() || tcx_at.is_unpin_raw(param_env.and(self))
|
self.is_trivially_unpin() || tcx.is_unpin_raw(param_env.and(self))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Fast path helper for testing if a type is `Unpin`.
|
/// Fast path helper for testing if a type is `Unpin`.
|
||||||
|
@ -153,12 +153,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||||||
|
|
||||||
if tcx.features().unsized_fn_params {
|
if tcx.features().unsized_fn_params {
|
||||||
let ty = expr.ty;
|
let ty = expr.ty;
|
||||||
let span = expr.span;
|
|
||||||
let param_env = this.param_env;
|
let param_env = this.param_env;
|
||||||
|
|
||||||
if !ty.is_sized(tcx.at(span), param_env) {
|
if !ty.is_sized(tcx, param_env) {
|
||||||
// !sized means !copy, so this is an unsized move
|
// !sized means !copy, so this is an unsized move
|
||||||
assert!(!ty.is_copy_modulo_regions(tcx.at(span), param_env));
|
assert!(!ty.is_copy_modulo_regions(tcx, param_env));
|
||||||
|
|
||||||
// As described above, detect the case where we are passing a value of unsized
|
// As described above, detect the case where we are passing a value of unsized
|
||||||
// type, and that value is coming from the deref of a box.
|
// type, and that value is coming from the deref of a box.
|
||||||
|
@ -260,7 +260,7 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
|
|||||||
};
|
};
|
||||||
match borrow_kind {
|
match borrow_kind {
|
||||||
BorrowKind::Shallow | BorrowKind::Shared | BorrowKind::Unique => {
|
BorrowKind::Shallow | BorrowKind::Shared | BorrowKind::Unique => {
|
||||||
if !ty.is_freeze(self.tcx.at(pat.span), self.param_env) {
|
if !ty.is_freeze(self.tcx, self.param_env) {
|
||||||
self.requires_unsafe(pat.span, BorrowOfLayoutConstrainedField);
|
self.requires_unsafe(pat.span, BorrowOfLayoutConstrainedField);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -457,9 +457,7 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
|
|||||||
if visitor.found {
|
if visitor.found {
|
||||||
match borrow_kind {
|
match borrow_kind {
|
||||||
BorrowKind::Shallow | BorrowKind::Shared | BorrowKind::Unique
|
BorrowKind::Shallow | BorrowKind::Shared | BorrowKind::Unique
|
||||||
if !self.thir[arg]
|
if !self.thir[arg].ty.is_freeze(self.tcx, self.param_env) =>
|
||||||
.ty
|
|
||||||
.is_freeze(self.tcx.at(self.thir[arg].span), self.param_env) =>
|
|
||||||
{
|
{
|
||||||
self.requires_unsafe(expr.span, BorrowOfLayoutConstrainedField)
|
self.requires_unsafe(expr.span, BorrowOfLayoutConstrainedField)
|
||||||
}
|
}
|
||||||
|
@ -1004,8 +1004,8 @@ fn maybe_point_at_variant<'a, 'p: 'a, 'tcx: 'a>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Check if a by-value binding is by-value. That is, check if the binding's type is not `Copy`.
|
/// Check if a by-value binding is by-value. That is, check if the binding's type is not `Copy`.
|
||||||
fn is_binding_by_move(cx: &MatchVisitor<'_, '_, '_>, hir_id: HirId, span: Span) -> bool {
|
fn is_binding_by_move(cx: &MatchVisitor<'_, '_, '_>, hir_id: HirId) -> bool {
|
||||||
!cx.typeck_results.node_type(hir_id).is_copy_modulo_regions(cx.tcx.at(span), cx.param_env)
|
!cx.typeck_results.node_type(hir_id).is_copy_modulo_regions(cx.tcx, cx.param_env)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Check that there are no borrow or move conflicts in `binding @ subpat` patterns.
|
/// Check that there are no borrow or move conflicts in `binding @ subpat` patterns.
|
||||||
@ -1031,7 +1031,7 @@ fn check_borrow_conflicts_in_at_patterns(cx: &MatchVisitor<'_, '_, '_>, pat: &Pa
|
|||||||
|
|
||||||
// Get the binding move, extract the mutability if by-ref.
|
// Get the binding move, extract the mutability if by-ref.
|
||||||
let mut_outer = match typeck_results.extract_binding_mode(sess, pat.hir_id, pat.span) {
|
let mut_outer = match typeck_results.extract_binding_mode(sess, pat.hir_id, pat.span) {
|
||||||
Some(ty::BindByValue(_)) if is_binding_by_move(cx, pat.hir_id, pat.span) => {
|
Some(ty::BindByValue(_)) if is_binding_by_move(cx, pat.hir_id) => {
|
||||||
// We have `x @ pat` where `x` is by-move. Reject all borrows in `pat`.
|
// We have `x @ pat` where `x` is by-move. Reject all borrows in `pat`.
|
||||||
let mut conflicts_ref = Vec::new();
|
let mut conflicts_ref = Vec::new();
|
||||||
sub.each_binding(|_, hir_id, span, _| {
|
sub.each_binding(|_, hir_id, span, _| {
|
||||||
@ -1070,7 +1070,7 @@ fn check_borrow_conflicts_in_at_patterns(cx: &MatchVisitor<'_, '_, '_>, pat: &Pa
|
|||||||
(Mutability::Mut, Mutability::Mut) => conflicts_mut_mut.push((span, name)), // 2x `ref mut`.
|
(Mutability::Mut, Mutability::Mut) => conflicts_mut_mut.push((span, name)), // 2x `ref mut`.
|
||||||
_ => conflicts_mut_ref.push((span, name)), // `ref` + `ref mut` in either direction.
|
_ => conflicts_mut_ref.push((span, name)), // `ref` + `ref mut` in either direction.
|
||||||
},
|
},
|
||||||
Some(ty::BindByValue(_)) if is_binding_by_move(cx, hir_id, span) => {
|
Some(ty::BindByValue(_)) if is_binding_by_move(cx, hir_id) => {
|
||||||
conflicts_move.push((span, name)) // `ref mut?` + by-move conflict.
|
conflicts_move.push((span, name)) // `ref mut?` + by-move conflict.
|
||||||
}
|
}
|
||||||
Some(ty::BindByValue(_)) | None => {} // `ref mut?` + by-copy is fine.
|
Some(ty::BindByValue(_)) | None => {} // `ref mut?` + by-copy is fine.
|
||||||
|
@ -506,7 +506,7 @@ impl<'tcx> ConstToPat<'tcx> {
|
|||||||
// convert the dereferenced constant to a pattern that is the sub-pattern of the
|
// convert the dereferenced constant to a pattern that is the sub-pattern of the
|
||||||
// deref pattern.
|
// deref pattern.
|
||||||
_ => {
|
_ => {
|
||||||
if !pointee_ty.is_sized(tcx.at(span), param_env) {
|
if !pointee_ty.is_sized(tcx, param_env) {
|
||||||
// `tcx.deref_mir_constant()` below will ICE with an unsized type
|
// `tcx.deref_mir_constant()` below will ICE with an unsized type
|
||||||
// (except slices, which are handled in a separate arm above).
|
// (except slices, which are handled in a separate arm above).
|
||||||
let msg = format!("cannot use unsized non-slice type `{}` in constant patterns", pointee_ty);
|
let msg = format!("cannot use unsized non-slice type `{}` in constant patterns", pointee_ty);
|
||||||
@ -534,7 +534,7 @@ impl<'tcx> ConstToPat<'tcx> {
|
|||||||
ty::Bool | ty::Char | ty::Int(_) | ty::Uint(_) | ty::FnDef(..) => {
|
ty::Bool | ty::Char | ty::Int(_) | ty::Uint(_) | ty::FnDef(..) => {
|
||||||
PatKind::Constant { value: cv }
|
PatKind::Constant { value: cv }
|
||||||
}
|
}
|
||||||
ty::RawPtr(pointee) if pointee.ty.is_sized(tcx.at(span), param_env) => {
|
ty::RawPtr(pointee) if pointee.ty.is_sized(tcx, param_env) => {
|
||||||
PatKind::Constant { value: cv }
|
PatKind::Constant { value: cv }
|
||||||
}
|
}
|
||||||
// FIXME: these can have very surprising behaviour where optimization levels or other
|
// FIXME: these can have very surprising behaviour where optimization levels or other
|
||||||
|
@ -312,7 +312,7 @@ impl<'tcx> UnsafetyChecker<'_, 'tcx> {
|
|||||||
} else if !place
|
} else if !place
|
||||||
.ty(self.body, self.tcx)
|
.ty(self.body, self.tcx)
|
||||||
.ty
|
.ty
|
||||||
.is_freeze(self.tcx.at(self.source_info.span), self.param_env)
|
.is_freeze(self.tcx, self.param_env)
|
||||||
{
|
{
|
||||||
UnsafetyViolationDetails::BorrowOfLayoutConstrainedField
|
UnsafetyViolationDetails::BorrowOfLayoutConstrainedField
|
||||||
} else {
|
} else {
|
||||||
|
@ -633,7 +633,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
|
|||||||
}
|
}
|
||||||
if !rvalue
|
if !rvalue
|
||||||
.ty(&self.ecx.frame().body.local_decls, *self.ecx.tcx)
|
.ty(&self.ecx.frame().body.local_decls, *self.ecx.tcx)
|
||||||
.is_sized(self.ecx.tcx, self.param_env)
|
.is_sized(*self.ecx.tcx, self.param_env)
|
||||||
{
|
{
|
||||||
// the interpreter doesn't support unsized locals (only unsized arguments),
|
// the interpreter doesn't support unsized locals (only unsized arguments),
|
||||||
// but rustc does (in a kinda broken way), so we have to skip them here
|
// but rustc does (in a kinda broken way), so we have to skip them here
|
||||||
|
@ -500,7 +500,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
|
|||||||
}
|
}
|
||||||
if !rvalue
|
if !rvalue
|
||||||
.ty(&self.ecx.frame().body.local_decls, *self.ecx.tcx)
|
.ty(&self.ecx.frame().body.local_decls, *self.ecx.tcx)
|
||||||
.is_sized(self.ecx.tcx, self.param_env)
|
.is_sized(*self.ecx.tcx, self.param_env)
|
||||||
{
|
{
|
||||||
// the interpreter doesn't support unsized locals (only unsized arguments),
|
// the interpreter doesn't support unsized locals (only unsized arguments),
|
||||||
// but rustc does (in a kinda broken way), so we have to skip them here
|
// but rustc does (in a kinda broken way), so we have to skip them here
|
||||||
|
@ -11,7 +11,6 @@ use rustc_middle::mir::visit::{NonMutatingUseContext, PlaceContext, Visitor};
|
|||||||
use rustc_middle::mir::{Body, Local, Location, Operand, Terminator, TerminatorKind, RETURN_PLACE};
|
use rustc_middle::mir::{Body, Local, Location, Operand, Terminator, TerminatorKind, RETURN_PLACE};
|
||||||
use rustc_middle::ty::{self, DeducedParamAttrs, ParamEnv, Ty, TyCtxt};
|
use rustc_middle::ty::{self, DeducedParamAttrs, ParamEnv, Ty, TyCtxt};
|
||||||
use rustc_session::config::OptLevel;
|
use rustc_session::config::OptLevel;
|
||||||
use rustc_span::DUMMY_SP;
|
|
||||||
|
|
||||||
/// A visitor that determines which arguments have been mutated. We can't use the mutability field
|
/// A visitor that determines which arguments have been mutated. We can't use the mutability field
|
||||||
/// on LocalDecl for this because it has no meaning post-optimization.
|
/// on LocalDecl for this because it has no meaning post-optimization.
|
||||||
@ -232,7 +231,7 @@ pub fn deduced_param_attrs<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> &'tcx [Ded
|
|||||||
body.local_decls.iter().skip(1).take(body.arg_count).enumerate().map(
|
body.local_decls.iter().skip(1).take(body.arg_count).enumerate().map(
|
||||||
|(arg_index, local_decl)| DeducedParamAttrs {
|
|(arg_index, local_decl)| DeducedParamAttrs {
|
||||||
read_only: !deduce_read_only.mutable_args.contains(arg_index)
|
read_only: !deduce_read_only.mutable_args.contains(arg_index)
|
||||||
&& local_decl.ty.is_freeze(tcx.at(DUMMY_SP), ParamEnv::reveal_all()),
|
&& local_decl.ty.is_freeze(tcx, ParamEnv::reveal_all()),
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
@ -312,7 +312,7 @@ fn build_clone_shim<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, self_ty: Ty<'tcx>) -
|
|||||||
let param_env = tcx.param_env(def_id);
|
let param_env = tcx.param_env(def_id);
|
||||||
|
|
||||||
let mut builder = CloneShimBuilder::new(tcx, def_id, self_ty);
|
let mut builder = CloneShimBuilder::new(tcx, def_id, self_ty);
|
||||||
let is_copy = self_ty.is_copy_modulo_regions(tcx.at(builder.span), param_env);
|
let is_copy = self_ty.is_copy_modulo_regions(tcx, param_env);
|
||||||
|
|
||||||
let dest = Place::return_place();
|
let dest = Place::return_place();
|
||||||
let src = tcx.mk_place_deref(Place::from(Local::new(1 + 0)));
|
let src = tcx.mk_place_deref(Place::from(Local::new(1 + 0)));
|
||||||
|
@ -1067,7 +1067,7 @@ fn find_vtable_types_for_unsizing<'tcx>(
|
|||||||
let ptr_vtable = |inner_source: Ty<'tcx>, inner_target: Ty<'tcx>| {
|
let ptr_vtable = |inner_source: Ty<'tcx>, inner_target: Ty<'tcx>| {
|
||||||
let param_env = ty::ParamEnv::reveal_all();
|
let param_env = ty::ParamEnv::reveal_all();
|
||||||
let type_has_metadata = |ty: Ty<'tcx>| -> bool {
|
let type_has_metadata = |ty: Ty<'tcx>| -> bool {
|
||||||
if ty.is_sized(tcx.at(DUMMY_SP), param_env) {
|
if ty.is_sized(tcx, param_env) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
let tail = tcx.struct_tail_erasing_lifetimes(ty, param_env);
|
let tail = tcx.struct_tail_erasing_lifetimes(ty, param_env);
|
||||||
|
@ -69,7 +69,7 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
|
|||||||
let ty = self.resolve_vars_if_possible(ty);
|
let ty = self.resolve_vars_if_possible(ty);
|
||||||
|
|
||||||
if !(param_env, ty).needs_infer() {
|
if !(param_env, ty).needs_infer() {
|
||||||
return ty.is_copy_modulo_regions(self.tcx.at(span), param_env);
|
return ty.is_copy_modulo_regions(self.tcx, param_env);
|
||||||
}
|
}
|
||||||
|
|
||||||
let copy_def_id = self.tcx.require_lang_item(LangItem::Copy, None);
|
let copy_def_id = self.tcx.require_lang_item(LangItem::Copy, None);
|
||||||
|
@ -4,7 +4,7 @@ use rustc_infer::infer::TyCtxtInferExt;
|
|||||||
use rustc_middle::traits::CodegenObligationError;
|
use rustc_middle::traits::CodegenObligationError;
|
||||||
use rustc_middle::ty::subst::SubstsRef;
|
use rustc_middle::ty::subst::SubstsRef;
|
||||||
use rustc_middle::ty::{self, Instance, TyCtxt, TypeVisitable};
|
use rustc_middle::ty::{self, Instance, TyCtxt, TypeVisitable};
|
||||||
use rustc_span::{sym, DUMMY_SP};
|
use rustc_span::sym;
|
||||||
use rustc_trait_selection::traits;
|
use rustc_trait_selection::traits;
|
||||||
use traits::{translate_substs, Reveal};
|
use traits::{translate_substs, Reveal};
|
||||||
|
|
||||||
@ -236,7 +236,7 @@ fn resolve_associated_item<'tcx>(
|
|||||||
if name == sym::clone {
|
if name == sym::clone {
|
||||||
let self_ty = trait_ref.self_ty();
|
let self_ty = trait_ref.self_ty();
|
||||||
|
|
||||||
let is_copy = self_ty.is_copy_modulo_regions(tcx.at(DUMMY_SP), param_env);
|
let is_copy = self_ty.is_copy_modulo_regions(tcx, param_env);
|
||||||
match self_ty.kind() {
|
match self_ty.kind() {
|
||||||
_ if is_copy => (),
|
_ if is_copy => (),
|
||||||
ty::Generator(..)
|
ty::Generator(..)
|
||||||
|
@ -399,7 +399,7 @@ fn layout_of_uncached<'tcx>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
let pointee = tcx.normalize_erasing_regions(param_env, pointee);
|
let pointee = tcx.normalize_erasing_regions(param_env, pointee);
|
||||||
if pointee.is_sized(tcx.at(DUMMY_SP), param_env) {
|
if pointee.is_sized(tcx, param_env) {
|
||||||
return Ok(tcx.intern_layout(LayoutS::scalar(cx, data_ptr)));
|
return Ok(tcx.intern_layout(LayoutS::scalar(cx, data_ptr)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -755,8 +755,7 @@ fn layout_of_uncached<'tcx>(
|
|||||||
} else {
|
} else {
|
||||||
let param_env = tcx.param_env(def.did());
|
let param_env = tcx.param_env(def.did());
|
||||||
let last_field = def.variant(v).fields.last().unwrap();
|
let last_field = def.variant(v).fields.last().unwrap();
|
||||||
let always_sized =
|
let always_sized = tcx.type_of(last_field.did).is_sized(tcx, param_env);
|
||||||
tcx.type_of(last_field.did).is_sized(tcx.at(DUMMY_SP), param_env);
|
|
||||||
if !always_sized { StructKind::MaybeUnsized } else { StructKind::AlwaysSized }
|
if !always_sized { StructKind::MaybeUnsized } else { StructKind::AlwaysSized }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -109,7 +109,7 @@ where
|
|||||||
|
|
||||||
for component in components {
|
for component in components {
|
||||||
match *component.kind() {
|
match *component.kind() {
|
||||||
_ if component.is_copy_modulo_regions(tcx.at(DUMMY_SP), self.param_env) => (),
|
_ if component.is_copy_modulo_regions(tcx, self.param_env) => (),
|
||||||
|
|
||||||
ty::Closure(_, substs) => {
|
ty::Closure(_, substs) => {
|
||||||
queue_type(self, substs.as_closure().tupled_upvars_ty());
|
queue_type(self, substs.as_closure().tupled_upvars_ty());
|
||||||
|
Loading…
Reference in New Issue
Block a user