Auto merge of #93148 - nnethercote:Uniq, r=fee1-dead

Overhaul interning.

A number of types are interned and `eq` and `hash` are implemented on
the pointer rather than the contents. But this is not well enforced
within the type system like you might expect.

This PR introduces a new type `Interned` which encapsulates this concept
more rigorously, and uses it to convert a couple of the less common
interned types.

r? `@fee1-dead`
This commit is contained in:
bors 2022-02-15 11:59:37 +00:00
commit 5569757491
252 changed files with 1927 additions and 1699 deletions

View file

@ -60,8 +60,8 @@ impl<'cg, 'cx, 'tcx> Visitor<'tcx> for ConstraintGeneration<'cg, 'cx, 'tcx> {
/// We sometimes have `region` within an rvalue, or within a
/// call. Make them live at the location where they appear.
fn visit_region(&mut self, region: &ty::Region<'tcx>, location: Location) {
self.add_regular_live_constraint(*region, location);
fn visit_region(&mut self, region: ty::Region<'tcx>, location: Location) {
self.add_regular_live_constraint(region, location);
self.super_region(region);
}

View file

@ -356,8 +356,8 @@ fn try_extract_error_from_fulfill_cx<'tcx>(
})?;
debug!(?sub_region, "cause = {:#?}", cause);
let nice_error = match (error_region, sub_region) {
(Some(error_region), &ty::ReVar(vid)) => NiceRegionError::new(
let nice_error = match (error_region, *sub_region) {
(Some(error_region), ty::ReVar(vid)) => NiceRegionError::new(
infcx,
RegionResolutionError::SubSupConflict(
vid,
@ -374,7 +374,7 @@ fn try_extract_error_from_fulfill_cx<'tcx>(
RegionResolutionError::ConcreteFailure(cause.clone(), error_region, placeholder_region),
),
// Note universe here is wrong...
(None, &ty::ReVar(vid)) => NiceRegionError::new(
(None, ty::ReVar(vid)) => NiceRegionError::new(
infcx,
RegionResolutionError::UpperBoundUniverseConflict(
vid,

View file

@ -2324,7 +2324,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
// This is also case 2 from above but for functions, return type is still an
// anonymous reference so we select the first argument.
let argument_span = fn_decl.inputs.first()?.span;
let argument_ty = sig.inputs().skip_binder().first()?;
let argument_ty = *sig.inputs().skip_binder().first()?;
let return_span = fn_decl.output.span();
let return_ty = sig.output().skip_binder();
@ -2379,27 +2379,27 @@ impl<'tcx> AnnotatedBorrowFnSignature<'tcx> {
diag: &mut DiagnosticBuilder<'_>,
) -> String {
match self {
AnnotatedBorrowFnSignature::Closure { argument_ty, argument_span } => {
&AnnotatedBorrowFnSignature::Closure { argument_ty, argument_span } => {
diag.span_label(
*argument_span,
argument_span,
format!("has type `{}`", cx.get_name_for_ty(argument_ty, 0)),
);
cx.get_region_name_for_ty(argument_ty, 0)
}
AnnotatedBorrowFnSignature::AnonymousFunction {
&AnnotatedBorrowFnSignature::AnonymousFunction {
argument_ty,
argument_span,
return_ty,
return_span,
} => {
let argument_ty_name = cx.get_name_for_ty(argument_ty, 0);
diag.span_label(*argument_span, format!("has type `{}`", argument_ty_name));
diag.span_label(argument_span, format!("has type `{}`", argument_ty_name));
let return_ty_name = cx.get_name_for_ty(return_ty, 0);
let types_equal = return_ty_name == argument_ty_name;
diag.span_label(
*return_span,
return_span,
format!(
"{}has type `{}`",
if types_equal { "also " } else { "" },
@ -2419,7 +2419,7 @@ impl<'tcx> AnnotatedBorrowFnSignature<'tcx> {
}
AnnotatedBorrowFnSignature::NamedFunction { arguments, return_ty, return_span } => {
// Region of return type and arguments checked to be the same earlier.
let region_name = cx.get_region_name_for_ty(return_ty, 0);
let region_name = cx.get_region_name_for_ty(*return_ty, 0);
for (_, argument_span) in arguments {
diag.span_label(*argument_span, format!("has lifetime `{}`", region_name));
}

View file

@ -331,7 +331,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
match place {
PlaceRef { local, projection: [] } => {
let local = &self.body.local_decls[local];
self.describe_field_from_ty(&local.ty, field, None)
self.describe_field_from_ty(local.ty, field, None)
}
PlaceRef { local, projection: [proj_base @ .., elem] } => match elem {
ProjectionElem::Deref => {
@ -339,10 +339,10 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
}
ProjectionElem::Downcast(_, variant_index) => {
let base_ty = place.ty(self.body, self.infcx.tcx).ty;
self.describe_field_from_ty(&base_ty, field, Some(*variant_index))
self.describe_field_from_ty(base_ty, field, Some(*variant_index))
}
ProjectionElem::Field(_, field_type) => {
self.describe_field_from_ty(&field_type, field, None)
self.describe_field_from_ty(*field_type, field, None)
}
ProjectionElem::Index(..)
| ProjectionElem::ConstantIndex { .. }
@ -362,7 +362,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
) -> String {
if ty.is_box() {
// If the type is a box, the field is described from the boxed type
self.describe_field_from_ty(&ty.boxed_ty(), field, variant_index)
self.describe_field_from_ty(ty.boxed_ty(), field, variant_index)
} else {
match *ty.kind() {
ty::Adt(def, _) => {
@ -376,10 +376,10 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
}
ty::Tuple(_) => field.index().to_string(),
ty::Ref(_, ty, _) | ty::RawPtr(ty::TypeAndMut { ty, .. }) => {
self.describe_field_from_ty(&ty, field, variant_index)
self.describe_field_from_ty(ty, field, variant_index)
}
ty::Array(ty, _) | ty::Slice(ty) => {
self.describe_field_from_ty(&ty, field, variant_index)
self.describe_field_from_ty(ty, field, variant_index)
}
ty::Closure(def_id, _) | ty::Generator(def_id, _, _) => {
// We won't be borrowck'ing here if the closure came from another crate,
@ -497,14 +497,14 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
// We need to add synthesized lifetimes where appropriate. We do
// this by hooking into the pretty printer and telling it to label the
// lifetimes without names with the value `'0`.
match ty.kind() {
ty::Ref(
ty::RegionKind::ReLateBound(_, ty::BoundRegion { kind: br, .. })
| ty::RegionKind::RePlaceholder(ty::PlaceholderRegion { name: br, .. }),
_,
_,
) => printer.region_highlight_mode.highlighting_bound_region(*br, counter),
_ => {}
if let ty::Ref(region, ..) = ty.kind() {
match **region {
ty::ReLateBound(_, ty::BoundRegion { kind: br, .. })
| ty::RePlaceholder(ty::PlaceholderRegion { name: br, .. }) => {
printer.region_highlight_mode.highlighting_bound_region(br, counter)
}
_ => {}
}
}
let _ = ty.print(printer);
@ -517,19 +517,17 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
let mut s = String::new();
let mut printer = ty::print::FmtPrinter::new(self.infcx.tcx, &mut s, Namespace::TypeNS);
let region = match ty.kind() {
ty::Ref(region, _, _) => {
match region {
ty::RegionKind::ReLateBound(_, ty::BoundRegion { kind: br, .. })
| ty::RegionKind::RePlaceholder(ty::PlaceholderRegion { name: br, .. }) => {
printer.region_highlight_mode.highlighting_bound_region(*br, counter)
}
_ => {}
let region = if let ty::Ref(region, ..) = ty.kind() {
match **region {
ty::ReLateBound(_, ty::BoundRegion { kind: br, .. })
| ty::RePlaceholder(ty::PlaceholderRegion { name: br, .. }) => {
printer.region_highlight_mode.highlighting_bound_region(br, counter)
}
region
_ => {}
}
_ => bug!("ty for annotation of borrow region is not a reference"),
region
} else {
bug!("ty for annotation of borrow region is not a reference");
};
let _ = region.print(printer);

View file

@ -246,18 +246,18 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
);
(
match kind {
IllegalMoveOriginKind::BorrowedContent { target_place } => self
&IllegalMoveOriginKind::BorrowedContent { target_place } => self
.report_cannot_move_from_borrowed_content(
original_path,
*target_place,
target_place,
span,
use_spans,
),
IllegalMoveOriginKind::InteriorOfTypeWithDestructor { container_ty: ty } => {
&IllegalMoveOriginKind::InteriorOfTypeWithDestructor { container_ty: ty } => {
self.cannot_move_out_of_interior_of_drop(span, ty)
}
IllegalMoveOriginKind::InteriorOfSliceOrArray { ty, is_index } => {
self.cannot_move_out_of_interior_noncopy(span, ty, Some(*is_index))
&IllegalMoveOriginKind::InteriorOfSliceOrArray { ty, is_index } => {
self.cannot_move_out_of_interior_noncopy(span, ty, Some(is_index))
}
},
span,

View file

@ -139,7 +139,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
/// Returns `true` if a closure is inferred to be an `FnMut` closure.
fn is_closure_fn_mut(&self, fr: RegionVid) -> bool {
if let Some(ty::ReFree(free_region)) = self.to_error_region(fr) {
if let Some(ty::ReFree(free_region)) = self.to_error_region(fr).as_deref() {
if let ty::BoundRegionKind::BrEnv = free_region.bound_region {
if let DefiningTy::Closure(_, substs) =
self.regioncx.universal_regions().defining_ty
@ -628,8 +628,8 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
fr_name: RegionName,
outlived_fr: RegionVid,
) {
if let (Some(f), Some(ty::RegionKind::ReStatic)) =
(self.to_error_region(fr), self.to_error_region(outlived_fr))
if let (Some(f), Some(ty::ReStatic)) =
(self.to_error_region(fr), self.to_error_region(outlived_fr).as_deref())
{
if let Some(&ty::Opaque(did, substs)) = self
.infcx
@ -652,7 +652,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
bound.kind().skip_binder()
{
let r = r.subst(self.infcx.tcx, substs);
if let ty::RegionKind::ReStatic = r {
if r.is_static() {
found = true;
break;
} else {

View file

@ -264,7 +264,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
let tcx = self.infcx.tcx;
debug!("give_region_a_name: error_region = {:?}", error_region);
match error_region {
match *error_region {
ty::ReEarlyBound(ebr) => {
if ebr.has_name() {
let span = tcx.hir().span_if_local(ebr.def_id).unwrap_or(DUMMY_SP);
@ -433,7 +433,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
span: Span,
counter: usize,
) -> RegionNameHighlight {
let mut highlight = RegionHighlightMode::default();
let mut highlight = RegionHighlightMode::new(self.infcx.tcx);
highlight.highlighting_region_vid(needle_fr, counter);
let type_name =
self.infcx.extract_inference_diagnostics_data(ty.into(), Some(highlight)).name;
@ -500,7 +500,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
}
// Otherwise, let's descend into the referent types.
search_stack.push((referent_ty, &referent_hir_ty.ty));
search_stack.push((*referent_ty, &referent_hir_ty.ty));
}
// Match up something like `Foo<'1>`
@ -539,7 +539,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
(ty::Slice(elem_ty), hir::TyKind::Slice(elem_hir_ty))
| (ty::Array(elem_ty, _), hir::TyKind::Array(elem_hir_ty, _)) => {
search_stack.push((elem_ty, elem_hir_ty));
search_stack.push((*elem_ty, elem_hir_ty));
}
(ty::RawPtr(mut_ty), hir::TyKind::Ptr(mut_hir_ty)) => {
@ -818,7 +818,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
return None;
}
let mut highlight = RegionHighlightMode::default();
let mut highlight = RegionHighlightMode::new(tcx);
highlight.highlighting_region_vid(fr, *self.next_region_name.try_borrow().unwrap());
let type_name =
self.infcx.extract_inference_diagnostics_data(yield_ty.into(), Some(highlight)).name;

View file

@ -8,7 +8,7 @@ use rustc_middle::mir::{
BasicBlock, Body, ClosureOutlivesSubject, ClosureRegionRequirements, LocalKind, Location,
Promoted,
};
use rustc_middle::ty::{self, OpaqueTypeKey, RegionKind, RegionVid, Ty};
use rustc_middle::ty::{self, OpaqueTypeKey, Region, RegionVid, Ty};
use rustc_span::symbol::sym;
use std::env;
use std::fmt::Debug;
@ -443,9 +443,9 @@ pub trait ToRegionVid {
fn to_region_vid(self) -> RegionVid;
}
impl<'tcx> ToRegionVid for &'tcx RegionKind {
impl<'tcx> ToRegionVid for Region<'tcx> {
fn to_region_vid(self) -> RegionVid {
if let ty::ReVar(vid) = self { *vid } else { bug!("region is not an ReVar: {:?}", self) }
if let ty::ReVar(vid) = *self { vid } else { bug!("region is not an ReVar: {:?}", self) }
}
}

View file

@ -1169,7 +1169,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
match verify_bound {
VerifyBound::IfEq(test_ty, verify_bound1) => {
self.eval_if_eq(tcx, body, generic_ty, lower_bound, test_ty, verify_bound1)
self.eval_if_eq(tcx, body, generic_ty, lower_bound, *test_ty, verify_bound1)
}
VerifyBound::IsEmpty => {
@ -1178,7 +1178,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
}
VerifyBound::OutlivedBy(r) => {
let r_vid = self.to_region_vid(r);
let r_vid = self.to_region_vid(*r);
self.eval_outlives(r_vid, lower_bound)
}

View file

@ -133,7 +133,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
for vid in self.rev_scc_graph.as_ref().unwrap().upper_bounds(scc) {
match self.definitions[vid].external_name {
None => {}
Some(&ty::ReStatic) => {}
Some(region) if region.is_static() => {}
Some(region) => return region,
}
}
@ -183,7 +183,7 @@ fn check_opaque_type_parameter_valid(
for (i, arg) in opaque_type_key.substs.iter().enumerate() {
let arg_is_param = match arg.unpack() {
GenericArgKind::Type(ty) => matches!(ty.kind(), ty::Param(_)),
GenericArgKind::Lifetime(ty::ReStatic) => {
GenericArgKind::Lifetime(lt) if lt.is_static() => {
tcx.sess
.struct_span_err(span, "non-defining opaque type use in defining scope")
.span_label(
@ -196,9 +196,9 @@ fn check_opaque_type_parameter_valid(
return false;
}
GenericArgKind::Lifetime(lt) => {
matches!(lt, ty::ReEarlyBound(_) | ty::ReFree(_))
matches!(*lt, ty::ReEarlyBound(_) | ty::ReFree(_))
}
GenericArgKind::Const(ct) => matches!(ct.val, ty::ConstKind::Param(_)),
GenericArgKind::Const(ct) => matches!(ct.val(), ty::ConstKind::Param(_)),
};
if arg_is_param {

View file

@ -57,7 +57,7 @@ impl<'a, 'tcx> MutVisitor<'tcx> for NllVisitor<'a, 'tcx> {
#[instrument(skip(self), level = "debug")]
fn visit_ty(&mut self, ty: &mut Ty<'tcx>, ty_context: TyContext) {
*ty = self.renumber_regions(ty);
*ty = self.renumber_regions(*ty);
debug!(?ty);
}
@ -72,12 +72,12 @@ impl<'a, 'tcx> MutVisitor<'tcx> for NllVisitor<'a, 'tcx> {
#[instrument(skip(self), level = "debug")]
fn visit_region(&mut self, region: &mut ty::Region<'tcx>, location: Location) {
let old_region = *region;
*region = self.renumber_regions(&old_region);
*region = self.renumber_regions(old_region);
debug!(?region);
}
fn visit_const(&mut self, constant: &mut &'tcx ty::Const<'tcx>, _location: Location) {
*constant = self.renumber_regions(&*constant);
fn visit_const(&mut self, constant: &mut ty::Const<'tcx>, _location: Location) {
*constant = self.renumber_regions(*constant);
}
}

View file

@ -105,8 +105,8 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> {
// create new region variables, which can't be done later when
// verifying these bounds.
if t1.has_placeholders() {
t1 = tcx.fold_regions(&t1, &mut false, |r, _| match *r {
ty::RegionKind::RePlaceholder(placeholder) => {
t1 = tcx.fold_regions(t1, &mut false, |r, _| match *r {
ty::RePlaceholder(placeholder) => {
self.constraints.placeholder_region(self.infcx, placeholder)
}
_ => r,
@ -142,8 +142,8 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> {
}
fn to_region_vid(&mut self, r: ty::Region<'tcx>) -> ty::RegionVid {
if let ty::RePlaceholder(placeholder) = r {
self.constraints.placeholder_region(self.infcx, *placeholder).to_region_vid()
if let ty::RePlaceholder(placeholder) = *r {
self.constraints.placeholder_region(self.infcx, placeholder).to_region_vid()
} else {
self.universal_regions.to_region_vid(r)
}

View file

@ -358,7 +358,7 @@ impl<'tcx> UniversalRegionRelationsBuilder<'_, 'tcx> {
// `where Type:` is lowered to `where Type: 'empty` so that
// we check `Type` is well formed, but there's no use for
// this bound here.
if let ty::ReEmpty(_) = r1 {
if r1.is_empty() {
return;
}

View file

@ -383,7 +383,7 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'tcx> {
} else {
let tcx = self.tcx();
let maybe_uneval = match constant.literal {
ConstantKind::Ty(ct) => match ct.val {
ConstantKind::Ty(ct) => match ct.val() {
ty::ConstKind::Unevaluated(uv) => Some(uv),
_ => None,
},
@ -482,7 +482,7 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'tcx> {
// then remove the outermost reference so we can check the
// type annotation for the remaining type.
if let ty::Ref(_, rty, _) = local_decl.ty.kind() {
rty
*rty
} else {
bug!("{:?} with ref binding has wrong type {}", local, local_decl.ty);
}
@ -716,7 +716,7 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> {
PlaceTy::from_ty(match base_ty.kind() {
ty::Array(inner, _) => {
assert!(!from_end, "array subslices should not use from_end");
tcx.mk_array(inner, to - from)
tcx.mk_array(*inner, to - from)
}
ty::Slice(..) => {
assert!(from_end, "slice subslices should use from_end");
@ -1737,7 +1737,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
ConstraintCategory::Boring
};
if let Err(terr) =
self.sub_types(op_arg_ty, fn_arg, term_location.to_locations(), category)
self.sub_types(op_arg_ty, *fn_arg, term_location.to_locations(), category)
{
span_mirbug!(
self,
@ -1956,7 +1956,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
fn check_operand(&mut self, op: &Operand<'tcx>, location: Location) {
if let Operand::Constant(constant) = op {
let maybe_uneval = match constant.literal {
ConstantKind::Ty(ct) => match ct.val {
ConstantKind::Ty(ct) => match ct.val() {
ty::ConstKind::Unevaluated(uv) => Some(uv),
_ => None,
},
@ -2048,7 +2048,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
}
}
Rvalue::NullaryOp(_, ty) => {
&Rvalue::NullaryOp(_, ty) => {
let trait_ref = ty::TraitRef {
def_id: tcx.require_lang_item(LangItem::Sized, Some(self.last_span)),
substs: tcx.mk_substs_trait(ty, &[]),
@ -2066,7 +2066,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
let trait_ref = ty::TraitRef {
def_id: tcx.require_lang_item(LangItem::Sized, Some(self.last_span)),
substs: tcx.mk_substs_trait(ty, &[]),
substs: tcx.mk_substs_trait(*ty, &[]),
};
self.prove_trait_ref(
@ -2093,7 +2093,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
let ty_fn_ptr_from = tcx.mk_fn_ptr(fn_sig);
if let Err(terr) = self.eq_types(
ty,
*ty,
ty_fn_ptr_from,
location.to_locations(),
ConstraintCategory::Cast,
@ -2117,7 +2117,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
let ty_fn_ptr_from = tcx.mk_fn_ptr(tcx.signature_unclosure(sig, *unsafety));
if let Err(terr) = self.eq_types(
ty,
*ty,
ty_fn_ptr_from,
location.to_locations(),
ConstraintCategory::Cast,
@ -2146,7 +2146,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
let ty_fn_ptr_from = tcx.safe_to_unsafe_fn_ty(fn_sig);
if let Err(terr) = self.eq_types(
ty,
*ty,
ty_fn_ptr_from,
location.to_locations(),
ConstraintCategory::Cast,
@ -2209,8 +2209,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
}
};
if let Err(terr) = self.sub_types(
ty_from,
ty_to,
*ty_from,
*ty_to,
location.to_locations(),
ConstraintCategory::Cast,
) {
@ -2278,8 +2278,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
}
if let Err(terr) = self.sub_types(
ty_elem,
ty_to,
*ty_elem,
*ty_to,
location.to_locations(),
ConstraintCategory::Cast,
) {
@ -2297,7 +2297,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
CastKind::Misc => {
let ty_from = op.ty(body, tcx);
let cast_ty_from = CastTy::from_ty(ty_from);
let cast_ty_to = CastTy::from_ty(ty);
let cast_ty_to = CastTy::from_ty(*ty);
match (cast_ty_from, cast_ty_to) {
(None, _)
| (_, None | Some(CastTy::FnPtr))
@ -2318,7 +2318,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
}
Rvalue::Ref(region, _borrow_kind, borrowed_place) => {
self.add_reborrow_constraint(&body, location, region, borrowed_place);
self.add_reborrow_constraint(&body, location, *region, borrowed_place);
}
Rvalue::BinaryOp(

View file

@ -117,7 +117,7 @@ impl<'tcx> TypeRelatingDelegate<'tcx> for NllTypeRelatingDelegate<'_, '_, 'tcx>
// We don't have to worry about the equality of consts during borrow checking
// as consts always have a static lifetime.
fn const_equate(&mut self, _a: &'tcx Const<'tcx>, _b: &'tcx Const<'tcx>) {}
fn const_equate(&mut self, _a: Const<'tcx>, _b: Const<'tcx>) {}
fn normalization() -> NormalizationStrategy {
NormalizationStrategy::Eager

View file

@ -323,7 +323,7 @@ impl<'tcx> UniversalRegions<'tcx> {
/// See `UniversalRegionIndices::to_region_vid`.
pub fn to_region_vid(&self, r: ty::Region<'tcx>) -> RegionVid {
if let ty::ReEmpty(ty::UniverseIndex::ROOT) = r {
if let ty::ReEmpty(ty::UniverseIndex::ROOT) = *r {
self.root_empty
} else {
self.indices.to_region_vid(r)
@ -512,7 +512,7 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
first_local_index,
num_universals,
defining_ty,
unnormalized_output_ty,
unnormalized_output_ty: *unnormalized_output_ty,
unnormalized_input_tys,
yield_ty,
}
@ -805,7 +805,7 @@ impl<'tcx> UniversalRegionIndices<'tcx> {
/// during initialization. Relies on the `indices` map having been
/// fully initialized.
pub fn to_region_vid(&self, r: ty::Region<'tcx>) -> RegionVid {
if let ty::ReVar(..) = r {
if let ty::ReVar(..) = *r {
r.to_region_vid()
} else {
*self

View file

@ -544,7 +544,7 @@ pub(crate) fn codegen_drop<'tcx>(
let arg_value = drop_place.place_ref(
fx,
fx.layout_of(fx.tcx.mk_ref(
&ty::RegionKind::ReErased,
fx.tcx.lifetimes.re_erased,
TypeAndMut { ty, mutbl: crate::rustc_hir::Mutability::Mut },
)),
);

View file

@ -79,7 +79,7 @@ pub(crate) fn codegen_fn<'tcx>(
let arg_uninhabited = fx
.mir
.args_iter()
.any(|arg| fx.layout_of(fx.monomorphize(&fx.mir.local_decls[arg].ty)).abi.is_uninhabited());
.any(|arg| fx.layout_of(fx.monomorphize(fx.mir.local_decls[arg].ty)).abi.is_uninhabited());
if !crate::constant::check_constants(&mut fx) {
fx.bcx.append_block_params_for_function_params(fx.block_map[START_BLOCK]);
@ -668,7 +668,7 @@ fn codegen_stmt<'tcx>(
let times = fx
.monomorphize(times)
.eval(fx.tcx, ParamEnv::reveal_all())
.val
.val()
.try_to_bits(fx.tcx.data_layout.pointer_size)
.unwrap();
if operand.layout().size.bytes() == 0 {
@ -818,16 +818,16 @@ pub(crate) fn codegen_place<'tcx>(
match cplace.layout().ty.kind() {
ty::Array(elem_ty, _len) => {
assert!(!from_end, "array subslices are never `from_end`");
let elem_layout = fx.layout_of(elem_ty);
let elem_layout = fx.layout_of(*elem_ty);
let ptr = cplace.to_ptr();
cplace = CPlace::for_ptr(
ptr.offset_i64(fx, elem_layout.size.bytes() as i64 * (from as i64)),
fx.layout_of(fx.tcx.mk_array(elem_ty, to - from)),
fx.layout_of(fx.tcx.mk_array(*elem_ty, to - from)),
);
}
ty::Slice(elem_ty) => {
assert!(from_end, "slice subslices should be `from_end`");
let elem_layout = fx.layout_of(elem_ty);
let elem_layout = fx.layout_of(*elem_ty);
let (ptr, len) = cplace.to_ptr_maybe_unsized();
let len = len.unwrap();
cplace = CPlace::for_ptr_with_extra(

View file

@ -61,7 +61,7 @@ fn clif_type_from_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Option<types::Typ
},
ty::FnPtr(_) => pointer_ty(tcx),
ty::RawPtr(TypeAndMut { ty: pointee_ty, mutbl: _ }) | ty::Ref(_, pointee_ty, _) => {
if has_ptr_meta(tcx, pointee_ty) {
if has_ptr_meta(tcx, *pointee_ty) {
return None;
} else {
pointer_ty(tcx)
@ -100,7 +100,7 @@ fn clif_pair_type_from_ty<'tcx>(
(a, b)
}
ty::RawPtr(TypeAndMut { ty: pointee_ty, mutbl: _ }) | ty::Ref(_, pointee_ty, _) => {
if has_ptr_meta(tcx, pointee_ty) {
if has_ptr_meta(tcx, *pointee_ty) {
(pointer_ty(tcx), pointer_ty(tcx))
} else {
return None;

View file

@ -46,7 +46,7 @@ pub(crate) fn check_constants(fx: &mut FunctionCx<'_, '_, '_>) -> bool {
ConstantKind::Ty(ct) => ct,
ConstantKind::Val(..) => continue,
};
match const_.val {
match const_.val() {
ConstKind::Value(_) => {}
ConstKind::Unevaluated(unevaluated) => {
if let Err(err) =
@ -127,7 +127,7 @@ pub(crate) fn codegen_constant<'tcx>(
ConstantKind::Ty(ct) => ct,
ConstantKind::Val(val, ty) => return codegen_const_value(fx, val, ty),
};
let const_val = match const_.val {
let const_val = match const_.val() {
ConstKind::Value(const_val) => const_val,
ConstKind::Unevaluated(ty::Unevaluated { def, substs, promoted })
if fx.tcx.is_static(def.did) =>
@ -135,7 +135,7 @@ pub(crate) fn codegen_constant<'tcx>(
assert!(substs.is_empty());
assert!(promoted.is_none());
return codegen_static_ref(fx, def.did, fx.layout_of(const_.ty)).to_cvalue(fx);
return codegen_static_ref(fx, def.did, fx.layout_of(const_.ty())).to_cvalue(fx);
}
ConstKind::Unevaluated(unevaluated) => {
match fx.tcx.const_eval_resolve(ParamEnv::reveal_all(), unevaluated, None) {
@ -152,7 +152,7 @@ pub(crate) fn codegen_constant<'tcx>(
| ConstKind::Error(_) => unreachable!("{:?}", const_),
};
codegen_const_value(fx, const_val, const_.ty)
codegen_const_value(fx, const_val, const_.ty())
}
pub(crate) fn codegen_const_value<'tcx>(
@ -465,7 +465,7 @@ pub(crate) fn mir_operand_get_const_val<'tcx>(
match operand {
Operand::Constant(const_) => match const_.literal {
ConstantKind::Ty(const_) => {
fx.monomorphize(const_).eval(fx.tcx, ParamEnv::reveal_all()).val.try_to_value()
fx.monomorphize(const_).eval(fx.tcx, ParamEnv::reveal_all()).val().try_to_value()
}
ConstantKind::Val(val, _) => Some(val),
},
@ -490,7 +490,7 @@ pub(crate) fn mir_operand_get_const_val<'tcx>(
return None;
}
let const_val = mir_operand_get_const_val(fx, operand)?;
if fx.layout_of(ty).size
if fx.layout_of(*ty).size
!= const_val.try_to_scalar_int()?.size()
{
return None;

View file

@ -114,7 +114,7 @@ impl<'tcx> DebugContext<'tcx> {
}
fn dwarf_ty(&mut self, ty: Ty<'tcx>) -> UnitEntryId {
if let Some(type_id) = self.types.get(ty) {
if let Some(type_id) = self.types.get(&ty) {
return *type_id;
}
@ -143,7 +143,7 @@ impl<'tcx> DebugContext<'tcx> {
// Ensure that type is inserted before recursing to avoid duplicates
self.types.insert(ty, type_id);
let pointee = self.dwarf_ty(pointee_ty);
let pointee = self.dwarf_ty(*pointee_ty);
let type_entry = self.dwarf.unit.get_mut(type_id);

View file

@ -66,7 +66,7 @@ fn unsize_ptr<'tcx>(
(&ty::Ref(_, a, _), &ty::Ref(_, b, _))
| (&ty::Ref(_, a, _), &ty::RawPtr(ty::TypeAndMut { ty: b, .. }))
| (&ty::RawPtr(ty::TypeAndMut { ty: a, .. }), &ty::RawPtr(ty::TypeAndMut { ty: b, .. })) => {
(src, unsized_info(fx, a, b, old_info))
(src, unsized_info(fx, *a, *b, old_info))
}
(&ty::Adt(def_a, _), &ty::Adt(def_b, _)) if def_a.is_box() && def_b.is_box() => {
let (a, b) = (src_layout.ty.boxed_ty(), dst_layout.ty.boxed_ty());

View file

@ -514,7 +514,7 @@ impl<'tcx> CPlace<'tcx> {
// Can only happen for vector types
let len =
u16::try_from(len.eval_usize(fx.tcx, ParamEnv::reveal_all())).unwrap();
let vector_ty = fx.clif_type(element).unwrap().by(len).unwrap();
let vector_ty = fx.clif_type(*element).unwrap().by(len).unwrap();
let data = match from.0 {
CValueInner::ByRef(ptr, None) => {
@ -721,8 +721,8 @@ impl<'tcx> CPlace<'tcx> {
index: Value,
) -> CPlace<'tcx> {
let (elem_layout, ptr) = match self.layout().ty.kind() {
ty::Array(elem_ty, _) => (fx.layout_of(elem_ty), self.to_ptr()),
ty::Slice(elem_ty) => (fx.layout_of(elem_ty), self.to_ptr_maybe_unsized().0),
ty::Array(elem_ty, _) => (fx.layout_of(*elem_ty), self.to_ptr()),
ty::Slice(elem_ty) => (fx.layout_of(*elem_ty), self.to_ptr_maybe_unsized().0),
_ => bug!("place_index({:?})", self.layout().ty),
};
@ -781,11 +781,11 @@ pub(crate) fn assert_assignable<'tcx>(
ty::RawPtr(TypeAndMut { ty: a, mutbl: _ }),
ty::RawPtr(TypeAndMut { ty: b, mutbl: _ }),
) => {
assert_assignable(fx, a, b);
assert_assignable(fx, *a, *b);
}
(ty::Ref(_, a, _), ty::RawPtr(TypeAndMut { ty: b, mutbl: _ }))
| (ty::RawPtr(TypeAndMut { ty: a, mutbl: _ }), ty::Ref(_, b, _)) => {
assert_assignable(fx, a, b);
assert_assignable(fx, *a, *b);
}
(ty::FnPtr(_), ty::FnPtr(_)) => {
let from_sig = fx.tcx.normalize_erasing_late_bound_regions(

View file

@ -185,9 +185,9 @@ impl<'ll, 'tcx> TypeMap<'ll, 'tcx> {
///
/// This function is used to remove the temporary metadata
/// mapping after we've computed the actual metadata.
fn remove_type(&mut self, type_: Ty<'tcx>) {
if self.type_to_metadata.remove(type_).is_none() {
bug!("type metadata `Ty` '{}' is not in the `TypeMap`!", type_);
fn remove_type(&mut self, ty: Ty<'tcx>) {
if self.type_to_metadata.remove(&ty).is_none() {
bug!("type metadata `Ty` '{}' is not in the `TypeMap`!", ty);
}
}
@ -397,7 +397,7 @@ fn fixed_size_array_metadata<'ll, 'tcx>(
bug!("fixed_size_array_metadata() called with non-ty::Array type `{:?}`", array_type)
};
let element_type_metadata = type_metadata(cx, element_type);
let element_type_metadata = type_metadata(cx, *element_type);
return_if_metadata_created_in_meantime!(cx, unique_type_id);
@ -546,7 +546,7 @@ fn subroutine_type_metadata<'ll, 'tcx>(
)
.chain(
// regular arguments
signature.inputs().iter().map(|argument_type| Some(type_metadata(cx, argument_type))),
signature.inputs().iter().map(|&argument_type| Some(type_metadata(cx, argument_type))),
)
.collect();
@ -601,7 +601,7 @@ fn slice_type_metadata<'ll, 'tcx>(
unique_type_id: UniqueTypeId,
) -> MetadataCreationResult<'ll> {
let element_type = match slice_type.kind() {
ty::Slice(element_type) => element_type,
ty::Slice(element_type) => *element_type,
ty::Str => cx.tcx.types.u8,
_ => {
bug!(

View file

@ -430,9 +430,9 @@ impl<'ll, 'tcx> DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
let t = arg.layout.ty;
let t = match t.kind() {
ty::Array(ct, _)
if (*ct == cx.tcx.types.u8) || cx.layout_of(ct).is_zst() =>
if (*ct == cx.tcx.types.u8) || cx.layout_of(*ct).is_zst() =>
{
cx.tcx.mk_imm_ptr(ct)
cx.tcx.mk_imm_ptr(*ct)
}
_ => t,
};

View file

@ -1132,8 +1132,8 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
fn simd_simple_float_intrinsic<'ll, 'tcx>(
name: Symbol,
in_elem: &::rustc_middle::ty::TyS<'_>,
in_ty: &::rustc_middle::ty::TyS<'_>,
in_elem: Ty<'_>,
in_ty: Ty<'_>,
in_len: u64,
bx: &mut Builder<'_, 'll, 'tcx>,
span: Span,

View file

@ -146,7 +146,7 @@ fn push_debuginfo_type_name<'tcx>(
if cpp_like_debuginfo {
output.push_str("array$<");
push_debuginfo_type_name(tcx, inner_type, true, output, visited);
match len.val {
match len.val() {
ty::ConstKind::Param(param) => write!(output, ",{}>", param.name).unwrap(),
_ => write!(output, ",{}>", len.eval_usize(tcx, ty::ParamEnv::reveal_all()))
.unwrap(),
@ -154,7 +154,7 @@ fn push_debuginfo_type_name<'tcx>(
} else {
output.push('[');
push_debuginfo_type_name(tcx, inner_type, true, output, visited);
match len.val {
match len.val() {
ty::ConstKind::Param(param) => write!(output, "; {}]", param.name).unwrap(),
_ => write!(output, "; {}]", len.eval_usize(tcx, ty::ParamEnv::reveal_all()))
.unwrap(),
@ -343,7 +343,7 @@ fn push_debuginfo_type_name<'tcx>(
// We only care about avoiding recursing
// directly back to the type we're currently
// processing
visited.remove(t);
visited.remove(&t);
}
ty::Closure(def_id, substs) | ty::Generator(def_id, substs, ..) => {
// Name will be "{closure_env#0}<T1, T2, ...>", "{generator_env#0}<T1, T2, ...>", or
@ -645,19 +645,19 @@ fn push_generic_params_internal<'tcx>(
true
}
fn push_const_param<'tcx>(tcx: TyCtxt<'tcx>, ct: &'tcx ty::Const<'tcx>, output: &mut String) {
match ct.val {
fn push_const_param<'tcx>(tcx: TyCtxt<'tcx>, ct: ty::Const<'tcx>, output: &mut String) {
match ct.val() {
ty::ConstKind::Param(param) => {
write!(output, "{}", param.name)
}
_ => match ct.ty.kind() {
_ => match ct.ty().kind() {
ty::Int(ity) => {
let bits = ct.eval_bits(tcx, ty::ParamEnv::reveal_all(), ct.ty);
let bits = ct.eval_bits(tcx, ty::ParamEnv::reveal_all(), ct.ty());
let val = Integer::from_int_ty(&tcx, *ity).size().sign_extend(bits) as i128;
write!(output, "{}", val)
}
ty::Uint(_) => {
let val = ct.eval_bits(tcx, ty::ParamEnv::reveal_all(), ct.ty);
let val = ct.eval_bits(tcx, ty::ParamEnv::reveal_all(), ct.ty());
write!(output, "{}", val)
}
ty::Bool => {
@ -672,7 +672,7 @@ fn push_const_param<'tcx>(tcx: TyCtxt<'tcx>, ct: &'tcx ty::Const<'tcx>, output:
let mut hasher = StableHasher::new();
hcx.while_hashing_spans(false, |hcx| {
hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
ct.val.hash_stable(hcx, &mut hasher);
ct.val().hash_stable(hcx, &mut hasher);
});
});
// Let's only emit 64 bits of the hash value. That should be plenty for

View file

@ -29,7 +29,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
mir::ConstantKind::Ty(ct) => ct,
mir::ConstantKind::Val(val, _) => return Ok(val),
};
match ct.val {
match ct.val() {
ty::ConstKind::Unevaluated(ct) => self
.cx
.tcx()
@ -61,11 +61,11 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
let c = ty::Const::from_value(bx.tcx(), val, ty);
let values: Vec<_> = bx
.tcx()
.destructure_const(ty::ParamEnv::reveal_all().and(&c))
.destructure_const(ty::ParamEnv::reveal_all().and(c))
.fields
.iter()
.map(|field| {
if let Some(prim) = field.val.try_to_scalar() {
if let Some(prim) = field.val().try_to_scalar() {
let layout = bx.layout_of(field_ty);
let scalar = match layout.abi {
Abi::Scalar(x) => x,
@ -78,7 +78,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
})
.collect();
let llval = bx.const_struct(&values, false);
(llval, c.ty)
(llval, c.ty())
})
.unwrap_or_else(|_| {
bx.tcx().sess.span_err(span, "could not evaluate shuffle_indices at compile time");

View file

@ -139,14 +139,14 @@ fn const_to_valtree_inner<'tcx>(
pub(crate) fn destructure_const<'tcx>(
tcx: TyCtxt<'tcx>,
param_env: ty::ParamEnv<'tcx>,
val: &'tcx ty::Const<'tcx>,
val: ty::Const<'tcx>,
) -> mir::DestructuredConst<'tcx> {
trace!("destructure_const: {:?}", val);
let ecx = mk_eval_cx(tcx, DUMMY_SP, param_env, false);
let op = ecx.const_to_op(val, None).unwrap();
// We go to `usize` as we cannot allocate anything bigger anyway.
let (field_count, variant, down) = match val.ty.kind() {
let (field_count, variant, down) = match val.ty().kind() {
ty::Array(_, len) => (usize::try_from(len.eval_usize(tcx, param_env)).unwrap(), None, op),
ty::Adt(def, _) if def.variants.is_empty() => {
return mir::DestructuredConst { variant: None, fields: &[] };
@ -173,8 +173,8 @@ pub(crate) fn destructure_const<'tcx>(
pub(crate) fn deref_const<'tcx>(
tcx: TyCtxt<'tcx>,
param_env: ty::ParamEnv<'tcx>,
val: &'tcx ty::Const<'tcx>,
) -> &'tcx ty::Const<'tcx> {
val: ty::Const<'tcx>,
) -> ty::Const<'tcx> {
trace!("deref_const: {:?}", val);
let ecx = mk_eval_cx(tcx, DUMMY_SP, param_env, false);
let op = ecx.const_to_op(val, None).unwrap();
@ -194,7 +194,7 @@ pub(crate) fn deref_const<'tcx>(
// In case of unsized types, figure out the real type behind.
MemPlaceMeta::Meta(scalar) => match mplace.layout.ty.kind() {
ty::Str => bug!("there's no sized equivalent of a `str`"),
ty::Slice(elem_ty) => tcx.mk_array(elem_ty, scalar.to_machine_usize(&tcx).unwrap()),
ty::Slice(elem_ty) => tcx.mk_array(*elem_ty, scalar.to_machine_usize(&tcx).unwrap()),
_ => bug!(
"type {} should not have metadata, but had {:?}",
mplace.layout.ty,
@ -203,5 +203,5 @@ pub(crate) fn deref_const<'tcx>(
},
};
tcx.mk_const(ty::Const { val: ty::ConstKind::Value(op_to_const(&ecx, &mplace.into())), ty })
tcx.mk_const(ty::ConstS { val: ty::ConstKind::Value(op_to_const(&ecx, &mplace.into())), ty })
}

View file

@ -315,7 +315,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
match (&src.layout.ty.kind(), &cast_ty.ty.kind()) {
(&ty::Ref(_, s, _), &ty::Ref(_, c, _) | &ty::RawPtr(TypeAndMut { ty: c, .. }))
| (&ty::RawPtr(TypeAndMut { ty: s, .. }), &ty::RawPtr(TypeAndMut { ty: c, .. })) => {
self.unsize_into_ptr(src, dest, s, c)
self.unsize_into_ptr(src, dest, *s, *c)
}
(&ty::Adt(def_a, _), &ty::Adt(def_b, _)) => {
assert_eq!(def_a, def_b);

View file

@ -68,7 +68,7 @@ impl<'tcx> Printer<'tcx> for AbsolutePathPrinter<'tcx> {
}
}
fn print_const(self, ct: &'tcx ty::Const<'tcx>) -> Result<Self::Const, Self::Error> {
fn print_const(self, ct: ty::Const<'tcx>) -> Result<Self::Const, Self::Error> {
self.pretty_print_const(ct, false)
}

View file

@ -561,10 +561,10 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
/// "universe" (param_env).
pub fn const_to_op(
&self,
val: &ty::Const<'tcx>,
val: ty::Const<'tcx>,
layout: Option<TyAndLayout<'tcx>>,
) -> InterpResult<'tcx, OpTy<'tcx, M::PointerTag>> {
match val.val {
match val.val() {
ty::ConstKind::Param(_) | ty::ConstKind::Bound(..) => throw_inval!(TooGeneric),
ty::ConstKind::Error(_) => throw_inval!(AlreadyReported(ErrorReported)),
ty::ConstKind::Unevaluated(uv) => {
@ -574,7 +574,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
ty::ConstKind::Infer(..) | ty::ConstKind::Placeholder(..) => {
span_bug!(self.cur_span(), "const_to_op: Unexpected ConstKind {:?}", val)
}
ty::ConstKind::Value(val_val) => self.const_val_to_op(val_val, val.ty, layout),
ty::ConstKind::Value(val_val) => self.const_val_to_op(val_val, val.ty(), layout),
}
}
@ -584,8 +584,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
layout: Option<TyAndLayout<'tcx>>,
) -> InterpResult<'tcx, OpTy<'tcx, M::PointerTag>> {
match val {
mir::ConstantKind::Ty(ct) => self.const_to_op(ct, layout),
mir::ConstantKind::Val(val, ty) => self.const_val_to_op(*val, ty, layout),
mir::ConstantKind::Ty(ct) => self.const_to_op(*ct, layout),
mir::ConstantKind::Val(val, ty) => self.const_val_to_op(*val, *ty, layout),
}
}

View file

@ -462,7 +462,7 @@ where
let (meta, ty) = match base.layout.ty.kind() {
// It is not nice to match on the type, but that seems to be the only way to
// implement this.
ty::Array(inner, _) => (MemPlaceMeta::None, self.tcx.mk_array(inner, inner_len)),
ty::Array(inner, _) => (MemPlaceMeta::None, self.tcx.mk_array(*inner, inner_len)),
ty::Slice(..) => {
let len = Scalar::from_machine_usize(inner_len, self);
(MemPlaceMeta::Meta(len), base.layout.ty)

View file

@ -55,7 +55,7 @@ where
assert!(matches!(ty.kind(), ty::Param(_)))
}
ty::subst::GenericArgKind::Const(ct) => {
assert!(matches!(ct.val, ty::ConstKind::Param(_)))
assert!(matches!(ct.val(), ty::ConstKind::Param(_)))
}
ty::subst::GenericArgKind::Lifetime(..) => (),
},
@ -68,8 +68,8 @@ where
}
}
fn visit_const(&mut self, c: &'tcx ty::Const<'tcx>) -> ControlFlow<Self::BreakTy> {
match c.val {
fn visit_const(&mut self, c: ty::Const<'tcx>) -> ControlFlow<Self::BreakTy> {
match c.val() {
ty::ConstKind::Param(..) => ControlFlow::Break(FoundParam),
_ => c.super_visit_with(self),
}

View file

@ -553,7 +553,7 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
{
// A mutable reference inside a const? That does not seem right (except if it is
// a ZST).
let layout = self.ecx.layout_of(ty)?;
let layout = self.ecx.layout_of(*ty)?;
if !layout.is_zst() {
throw_validation_failure!(self.path, { "mutable reference in a `const`" });
}
@ -837,7 +837,7 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M>
// This is the length of the array/slice.
let len = mplace.len(self.ecx)?;
// This is the element type size.
let layout = self.ecx.layout_of(tys)?;
let layout = self.ecx.layout_of(*tys)?;
// This is the size in bytes of the whole array. (This checks for overflow.)
let size = layout.size * len;
@ -896,7 +896,7 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M>
// Fast path for arrays and slices of ZSTs. We only need to check a single ZST element
// of an array and not all of them, because there's only a single value of a specific
// ZST type, so either validation fails for all elements or none.
ty::Array(tys, ..) | ty::Slice(tys) if self.ecx.layout_of(tys)?.is_zst() => {
ty::Array(tys, ..) | ty::Slice(tys) if self.ecx.layout_of(*tys)?.is_zst() => {
// Validate just the first element (if any).
self.walk_aggregate(op, fields.take(1))?
}

View file

@ -233,7 +233,7 @@ impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> {
let mut tmp_ty = self_ty;
while let rustc_middle::ty::Ref(_, inner_ty, _) = tmp_ty.kind() {
num_refs += 1;
tmp_ty = inner_ty;
tmp_ty = *inner_ty;
}
let deref = "*".repeat(num_refs);

View file

@ -355,7 +355,7 @@ where
// Check the qualifs of the value of `const` items.
if let Some(ct) = constant.literal.const_for_ty() {
if let ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs: _, promoted }) = ct.val {
if let ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs: _, promoted }) = ct.val() {
// Use qualifs of the type for the promoted. Promoteds in MIR body should be possible
// only for `NeedsNonConstDrop` with precise drop checking. This is the only const
// check performed after the promotion. Verify that with an assertion.

View file

@ -496,7 +496,7 @@ impl<'tcx> Validator<'_, 'tcx> {
if matches!(kind, CastKind::Misc) {
let operand_ty = operand.ty(self.body, self.tcx);
let cast_in = CastTy::from_ty(operand_ty).expect("bad input type for cast");
let cast_out = CastTy::from_ty(cast_ty).expect("bad output type for cast");
let cast_out = CastTy::from_ty(*cast_ty).expect("bad output type for cast");
if let (CastTy::Ptr(_) | CastTy::FnPtr, CastTy::Int(_)) = (cast_in, cast_out) {
// ptr-to-int casts are not possible in consts and thus not promotable
return Err(Unpromotable);
@ -839,7 +839,7 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> {
span,
user_ty: None,
literal: tcx
.mk_const(ty::Const {
.mk_const(ty::ConstS {
ty,
val: ty::ConstKind::Unevaluated(ty::Unevaluated {
def,

View file

@ -0,0 +1,98 @@
use std::cmp::Ordering;
use std::hash::{Hash, Hasher};
use std::ops::Deref;
use std::ptr;
mod private {
#[derive(Clone, Copy, Debug)]
pub struct PrivateZst;
}
/// A reference to a value that is interned, and is known to be unique.
///
/// Note that it is possible to have a `T` and a `Interned<T>` that are (or
/// refer to) equal but different values. But if you have two different
/// `Interned<T>`s, they both refer to the same value, at a single location in
/// memory. This means that equality and hashing can be done on the value's
/// address rather than the value's contents, which can improve performance.
///
/// The `PrivateZst` field means you can pattern match with `Interned(v, _)`
/// but you can only construct a `Interned` with `new_unchecked`, and not
/// directly.
#[derive(Debug)]
#[cfg_attr(not(bootstrap), rustc_pass_by_value)]
pub struct Interned<'a, T>(pub &'a T, pub private::PrivateZst);
impl<'a, T> Interned<'a, T> {
/// Create a new `Interned` value. The value referred to *must* be interned
/// and thus be unique, and it *must* remain unique in the future. This
/// function has `_unchecked` in the name but is not `unsafe`, because if
/// the uniqueness condition is violated condition it will cause incorrect
/// behaviour but will not affect memory safety.
#[inline]
pub const fn new_unchecked(t: &'a T) -> Self {
Interned(t, private::PrivateZst)
}
}
impl<'a, T> Clone for Interned<'a, T> {
fn clone(&self) -> Self {
*self
}
}
impl<'a, T> Copy for Interned<'a, T> {}
impl<'a, T> Deref for Interned<'a, T> {
type Target = T;
#[inline]
fn deref(&self) -> &T {
self.0
}
}
impl<'a, T> PartialEq for Interned<'a, T> {
#[inline]
fn eq(&self, other: &Self) -> bool {
// Pointer equality implies equality, due to the uniqueness constraint.
ptr::eq(self.0, other.0)
}
}
impl<'a, T> Eq for Interned<'a, T> {}
// In practice you can't intern any `T` that doesn't implement `Eq`, because
// that's needed for hashing. Therefore, we won't be interning any `T` that
// implements `PartialOrd` without also implementing `Ord`. So we can have the
// bound `T: Ord` here and avoid duplication with the `Ord` impl below.
impl<'a, T: Ord> PartialOrd for Interned<'a, T> {
fn partial_cmp(&self, other: &Interned<'a, T>) -> Option<Ordering> {
Some(self.cmp(other))
}
}
impl<'a, T: Ord> Ord for Interned<'a, T> {
fn cmp(&self, other: &Interned<'a, T>) -> Ordering {
// Pointer equality implies equality, due to the uniqueness constraint,
// but the contents must be compared otherwise.
if ptr::eq(self.0, other.0) {
Ordering::Equal
} else {
let res = self.0.cmp(&other.0);
debug_assert_ne!(res, Ordering::Equal);
res
}
}
}
impl<'a, T> Hash for Interned<'a, T> {
#[inline]
fn hash<H: Hasher>(&self, s: &mut H) {
// Pointer hashing is sufficient, due to the uniqueness constraint.
ptr::hash(self.0, s)
}
}
#[cfg(test)]
mod tests;

View file

@ -0,0 +1,59 @@
use super::*;
use std::cmp::Ordering;
#[derive(Debug)]
struct S(u32);
impl PartialEq for S {
fn eq(&self, _other: &Self) -> bool {
panic!("shouldn't be called");
}
}
impl Eq for S {}
impl PartialOrd for S {
fn partial_cmp(&self, other: &S) -> Option<Ordering> {
// The `==` case should be handled by `Interned`.
assert_ne!(self.0, other.0);
self.0.partial_cmp(&other.0)
}
}
impl Ord for S {
fn cmp(&self, other: &S) -> Ordering {
// The `==` case should be handled by `Interned`.
assert_ne!(self.0, other.0);
self.0.cmp(&other.0)
}
}
#[test]
fn test_uniq() {
let s1 = S(1);
let s2 = S(2);
let s3 = S(3);
let s4 = S(1); // violates uniqueness
let v1 = Interned::new_unchecked(&s1);
let v2 = Interned::new_unchecked(&s2);
let v3a = Interned::new_unchecked(&s3);
let v3b = Interned::new_unchecked(&s3);
let v4 = Interned::new_unchecked(&s4); // violates uniqueness
assert_ne!(v1, v2);
assert_ne!(v2, v3a);
assert_eq!(v1, v1);
assert_eq!(v3a, v3b);
assert_ne!(v1, v4); // same content but different addresses: not equal
assert_eq!(v1.cmp(&v2), Ordering::Less);
assert_eq!(v3a.cmp(&v2), Ordering::Greater);
assert_eq!(v1.cmp(&v1), Ordering::Equal); // only uses Interned::eq, not S::cmp
assert_eq!(v3a.cmp(&v3b), Ordering::Equal); // only uses Interned::eq, not S::cmp
assert_eq!(v1.partial_cmp(&v2), Some(Ordering::Less));
assert_eq!(v3a.partial_cmp(&v2), Some(Ordering::Greater));
assert_eq!(v1.partial_cmp(&v1), Some(Ordering::Equal)); // only uses Interned::eq, not S::cmp
assert_eq!(v3a.partial_cmp(&v3b), Some(Ordering::Equal)); // only uses Interned::eq, not S::cmp
}

View file

@ -21,6 +21,7 @@
#![feature(type_alias_impl_trait)]
#![feature(new_uninit)]
#![feature(once_cell)]
#![feature(rustc_attrs)]
#![feature(test)]
#![feature(thread_id_value)]
#![feature(vec_into_raw_parts)]
@ -68,12 +69,12 @@ pub mod flock;
pub mod functor;
pub mod fx;
pub mod graph;
pub mod intern;
pub mod jobserver;
pub mod macros;
pub mod map_in_place;
pub mod obligation_forest;
pub mod owning_ref;
pub mod ptr_key;
pub mod sip128;
pub mod small_c_str;
pub mod snapshot_map;

View file

@ -1,37 +0,0 @@
use std::ops::Deref;
use std::{hash, ptr};
/// A wrapper around reference that compares and hashes like a pointer.
/// Can be used as a key in sets/maps indexed by pointers to avoid `unsafe`.
#[derive(Debug)]
pub struct PtrKey<'a, T>(pub &'a T);
impl<'a, T> Clone for PtrKey<'a, T> {
fn clone(&self) -> Self {
*self
}
}
impl<'a, T> Copy for PtrKey<'a, T> {}
impl<'a, T> PartialEq for PtrKey<'a, T> {
fn eq(&self, rhs: &Self) -> bool {
ptr::eq(self.0, rhs.0)
}
}
impl<'a, T> Eq for PtrKey<'a, T> {}
impl<'a, T> hash::Hash for PtrKey<'a, T> {
fn hash<H: hash::Hasher>(&self, hasher: &mut H) {
(self.0 as *const T).hash(hasher)
}
}
impl<'a, T> Deref for PtrKey<'a, T> {
type Target = T;
fn deref(&self) -> &Self::Target {
self.0
}
}

View file

@ -299,7 +299,7 @@ impl<'tcx> ToTrace<'tcx> for ty::Region<'tcx> {
}
}
impl<'tcx> ToTrace<'tcx> for &'tcx Const<'tcx> {
impl<'tcx> ToTrace<'tcx> for Const<'tcx> {
fn to_trace(
_: TyCtxt<'tcx>,
cause: &ObligationCause<'tcx>,

View file

@ -179,7 +179,7 @@ impl CanonicalizeMode for CanonicalizeQueryResponse {
canonicalizer: &mut Canonicalizer<'_, 'tcx>,
r: ty::Region<'tcx>,
) -> ty::Region<'tcx> {
match r {
match *r {
ty::ReFree(_)
| ty::ReErased
| ty::ReStatic
@ -187,12 +187,12 @@ impl CanonicalizeMode for CanonicalizeQueryResponse {
| ty::ReEarlyBound(..) => r,
ty::RePlaceholder(placeholder) => canonicalizer.canonical_var_for_region(
CanonicalVarInfo { kind: CanonicalVarKind::PlaceholderRegion(*placeholder) },
CanonicalVarInfo { kind: CanonicalVarKind::PlaceholderRegion(placeholder) },
r,
),
ty::ReVar(vid) => {
let universe = canonicalizer.region_var_universe(*vid);
let universe = canonicalizer.region_var_universe(vid);
canonicalizer.canonical_var_for_region(
CanonicalVarInfo { kind: CanonicalVarKind::Region(universe) },
r,
@ -240,7 +240,7 @@ impl CanonicalizeMode for CanonicalizeUserTypeAnnotation {
canonicalizer: &mut Canonicalizer<'_, 'tcx>,
r: ty::Region<'tcx>,
) -> ty::Region<'tcx> {
match r {
match *r {
ty::ReEarlyBound(_) | ty::ReFree(_) | ty::ReErased | ty::ReStatic => r,
ty::ReVar(_) => canonicalizer.canonical_var_for_region_in_root_universe(r),
_ => {
@ -311,11 +311,7 @@ impl CanonicalizeMode for CanonicalizeFreeRegionsOtherThanStatic {
canonicalizer: &mut Canonicalizer<'_, 'tcx>,
r: ty::Region<'tcx>,
) -> ty::Region<'tcx> {
if let ty::ReStatic = r {
r
} else {
canonicalizer.canonical_var_for_region_in_root_universe(r)
}
if r.is_static() { r } else { canonicalizer.canonical_var_for_region_in_root_universe(r) }
}
fn any(&self) -> bool {
@ -479,8 +475,8 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for Canonicalizer<'cx, 'tcx> {
}
}
fn fold_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
match ct.val {
fn fold_const(&mut self, ct: ty::Const<'tcx>) -> ty::Const<'tcx> {
match ct.val() {
ty::ConstKind::Infer(InferConst::Var(vid)) => {
debug!("canonical: const var found with vid {:?}", vid);
match self.infcx.probe_const_var(vid) {
@ -497,7 +493,7 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for Canonicalizer<'cx, 'tcx> {
ui = ty::UniverseIndex::ROOT;
}
return self.canonicalize_const_var(
CanonicalVarInfo { kind: CanonicalVarKind::Const(ui, ct.ty) },
CanonicalVarInfo { kind: CanonicalVarKind::Const(ui, ct.ty()) },
ct,
);
}
@ -773,17 +769,17 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> {
fn canonicalize_const_var(
&mut self,
info: CanonicalVarInfo<'tcx>,
const_var: &'tcx ty::Const<'tcx>,
) -> &'tcx ty::Const<'tcx> {
const_var: ty::Const<'tcx>,
) -> ty::Const<'tcx> {
let infcx = self.infcx;
let bound_to = infcx.shallow_resolve(const_var);
if bound_to != const_var {
self.fold_const(bound_to)
} else {
let var = self.canonical_var(info, const_var.into());
self.tcx().mk_const(ty::Const {
self.tcx().mk_const(ty::ConstS {
val: ty::ConstKind::Bound(self.binder_index, var),
ty: self.fold_ty(const_var.ty),
ty: self.fold_ty(const_var.ty()),
})
}
}

View file

@ -149,7 +149,7 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> {
let universe_mapped = universe_map(universe);
let placeholder_mapped = ty::PlaceholderConst { universe: universe_mapped, name };
self.tcx
.mk_const(ty::Const {
.mk_const(ty::ConstS {
val: ty::ConstKind::Placeholder(placeholder_mapped),
ty: name.ty,
})

View file

@ -237,10 +237,9 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> {
v.var_values[BoundVar::new(index)]
});
match (original_value.unpack(), result_value.unpack()) {
(
GenericArgKind::Lifetime(ty::ReErased),
GenericArgKind::Lifetime(ty::ReErased),
) => {
(GenericArgKind::Lifetime(re1), GenericArgKind::Lifetime(re2))
if re1.is_erased() && re2.is_erased() =>
{
// No action needed.
}
@ -429,7 +428,7 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> {
}
GenericArgKind::Lifetime(result_value) => {
// e.g., here `result_value` might be `'?1` in the example above...
if let &ty::RegionKind::ReLateBound(debruijn, br) = result_value {
if let ty::ReLateBound(debruijn, br) = *result_value {
// ... in which case we would set `canonical_vars[0]` to `Some('static)`.
// We only allow a `ty::INNERMOST` index in substitutions.
@ -438,12 +437,12 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> {
}
}
GenericArgKind::Const(result_value) => {
if let ty::Const { val: ty::ConstKind::Bound(debrujin, b), .. } = result_value {
if let ty::ConstKind::Bound(debrujin, b) = result_value.val() {
// ...in which case we would set `canonical_vars[0]` to `Some(const X)`.
// We only allow a `ty::INNERMOST` index in substitutions.
assert_eq!(*debrujin, ty::INNERMOST);
opt_values[*b] = Some(*original_value);
assert_eq!(debrujin, ty::INNERMOST);
opt_values[b] = Some(*original_value);
}
}
}
@ -558,10 +557,9 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> {
obligations
.extend(self.at(cause, param_env).eq(v1, v2)?.into_obligations());
}
(
GenericArgKind::Lifetime(ty::ReErased),
GenericArgKind::Lifetime(ty::ReErased),
) => {
(GenericArgKind::Lifetime(re1), GenericArgKind::Lifetime(re2))
if re1.is_erased() && re2.is_erased() =>
{
// no action needed
}
(GenericArgKind::Lifetime(v1), GenericArgKind::Lifetime(v2)) => {
@ -672,7 +670,7 @@ impl<'tcx> TypeRelatingDelegate<'tcx> for QueryTypeRelatingDelegate<'_, 'tcx> {
});
}
fn const_equate(&mut self, _a: &'tcx Const<'tcx>, _b: &'tcx Const<'tcx>) {
fn const_equate(&mut self, _a: Const<'tcx>, _b: Const<'tcx>) {
span_bug!(
self.cause.span(self.infcx.tcx),
"generic_const_exprs: unreachable `const_equate`"

View file

@ -123,9 +123,9 @@ impl<'infcx, 'tcx> InferCtxt<'infcx, 'tcx> {
pub fn super_combine_consts<R>(
&self,
relation: &mut R,
a: &'tcx ty::Const<'tcx>,
b: &'tcx ty::Const<'tcx>,
) -> RelateResult<'tcx, &'tcx ty::Const<'tcx>>
a: ty::Const<'tcx>,
b: ty::Const<'tcx>,
) -> RelateResult<'tcx, ty::Const<'tcx>>
where
R: ConstEquateRelation<'tcx>,
{
@ -139,7 +139,7 @@ impl<'infcx, 'tcx> InferCtxt<'infcx, 'tcx> {
let a_is_expected = relation.a_is_expected();
match (a.val, b.val) {
match (a.val(), b.val()) {
(
ty::ConstKind::Infer(InferConst::Var(a_vid)),
ty::ConstKind::Infer(InferConst::Var(b_vid)),
@ -226,9 +226,9 @@ impl<'infcx, 'tcx> InferCtxt<'infcx, 'tcx> {
&self,
param_env: ty::ParamEnv<'tcx>,
target_vid: ty::ConstVid<'tcx>,
ct: &'tcx ty::Const<'tcx>,
ct: ty::Const<'tcx>,
vid_is_expected: bool,
) -> RelateResult<'tcx, &'tcx ty::Const<'tcx>> {
) -> RelateResult<'tcx, ty::Const<'tcx>> {
let (for_universe, span) = {
let mut inner = self.inner.borrow_mut();
let variable_table = &mut inner.const_unification_table();
@ -451,8 +451,8 @@ impl<'infcx, 'tcx> CombineFields<'infcx, 'tcx> {
pub fn add_const_equate_obligation(
&mut self,
a_is_expected: bool,
a: &'tcx ty::Const<'tcx>,
b: &'tcx ty::Const<'tcx>,
a: ty::Const<'tcx>,
b: ty::Const<'tcx>,
) {
let predicate = if a_is_expected {
ty::PredicateKind::ConstEquate(a, b)
@ -716,12 +716,12 @@ impl<'tcx> TypeRelation<'tcx> for Generalizer<'_, 'tcx> {
fn consts(
&mut self,
c: &'tcx ty::Const<'tcx>,
c2: &'tcx ty::Const<'tcx>,
) -> RelateResult<'tcx, &'tcx ty::Const<'tcx>> {
c: ty::Const<'tcx>,
c2: ty::Const<'tcx>,
) -> RelateResult<'tcx, ty::Const<'tcx>> {
assert_eq!(c, c2); // we are abusing TypeRelation here; both LHS and RHS ought to be ==
match c.val {
match c.val() {
ty::ConstKind::Infer(InferConst::Var(vid)) => {
let mut inner = self.infcx.inner.borrow_mut();
let variable_table = &mut inner.const_unification_table();
@ -739,7 +739,7 @@ impl<'tcx> TypeRelation<'tcx> for Generalizer<'_, 'tcx> {
origin: var_value.origin,
val: ConstVariableValue::Unknown { universe: self.for_universe },
});
Ok(self.tcx().mk_const_var(new_var_id, c.ty))
Ok(self.tcx().mk_const_var(new_var_id, c.ty()))
}
}
}
@ -754,8 +754,8 @@ impl<'tcx> TypeRelation<'tcx> for Generalizer<'_, 'tcx> {
substs,
substs,
)?;
Ok(self.tcx().mk_const(ty::Const {
ty: c.ty,
Ok(self.tcx().mk_const(ty::ConstS {
ty: c.ty(),
val: ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs, promoted }),
}))
}
@ -768,7 +768,7 @@ pub trait ConstEquateRelation<'tcx>: TypeRelation<'tcx> {
/// Register an obligation that both constants must be equal to each other.
///
/// If they aren't equal then the relation doesn't hold.
fn const_equate_obligation(&mut self, a: &'tcx ty::Const<'tcx>, b: &'tcx ty::Const<'tcx>);
fn const_equate_obligation(&mut self, a: ty::Const<'tcx>, b: ty::Const<'tcx>);
}
pub trait RelateResultCompare<'tcx, T> {
@ -788,7 +788,7 @@ impl<'tcx, T: Clone + PartialEq> RelateResultCompare<'tcx, T> for RelateResult<'
pub fn const_unification_error<'tcx>(
a_is_expected: bool,
(a, b): (&'tcx ty::Const<'tcx>, &'tcx ty::Const<'tcx>),
(a, b): (ty::Const<'tcx>, ty::Const<'tcx>),
) -> TypeError<'tcx> {
TypeError::ConstMismatch(ExpectedFound::new(a_is_expected, a, b))
}
@ -915,7 +915,7 @@ impl<'tcx> TypeRelation<'tcx> for ConstInferUnifier<'_, 'tcx> {
debug_assert_eq!(r, _r);
debug!("ConstInferUnifier: r={:?}", r);
match r {
match *r {
// Never make variables for regions bound within the type itself,
// nor for erased regions.
ty::ReLateBound(..) | ty::ReErased => {
@ -945,13 +945,13 @@ impl<'tcx> TypeRelation<'tcx> for ConstInferUnifier<'_, 'tcx> {
#[tracing::instrument(level = "debug", skip(self))]
fn consts(
&mut self,
c: &'tcx ty::Const<'tcx>,
_c: &'tcx ty::Const<'tcx>,
) -> RelateResult<'tcx, &'tcx ty::Const<'tcx>> {
c: ty::Const<'tcx>,
_c: ty::Const<'tcx>,
) -> RelateResult<'tcx, ty::Const<'tcx>> {
debug_assert_eq!(c, _c);
debug!("ConstInferUnifier: c={:?}", c);
match c.val {
match c.val() {
ty::ConstKind::Infer(InferConst::Var(vid)) => {
// Check if the current unification would end up
// unifying `target_vid` with a const which contains
@ -985,7 +985,7 @@ impl<'tcx> TypeRelation<'tcx> for ConstInferUnifier<'_, 'tcx> {
},
},
);
Ok(self.tcx().mk_const_var(new_var_id, c.ty))
Ok(self.tcx().mk_const_var(new_var_id, c.ty()))
}
}
}
@ -1000,8 +1000,8 @@ impl<'tcx> TypeRelation<'tcx> for ConstInferUnifier<'_, 'tcx> {
substs,
substs,
)?;
Ok(self.tcx().mk_const(ty::Const {
ty: c.ty,
Ok(self.tcx().mk_const(ty::ConstS {
ty: c.ty(),
val: ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs, promoted }),
}))
}

View file

@ -117,9 +117,9 @@ impl<'tcx> TypeRelation<'tcx> for Equate<'_, '_, 'tcx> {
fn consts(
&mut self,
a: &'tcx ty::Const<'tcx>,
b: &'tcx ty::Const<'tcx>,
) -> RelateResult<'tcx, &'tcx ty::Const<'tcx>> {
a: ty::Const<'tcx>,
b: ty::Const<'tcx>,
) -> RelateResult<'tcx, ty::Const<'tcx>> {
self.fields.infcx.super_combine_consts(self, a, b)
}
@ -143,7 +143,7 @@ impl<'tcx> TypeRelation<'tcx> for Equate<'_, '_, 'tcx> {
}
impl<'tcx> ConstEquateRelation<'tcx> for Equate<'_, '_, 'tcx> {
fn const_equate_obligation(&mut self, a: &'tcx ty::Const<'tcx>, b: &'tcx ty::Const<'tcx>) {
fn const_equate_obligation(&mut self, a: ty::Const<'tcx>, b: ty::Const<'tcx>) {
self.fields.add_const_equate_obligation(self.a_is_expected, a, b);
}
}

View file

@ -239,7 +239,7 @@ pub fn unexpected_hidden_region_diagnostic<'tcx>(
);
// Explain the region we are capturing.
match hidden_region {
match *hidden_region {
ty::ReEmpty(ty::UniverseIndex::ROOT) => {
// All lifetimes shorter than the function body are `empty` in
// lexical region resolution. The default explanation of "an empty
@ -515,7 +515,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
Err(NonTrivialPath)
}
fn print_const(self, _ct: &'tcx ty::Const<'tcx>) -> Result<Self::Const, Self::Error> {
fn print_const(self, _ct: ty::Const<'tcx>) -> Result<Self::Const, Self::Error> {
Err(NonTrivialPath)
}
@ -915,13 +915,13 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
) -> Option<()> {
for (i, ta) in sub.types().enumerate() {
if ta == other_ty {
self.highlight_outer(&mut t1_out, &mut t2_out, path, sub, i, &other_ty);
self.highlight_outer(&mut t1_out, &mut t2_out, path, sub, i, other_ty);
return Some(());
}
if let ty::Adt(def, _) = ta.kind() {
let path_ = self.tcx.def_path_str(def.did);
if path_ == other_path {
self.highlight_outer(&mut t1_out, &mut t2_out, path, sub, i, &other_ty);
self.highlight_outer(&mut t1_out, &mut t2_out, path, sub, i, other_ty);
return Some(());
}
}
@ -1036,7 +1036,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
let len2 = sig2.inputs().len();
if len1 == len2 {
for (i, (l, r)) in iter::zip(sig1.inputs(), sig2.inputs()).enumerate() {
let (x1, x2) = self.cmp(l, r);
let (x1, x2) = self.cmp(*l, *r);
(values.0).0.extend(x1.0);
(values.1).0.extend(x2.0);
self.push_comma(&mut values.0, &mut values.1, len1, i);
@ -1114,7 +1114,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
}
fn push_ty_ref<'tcx>(
region: &ty::Region<'tcx>,
region: ty::Region<'tcx>,
ty: Ty<'tcx>,
mutbl: hir::Mutability,
s: &mut DiagnosticStyledString,
@ -1263,7 +1263,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
path1.clone(),
sub_no_defaults_1,
path2.clone(),
&t2,
t2,
)
.is_some()
{
@ -1281,7 +1281,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
path2,
sub_no_defaults_2,
path1,
&t1,
t1,
)
.is_some()
{
@ -1333,26 +1333,26 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
}
// When finding T != &T, highlight only the borrow
(&ty::Ref(r1, ref_ty1, mutbl1), _) if equals(&ref_ty1, &t2) => {
(&ty::Ref(r1, ref_ty1, mutbl1), _) if equals(ref_ty1, t2) => {
let mut values = (DiagnosticStyledString::new(), DiagnosticStyledString::new());
push_ty_ref(&r1, ref_ty1, mutbl1, &mut values.0);
push_ty_ref(r1, ref_ty1, mutbl1, &mut values.0);
values.1.push_normal(t2.to_string());
values
}
(_, &ty::Ref(r2, ref_ty2, mutbl2)) if equals(&t1, &ref_ty2) => {
(_, &ty::Ref(r2, ref_ty2, mutbl2)) if equals(t1, ref_ty2) => {
let mut values = (DiagnosticStyledString::new(), DiagnosticStyledString::new());
values.0.push_normal(t1.to_string());
push_ty_ref(&r2, ref_ty2, mutbl2, &mut values.1);
push_ty_ref(r2, ref_ty2, mutbl2, &mut values.1);
values
}
// When encountering &T != &mut T, highlight only the borrow
(&ty::Ref(r1, ref_ty1, mutbl1), &ty::Ref(r2, ref_ty2, mutbl2))
if equals(&ref_ty1, &ref_ty2) =>
if equals(ref_ty1, ref_ty2) =>
{
let mut values = (DiagnosticStyledString::new(), DiagnosticStyledString::new());
push_ty_ref(&r1, ref_ty1, mutbl1, &mut values.0);
push_ty_ref(&r2, ref_ty2, mutbl2, &mut values.1);
push_ty_ref(r1, ref_ty1, mutbl1, &mut values.0);
push_ty_ref(r2, ref_ty2, mutbl2, &mut values.1);
values
}
@ -1923,7 +1923,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
.iter()
.filter(|field| field.vis.is_accessible_from(field.did, self.tcx))
.map(|field| (field.name, field.ty(self.tcx, expected_substs)))
.find(|(_, ty)| same_type_modulo_infer(ty, exp_found.found))
.find(|(_, ty)| same_type_modulo_infer(*ty, exp_found.found))
{
if let ObligationCauseCode::Pattern { span: Some(span), .. } = *cause.code() {
if let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span) {
@ -2116,7 +2116,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
let [expected_tup_elem] = &expected.tuple_fields().collect::<Vec<_>>()[..]
else { return };
if !same_type_modulo_infer(expected_tup_elem, found) {
if !same_type_modulo_infer(*expected_tup_elem, found) {
return;
}

View file

@ -369,7 +369,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
pub fn extract_inference_diagnostics_data(
&self,
arg: GenericArg<'tcx>,
highlight: Option<ty::print::RegionHighlightMode>,
highlight: Option<ty::print::RegionHighlightMode<'tcx>>,
) -> InferenceDiagnosticsData {
match arg.unpack() {
GenericArgKind::Type(ty) => {
@ -409,7 +409,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
}
}
GenericArgKind::Const(ct) => {
match ct.val {
match ct.val() {
ty::ConstKind::Infer(InferConst::Var(vid)) => {
let origin = self
.inner
@ -459,7 +459,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
}
_ => {}
},
GenericArgKind::Const(c) => match c.val {
GenericArgKind::Const(c) => match c.val() {
ty::ConstKind::Infer(InferConst::Var(_)) => {
return self.extract_inference_diagnostics_data(s, None);
}
@ -935,9 +935,9 @@ impl<'tcx> ResolvedTypeParamEraser<'tcx> {
}
/// Replace not yet inferred const params with their def name.
fn replace_infers(&self, c: &'tcx Const<'tcx>, index: u32, name: Symbol) -> &'tcx Const<'tcx> {
match c.val {
ty::ConstKind::Infer(..) => self.tcx().mk_const_param(index, name, c.ty),
fn replace_infers(&self, c: Const<'tcx>, index: u32, name: Symbol) -> Const<'tcx> {
match c.val() {
ty::ConstKind::Infer(..) => self.tcx().mk_const_param(index, name, c.ty()),
_ => c,
}
}
@ -962,7 +962,7 @@ impl<'tcx> TypeFolder<'tcx> for ResolvedTypeParamEraser<'tcx> {
.map(|(subst, param)| match &(subst.unpack(), &param.kind) {
(_, ty::GenericParamDefKind::Type { has_default: true, .. }) => subst,
(crate::infer::GenericArgKind::Const(c), _) => {
self.replace_infers(c, param.index, param.name).into()
self.replace_infers(*c, param.index, param.name).into()
}
_ => subst.super_fold_with(self),
})
@ -985,7 +985,7 @@ impl<'tcx> TypeFolder<'tcx> for ResolvedTypeParamEraser<'tcx> {
}
}
ty::Ref(_, ty, _) => {
let ty = self.fold_ty(ty);
let ty = self.fold_ty(*ty);
match ty.kind() {
// Avoid `&_`, these can be safely presented as `_`.
ty::Error(_) => self.tcx().ty_error(),
@ -1002,7 +1002,7 @@ impl<'tcx> TypeFolder<'tcx> for ResolvedTypeParamEraser<'tcx> {
| ty::Projection(_)
| ty::Never => t.super_fold_with(self),
ty::Array(ty, c) => {
self.tcx().mk_ty(ty::Array(self.fold_ty(ty), self.replace_infers(c, 0, sym::N)))
self.tcx().mk_ty(ty::Array(self.fold_ty(*ty), self.replace_infers(*c, 0, sym::N)))
}
// We don't want to hide type params that haven't been resolved yet.
// This would be the type that will be written out with the type param

View file

@ -10,7 +10,7 @@ use rustc_data_structures::stable_set::FxHashSet;
use rustc_errors::{Applicability, ErrorReported};
use rustc_hir as hir;
use rustc_hir::intravisit::Visitor;
use rustc_middle::ty::{self, TypeVisitor};
use rustc_middle::ty::TypeVisitor;
use rustc_span::MultiSpan;
impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
@ -22,7 +22,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
RegionResolutionError::ConcreteFailure(origin, sub, sup) => (origin, sub, sup),
_ => return None,
};
if *sub != ty::RegionKind::ReStatic {
if !sub.is_static() {
return None;
}
let cause = match origin {

View file

@ -66,9 +66,9 @@ impl<'cx, 'tcx> NiceRegionError<'cx, 'tcx> {
pub fn regions(&self) -> Option<(Span, ty::Region<'tcx>, ty::Region<'tcx>)> {
match (&self.error, self.regions) {
(Some(ConcreteFailure(origin, sub, sup)), None) => Some((origin.span(), sub, sup)),
(Some(ConcreteFailure(origin, sub, sup)), None) => Some((origin.span(), *sub, *sup)),
(Some(SubSupConflict(_, _, origin, sub, _, sup, _)), None) => {
Some((origin.span(), sub, sup))
Some((origin.span(), *sub, *sup))
}
(None, Some((span, sub, sup))) => Some((span, sub, sup)),
_ => None,

View file

@ -48,7 +48,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
// Suggesting to add a `'static` lifetime to a parameter is nearly always incorrect,
// and can steer users down the wrong path.
if *named == ty::ReStatic {
if named.is_static() {
return None;
}

View file

@ -3,13 +3,14 @@ use crate::infer::lexical_region_resolve::RegionResolutionError;
use crate::infer::ValuePairs;
use crate::infer::{SubregionOrigin, TypeTrace};
use crate::traits::{ObligationCause, ObligationCauseCode};
use rustc_data_structures::intern::Interned;
use rustc_errors::DiagnosticBuilder;
use rustc_hir::def::Namespace;
use rustc_hir::def_id::DefId;
use rustc_middle::ty::error::ExpectedFound;
use rustc_middle::ty::print::{FmtPrinter, Print, RegionHighlightMode};
use rustc_middle::ty::subst::SubstsRef;
use rustc_middle::ty::{self, TyCtxt};
use rustc_middle::ty::{self, RePlaceholder, ReVar, Region, TyCtxt};
use std::fmt::{self, Write};
@ -31,15 +32,15 @@ impl<'tcx> NiceRegionError<'_, 'tcx> {
vid,
_,
SubregionOrigin::Subtype(box TypeTrace { cause, values }),
sub_placeholder @ ty::RePlaceholder(_),
sub_placeholder @ Region(Interned(RePlaceholder(_), _)),
_,
sup_placeholder @ ty::RePlaceholder(_),
sup_placeholder @ Region(Interned(RePlaceholder(_), _)),
_,
)) => self.try_report_trait_placeholder_mismatch(
Some(self.tcx().mk_region(ty::ReVar(*vid))),
Some(self.tcx().mk_region(ReVar(*vid))),
cause,
Some(sub_placeholder),
Some(sup_placeholder),
Some(*sub_placeholder),
Some(*sup_placeholder),
values,
),
@ -47,14 +48,14 @@ impl<'tcx> NiceRegionError<'_, 'tcx> {
vid,
_,
SubregionOrigin::Subtype(box TypeTrace { cause, values }),
sub_placeholder @ ty::RePlaceholder(_),
sub_placeholder @ Region(Interned(RePlaceholder(_), _)),
_,
_,
_,
)) => self.try_report_trait_placeholder_mismatch(
Some(self.tcx().mk_region(ty::ReVar(*vid))),
Some(self.tcx().mk_region(ReVar(*vid))),
cause,
Some(sub_placeholder),
Some(*sub_placeholder),
None,
values,
),
@ -65,10 +66,10 @@ impl<'tcx> NiceRegionError<'_, 'tcx> {
SubregionOrigin::Subtype(box TypeTrace { cause, values }),
_,
_,
sup_placeholder @ ty::RePlaceholder(_),
sup_placeholder @ Region(Interned(RePlaceholder(_), _)),
_,
)) => self.try_report_trait_placeholder_mismatch(
Some(self.tcx().mk_region(ty::ReVar(*vid))),
Some(self.tcx().mk_region(ReVar(*vid))),
cause,
None,
Some(*sup_placeholder),
@ -81,10 +82,10 @@ impl<'tcx> NiceRegionError<'_, 'tcx> {
_,
_,
SubregionOrigin::Subtype(box TypeTrace { cause, values }),
sup_placeholder @ ty::RePlaceholder(_),
sup_placeholder @ Region(Interned(RePlaceholder(_), _)),
_,
)) => self.try_report_trait_placeholder_mismatch(
Some(self.tcx().mk_region(ty::ReVar(*vid))),
Some(self.tcx().mk_region(ReVar(*vid))),
cause,
None,
Some(*sup_placeholder),
@ -96,9 +97,9 @@ impl<'tcx> NiceRegionError<'_, 'tcx> {
_,
_,
SubregionOrigin::Subtype(box TypeTrace { cause, values }),
sup_placeholder @ ty::RePlaceholder(_),
sup_placeholder @ Region(Interned(RePlaceholder(_), _)),
)) => self.try_report_trait_placeholder_mismatch(
Some(self.tcx().mk_region(ty::ReVar(*vid))),
Some(self.tcx().mk_region(ReVar(*vid))),
cause,
None,
Some(*sup_placeholder),
@ -107,8 +108,8 @@ impl<'tcx> NiceRegionError<'_, 'tcx> {
Some(RegionResolutionError::ConcreteFailure(
SubregionOrigin::Subtype(box TypeTrace { cause, values }),
sub_region @ ty::RePlaceholder(_),
sup_region @ ty::RePlaceholder(_),
sub_region @ Region(Interned(RePlaceholder(_), _)),
sup_region @ Region(Interned(RePlaceholder(_), _)),
)) => self.try_report_trait_placeholder_mismatch(
None,
cause,
@ -119,12 +120,12 @@ impl<'tcx> NiceRegionError<'_, 'tcx> {
Some(RegionResolutionError::ConcreteFailure(
SubregionOrigin::Subtype(box TypeTrace { cause, values }),
sub_region @ ty::RePlaceholder(_),
sub_region @ Region(Interned(RePlaceholder(_), _)),
sup_region,
)) => self.try_report_trait_placeholder_mismatch(
(!sup_region.has_name()).then_some(sup_region),
(!sup_region.has_name()).then_some(*sup_region),
cause,
Some(sub_region),
Some(*sub_region),
None,
values,
),
@ -132,12 +133,12 @@ impl<'tcx> NiceRegionError<'_, 'tcx> {
Some(RegionResolutionError::ConcreteFailure(
SubregionOrigin::Subtype(box TypeTrace { cause, values }),
sub_region,
sup_region @ ty::RePlaceholder(_),
sup_region @ Region(Interned(RePlaceholder(_), _)),
)) => self.try_report_trait_placeholder_mismatch(
(!sub_region.has_name()).then_some(sub_region),
(!sub_region.has_name()).then_some(*sub_region),
cause,
None,
Some(sup_region),
Some(*sup_region),
values,
),
@ -147,10 +148,10 @@ impl<'tcx> NiceRegionError<'_, 'tcx> {
fn try_report_trait_placeholder_mismatch(
&self,
vid: Option<ty::Region<'tcx>>,
vid: Option<Region<'tcx>>,
cause: &ObligationCause<'tcx>,
sub_placeholder: Option<ty::Region<'tcx>>,
sup_placeholder: Option<ty::Region<'tcx>>,
sub_placeholder: Option<Region<'tcx>>,
sup_placeholder: Option<Region<'tcx>>,
value_pairs: &ValuePairs<'tcx>,
) -> Option<DiagnosticBuilder<'tcx>> {
let (expected_substs, found_substs, trait_def_id) = match value_pairs {
@ -193,10 +194,10 @@ impl<'tcx> NiceRegionError<'_, 'tcx> {
#[instrument(level = "debug", skip(self))]
fn report_trait_placeholder_mismatch(
&self,
vid: Option<ty::Region<'tcx>>,
vid: Option<Region<'tcx>>,
cause: &ObligationCause<'tcx>,
sub_placeholder: Option<ty::Region<'tcx>>,
sup_placeholder: Option<ty::Region<'tcx>>,
sub_placeholder: Option<Region<'tcx>>,
sup_placeholder: Option<Region<'tcx>>,
trait_def_id: DefId,
expected_substs: SubstsRef<'tcx>,
actual_substs: SubstsRef<'tcx>,
@ -306,13 +307,13 @@ impl<'tcx> NiceRegionError<'_, 'tcx> {
fn explain_actual_impl_that_was_found(
&self,
err: &mut DiagnosticBuilder<'_>,
sub_placeholder: Option<ty::Region<'tcx>>,
sup_placeholder: Option<ty::Region<'tcx>>,
sub_placeholder: Option<Region<'tcx>>,
sup_placeholder: Option<Region<'tcx>>,
has_sub: Option<usize>,
has_sup: Option<usize>,
expected_trait_ref: ty::TraitRef<'tcx>,
actual_trait_ref: ty::TraitRef<'tcx>,
vid: Option<ty::Region<'tcx>>,
vid: Option<Region<'tcx>>,
expected_has_vid: Option<usize>,
actual_has_vid: Option<usize>,
any_self_ty_has_vid: bool,
@ -322,7 +323,7 @@ impl<'tcx> NiceRegionError<'_, 'tcx> {
#[derive(Copy, Clone)]
struct Highlighted<'tcx, T> {
tcx: TyCtxt<'tcx>,
highlight: RegionHighlightMode,
highlight: RegionHighlightMode<'tcx>,
value: T,
}
@ -366,7 +367,7 @@ impl<'tcx> NiceRegionError<'_, 'tcx> {
let highlight_trait_ref = |trait_ref| Highlighted {
tcx: self.tcx(),
highlight: RegionHighlightMode::default(),
highlight: RegionHighlightMode::new(self.tcx()),
value: trait_ref,
};

View file

@ -10,8 +10,7 @@ use rustc_hir::def_id::DefId;
use rustc_hir::intravisit::{walk_ty, Visitor};
use rustc_hir::{self as hir, GenericBound, Item, ItemKind, Lifetime, LifetimeName, Node, TyKind};
use rustc_middle::ty::{
self, AssocItemContainer, RegionKind, StaticLifetimeVisitor, Ty, TyCtxt, TypeFoldable,
TypeVisitor,
self, AssocItemContainer, StaticLifetimeVisitor, Ty, TyCtxt, TypeFoldable, TypeVisitor,
};
use rustc_span::symbol::Ident;
use rustc_span::{MultiSpan, Span};
@ -33,25 +32,23 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
sup_origin,
sup_r,
spans,
) if **sub_r == RegionKind::ReStatic => {
(var_origin, sub_origin, sub_r, sup_origin, sup_r, spans)
}
) if sub_r.is_static() => (var_origin, sub_origin, sub_r, sup_origin, sup_r, spans),
RegionResolutionError::ConcreteFailure(
SubregionOrigin::Subtype(box TypeTrace { cause, .. }),
sub_r,
sup_r,
) if **sub_r == RegionKind::ReStatic => {
) if sub_r.is_static() => {
// This is for an implicit `'static` requirement coming from `impl dyn Trait {}`.
if let ObligationCauseCode::UnifyReceiver(ctxt) = cause.code() {
// This may have a closure and it would cause ICE
// through `find_param_with_region` (#78262).
let anon_reg_sup = tcx.is_suitable_region(sup_r)?;
let anon_reg_sup = tcx.is_suitable_region(*sup_r)?;
let fn_returns = tcx.return_type_impl_or_dyn_traits(anon_reg_sup.def_id);
if fn_returns.is_empty() {
return None;
}
let param = self.find_param_with_region(sup_r, sub_r)?;
let param = self.find_param_with_region(*sup_r, *sub_r)?;
let lifetime = if sup_r.has_name() {
format!("lifetime `{}`", sup_r)
} else {
@ -101,11 +98,11 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
"try_report_static_impl_trait(var={:?}, sub={:?} {:?} sup={:?} {:?})",
var_origin, sub_origin, sub_r, sup_origin, sup_r
);
let anon_reg_sup = tcx.is_suitable_region(sup_r)?;
let anon_reg_sup = tcx.is_suitable_region(*sup_r)?;
debug!("try_report_static_impl_trait: anon_reg_sup={:?}", anon_reg_sup);
let sp = var_origin.span();
let return_sp = sub_origin.span();
let param = self.find_param_with_region(sup_r, sub_r)?;
let param = self.find_param_with_region(*sup_r, *sub_r)?;
let (lifetime_name, lifetime) = if sup_r.has_name() {
(sup_r.to_string(), format!("lifetime `{}`", sup_r))
} else {
@ -560,7 +557,7 @@ pub(super) struct TraitObjectVisitor(pub(super) FxHashSet<DefId>);
impl<'tcx> TypeVisitor<'tcx> for TraitObjectVisitor {
fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
match t.kind() {
ty::Dynamic(preds, RegionKind::ReStatic) => {
ty::Dynamic(preds, re) if re.is_static() => {
if let Some(def_id) = preds.principal_def_id() {
self.0.insert(def_id);
}

View file

@ -42,8 +42,8 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
if sup_expected_found == sub_expected_found {
self.emit_err(
var_origin.span(),
sub_expected,
sub_found,
*sub_expected,
*sub_found,
*trait_item_def_id,
);
return Some(ErrorReported);
@ -81,21 +81,21 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
// Mark all unnamed regions in the type with a number.
// This diagnostic is called in response to lifetime errors, so be informative.
struct HighlightBuilder {
highlight: RegionHighlightMode,
struct HighlightBuilder<'tcx> {
highlight: RegionHighlightMode<'tcx>,
counter: usize,
}
impl HighlightBuilder {
fn build(ty: Ty<'_>) -> RegionHighlightMode {
impl<'tcx> HighlightBuilder<'tcx> {
fn build(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> RegionHighlightMode<'tcx> {
let mut builder =
HighlightBuilder { highlight: RegionHighlightMode::default(), counter: 1 };
HighlightBuilder { highlight: RegionHighlightMode::new(tcx), counter: 1 };
builder.visit_ty(ty);
builder.highlight
}
}
impl<'tcx> ty::fold::TypeVisitor<'tcx> for HighlightBuilder {
impl<'tcx> ty::fold::TypeVisitor<'tcx> for HighlightBuilder<'tcx> {
fn visit_region(&mut self, r: ty::Region<'tcx>) -> ControlFlow<Self::BreakTy> {
if !r.has_name() && self.counter <= 3 {
self.highlight.highlighting_region(r, self.counter);
@ -105,12 +105,12 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
}
}
let expected_highlight = HighlightBuilder::build(expected);
let expected_highlight = HighlightBuilder::build(self.tcx(), expected);
let expected = self
.infcx
.extract_inference_diagnostics_data(expected.into(), Some(expected_highlight))
.name;
let found_highlight = HighlightBuilder::build(found);
let found_highlight = HighlightBuilder::build(self.tcx(), found);
let found =
self.infcx.extract_inference_diagnostics_data(found.into(), Some(found_highlight)).name;

View file

@ -70,7 +70,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
let ty = fn_sig.inputs()[index];
let mut found_anon_region = false;
let new_param_ty = self.tcx().fold_regions(ty, &mut false, |r, _| {
if *r == *anon_region {
if r == anon_region {
found_anon_region = true;
replace_region
} else {

View file

@ -115,7 +115,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
infer::Subtype(box trace) => {
let terr = TypeError::RegionsDoesNotOutlive(sup, sub);
let mut err = self.report_and_explain_type_error(trace, &terr);
match (sub, sup) {
match (*sub, *sup) {
(ty::RePlaceholder(_), ty::RePlaceholder(_)) => {}
(ty::RePlaceholder(_), _) => {
note_and_explain_region(

View file

@ -41,8 +41,8 @@ pub struct FreeRegionMap<'tcx> {
}
impl<'tcx> FreeRegionMap<'tcx> {
pub fn elements(&self) -> impl Iterator<Item = &Region<'tcx>> {
self.relation.elements()
pub fn elements(&self) -> impl Iterator<Item = Region<'tcx>> + '_ {
self.relation.elements().copied()
}
pub fn is_empty(&self) -> bool {
@ -91,7 +91,7 @@ impl<'tcx> FreeRegionMap<'tcx> {
/// True for free regions other than `'static`.
pub fn is_free(&self, r: Region<'_>) -> bool {
matches!(r, ty::ReEarlyBound(_) | ty::ReFree(_))
matches!(*r, ty::ReEarlyBound(_) | ty::ReFree(_))
}
/// True if `r` is a free region or static of the sort that this

View file

@ -46,7 +46,7 @@ pub struct TypeFreshener<'a, 'tcx> {
ty_freshen_count: u32,
const_freshen_count: u32,
ty_freshen_map: FxHashMap<ty::InferTy, Ty<'tcx>>,
const_freshen_map: FxHashMap<ty::InferConst<'tcx>, &'tcx ty::Const<'tcx>>,
const_freshen_map: FxHashMap<ty::InferConst<'tcx>, ty::Const<'tcx>>,
keep_static: bool,
}
@ -89,11 +89,11 @@ impl<'a, 'tcx> TypeFreshener<'a, 'tcx> {
fn freshen_const<F>(
&mut self,
opt_ct: Option<&'tcx ty::Const<'tcx>>,
opt_ct: Option<ty::Const<'tcx>>,
key: ty::InferConst<'tcx>,
freshener: F,
ty: Ty<'tcx>,
) -> &'tcx ty::Const<'tcx>
) -> ty::Const<'tcx>
where
F: FnOnce(u32) -> ty::InferConst<'tcx>,
{
@ -221,8 +221,8 @@ impl<'a, 'tcx> TypeFolder<'tcx> for TypeFreshener<'a, 'tcx> {
}
}
fn fold_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
match ct.val {
fn fold_const(&mut self, ct: ty::Const<'tcx>) -> ty::Const<'tcx> {
match ct.val() {
ty::ConstKind::Infer(ty::InferConst::Var(v)) => {
let opt_ct = self
.infcx
@ -236,7 +236,7 @@ impl<'a, 'tcx> TypeFolder<'tcx> for TypeFreshener<'a, 'tcx> {
opt_ct,
ty::InferConst::Var(v),
ty::InferConst::Fresh,
ct.ty,
ct.ty(),
);
}
ty::ConstKind::Infer(ty::InferConst::Fresh(i)) => {

View file

@ -230,14 +230,14 @@ impl<'a, 'tcx> TypeFolder<'tcx> for InferenceFudger<'a, 'tcx> {
r
}
fn fold_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
if let ty::Const { val: ty::ConstKind::Infer(ty::InferConst::Var(vid)), ty } = ct {
fn fold_const(&mut self, ct: ty::Const<'tcx>) -> ty::Const<'tcx> {
if let ty::ConstKind::Infer(ty::InferConst::Var(vid)) = ct.val() {
if self.const_vars.0.contains(&vid) {
// This variable was created during the fudging.
// Recreate it with a fresh variable here.
let idx = (vid.index - self.const_vars.0.start.index) as usize;
let origin = self.const_vars.1[idx];
self.infcx.next_const_var(ty, origin)
self.infcx.next_const_var(ct.ty(), origin)
} else {
ct
}

View file

@ -78,9 +78,9 @@ impl<'tcx> TypeRelation<'tcx> for Glb<'_, '_, 'tcx> {
fn consts(
&mut self,
a: &'tcx ty::Const<'tcx>,
b: &'tcx ty::Const<'tcx>,
) -> RelateResult<'tcx, &'tcx ty::Const<'tcx>> {
a: ty::Const<'tcx>,
b: ty::Const<'tcx>,
) -> RelateResult<'tcx, ty::Const<'tcx>> {
self.fields.infcx.super_combine_consts(self, a, b)
}
@ -120,7 +120,7 @@ impl<'combine, 'infcx, 'tcx> LatticeDir<'infcx, 'tcx> for Glb<'combine, 'infcx,
}
impl<'tcx> ConstEquateRelation<'tcx> for Glb<'_, '_, 'tcx> {
fn const_equate_obligation(&mut self, a: &'tcx ty::Const<'tcx>, b: &'tcx ty::Const<'tcx>) {
fn const_equate_obligation(&mut self, a: ty::Const<'tcx>, b: ty::Const<'tcx>) {
self.fields.add_const_equate_obligation(self.a_is_expected, a, b);
}
}

View file

@ -94,7 +94,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
};
let fld_c = |bound_var: ty::BoundVar, ty| {
self.tcx.mk_const(ty::Const {
self.tcx.mk_const(ty::ConstS {
val: ty::ConstKind::Placeholder(ty::PlaceholderConst {
universe: next_universe,
name: ty::BoundConst { var: bound_var, ty },

View file

@ -13,6 +13,7 @@ use rustc_data_structures::fx::FxHashSet;
use rustc_data_structures::graph::implementation::{
Direction, Graph, NodeIndex, INCOMING, OUTGOING,
};
use rustc_data_structures::intern::Interned;
use rustc_index::vec::{Idx, IndexVec};
use rustc_middle::ty::fold::TypeFoldable;
use rustc_middle::ty::{self, Ty, TyCtxt};
@ -250,8 +251,8 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
changes.push(b_vid);
}
if let Some(a_vid) = a_vid {
match *b_data {
VarValue::Value(ReStatic) | VarValue::ErrorValue => (),
match b_data {
VarValue::Value(Region(Interned(ReStatic, _))) | VarValue::ErrorValue => (),
_ => {
constraints[a_vid].push((a_vid, b_vid));
constraints[b_vid].push((a_vid, b_vid));
@ -270,7 +271,10 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
if self.expand_node(a_region, b_vid, b_data) {
changes.push(b_vid);
}
!matches!(b_data, VarValue::Value(ReStatic) | VarValue::ErrorValue)
!matches!(
b_data,
VarValue::Value(Region(Interned(ReStatic, _))) | VarValue::ErrorValue
)
});
}
}
@ -301,8 +305,8 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
// check below for a common case, here purely as an
// optimization.
let b_universe = self.var_infos[b_vid].universe;
if let ReEmpty(a_universe) = a_region {
if *a_universe == b_universe {
if let ReEmpty(a_universe) = *a_region {
if a_universe == b_universe {
return false;
}
}
@ -321,7 +325,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
// tighter bound than `'static`.
//
// (This might e.g. arise from being asked to prove `for<'a> { 'b: 'a }`.)
if let ty::RePlaceholder(p) = lub {
if let ty::RePlaceholder(p) = *lub {
if b_universe.cannot_name(p.universe) {
lub = self.tcx().lifetimes.re_static;
}
@ -372,12 +376,12 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
/// term "concrete regions").
#[instrument(level = "trace", skip(self))]
fn lub_concrete_regions(&self, a: Region<'tcx>, b: Region<'tcx>) -> Region<'tcx> {
let r = match (a, b) {
(&ReLateBound(..), _) | (_, &ReLateBound(..)) | (&ReErased, _) | (_, &ReErased) => {
let r = match (*a, *b) {
(ReLateBound(..), _) | (_, ReLateBound(..)) | (ReErased, _) | (_, ReErased) => {
bug!("cannot relate region: LUB({:?}, {:?})", a, b);
}
(&ReVar(v_id), _) | (_, &ReVar(v_id)) => {
(ReVar(v_id), _) | (_, ReVar(v_id)) => {
span_bug!(
self.var_infos[v_id].origin.span(),
"lub_concrete_regions invoked with non-concrete \
@ -387,27 +391,32 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
);
}
(&ReStatic, _) | (_, &ReStatic) => {
(ReStatic, _) | (_, ReStatic) => {
// nothing lives longer than `'static`
self.tcx().lifetimes.re_static
}
(&ReEmpty(_), r @ (ReEarlyBound(_) | ReFree(_)))
| (r @ (ReEarlyBound(_) | ReFree(_)), &ReEmpty(_)) => {
(ReEmpty(_), ReEarlyBound(_) | ReFree(_)) => {
// All empty regions are less than early-bound, free,
// and scope regions.
r
b
}
(&ReEmpty(a_ui), &ReEmpty(b_ui)) => {
(ReEarlyBound(_) | ReFree(_), ReEmpty(_)) => {
// All empty regions are less than early-bound, free,
// and scope regions.
a
}
(ReEmpty(a_ui), ReEmpty(b_ui)) => {
// Empty regions are ordered according to the universe
// they are associated with.
let ui = a_ui.min(b_ui);
self.tcx().mk_region(ReEmpty(ui))
}
(&ReEmpty(empty_ui), &RePlaceholder(placeholder))
| (&RePlaceholder(placeholder), &ReEmpty(empty_ui)) => {
(ReEmpty(empty_ui), RePlaceholder(placeholder))
| (RePlaceholder(placeholder), ReEmpty(empty_ui)) => {
// If this empty region is from a universe that can
// name the placeholder, then the placeholder is
// larger; otherwise, the only ancestor is `'static`.
@ -418,13 +427,13 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
}
}
(&ReEarlyBound(_) | &ReFree(_), &ReEarlyBound(_) | &ReFree(_)) => {
(ReEarlyBound(_) | ReFree(_), ReEarlyBound(_) | ReFree(_)) => {
self.region_rels.lub_free_regions(a, b)
}
// For these types, we cannot define any additional
// relationship:
(&RePlaceholder(..), _) | (_, &RePlaceholder(..)) => {
(RePlaceholder(..), _) | (_, RePlaceholder(..)) => {
if a == b {
a
} else {
@ -676,7 +685,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
let node_universe = self.var_infos[node_idx].universe;
for lower_bound in &lower_bounds {
let effective_lower_bound = if let ty::RePlaceholder(p) = lower_bound.region {
let effective_lower_bound = if let ty::RePlaceholder(p) = *lower_bound.region {
if node_universe.cannot_name(p.universe) {
self.tcx().lifetimes.re_static
} else {
@ -721,7 +730,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
.expect("lower_vid_bounds should at least include `node_idx`");
for upper_bound in &upper_bounds {
if let ty::RePlaceholder(p) = upper_bound.region {
if let ty::RePlaceholder(p) = *upper_bound.region {
if min_universe.cannot_name(p.universe) {
let origin = self.var_infos[node_idx].origin;
errors.push(RegionResolutionError::UpperBoundUniverseConflict(
@ -855,11 +864,11 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
}
VerifyBound::OutlivedBy(r) => {
self.sub_concrete_regions(min, var_values.normalize(self.tcx(), r))
self.sub_concrete_regions(min, var_values.normalize(self.tcx(), *r))
}
VerifyBound::IsEmpty => {
matches!(min, ty::ReEmpty(_))
matches!(*min, ty::ReEmpty(_))
}
VerifyBound::AnyBound(bs) => {
@ -884,8 +893,8 @@ impl<'tcx> LexicalRegionResolutions<'tcx> {
where
T: TypeFoldable<'tcx>,
{
tcx.fold_regions(value, &mut false, |r, _db| match r {
ty::ReVar(rid) => self.resolve_var(*rid),
tcx.fold_regions(value, &mut false, |r, _db| match *r {
ty::ReVar(rid) => self.resolve_var(rid),
_ => r,
})
}

View file

@ -78,9 +78,9 @@ impl<'tcx> TypeRelation<'tcx> for Lub<'_, '_, 'tcx> {
fn consts(
&mut self,
a: &'tcx ty::Const<'tcx>,
b: &'tcx ty::Const<'tcx>,
) -> RelateResult<'tcx, &'tcx ty::Const<'tcx>> {
a: ty::Const<'tcx>,
b: ty::Const<'tcx>,
) -> RelateResult<'tcx, ty::Const<'tcx>> {
self.fields.infcx.super_combine_consts(self, a, b)
}
@ -103,7 +103,7 @@ impl<'tcx> TypeRelation<'tcx> for Lub<'_, '_, 'tcx> {
}
impl<'tcx> ConstEquateRelation<'tcx> for Lub<'_, '_, 'tcx> {
fn const_equate_obligation(&mut self, a: &'tcx ty::Const<'tcx>, b: &'tcx ty::Const<'tcx>) {
fn const_equate_obligation(&mut self, a: ty::Const<'tcx>, b: ty::Const<'tcx>) {
self.fields.add_const_equate_obligation(self.a_is_expected, a, b);
}
}

View file

@ -382,7 +382,7 @@ impl<'tcx> ValuePairs<'tcx> {
found: ty::Term::Ty(found),
}) = self
{
Some((expected, found))
Some((*expected, *found))
} else {
None
}
@ -1079,11 +1079,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
self.tcx.mk_ty_var(vid)
}
pub fn next_const_var(
&self,
ty: Ty<'tcx>,
origin: ConstVariableOrigin,
) -> &'tcx ty::Const<'tcx> {
pub fn next_const_var(&self, ty: Ty<'tcx>, origin: ConstVariableOrigin) -> ty::Const<'tcx> {
self.tcx.mk_const_var(self.next_const_var_id(origin), ty)
}
@ -1092,7 +1088,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
ty: Ty<'tcx>,
origin: ConstVariableOrigin,
universe: ty::UniverseIndex,
) -> &'tcx ty::Const<'tcx> {
) -> ty::Const<'tcx> {
let vid = self
.inner
.borrow_mut()
@ -1435,7 +1431,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
pub fn probe_const_var(
&self,
vid: ty::ConstVid<'tcx>,
) -> Result<&'tcx ty::Const<'tcx>, ty::UniverseIndex> {
) -> Result<ty::Const<'tcx>, ty::UniverseIndex> {
match self.inner.borrow_mut().const_unification_table().probe_value(vid).val {
ConstVariableValue::Known { value } => Ok(value),
ConstVariableValue::Unknown { universe } => Err(universe),
@ -1501,8 +1497,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
pub fn report_mismatched_consts(
&self,
cause: &ObligationCause<'tcx>,
expected: &'tcx ty::Const<'tcx>,
actual: &'tcx ty::Const<'tcx>,
expected: ty::Const<'tcx>,
actual: ty::Const<'tcx>,
err: TypeError<'tcx>,
) -> DiagnosticBuilder<'tcx> {
let trace = TypeTrace::consts(cause, true, expected, actual);
@ -1756,8 +1752,8 @@ impl<'tcx> TyOrConstInferVar<'tcx> {
/// Tries to extract an inference variable from a constant, returns `None`
/// for constants other than `ty::ConstKind::Infer(_)` (or `InferConst::Fresh`).
pub fn maybe_from_const(ct: &'tcx ty::Const<'tcx>) -> Option<Self> {
match ct.val {
pub fn maybe_from_const(ct: ty::Const<'tcx>) -> Option<Self> {
match ct.val() {
ty::ConstKind::Infer(InferConst::Var(v)) => Some(TyOrConstInferVar::Const(v)),
_ => None,
}
@ -1777,13 +1773,13 @@ impl<'a, 'tcx> TypeFolder<'tcx> for ShallowResolver<'a, 'tcx> {
self.infcx.shallow_resolve_ty(ty)
}
fn fold_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
if let ty::Const { val: ty::ConstKind::Infer(InferConst::Var(vid)), .. } = ct {
fn fold_const(&mut self, ct: ty::Const<'tcx>) -> ty::Const<'tcx> {
if let ty::ConstKind::Infer(InferConst::Var(vid)) = ct.val() {
self.infcx
.inner
.borrow_mut()
.const_unification_table()
.probe_value(*vid)
.probe_value(vid)
.val
.known()
.unwrap_or(ct)
@ -1813,8 +1809,8 @@ impl<'tcx> TypeTrace<'tcx> {
pub fn consts(
cause: &ObligationCause<'tcx>,
a_is_expected: bool,
a: &'tcx ty::Const<'tcx>,
b: &'tcx ty::Const<'tcx>,
a: ty::Const<'tcx>,
b: ty::Const<'tcx>,
) -> TypeTrace<'tcx> {
TypeTrace {
cause: cause.clone(),

View file

@ -87,7 +87,7 @@ pub trait TypeRelatingDelegate<'tcx> {
info: ty::VarianceDiagInfo<'tcx>,
);
fn const_equate(&mut self, a: &'tcx ty::Const<'tcx>, b: &'tcx ty::Const<'tcx>);
fn const_equate(&mut self, a: ty::Const<'tcx>, b: ty::Const<'tcx>);
/// Creates a new universe index. Used when instantiating placeholders.
fn create_next_universe(&mut self) -> ty::UniverseIndex;
@ -244,8 +244,8 @@ where
scopes: &[BoundRegionScope<'tcx>],
) -> ty::Region<'tcx> {
debug!("replace_bound_regions(scopes={:?})", scopes);
if let ty::ReLateBound(debruijn, br) = r {
Self::lookup_bound_region(*debruijn, br, first_free_index, scopes)
if let ty::ReLateBound(debruijn, br) = *r {
Self::lookup_bound_region(debruijn, &br, first_free_index, scopes)
} else {
r
}
@ -450,7 +450,7 @@ impl<'tcx> VidValuePair<'tcx> for (ty::TyVid, Ty<'tcx>) {
where
D: TypeRelatingDelegate<'tcx>,
{
relate.relate(&generalized_ty, &self.value_ty())
relate.relate(generalized_ty, self.value_ty())
}
}
@ -482,7 +482,7 @@ impl<'tcx> VidValuePair<'tcx> for (Ty<'tcx>, ty::TyVid) {
where
D: TypeRelatingDelegate<'tcx>,
{
relate.relate(&self.value_ty(), &generalized_ty)
relate.relate(self.value_ty(), generalized_ty)
}
}
@ -609,16 +609,16 @@ where
fn consts(
&mut self,
a: &'tcx ty::Const<'tcx>,
mut b: &'tcx ty::Const<'tcx>,
) -> RelateResult<'tcx, &'tcx ty::Const<'tcx>> {
a: ty::Const<'tcx>,
mut b: ty::Const<'tcx>,
) -> RelateResult<'tcx, ty::Const<'tcx>> {
let a = self.infcx.shallow_resolve(a);
if !D::forbid_inference_vars() {
b = self.infcx.shallow_resolve(b);
}
match b.val {
match b.val() {
ty::ConstKind::Infer(InferConst::Var(_)) if D::forbid_inference_vars() => {
// Forbid inference variables in the RHS.
bug!("unexpected inference var {:?}", b)
@ -745,7 +745,7 @@ impl<'tcx, D> ConstEquateRelation<'tcx> for TypeRelating<'_, 'tcx, D>
where
D: TypeRelatingDelegate<'tcx>,
{
fn const_equate_obligation(&mut self, a: &'tcx ty::Const<'tcx>, b: &'tcx ty::Const<'tcx>) {
fn const_equate_obligation(&mut self, a: ty::Const<'tcx>, b: ty::Const<'tcx>) {
self.delegate.const_equate(a, b);
}
}
@ -779,9 +779,9 @@ impl<'me, 'tcx> TypeVisitor<'tcx> for ScopeInstantiator<'me, 'tcx> {
fn visit_region(&mut self, r: ty::Region<'tcx>) -> ControlFlow<Self::BreakTy> {
let ScopeInstantiator { bound_region_scope, next_region, .. } = self;
match r {
ty::ReLateBound(debruijn, br) if *debruijn == self.target_index => {
bound_region_scope.map.entry(*br).or_insert_with(|| next_region(*br));
match *r {
ty::ReLateBound(debruijn, br) if debruijn == self.target_index => {
bound_region_scope.map.entry(br).or_insert_with(|| next_region(br));
}
_ => {}
@ -963,8 +963,8 @@ where
) -> RelateResult<'tcx, ty::Region<'tcx>> {
debug!("TypeGeneralizer::regions(a={:?})", a);
if let ty::ReLateBound(debruijn, _) = a {
if *debruijn < self.first_free_index {
if let ty::ReLateBound(debruijn, _) = *a {
if debruijn < self.first_free_index {
return Ok(a);
}
}
@ -992,10 +992,10 @@ where
fn consts(
&mut self,
a: &'tcx ty::Const<'tcx>,
_: &'tcx ty::Const<'tcx>,
) -> RelateResult<'tcx, &'tcx ty::Const<'tcx>> {
match a.val {
a: ty::Const<'tcx>,
_: ty::Const<'tcx>,
) -> RelateResult<'tcx, ty::Const<'tcx>> {
match a.val() {
ty::ConstKind::Infer(InferConst::Var(_)) if D::forbid_inference_vars() => {
bug!("unexpected inference variable encountered in NLL generalization: {:?}", a);
}
@ -1010,7 +1010,7 @@ where
origin: var_value.origin,
val: ConstVariableValue::Unknown { universe: self.universe },
});
Ok(self.tcx().mk_const_var(new_var_id, a.ty))
Ok(self.tcx().mk_const_var(new_var_id, a.ty()))
}
}
}

View file

@ -2,8 +2,9 @@ use crate::infer::free_regions::FreeRegionMap;
use crate::infer::{GenericKind, InferCtxt};
use crate::traits::query::OutlivesBound;
use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::intern::Interned;
use rustc_hir as hir;
use rustc_middle::ty;
use rustc_middle::ty::{self, ReEarlyBound, ReFree, ReVar, Region};
use super::explicit_outlives_bounds;
@ -66,7 +67,7 @@ pub struct OutlivesEnvironment<'tcx> {
/// "Region-bound pairs" tracks outlives relations that are known to
/// be true, either because of explicit where-clauses like `T: 'a` or
/// because of implied bounds.
pub type RegionBoundPairs<'tcx> = Vec<(ty::Region<'tcx>, GenericKind<'tcx>)>;
pub type RegionBoundPairs<'tcx> = Vec<(Region<'tcx>, GenericKind<'tcx>)>;
impl<'a, 'tcx> OutlivesEnvironment<'tcx> {
pub fn new(param_env: ty::ParamEnv<'tcx>) -> Self {
@ -164,10 +165,10 @@ impl<'a, 'tcx> OutlivesEnvironment<'tcx> {
debug!("add_outlives_bounds: outlives_bound={:?}", outlives_bound);
match outlives_bound {
OutlivesBound::RegionSubRegion(
r_a @ (&ty::ReEarlyBound(_) | &ty::ReFree(_)),
&ty::ReVar(vid_b),
r_a @ (Region(Interned(ReEarlyBound(_), _)) | Region(Interned(ReFree(_), _))),
Region(Interned(ReVar(vid_b), _)),
) => {
infcx.expect("no infcx provided but region vars found").add_given(r_a, vid_b);
infcx.expect("no infcx provided but region vars found").add_given(r_a, *vid_b);
}
OutlivesBound::RegionSubParam(r_a, param_b) => {
self.region_bound_pairs_accum.push((r_a, GenericKind::Param(param_b)));

View file

@ -285,7 +285,7 @@ where
let origin = origin.clone();
match component {
Component::Region(region1) => {
self.delegate.push_sub_region_constraint(origin, region, region1);
self.delegate.push_sub_region_constraint(origin, region, *region1);
}
Component::Param(param_ty) => {
self.param_ty_must_outlive(origin, region, *param_ty);

View file

@ -154,17 +154,17 @@ impl<'me, 'tcx> LeakCheck<'me, 'tcx> {
let scc = self.mini_graph.sccs.scc(*leak_check_node);
// Set the universe of each SCC to be the minimum of its constituent universes
let universe = self.rcc.universe(region);
let universe = self.rcc.universe(*region);
debug!(
"assign_placeholder_values: scc={:?} universe={:?} region={:?}",
scc, universe, region
);
self.scc_universes[scc].take_min(universe, region);
self.scc_universes[scc].take_min(universe, *region);
// Detect those SCCs that directly contain a placeholder
if let ty::RePlaceholder(placeholder) = region {
if let ty::RePlaceholder(placeholder) = **region {
if self.universe_at_start_of_snapshot.cannot_name(placeholder.universe) {
self.assign_scc_value(scc, *placeholder)?;
self.assign_scc_value(scc, placeholder)?;
}
}
}

View file

@ -8,6 +8,7 @@ use super::{
};
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_data_structures::intern::Interned;
use rustc_data_structures::sync::Lrc;
use rustc_data_structures::undo_log::UndoLogs;
use rustc_data_structures::unify as ut;
@ -502,14 +503,15 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> {
self.make_subregion(origin, sup, sub);
match (sub, sup) {
(&ty::ReVar(sub), &ty::ReVar(sup)) => {
(Region(Interned(ReVar(sub), _)), Region(Interned(ReVar(sup), _))) => {
debug!("make_eqregion: unifying {:?} with {:?}", sub, sup);
self.unification_table().union(sub, sup);
self.unification_table().union(*sub, *sup);
self.any_unifications = true;
}
(&ty::ReVar(vid), value) | (value, &ty::ReVar(vid)) => {
(Region(Interned(ReVar(vid), _)), value)
| (value, Region(Interned(ReVar(vid), _))) => {
debug!("make_eqregion: unifying {:?} with {:?}", vid, value);
self.unification_table().union_value(vid, UnifiedRegion(Some(value)));
self.unification_table().union_value(*vid, UnifiedRegion(Some(value)));
self.any_unifications = true;
}
(_, _) => {}
@ -550,20 +552,20 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> {
// cannot add constraints once regions are resolved
debug!("origin = {:#?}", origin);
match (sub, sup) {
(&ReLateBound(..), _) | (_, &ReLateBound(..)) => {
match (*sub, *sup) {
(ReLateBound(..), _) | (_, ReLateBound(..)) => {
span_bug!(origin.span(), "cannot relate bound region: {:?} <= {:?}", sub, sup);
}
(_, &ReStatic) => {
(_, ReStatic) => {
// all regions are subregions of static, so we can ignore this
}
(&ReVar(sub_id), &ReVar(sup_id)) => {
(ReVar(sub_id), ReVar(sup_id)) => {
self.add_constraint(Constraint::VarSubVar(sub_id, sup_id), origin);
}
(_, &ReVar(sup_id)) => {
(_, ReVar(sup_id)) => {
self.add_constraint(Constraint::RegSubVar(sub, sup_id), origin);
}
(&ReVar(sub_id), _) => {
(ReVar(sub_id), _) => {
self.add_constraint(Constraint::VarSubReg(sub_id, sup), origin);
}
_ => {
@ -591,16 +593,12 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> {
) -> Region<'tcx> {
// cannot add constraints once regions are resolved
debug!("RegionConstraintCollector: lub_regions({:?}, {:?})", a, b);
match (a, b) {
(r @ &ReStatic, _) | (_, r @ &ReStatic) => {
r // nothing lives longer than static
}
_ if a == b => {
a // LUB(a,a) = a
}
_ => self.combine_vars(tcx, Lub, a, b, origin),
if a.is_static() || b.is_static() {
a // nothing lives longer than static
} else if a == b {
a // LUB(a,a) = a
} else {
self.combine_vars(tcx, Lub, a, b, origin)
}
}
@ -613,16 +611,14 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> {
) -> Region<'tcx> {
// cannot add constraints once regions are resolved
debug!("RegionConstraintCollector: glb_regions({:?}, {:?})", a, b);
match (a, b) {
(&ReStatic, r) | (r, &ReStatic) => {
r // static lives longer than everything else
}
_ if a == b => {
a // GLB(a,a) = a
}
_ => self.combine_vars(tcx, Glb, a, b, origin),
if a.is_static() {
b // static lives longer than everything else
} else if b.is_static() {
a // static lives longer than everything else
} else if a == b {
a // GLB(a,a) = a
} else {
self.combine_vars(tcx, Glb, a, b, origin)
}
}
@ -639,11 +635,11 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> {
tcx: TyCtxt<'tcx>,
region: ty::Region<'tcx>,
) -> ty::Region<'tcx> {
match region {
match *region {
ty::ReVar(rid) => {
let unified_region = self.unification_table().probe_value(*rid);
let unified_region = self.unification_table().probe_value(rid);
unified_region.0.unwrap_or_else(|| {
let root = self.unification_table().find(*rid).vid;
let root = self.unification_table().find(rid).vid;
tcx.reuse_or_mk_region(region, ty::ReVar(root))
})
}
@ -767,8 +763,7 @@ impl<'tcx> VerifyBound<'tcx> {
pub fn must_hold(&self) -> bool {
match self {
VerifyBound::IfEq(..) => false,
VerifyBound::OutlivedBy(ty::ReStatic) => true,
VerifyBound::OutlivedBy(_) => false,
VerifyBound::OutlivedBy(re) => re.is_static(),
VerifyBound::IsEmpty => false,
VerifyBound::AnyBound(bs) => bs.iter().any(|b| b.must_hold()),
VerifyBound::AllBounds(bs) => bs.iter().all(|b| b.must_hold()),

View file

@ -39,7 +39,7 @@ impl<'a, 'tcx> TypeFolder<'tcx> for OpportunisticVarResolver<'a, 'tcx> {
}
}
fn fold_const(&mut self, ct: &'tcx Const<'tcx>) -> &'tcx Const<'tcx> {
fn fold_const(&mut self, ct: Const<'tcx>) -> Const<'tcx> {
if !ct.has_infer_types_or_consts() {
ct // micro-optimize -- if there is nothing in this const that this fold affects...
} else {
@ -98,7 +98,7 @@ impl<'a, 'tcx> TypeFolder<'tcx> for OpportunisticRegionResolver<'a, 'tcx> {
}
}
fn fold_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
fn fold_const(&mut self, ct: ty::Const<'tcx>) -> ty::Const<'tcx> {
if !ct.has_infer_regions() {
ct // micro-optimize -- if there is nothing in this const that this fold affects...
} else {
@ -218,15 +218,12 @@ impl<'a, 'tcx> FallibleTypeFolder<'tcx> for FullTypeResolver<'a, 'tcx> {
}
}
fn try_fold_const(
&mut self,
c: &'tcx ty::Const<'tcx>,
) -> Result<&'tcx ty::Const<'tcx>, Self::Error> {
fn try_fold_const(&mut self, c: ty::Const<'tcx>) -> Result<ty::Const<'tcx>, Self::Error> {
if !c.needs_infer() {
Ok(c) // micro-optimize -- if there is nothing in this const that this fold affects...
} else {
let c = self.infcx.shallow_resolve(c);
match c.val {
match c.val() {
ty::ConstKind::Infer(InferConst::Var(vid)) => {
return Err(FixupError::UnresolvedConst(vid));
}

View file

@ -151,9 +151,9 @@ impl<'tcx> TypeRelation<'tcx> for Sub<'_, '_, 'tcx> {
fn consts(
&mut self,
a: &'tcx ty::Const<'tcx>,
b: &'tcx ty::Const<'tcx>,
) -> RelateResult<'tcx, &'tcx ty::Const<'tcx>> {
a: ty::Const<'tcx>,
b: ty::Const<'tcx>,
) -> RelateResult<'tcx, ty::Const<'tcx>> {
self.fields.infcx.super_combine_consts(self, a, b)
}
@ -170,7 +170,7 @@ impl<'tcx> TypeRelation<'tcx> for Sub<'_, '_, 'tcx> {
}
impl<'tcx> ConstEquateRelation<'tcx> for Sub<'_, '_, 'tcx> {
fn const_equate_obligation(&mut self, a: &'tcx ty::Const<'tcx>, b: &'tcx ty::Const<'tcx>) {
fn const_equate_obligation(&mut self, a: ty::Const<'tcx>, b: ty::Const<'tcx>) {
self.fields.add_const_equate_obligation(self.a_is_expected, a, b);
}
}

View file

@ -101,7 +101,7 @@ pub enum FulfillmentErrorCode<'tcx> {
CodeSelectionError(SelectionError<'tcx>),
CodeProjectionError(MismatchedProjectionTypes<'tcx>),
CodeSubtypeError(ExpectedFound<Ty<'tcx>>, TypeError<'tcx>), // always comes from a SubtypePredicate
CodeConstEquateError(ExpectedFound<&'tcx Const<'tcx>>, TypeError<'tcx>),
CodeConstEquateError(ExpectedFound<Const<'tcx>>, TypeError<'tcx>),
CodeAmbiguity,
}

View file

@ -2050,7 +2050,7 @@ impl ExplicitOutlivesRequirements {
inferred_outlives
.iter()
.filter_map(|(pred, _)| match pred.kind().skip_binder() {
ty::PredicateKind::RegionOutlives(ty::OutlivesPredicate(a, b)) => match a {
ty::PredicateKind::RegionOutlives(ty::OutlivesPredicate(a, b)) => match *a {
ty::ReEarlyBound(ebr) if ebr.index == index => Some(b),
_ => None,
},
@ -2111,10 +2111,10 @@ impl ExplicitOutlivesRequirements {
if let hir::GenericBound::Outlives(lifetime) = bound {
let is_inferred = match tcx.named_region(lifetime.hir_id) {
Some(Region::Static) if infer_static => {
inferred_outlives.iter().any(|r| matches!(r, ty::ReStatic))
inferred_outlives.iter().any(|r| matches!(**r, ty::ReStatic))
}
Some(Region::EarlyBound(index, ..)) => inferred_outlives.iter().any(|r| {
if let ty::ReEarlyBound(ebr) = r { ebr.index == index } else { false }
if let ty::ReEarlyBound(ebr) = **r { ebr.index == index } else { false }
}),
_ => false,
};
@ -2895,26 +2895,22 @@ impl ClashingExternDeclarations {
}
(Array(a_ty, a_const), Array(b_ty, b_const)) => {
// For arrays, we also check the constness of the type.
a_const.val == b_const.val
&& structurally_same_type_impl(seen_types, cx, a_ty, b_ty, ckind)
a_const.val() == b_const.val()
&& structurally_same_type_impl(seen_types, cx, *a_ty, *b_ty, ckind)
}
(Slice(a_ty), Slice(b_ty)) => {
structurally_same_type_impl(seen_types, cx, a_ty, b_ty, ckind)
structurally_same_type_impl(seen_types, cx, *a_ty, *b_ty, ckind)
}
(RawPtr(a_tymut), RawPtr(b_tymut)) => {
a_tymut.mutbl == b_tymut.mutbl
&& structurally_same_type_impl(
seen_types,
cx,
&a_tymut.ty,
&b_tymut.ty,
ckind,
seen_types, cx, a_tymut.ty, b_tymut.ty, ckind,
)
}
(Ref(_a_region, a_ty, a_mut), Ref(_b_region, b_ty, b_mut)) => {
// For structural sameness, we don't need the region to be same.
a_mut == b_mut
&& structurally_same_type_impl(seen_types, cx, a_ty, b_ty, ckind)
&& structurally_same_type_impl(seen_types, cx, *a_ty, *b_ty, ckind)
}
(FnDef(..), FnDef(..)) => {
let a_poly_sig = a.fn_sig(tcx);
@ -2927,7 +2923,7 @@ impl ClashingExternDeclarations {
(a_sig.abi, a_sig.unsafety, a_sig.c_variadic)
== (b_sig.abi, b_sig.unsafety, b_sig.c_variadic)
&& a_sig.inputs().iter().eq_by(b_sig.inputs().iter(), |a, b| {
structurally_same_type_impl(seen_types, cx, a, b, ckind)
structurally_same_type_impl(seen_types, cx, *a, *b, ckind)
})
&& structurally_same_type_impl(
seen_types,

View file

@ -974,7 +974,7 @@ impl<'tcx> LateContext<'tcx> {
Ok(())
}
fn print_const(self, _ct: &'tcx ty::Const<'tcx>) -> Result<Self::Const, Self::Error> {
fn print_const(self, _ct: ty::Const<'tcx>) -> Result<Self::Const, Self::Error> {
Ok(())
}

View file

@ -7,9 +7,10 @@ use rustc_middle::ty;
use rustc_span::symbol::sym;
declare_tool_lint! {
/// The `rustc_pass_by_value` lint marks a type with `#[rustc_pass_by_value]` requiring it to always be passed by value.
/// This is usually used for types that are thin wrappers around references, so there is no benefit to an extra
/// layer of indirection. (Example: `Ty` which is a reference to a `TyS`)
/// The `rustc_pass_by_value` lint marks a type with `#[rustc_pass_by_value]` requiring it to
/// always be passed by value. This is usually used for types that are thin wrappers around
/// references, so there is no benefit to an extra layer of indirection. (Example: `Ty` which
/// is a reference to an `Interned<TyS>`)
pub rustc::PASS_BY_VALUE,
Warn,
"pass by reference of a type flagged as `#[rustc_pass_by_value]`",

View file

@ -249,7 +249,7 @@ fn report_bin_hex_error(
));
}
if let Some(sugg_ty) =
get_type_suggestion(&cx.typeck_results().node_type(expr.hir_id), val, negative)
get_type_suggestion(cx.typeck_results().node_type(expr.hir_id), val, negative)
{
if let Some(pos) = repr_str.chars().position(|c| c == 'i' || c == 'u') {
let (sans_suffix, _) = repr_str.split_at(pos);
@ -367,7 +367,7 @@ fn lint_int_literal<'tcx>(
max,
));
if let Some(sugg_ty) =
get_type_suggestion(&cx.typeck_results().node_type(e.hir_id), v, negative)
get_type_suggestion(cx.typeck_results().node_type(e.hir_id), v, negative)
{
err.help(&format!("consider using the type `{}` instead", sugg_ty));
}
@ -1095,7 +1095,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
}
}
for arg in sig.inputs() {
let r = self.check_type_for_ffi(cache, arg);
let r = self.check_type_for_ffi(cache, *arg);
match r {
FfiSafe => {}
_ => {
@ -1257,7 +1257,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
let sig = self.cx.tcx.erase_late_bound_regions(sig);
for (input_ty, input_hir) in iter::zip(sig.inputs(), decl.inputs) {
self.check_type_for_ffi_and_report_errors(input_hir.span, input_ty, false, false);
self.check_type_for_ffi_and_report_errors(input_hir.span, *input_ty, false, false);
}
if let hir::FnRetTy::Return(ref ret_hir) = decl.output {

View file

@ -117,7 +117,7 @@ provide! { <'tcx> tcx, def_id, other, cdata,
promoted_mir => { tcx.arena.alloc(cdata.get_promoted_mir(tcx, def_id.index)) }
thir_abstract_const => { cdata.get_thir_abstract_const(tcx, def_id.index) }
unused_generic_params => { cdata.get_unused_generic_params(def_id.index) }
const_param_default => { tcx.mk_const(cdata.get_const_param_default(tcx, def_id.index)) }
const_param_default => { cdata.get_const_param_default(tcx, def_id.index) }
mir_const_qualif => { cdata.mir_const_qualif(def_id.index) }
fn_sig => { cdata.fn_sig(def_id.index, tcx) }
inherent_impls => { cdata.get_inherent_implementations_for_type(tcx, def_id.index) }

View file

@ -88,7 +88,8 @@ macro_rules! arena_types {
// Interned types
[] tys: rustc_middle::ty::TyS<'tcx>,
[] predicates: rustc_middle::ty::PredicateInner<'tcx>,
[] predicates: rustc_middle::ty::PredicateS<'tcx>,
[] consts: rustc_middle::ty::ConstS<'tcx>,
// Note that this deliberately duplicates items in the `rustc_hir::arena`,
// since we need to allocate this type on both the `rustc_hir` arena

View file

@ -328,8 +328,8 @@ impl<'tcx> CanonicalVarValues<'tcx> {
tcx.mk_region(ty::ReLateBound(ty::INNERMOST, br)).into()
}
GenericArgKind::Const(ct) => tcx
.mk_const(ty::Const {
ty: ct.ty,
.mk_const(ty::ConstS {
ty: ct.ty(),
val: ty::ConstKind::Bound(ty::INNERMOST, ty::BoundVar::from_u32(i)),
})
.into(),

View file

@ -95,14 +95,14 @@ pub enum ConstVariableOriginKind {
#[derive(Copy, Clone, Debug)]
pub enum ConstVariableValue<'tcx> {
Known { value: &'tcx ty::Const<'tcx> },
Known { value: ty::Const<'tcx> },
Unknown { universe: ty::UniverseIndex },
}
impl<'tcx> ConstVariableValue<'tcx> {
/// If this value is known, returns the const it is known to be.
/// Otherwise, `None`.
pub fn known(&self) -> Option<&'tcx ty::Const<'tcx>> {
pub fn known(&self) -> Option<ty::Const<'tcx>> {
match *self {
ConstVariableValue::Unknown { .. } => None,
ConstVariableValue::Known { value } => Some(value),
@ -130,7 +130,7 @@ impl<'tcx> UnifyKey for ty::ConstVid<'tcx> {
}
impl<'tcx> UnifyValue for ConstVarValue<'tcx> {
type Error = (&'tcx ty::Const<'tcx>, &'tcx ty::Const<'tcx>);
type Error = (ty::Const<'tcx>, ty::Const<'tcx>);
fn unify_values(&value1: &Self, &value2: &Self) -> Result<Self, Self::Error> {
Ok(match (value1.val, value2.val) {
@ -162,18 +162,18 @@ impl<'tcx> UnifyValue for ConstVarValue<'tcx> {
}
}
impl<'tcx> EqUnifyValue for &'tcx ty::Const<'tcx> {}
impl<'tcx> EqUnifyValue for ty::Const<'tcx> {}
pub fn replace_if_possible<'tcx, V, L>(
table: &mut UnificationTable<InPlace<ty::ConstVid<'tcx>, V, L>>,
c: &'tcx ty::Const<'tcx>,
) -> &'tcx ty::Const<'tcx>
c: ty::Const<'tcx>,
) -> ty::Const<'tcx>
where
V: snapshot_vec::VecLike<unify::Delegate<ty::ConstVid<'tcx>>>,
L: UndoLogs<snapshot_vec::UndoLog<unify::Delegate<ty::ConstVid<'tcx>>>>,
{
if let ty::Const { val: ty::ConstKind::Infer(InferConst::Var(vid)), .. } = c {
match table.probe_value(*vid).val.known() {
if let ty::ConstKind::Infer(InferConst::Var(vid)) = c.val() {
match table.probe_value(vid).val.known() {
Some(c) => c,
None => c,
}

View file

@ -2185,7 +2185,7 @@ pub enum Rvalue<'tcx> {
Use(Operand<'tcx>),
/// [x; 32]
Repeat(Operand<'tcx>, &'tcx ty::Const<'tcx>),
Repeat(Operand<'tcx>, ty::Const<'tcx>),
/// &x or &mut x
Ref(Region<'tcx>, BorrowKind, Place<'tcx>),
@ -2335,7 +2335,7 @@ impl<'tcx> Debug for Rvalue<'tcx> {
match *self {
Use(ref place) => write!(fmt, "{:?}", place),
Repeat(ref a, ref b) => {
Repeat(ref a, b) => {
write!(fmt, "[{:?}; ", a)?;
pretty_print_const(b, fmt, false)?;
write!(fmt, "]")
@ -2514,7 +2514,7 @@ pub struct Constant<'tcx> {
#[derive(Lift)]
pub enum ConstantKind<'tcx> {
/// This constant came from the type system
Ty(&'tcx ty::Const<'tcx>),
Ty(ty::Const<'tcx>),
/// This constant cannot go back into the type system, as it represents
/// something the type system cannot handle (e.g. pointers).
Val(interpret::ConstValue<'tcx>, Ty<'tcx>),
@ -2522,7 +2522,7 @@ pub enum ConstantKind<'tcx> {
impl<'tcx> Constant<'tcx> {
pub fn check_static_ptr(&self, tcx: TyCtxt<'_>) -> Option<DefId> {
match self.literal.const_for_ty()?.val.try_to_scalar() {
match self.literal.const_for_ty()?.val().try_to_scalar() {
Some(Scalar::Ptr(ptr, _size)) => match tcx.global_alloc(ptr.provenance) {
GlobalAlloc::Static(def_id) => {
assert!(!tcx.is_thread_local_static(def_id));
@ -2539,33 +2539,33 @@ impl<'tcx> Constant<'tcx> {
}
}
impl<'tcx> From<&'tcx ty::Const<'tcx>> for ConstantKind<'tcx> {
impl<'tcx> From<ty::Const<'tcx>> for ConstantKind<'tcx> {
#[inline]
fn from(ct: &'tcx ty::Const<'tcx>) -> Self {
fn from(ct: ty::Const<'tcx>) -> Self {
Self::Ty(ct)
}
}
impl<'tcx> ConstantKind<'tcx> {
/// Returns `None` if the constant is not trivially safe for use in the type system.
pub fn const_for_ty(&self) -> Option<&'tcx ty::Const<'tcx>> {
pub fn const_for_ty(&self) -> Option<ty::Const<'tcx>> {
match self {
ConstantKind::Ty(c) => Some(c),
ConstantKind::Ty(c) => Some(*c),
ConstantKind::Val(..) => None,
}
}
pub fn ty(&self) -> Ty<'tcx> {
match self {
ConstantKind::Ty(c) => c.ty,
ConstantKind::Val(_, ty) => ty,
ConstantKind::Ty(c) => c.ty(),
ConstantKind::Val(_, ty) => *ty,
}
}
#[inline]
pub fn try_to_value(self) -> Option<interpret::ConstValue<'tcx>> {
match self {
ConstantKind::Ty(c) => c.val.try_to_value(),
ConstantKind::Ty(c) => c.val().try_to_value(),
ConstantKind::Val(val, _) => Some(val),
}
}
@ -2829,7 +2829,7 @@ impl<'tcx> Display for ConstantKind<'tcx> {
}
fn pretty_print_const<'tcx>(
c: &ty::Const<'tcx>,
c: ty::Const<'tcx>,
fmt: &mut Formatter<'_>,
print_types: bool,
) -> fmt::Result {

View file

@ -17,7 +17,7 @@ use rustc_middle::mir::interpret::{
use rustc_middle::mir::visit::Visitor;
use rustc_middle::mir::MirSource;
use rustc_middle::mir::*;
use rustc_middle::ty::{self, TyCtxt, TyS, TypeFoldable, TypeVisitor};
use rustc_middle::ty::{self, TyCtxt, TypeFoldable, TypeVisitor};
use rustc_target::abi::Size;
use std::ops::ControlFlow;
@ -427,12 +427,12 @@ impl<'tcx> ExtraComments<'tcx> {
}
}
fn use_verbose<'tcx>(ty: &&TyS<'tcx>, fn_def: bool) -> bool {
match ty.kind() {
fn use_verbose<'tcx>(ty: Ty<'tcx>, fn_def: bool) -> bool {
match *ty.kind() {
ty::Int(_) | ty::Uint(_) | ty::Bool | ty::Char | ty::Float(_) => false,
// Unit type
ty::Tuple(g_args) if g_args.is_empty() => false,
ty::Tuple(g_args) => g_args.iter().any(|g_arg| use_verbose(&g_arg.expect_ty(), fn_def)),
ty::Tuple(g_args) => g_args.iter().any(|g_arg| use_verbose(g_arg.expect_ty(), fn_def)),
ty::Array(ty, _) => use_verbose(ty, fn_def),
ty::FnDef(..) => fn_def,
_ => true,
@ -443,7 +443,7 @@ impl<'tcx> Visitor<'tcx> for ExtraComments<'tcx> {
fn visit_constant(&mut self, constant: &Constant<'tcx>, location: Location) {
self.super_constant(constant, location);
let Constant { span, user_ty, literal } = constant;
if use_verbose(&literal.ty(), true) {
if use_verbose(literal.ty(), true) {
self.push("mir::Constant");
self.push(&format!(
"+ span: {}",
@ -462,9 +462,10 @@ impl<'tcx> Visitor<'tcx> for ExtraComments<'tcx> {
}
}
fn visit_const(&mut self, constant: &&'tcx ty::Const<'tcx>, _: Location) {
fn visit_const(&mut self, constant: ty::Const<'tcx>, _: Location) {
self.super_const(constant);
let ty::Const { ty, val, .. } = constant;
let ty = constant.ty();
let val = constant.val();
if use_verbose(ty, false) {
self.push("ty::Const");
self.push(&format!("+ ty: {:?}", ty));
@ -683,8 +684,8 @@ pub fn write_allocations<'tcx>(
}
struct CollectAllocIds(BTreeSet<AllocId>);
impl<'tcx> TypeVisitor<'tcx> for CollectAllocIds {
fn visit_const(&mut self, c: &'tcx ty::Const<'tcx>) -> ControlFlow<Self::BreakTy> {
if let ty::ConstKind::Value(val) = c.val {
fn visit_const(&mut self, c: ty::Const<'tcx>) -> ControlFlow<Self::BreakTy> {
if let ty::ConstKind::Value(val) = c.val() {
self.0.extend(alloc_ids_from_const(val));
}
c.super_visit_with(self)

View file

@ -387,7 +387,7 @@ pub enum ClosureOutlivesSubject<'tcx> {
#[derive(Copy, Clone, Debug, HashStable)]
pub struct DestructuredConst<'tcx> {
pub variant: Option<VariantIdx>,
pub fields: &'tcx [&'tcx ty::Const<'tcx>],
pub fields: &'tcx [ty::Const<'tcx>],
}
/// Coverage information summarized from a MIR if instrumented for source code coverage (see

View file

@ -57,7 +57,7 @@ impl<'tcx> PlaceTy<'tcx> {
/// `PlaceElem`, where we can just use the `Ty` that is already
/// stored inline on field projection elems.
pub fn projection_ty(self, tcx: TyCtxt<'tcx>, elem: PlaceElem<'tcx>) -> PlaceTy<'tcx> {
self.projection_ty_core(tcx, ty::ParamEnv::empty(), &elem, |_, _, ty| ty)
self.projection_ty_core(tcx, ty::ParamEnv::empty(), &elem, |_, _, &ty| ty)
}
/// `place_ty.projection_ty_core(tcx, elem, |...| { ... })`
@ -93,11 +93,11 @@ impl<'tcx> PlaceTy<'tcx> {
ProjectionElem::Subslice { from, to, from_end } => {
PlaceTy::from_ty(match self.ty.kind() {
ty::Slice(..) => self.ty,
ty::Array(inner, _) if !from_end => tcx.mk_array(inner, (to - from) as u64),
ty::Array(inner, _) if !from_end => tcx.mk_array(*inner, (to - from) as u64),
ty::Array(inner, size) if from_end => {
let size = size.eval_usize(tcx, param_env);
let len = size - (from as u64) - (to as u64);
tcx.mk_array(inner, len)
tcx.mk_array(*inner, len)
}
_ => bug!("cannot subslice non-array type: `{:?}`", self),
})

View file

@ -430,7 +430,7 @@ impl<'tcx> TerminatorKind<'tcx> {
pub fn as_switch(&self) -> Option<(&Operand<'tcx>, Ty<'tcx>, &SwitchTargets)> {
match self {
TerminatorKind::SwitchInt { discr, switch_ty, targets } => {
Some((discr, switch_ty, targets))
Some((discr, *switch_ty, targets))
}
_ => None,
}

View file

@ -194,13 +194,13 @@ macro_rules! make_mir_visitor {
}
fn visit_region(&mut self,
region: & $($mutability)? ty::Region<'tcx>,
region: $(& $mutability)? ty::Region<'tcx>,
_: Location) {
self.super_region(region);
}
fn visit_const(&mut self,
constant: & $($mutability)? &'tcx ty::Const<'tcx>,
constant: $(& $mutability)? ty::Const<'tcx>,
_: Location) {
self.super_const(constant);
}
@ -242,7 +242,7 @@ macro_rules! make_mir_visitor {
) {
let span = body.span;
if let Some(gen) = &$($mutability)? body.generator {
if let Some(yield_ty) = &$($mutability)? gen.yield_ty {
if let Some(yield_ty) = $(& $mutability)? gen.yield_ty {
self.visit_ty(
yield_ty,
TyContext::YieldTy(SourceInfo::outermost(span))
@ -266,7 +266,7 @@ macro_rules! make_mir_visitor {
}
self.visit_ty(
&$($mutability)? body.return_ty(),
$(& $mutability)? body.return_ty(),
TyContext::ReturnTy(SourceInfo::outermost(body.span))
);
@ -355,7 +355,7 @@ macro_rules! make_mir_visitor {
ty::InstanceDef::DropGlue(_def_id, Some(ty)) |
ty::InstanceDef::CloneShim(_def_id, ty) => {
// FIXME(eddyb) use a better `TyContext` here.
self.visit_ty(ty, TyContext::Location(location));
self.visit_ty($(& $mutability)? *ty, TyContext::Location(location));
}
}
self.visit_substs(callee_substs, location);
@ -487,7 +487,7 @@ macro_rules! make_mir_visitor {
targets: _
} => {
self.visit_operand(discr, location);
self.visit_ty(switch_ty, TyContext::Location(location));
self.visit_ty($(& $mutability)? *switch_ty, TyContext::Location(location));
}
TerminatorKind::Drop {
@ -641,7 +641,7 @@ macro_rules! make_mir_visitor {
Rvalue::ThreadLocalRef(_) => {}
Rvalue::Ref(r, bk, path) => {
self.visit_region(r, location);
self.visit_region($(& $mutability)? *r, location);
let ctx = match bk {
BorrowKind::Shared => PlaceContext::NonMutatingUse(
NonMutatingUseContext::SharedBorrow
@ -680,7 +680,7 @@ macro_rules! make_mir_visitor {
Rvalue::Cast(_cast_kind, operand, ty) => {
self.visit_operand(operand, location);
self.visit_ty(ty, TyContext::Location(location));
self.visit_ty($(& $mutability)? *ty, TyContext::Location(location));
}
Rvalue::BinaryOp(_bin_op, box(lhs, rhs))
@ -702,14 +702,14 @@ macro_rules! make_mir_visitor {
}
Rvalue::NullaryOp(_op, ty) => {
self.visit_ty(ty, TyContext::Location(location));
self.visit_ty($(& $mutability)? *ty, TyContext::Location(location));
}
Rvalue::Aggregate(kind, operands) => {
let kind = &$($mutability)? **kind;
match kind {
AggregateKind::Array(ty) => {
self.visit_ty(ty, TyContext::Location(location));
self.visit_ty($(& $mutability)? *ty, TyContext::Location(location));
}
AggregateKind::Tuple => {
}
@ -744,7 +744,7 @@ macro_rules! make_mir_visitor {
Rvalue::ShallowInitBox(operand, ty) => {
self.visit_operand(operand, location);
self.visit_ty(ty, TyContext::Location(location));
self.visit_ty($(& $mutability)? *ty, TyContext::Location(location));
}
}
}
@ -815,7 +815,7 @@ macro_rules! make_mir_visitor {
is_block_tail: _,
} = local_decl;
self.visit_ty(ty, TyContext::LocalDecl {
self.visit_ty($(& $mutability)? *ty, TyContext::LocalDecl {
local,
source_info: *source_info,
});
@ -864,8 +864,8 @@ macro_rules! make_mir_visitor {
self.visit_span(span);
drop(user_ty); // no visit method for this
match literal {
ConstantKind::Ty(ct) => self.visit_const(ct, location),
ConstantKind::Val(_, t) => self.visit_ty(t, TyContext::Location(location)),
ConstantKind::Ty(ct) => self.visit_const($(& $mutability)? *ct, location),
ConstantKind::Val(_, ty) => self.visit_ty($(& $mutability)? *ty, TyContext::Location(location)),
}
}
@ -894,16 +894,16 @@ macro_rules! make_mir_visitor {
ty: & $($mutability)? CanonicalUserTypeAnnotation<'tcx>,
) {
self.visit_span(& $($mutability)? ty.span);
self.visit_ty(& $($mutability)? ty.inferred_ty, TyContext::UserTy(ty.span));
self.visit_ty($(& $mutability)? ty.inferred_ty, TyContext::UserTy(ty.span));
}
fn super_ty(&mut self, _ty: $(& $mutability)? Ty<'tcx>) {
}
fn super_region(&mut self, _region: & $($mutability)? ty::Region<'tcx>) {
fn super_region(&mut self, _region: $(& $mutability)? ty::Region<'tcx>) {
}
fn super_const(&mut self, _const: & $($mutability)? &'tcx ty::Const<'tcx>) {
fn super_const(&mut self, _const: $(& $mutability)? ty::Const<'tcx>) {
}
fn super_substs(&mut self, _substs: & $($mutability)? SubstsRef<'tcx>) {

View file

@ -113,7 +113,7 @@ rustc_queries! {
/// Given the def_id of a const-generic parameter, computes the associated default const
/// parameter. e.g. `fn example<const N: usize=3>` called on `N` would return `3`.
query const_param_default(param: DefId) -> &'tcx ty::Const<'tcx> {
query const_param_default(param: DefId) -> ty::Const<'tcx> {
desc { |tcx| "compute const default for a given parameter `{}`", tcx.def_path_str(param) }
separate_provide_extern
}
@ -926,7 +926,7 @@ rustc_queries! {
/// Destructure a constant ADT or array into its variant index and its
/// field values.
query destructure_const(
key: ty::ParamEnvAnd<'tcx, &'tcx ty::Const<'tcx>>
key: ty::ParamEnvAnd<'tcx, ty::Const<'tcx>>
) -> mir::DestructuredConst<'tcx> {
desc { "destructure constant" }
remap_env_constness
@ -935,8 +935,8 @@ rustc_queries! {
/// Dereference a constant reference or raw pointer and turn the result into a constant
/// again.
query deref_const(
key: ty::ParamEnvAnd<'tcx, &'tcx ty::Const<'tcx>>
) -> &'tcx ty::Const<'tcx> {
key: ty::ParamEnvAnd<'tcx, ty::Const<'tcx>>
) -> ty::Const<'tcx> {
desc { "deref constant" }
remap_env_constness
}
@ -947,7 +947,7 @@ rustc_queries! {
query lit_to_const(
key: LitToConstInput<'tcx>
) -> Result<&'tcx ty::Const<'tcx>, LitToConstError> {
) -> Result<ty::Const<'tcx>, LitToConstError> {
desc { "converting literal to const" }
}
@ -1146,33 +1146,33 @@ rustc_queries! {
desc { "computing whether `{}` is `Copy`", env.value }
remap_env_constness
}
/// Query backing `TyS::is_sized`.
/// Query backing `Ty::is_sized`.
query is_sized_raw(env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool {
desc { "computing whether `{}` is `Sized`", env.value }
remap_env_constness
}
/// Query backing `TyS::is_freeze`.
/// Query backing `Ty::is_freeze`.
query is_freeze_raw(env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool {
desc { "computing whether `{}` is freeze", env.value }
remap_env_constness
}
/// Query backing `TyS::is_unpin`.
/// Query backing `Ty::is_unpin`.
query is_unpin_raw(env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool {
desc { "computing whether `{}` is `Unpin`", env.value }
remap_env_constness
}
/// Query backing `TyS::needs_drop`.
/// Query backing `Ty::needs_drop`.
query needs_drop_raw(env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool {
desc { "computing whether `{}` needs drop", env.value }
remap_env_constness
}
/// Query backing `TyS::has_significant_drop_raw`.
/// Query backing `Ty::has_significant_drop_raw`.
query has_significant_drop_raw(env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool {
desc { "computing whether `{}` has a significant drop", env.value }
remap_env_constness
}
/// Query backing `TyS::is_structural_eq_shallow`.
/// Query backing `Ty::is_structural_eq_shallow`.
///
/// This is only correct for ADTs. Call `is_structural_eq_shallow` to handle all types
/// correctly.

View file

@ -368,12 +368,12 @@ pub enum ExprKind<'tcx> {
},
/// An inline `const` block, e.g. `const {}`.
ConstBlock {
value: &'tcx Const<'tcx>,
value: Const<'tcx>,
},
/// An array literal constructed from one repeated element, e.g. `[1; 5]`.
Repeat {
value: ExprId,
count: &'tcx Const<'tcx>,
count: Const<'tcx>,
},
/// An array, e.g. `[a, b, c, d]`.
Array {
@ -407,7 +407,7 @@ pub enum ExprKind<'tcx> {
},
/// A literal.
Literal {
literal: &'tcx Const<'tcx>,
literal: Const<'tcx>,
user_ty: Option<Canonical<'tcx, UserType<'tcx>>>,
/// The `DefId` of the `const` item this literal
/// was produced from, if this is not a user-written
@ -419,7 +419,7 @@ pub enum ExprKind<'tcx> {
/// This is only distinguished from `Literal` so that we can register some
/// info for diagnostics.
StaticRef {
literal: &'tcx Const<'tcx>,
literal: Const<'tcx>,
def_id: DefId,
},
/// Inline assembly, i.e. `asm!()`.
@ -501,7 +501,7 @@ pub enum InlineAsmOperand<'tcx> {
out_expr: Option<ExprId>,
},
Const {
value: &'tcx Const<'tcx>,
value: Const<'tcx>,
span: Span,
},
SymFn {
@ -640,7 +640,7 @@ pub enum PatKind<'tcx> {
/// * Opaque constants, that must not be matched structurally. So anything that does not derive
/// `PartialEq` and `Eq`.
Constant {
value: &'tcx ty::Const<'tcx>,
value: ty::Const<'tcx>,
},
Range(PatRange<'tcx>),
@ -670,8 +670,8 @@ pub enum PatKind<'tcx> {
#[derive(Copy, Clone, Debug, PartialEq, HashStable)]
pub struct PatRange<'tcx> {
pub lo: &'tcx ty::Const<'tcx>,
pub hi: &'tcx ty::Const<'tcx>,
pub lo: ty::Const<'tcx>,
pub hi: ty::Const<'tcx>,
pub end: RangeEnd,
}

View file

@ -22,7 +22,7 @@ pub enum CastKind {
/// A node of an `AbstractConst`.
#[derive(Debug, Clone, Copy, PartialEq, Eq, HashStable, TyEncodable, TyDecodable)]
pub enum Node<'tcx> {
Leaf(&'tcx ty::Const<'tcx>),
Leaf(ty::Const<'tcx>),
Binop(mir::BinOp, NodeId, NodeId),
UnaryOp(mir::UnOp, NodeId),
FunctionCall(NodeId, &'tcx [NodeId]),

View file

@ -26,7 +26,7 @@ pub trait Visitor<'a, 'tcx: 'a>: Sized {
walk_pat(self, pat);
}
fn visit_const(&mut self, _cnst: &'tcx Const<'tcx>) {}
fn visit_const(&mut self, _cnst: Const<'tcx>) {}
}
pub fn walk_expr<'a, 'tcx: 'a, V: Visitor<'a, 'tcx>>(visitor: &mut V, expr: &Expr<'tcx>) {
@ -209,7 +209,7 @@ pub fn walk_pat<'a, 'tcx: 'a, V: Visitor<'a, 'tcx>>(visitor: &mut V, pat: &Pat<'
visitor.visit_pat(&subpattern.pattern);
}
}
Constant { value } => visitor.visit_const(value),
Constant { value } => visitor.visit_const(*value),
Range(range) => {
visitor.visit_const(range.lo);
visitor.visit_const(range.hi);

View file

@ -77,7 +77,7 @@ impl<'tcx> TypeRelation<'tcx> for Match<'tcx> {
) => Ok(a),
(&ty::Infer(_), _) | (_, &ty::Infer(_)) => {
Err(TypeError::Sorts(relate::expected_found(self, &a, &b)))
Err(TypeError::Sorts(relate::expected_found(self, a, b)))
}
(&ty::Error(_), _) | (_, &ty::Error(_)) => Ok(self.tcx().ty_error()),
@ -88,21 +88,21 @@ impl<'tcx> TypeRelation<'tcx> for Match<'tcx> {
fn consts(
&mut self,
a: &'tcx ty::Const<'tcx>,
b: &'tcx ty::Const<'tcx>,
) -> RelateResult<'tcx, &'tcx ty::Const<'tcx>> {
a: ty::Const<'tcx>,
b: ty::Const<'tcx>,
) -> RelateResult<'tcx, ty::Const<'tcx>> {
debug!("{}.consts({:?}, {:?})", self.tag(), a, b);
if a == b {
return Ok(a);
}
match (a.val, b.val) {
match (a.val(), b.val()) {
(_, ty::ConstKind::Infer(InferConst::Fresh(_))) => {
return Ok(a);
}
(ty::ConstKind::Infer(_), _) | (_, ty::ConstKind::Infer(_)) => {
return Err(TypeError::ConstMismatch(relate::expected_found(self, &a, &b)));
return Err(TypeError::ConstMismatch(relate::expected_found(self, a, b)));
}
_ => {}

View file

@ -116,7 +116,7 @@ impl<'tcx> ClosureKind {
}
/// Returns the representative scalar type for this closure kind.
/// See `TyS::to_opt_closure_kind` for more details.
/// See `Ty::to_opt_closure_kind` for more details.
pub fn to_ty(self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
match self {
ty::ClosureKind::Fn => tcx.types.i8,

View file

@ -138,6 +138,18 @@ impl<'tcx, E: TyEncoder<'tcx>> Encodable<E> for ty::Predicate<'tcx> {
}
}
impl<'tcx, E: TyEncoder<'tcx>> Encodable<E> for ty::Region<'tcx> {
fn encode(&self, e: &mut E) -> Result<(), E::Error> {
self.kind().encode(e)
}
}
impl<'tcx, E: TyEncoder<'tcx>> Encodable<E> for ty::Const<'tcx> {
fn encode(&self, e: &mut E) -> Result<(), E::Error> {
self.0.0.encode(e)
}
}
impl<'tcx, E: TyEncoder<'tcx>> Encodable<E> for AllocId {
fn encode(&self, e: &mut E) -> Result<(), E::Error> {
e.encode_alloc_id(self)
@ -156,7 +168,6 @@ macro_rules! encodable_via_deref {
encodable_via_deref! {
&'tcx ty::TypeckResults<'tcx>,
ty::Region<'tcx>,
&'tcx traits::ImplSource<'tcx, ()>,
&'tcx mir::Body<'tcx>,
&'tcx mir::UnsafetyCheckResult,
@ -330,8 +341,8 @@ impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D>
}
}
impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D> for ty::Const<'tcx> {
fn decode(decoder: &mut D) -> &'tcx Self {
impl<'tcx, D: TyDecoder<'tcx>> Decodable<D> for ty::Const<'tcx> {
fn decode(decoder: &mut D) -> Self {
decoder.tcx().mk_const(Decodable::decode(decoder))
}
}

View file

@ -4,10 +4,12 @@ use crate::ty::{
self, InlineConstSubsts, InlineConstSubstsParts, InternalSubsts, ParamEnv, ParamEnvAnd, Ty,
TyCtxt, TypeFoldable,
};
use rustc_data_structures::intern::Interned;
use rustc_errors::ErrorReported;
use rustc_hir as hir;
use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_macros::HashStable;
use std::fmt;
mod int;
mod kind;
@ -17,22 +19,42 @@ pub use int::*;
pub use kind::*;
pub use valtree::*;
/// Typed constant value.
#[derive(Copy, Clone, Debug, Hash, TyEncodable, TyDecodable, Eq, PartialEq, Ord, PartialOrd)]
#[derive(HashStable)]
pub struct Const<'tcx> {
pub ty: Ty<'tcx>,
/// Use this rather than `ConstS`, whenever possible.
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, HashStable)]
#[cfg_attr(not(bootstrap), rustc_pass_by_value)]
pub struct Const<'tcx>(pub Interned<'tcx, ConstS<'tcx>>);
impl<'tcx> fmt::Debug for Const<'tcx> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
// This reflects what `Const` looked liked before `Interned` was
// introduced. We print it like this to avoid having to update expected
// output in a lot of tests.
write!(f, "Const {{ ty: {:?}, val: {:?} }}", self.ty(), self.val())
}
}
/// Typed constant value.
#[derive(PartialEq, Eq, PartialOrd, Ord, Hash, HashStable, TyEncodable, TyDecodable)]
pub struct ConstS<'tcx> {
pub ty: Ty<'tcx>,
pub val: ConstKind<'tcx>,
}
#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
static_assert_size!(Const<'_>, 48);
static_assert_size!(ConstS<'_>, 48);
impl<'tcx> Const<'tcx> {
pub fn ty(self) -> Ty<'tcx> {
self.0.ty
}
pub fn val(self) -> ConstKind<'tcx> {
self.0.val
}
/// Literals and const generic parameters are eagerly converted to a constant, everything else
/// becomes `Unevaluated`.
pub fn from_anon_const(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> &'tcx Self {
pub fn from_anon_const(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Self {
Self::from_opt_const_arg_anon_const(tcx, ty::WithOptConstParam::unknown(def_id))
}
@ -40,7 +62,7 @@ impl<'tcx> Const<'tcx> {
pub fn from_opt_const_arg_anon_const(
tcx: TyCtxt<'tcx>,
def: ty::WithOptConstParam<LocalDefId>,
) -> &'tcx Self {
) -> Self {
debug!("Const::from_anon_const(def={:?})", def);
let body_id = match tcx.hir().get_by_def_id(def.did) {
@ -58,7 +80,7 @@ impl<'tcx> Const<'tcx> {
match Self::try_eval_lit_or_param(tcx, ty, expr) {
Some(v) => v,
None => tcx.mk_const(ty::Const {
None => tcx.mk_const(ty::ConstS {
val: ty::ConstKind::Unevaluated(ty::Unevaluated {
def: def.to_global(),
substs: InternalSubsts::identity_for_item(tcx, def.did.to_def_id()),
@ -74,7 +96,7 @@ impl<'tcx> Const<'tcx> {
tcx: TyCtxt<'tcx>,
ty: Ty<'tcx>,
expr: &'tcx hir::Expr<'tcx>,
) -> Option<&'tcx Self> {
) -> Option<Self> {
// Unwrap a block, so that e.g. `{ P }` is recognised as a parameter. Const arguments
// currently have to be wrapped in curly brackets, so it's necessary to special-case.
let expr = match &expr.kind {
@ -120,7 +142,7 @@ impl<'tcx> Const<'tcx> {
let generics = tcx.generics_of(item_def_id.to_def_id());
let index = generics.param_def_id_to_index[&def_id];
let name = tcx.hir().name(hir_id);
Some(tcx.mk_const(ty::Const {
Some(tcx.mk_const(ty::ConstS {
val: ty::ConstKind::Param(ty::ParamConst::new(index, name)),
ty,
}))
@ -129,7 +151,7 @@ impl<'tcx> Const<'tcx> {
}
}
pub fn from_inline_const(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> &'tcx Self {
pub fn from_inline_const(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Self {
debug!("Const::from_inline_const(def_id={:?})", def_id);
let hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
@ -155,7 +177,7 @@ impl<'tcx> Const<'tcx> {
let substs =
InlineConstSubsts::new(tcx, InlineConstSubstsParts { parent_substs, ty })
.substs;
tcx.mk_const(ty::Const {
tcx.mk_const(ty::ConstS {
val: ty::ConstKind::Unevaluated(ty::Unevaluated {
def: ty::WithOptConstParam::unknown(def_id).to_global(),
substs,
@ -171,19 +193,19 @@ impl<'tcx> Const<'tcx> {
/// Interns the given value as a constant.
#[inline]
pub fn from_value(tcx: TyCtxt<'tcx>, val: ConstValue<'tcx>, ty: Ty<'tcx>) -> &'tcx Self {
tcx.mk_const(Self { val: ConstKind::Value(val), ty })
pub fn from_value(tcx: TyCtxt<'tcx>, val: ConstValue<'tcx>, ty: Ty<'tcx>) -> Self {
tcx.mk_const(ConstS { val: ConstKind::Value(val), ty })
}
#[inline]
/// Interns the given scalar as a constant.
pub fn from_scalar(tcx: TyCtxt<'tcx>, val: Scalar, ty: Ty<'tcx>) -> &'tcx Self {
pub fn from_scalar(tcx: TyCtxt<'tcx>, val: Scalar, ty: Ty<'tcx>) -> Self {
Self::from_value(tcx, ConstValue::Scalar(val), ty)
}
#[inline]
/// Creates a constant with the given integer value and interns it.
pub fn from_bits(tcx: TyCtxt<'tcx>, bits: u128, ty: ParamEnvAnd<'tcx, Ty<'tcx>>) -> &'tcx Self {
pub fn from_bits(tcx: TyCtxt<'tcx>, bits: u128, ty: ParamEnvAnd<'tcx, Ty<'tcx>>) -> Self {
let size = tcx
.layout_of(ty)
.unwrap_or_else(|e| panic!("could not compute layout for {:?}: {:?}", ty, e))
@ -193,19 +215,19 @@ impl<'tcx> Const<'tcx> {
#[inline]
/// Creates an interned zst constant.
pub fn zero_sized(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> &'tcx Self {
pub fn zero_sized(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Self {
Self::from_scalar(tcx, Scalar::ZST, ty)
}
#[inline]
/// Creates an interned bool constant.
pub fn from_bool(tcx: TyCtxt<'tcx>, v: bool) -> &'tcx Self {
pub fn from_bool(tcx: TyCtxt<'tcx>, v: bool) -> Self {
Self::from_bits(tcx, v as u128, ParamEnv::empty().and(tcx.types.bool))
}
#[inline]
/// Creates an interned usize constant.
pub fn from_usize(tcx: TyCtxt<'tcx>, n: u64) -> &'tcx Self {
pub fn from_usize(tcx: TyCtxt<'tcx>, n: u64) -> Self {
Self::from_bits(tcx, n as u128, ParamEnv::empty().and(tcx.types.usize))
}
@ -214,35 +236,35 @@ impl<'tcx> Const<'tcx> {
/// generics (or erroneous code) or if the value can't be represented as bits (e.g. because it
/// contains const generic parameters or pointers).
pub fn try_eval_bits(
&self,
self,
tcx: TyCtxt<'tcx>,
param_env: ParamEnv<'tcx>,
ty: Ty<'tcx>,
) -> Option<u128> {
assert_eq!(self.ty, ty);
assert_eq!(self.ty(), ty);
let size = tcx.layout_of(param_env.with_reveal_all_normalized(tcx).and(ty)).ok()?.size;
// if `ty` does not depend on generic parameters, use an empty param_env
self.val.eval(tcx, param_env).try_to_bits(size)
self.val().eval(tcx, param_env).try_to_bits(size)
}
#[inline]
pub fn try_eval_bool(&self, tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>) -> Option<bool> {
self.val.eval(tcx, param_env).try_to_bool()
pub fn try_eval_bool(self, tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>) -> Option<bool> {
self.val().eval(tcx, param_env).try_to_bool()
}
#[inline]
pub fn try_eval_usize(&self, tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>) -> Option<u64> {
self.val.eval(tcx, param_env).try_to_machine_usize(tcx)
pub fn try_eval_usize(self, tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>) -> Option<u64> {
self.val().eval(tcx, param_env).try_to_machine_usize(tcx)
}
#[inline]
/// Tries to evaluate the constant if it is `Unevaluated`. If that doesn't succeed, return the
/// unevaluated constant.
pub fn eval(&self, tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>) -> &Const<'tcx> {
if let Some(val) = self.val.try_eval(tcx, param_env) {
pub fn eval(self, tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>) -> Const<'tcx> {
if let Some(val) = self.val().try_eval(tcx, param_env) {
match val {
Ok(val) => Const::from_value(tcx, val, self.ty),
Err(ErrorReported) => tcx.const_error(self.ty),
Ok(val) => Const::from_value(tcx, val, self.ty()),
Err(ErrorReported) => tcx.const_error(self.ty()),
}
} else {
self
@ -251,20 +273,20 @@ impl<'tcx> Const<'tcx> {
#[inline]
/// Panics if the value cannot be evaluated or doesn't contain a valid integer of the given type.
pub fn eval_bits(&self, tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>, ty: Ty<'tcx>) -> u128 {
pub fn eval_bits(self, tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>, ty: Ty<'tcx>) -> u128 {
self.try_eval_bits(tcx, param_env, ty)
.unwrap_or_else(|| bug!("expected bits of {:#?}, got {:#?}", ty, self))
}
#[inline]
/// Panics if the value cannot be evaluated or doesn't contain a valid `usize`.
pub fn eval_usize(&self, tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>) -> u64 {
pub fn eval_usize(self, tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>) -> u64 {
self.try_eval_usize(tcx, param_env)
.unwrap_or_else(|| bug!("expected usize, got {:#?}", self))
}
}
pub fn const_param_default<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> &'tcx Const<'tcx> {
pub fn const_param_default<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> Const<'tcx> {
let default_def_id = match tcx.hir().get_by_def_id(def_id.expect_local()) {
hir::Node::GenericParam(hir::GenericParam {
kind: hir::GenericParamKind::Const { ty: _, default: Some(ac) },

View file

@ -18,14 +18,15 @@ use crate::ty::subst::{GenericArg, GenericArgKind, InternalSubsts, Subst, Substs
use crate::ty::TyKind::*;
use crate::ty::{
self, AdtDef, AdtKind, Binder, BindingMode, BoundVar, CanonicalPolyFnSig,
ClosureSizeProfileData, Const, ConstVid, DefIdTree, ExistentialPredicate, FloatTy, FloatVar,
FloatVid, GenericParamDefKind, InferConst, InferTy, IntTy, IntVar, IntVid, List, ParamConst,
ParamTy, PolyFnSig, Predicate, PredicateInner, PredicateKind, ProjectionTy, Region, RegionKind,
ReprOptions, TraitObjectVisitor, Ty, TyKind, TyS, TyVar, TyVid, TypeAndMut, UintTy,
ClosureSizeProfileData, Const, ConstS, ConstVid, DefIdTree, ExistentialPredicate, FloatTy,
FloatVar, FloatVid, GenericParamDefKind, InferConst, InferTy, IntTy, IntVar, IntVid, List,
ParamConst, ParamTy, PolyFnSig, Predicate, PredicateKind, PredicateS, ProjectionTy, Region,
RegionKind, ReprOptions, TraitObjectVisitor, Ty, TyKind, TyS, TyVar, TyVid, TypeAndMut, UintTy,
};
use rustc_ast as ast;
use rustc_attr as attr;
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_data_structures::intern::Interned;
use rustc_data_structures::memmap::Mmap;
use rustc_data_structures::profiling::SelfProfilerRef;
use rustc_data_structures::sharded::{IntoPointer, ShardedHashMap};
@ -91,7 +92,7 @@ pub trait OnDiskCache<'tcx>: rustc_data_structures::sync::Sync {
#[derive(TyEncodable, TyDecodable, HashStable)]
pub struct DelaySpanBugEmitted(());
type InternedSet<'tcx, T> = ShardedHashMap<Interned<'tcx, T>, ()>;
type InternedSet<'tcx, T> = ShardedHashMap<InternedInSet<'tcx, T>, ()>;
pub struct CtxtInterners<'tcx> {
/// The arena that types, regions, etc. are allocated from.
@ -106,11 +107,11 @@ pub struct CtxtInterners<'tcx> {
region: InternedSet<'tcx, RegionKind>,
poly_existential_predicates:
InternedSet<'tcx, List<ty::Binder<'tcx, ExistentialPredicate<'tcx>>>>,
predicate: InternedSet<'tcx, PredicateInner<'tcx>>,
predicate: InternedSet<'tcx, PredicateS<'tcx>>,
predicates: InternedSet<'tcx, List<Predicate<'tcx>>>,
projs: InternedSet<'tcx, List<ProjectionKind>>,
place_elems: InternedSet<'tcx, List<PlaceElem<'tcx>>>,
const_: InternedSet<'tcx, Const<'tcx>>,
const_: InternedSet<'tcx, ConstS<'tcx>>,
const_allocation: InternedSet<'tcx, Allocation>,
bound_variable_kinds: InternedSet<'tcx, List<ty::BoundVariableKind>>,
layout: InternedSet<'tcx, Layout>,
@ -151,39 +152,40 @@ impl<'tcx> CtxtInterners<'tcx> {
#[allow(rustc::usage_of_ty_tykind)]
#[inline(never)]
fn intern_ty(&self, kind: TyKind<'tcx>) -> Ty<'tcx> {
self.type_
.intern(kind, |kind| {
let flags = super::flags::FlagComputation::for_kind(&kind);
Ty(Interned::new_unchecked(
self.type_
.intern(kind, |kind| {
let flags = super::flags::FlagComputation::for_kind(&kind);
let ty_struct = TyS {
kind,
flags: flags.flags,
outer_exclusive_binder: flags.outer_exclusive_binder,
};
let ty_struct = TyS {
kind,
flags: flags.flags,
outer_exclusive_binder: flags.outer_exclusive_binder,
};
Interned(self.arena.alloc(ty_struct))
})
.0
InternedInSet(self.arena.alloc(ty_struct))
})
.0,
))
}
#[inline(never)]
fn intern_predicate(
&self,
kind: Binder<'tcx, PredicateKind<'tcx>>,
) -> &'tcx PredicateInner<'tcx> {
self.predicate
.intern(kind, |kind| {
let flags = super::flags::FlagComputation::for_predicate(kind);
fn intern_predicate(&self, kind: Binder<'tcx, PredicateKind<'tcx>>) -> Predicate<'tcx> {
Predicate(Interned::new_unchecked(
self.predicate
.intern(kind, |kind| {
let flags = super::flags::FlagComputation::for_predicate(kind);
let predicate_struct = PredicateInner {
kind,
flags: flags.flags,
outer_exclusive_binder: flags.outer_exclusive_binder,
};
let predicate_struct = PredicateS {
kind,
flags: flags.flags,
outer_exclusive_binder: flags.outer_exclusive_binder,
};
Interned(self.arena.alloc(predicate_struct))
})
.0
InternedInSet(self.arena.alloc(predicate_struct))
})
.0,
))
}
}
@ -227,7 +229,7 @@ pub struct CommonLifetimes<'tcx> {
}
pub struct CommonConsts<'tcx> {
pub unit: &'tcx Const<'tcx>,
pub unit: Const<'tcx>,
}
pub struct LocalTableInContext<'a, V> {
@ -858,16 +860,16 @@ impl<'tcx> CanonicalUserType<'tcx> {
_ => false,
},
GenericArgKind::Lifetime(r) => match r {
GenericArgKind::Lifetime(r) => match *r {
ty::ReLateBound(debruijn, br) => {
// We only allow a `ty::INNERMOST` index in substitutions.
assert_eq!(*debruijn, ty::INNERMOST);
assert_eq!(debruijn, ty::INNERMOST);
cvar == br.var
}
_ => false,
},
GenericArgKind::Const(ct) => match ct.val {
GenericArgKind::Const(ct) => match ct.val() {
ty::ConstKind::Bound(debruijn, b) => {
// We only allow a `ty::INNERMOST` index in substitutions.
assert_eq!(debruijn, ty::INNERMOST);
@ -928,22 +930,30 @@ impl<'tcx> CommonTypes<'tcx> {
impl<'tcx> CommonLifetimes<'tcx> {
fn new(interners: &CtxtInterners<'tcx>) -> CommonLifetimes<'tcx> {
let mk = |r| interners.region.intern(r, |r| Interned(interners.arena.alloc(r))).0;
let mk = |r| {
Region(Interned::new_unchecked(
interners.region.intern(r, |r| InternedInSet(interners.arena.alloc(r))).0,
))
};
CommonLifetimes {
re_root_empty: mk(RegionKind::ReEmpty(ty::UniverseIndex::ROOT)),
re_static: mk(RegionKind::ReStatic),
re_erased: mk(RegionKind::ReErased),
re_root_empty: mk(ty::ReEmpty(ty::UniverseIndex::ROOT)),
re_static: mk(ty::ReStatic),
re_erased: mk(ty::ReErased),
}
}
}
impl<'tcx> CommonConsts<'tcx> {
fn new(interners: &CtxtInterners<'tcx>, types: &CommonTypes<'tcx>) -> CommonConsts<'tcx> {
let mk_const = |c| interners.const_.intern(c, |c| Interned(interners.arena.alloc(c))).0;
let mk_const = |c| {
Const(Interned::new_unchecked(
interners.const_.intern(c, |c| InternedInSet(interners.arena.alloc(c))).0,
))
};
CommonConsts {
unit: mk_const(ty::Const {
unit: mk_const(ty::ConstS {
val: ty::ConstKind::Value(ConstValue::Scalar(Scalar::ZST)),
ty: types.unit,
}),
@ -1215,7 +1225,7 @@ impl<'tcx> TyCtxt<'tcx> {
/// Like [TyCtxt::ty_error] but for constants.
#[track_caller]
pub fn const_error(self, ty: Ty<'tcx>) -> &'tcx Const<'tcx> {
pub fn const_error(self, ty: Ty<'tcx>) -> Const<'tcx> {
self.const_error_with_message(
ty,
DUMMY_SP,
@ -1230,9 +1240,9 @@ impl<'tcx> TyCtxt<'tcx> {
ty: Ty<'tcx>,
span: S,
msg: &str,
) -> &'tcx Const<'tcx> {
) -> Const<'tcx> {
self.sess.delay_span_bug(span, msg);
self.mk_const(ty::Const { val: ty::ConstKind::Error(DelaySpanBugEmitted(())), ty })
self.mk_const(ty::ConstS { val: ty::ConstKind::Error(DelaySpanBugEmitted(())), ty })
}
pub fn consider_optimizing<T: Fn() -> String>(self, msg: T) -> bool {
@ -1627,12 +1637,28 @@ pub trait Lift<'tcx>: fmt::Debug {
fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted>;
}
// Deprecated: we are in the process of converting all uses to `nop_lift`.
macro_rules! nop_lift_old {
($set:ident; $ty:ty => $lifted:ty) => {
impl<'a, 'tcx> Lift<'tcx> for $ty {
type Lifted = $lifted;
fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
if tcx.interners.$set.contains_pointer_to(&InternedInSet(self)) {
Some(unsafe { mem::transmute(self) })
} else {
None
}
}
}
};
}
macro_rules! nop_lift {
($set:ident; $ty:ty => $lifted:ty) => {
impl<'a, 'tcx> Lift<'tcx> for $ty {
type Lifted = $lifted;
fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
if tcx.interners.$set.contains_pointer_to(&Interned(self)) {
if tcx.interners.$set.contains_pointer_to(&InternedInSet(self.0.0)) {
Some(unsafe { mem::transmute(self) })
} else {
None
@ -1650,7 +1676,7 @@ macro_rules! nop_list_lift {
if self.is_empty() {
return Some(List::empty());
}
if tcx.interners.$set.contains_pointer_to(&Interned(self)) {
if tcx.interners.$set.contains_pointer_to(&InternedInSet(self)) {
Some(unsafe { mem::transmute(self) })
} else {
None
@ -1662,9 +1688,9 @@ macro_rules! nop_list_lift {
nop_lift! {type_; Ty<'a> => Ty<'tcx>}
nop_lift! {region; Region<'a> => Region<'tcx>}
nop_lift! {const_; &'a Const<'a> => &'tcx Const<'tcx>}
nop_lift! {const_allocation; &'a Allocation => &'tcx Allocation}
nop_lift! {predicate; &'a PredicateInner<'a> => &'tcx PredicateInner<'tcx>}
nop_lift! {const_; Const<'a> => Const<'tcx>}
nop_lift_old! {const_allocation; &'a Allocation => &'tcx Allocation}
nop_lift! {predicate; Predicate<'a> => Predicate<'tcx>}
nop_list_lift! {type_list; Ty<'a> => Ty<'tcx>}
nop_list_lift! {poly_existential_predicates; ty::Binder<'a, ExistentialPredicate<'a>> => ty::Binder<'tcx, ExistentialPredicate<'tcx>>}
@ -1857,7 +1883,7 @@ macro_rules! sty_debug_print {
#[allow(non_snake_case)]
mod inner {
use crate::ty::{self, TyCtxt};
use crate::ty::context::Interned;
use crate::ty::context::InternedInSet;
#[derive(Copy, Clone)]
struct DebugStat {
@ -1880,16 +1906,16 @@ macro_rules! sty_debug_print {
let shards = tcx.interners.type_.lock_shards();
let types = shards.iter().flat_map(|shard| shard.keys());
for &Interned(t) in types {
let variant = match t.kind() {
for &InternedInSet(t) in types {
let variant = match t.kind {
ty::Bool | ty::Char | ty::Int(..) | ty::Uint(..) |
ty::Float(..) | ty::Str | ty::Never => continue,
ty::Error(_) => /* unimportant */ continue,
$(ty::$variant(..) => &mut $variant,)*
};
let lt = t.flags().intersects(ty::TypeFlags::HAS_RE_INFER);
let ty = t.flags().intersects(ty::TypeFlags::HAS_TY_INFER);
let ct = t.flags().intersects(ty::TypeFlags::HAS_CT_INFER);
let lt = t.flags.intersects(ty::TypeFlags::HAS_RE_INFER);
let ty = t.flags.intersects(ty::TypeFlags::HAS_TY_INFER);
let ct = t.flags.intersects(ty::TypeFlags::HAS_CT_INFER);
variant.total += 1;
total.total += 1;
@ -1980,86 +2006,86 @@ impl<'tcx> TyCtxt<'tcx> {
// this type just holds a pointer to it, but it still effectively owns it. It
// impls `Borrow` so that it can be looked up using the original
// (non-arena-memory-owning) types.
struct Interned<'tcx, T: ?Sized>(&'tcx T);
struct InternedInSet<'tcx, T: ?Sized>(&'tcx T);
impl<'tcx, T: 'tcx + ?Sized> Clone for Interned<'tcx, T> {
impl<'tcx, T: 'tcx + ?Sized> Clone for InternedInSet<'tcx, T> {
fn clone(&self) -> Self {
Interned(self.0)
InternedInSet(self.0)
}
}
impl<'tcx, T: 'tcx + ?Sized> Copy for Interned<'tcx, T> {}
impl<'tcx, T: 'tcx + ?Sized> Copy for InternedInSet<'tcx, T> {}
impl<'tcx, T: 'tcx + ?Sized> IntoPointer for Interned<'tcx, T> {
impl<'tcx, T: 'tcx + ?Sized> IntoPointer for InternedInSet<'tcx, T> {
fn into_pointer(&self) -> *const () {
self.0 as *const _ as *const ()
}
}
#[allow(rustc::usage_of_ty_tykind)]
impl<'tcx> Borrow<TyKind<'tcx>> for Interned<'tcx, TyS<'tcx>> {
impl<'tcx> Borrow<TyKind<'tcx>> for InternedInSet<'tcx, TyS<'tcx>> {
fn borrow<'a>(&'a self) -> &'a TyKind<'tcx> {
&self.0.kind()
}
}
impl<'tcx> PartialEq for Interned<'tcx, TyS<'tcx>> {
fn eq(&self, other: &Interned<'tcx, TyS<'tcx>>) -> bool {
// The `Borrow` trait requires that `x.borrow() == y.borrow()` equals
// `x == y`.
self.0.kind() == other.0.kind()
}
}
impl<'tcx> Eq for Interned<'tcx, TyS<'tcx>> {}
impl<'tcx> Hash for Interned<'tcx, TyS<'tcx>> {
fn hash<H: Hasher>(&self, s: &mut H) {
// The `Borrow` trait requires that `x.borrow().hash(s) == x.hash(s)`.
self.0.kind().hash(s)
}
}
impl<'tcx> Borrow<Binder<'tcx, PredicateKind<'tcx>>> for Interned<'tcx, PredicateInner<'tcx>> {
fn borrow<'a>(&'a self) -> &'a Binder<'tcx, PredicateKind<'tcx>> {
&self.0.kind
}
}
impl<'tcx> PartialEq for Interned<'tcx, PredicateInner<'tcx>> {
fn eq(&self, other: &Interned<'tcx, PredicateInner<'tcx>>) -> bool {
impl<'tcx> PartialEq for InternedInSet<'tcx, TyS<'tcx>> {
fn eq(&self, other: &InternedInSet<'tcx, TyS<'tcx>>) -> bool {
// The `Borrow` trait requires that `x.borrow() == y.borrow()` equals
// `x == y`.
self.0.kind == other.0.kind
}
}
impl<'tcx> Eq for Interned<'tcx, PredicateInner<'tcx>> {}
impl<'tcx> Eq for InternedInSet<'tcx, TyS<'tcx>> {}
impl<'tcx> Hash for Interned<'tcx, PredicateInner<'tcx>> {
impl<'tcx> Hash for InternedInSet<'tcx, TyS<'tcx>> {
fn hash<H: Hasher>(&self, s: &mut H) {
// The `Borrow` trait requires that `x.borrow().hash(s) == x.hash(s)`.
self.0.kind.hash(s)
}
}
impl<'tcx, T> Borrow<[T]> for Interned<'tcx, List<T>> {
impl<'tcx> Borrow<Binder<'tcx, PredicateKind<'tcx>>> for InternedInSet<'tcx, PredicateS<'tcx>> {
fn borrow<'a>(&'a self) -> &'a Binder<'tcx, PredicateKind<'tcx>> {
&self.0.kind
}
}
impl<'tcx> PartialEq for InternedInSet<'tcx, PredicateS<'tcx>> {
fn eq(&self, other: &InternedInSet<'tcx, PredicateS<'tcx>>) -> bool {
// The `Borrow` trait requires that `x.borrow() == y.borrow()` equals
// `x == y`.
self.0.kind == other.0.kind
}
}
impl<'tcx> Eq for InternedInSet<'tcx, PredicateS<'tcx>> {}
impl<'tcx> Hash for InternedInSet<'tcx, PredicateS<'tcx>> {
fn hash<H: Hasher>(&self, s: &mut H) {
// The `Borrow` trait requires that `x.borrow().hash(s) == x.hash(s)`.
self.0.kind.hash(s)
}
}
impl<'tcx, T> Borrow<[T]> for InternedInSet<'tcx, List<T>> {
fn borrow<'a>(&'a self) -> &'a [T] {
&self.0[..]
}
}
impl<'tcx, T: PartialEq> PartialEq for Interned<'tcx, List<T>> {
fn eq(&self, other: &Interned<'tcx, List<T>>) -> bool {
impl<'tcx, T: PartialEq> PartialEq for InternedInSet<'tcx, List<T>> {
fn eq(&self, other: &InternedInSet<'tcx, List<T>>) -> bool {
// The `Borrow` trait requires that `x.borrow() == y.borrow()` equals
// `x == y`.
self.0[..] == other.0[..]
}
}
impl<'tcx, T: Eq> Eq for Interned<'tcx, List<T>> {}
impl<'tcx, T: Eq> Eq for InternedInSet<'tcx, List<T>> {}
impl<'tcx, T: Hash> Hash for Interned<'tcx, List<T>> {
impl<'tcx, T: Hash> Hash for InternedInSet<'tcx, List<T>> {
fn hash<H: Hasher>(&self, s: &mut H) {
// The `Borrow` trait requires that `x.borrow().hash(s) == x.hash(s)`.
self.0[..].hash(s)
@ -2067,14 +2093,14 @@ impl<'tcx, T: Hash> Hash for Interned<'tcx, List<T>> {
}
macro_rules! direct_interners {
($($name:ident: $method:ident($ty:ty),)+) => {
$(impl<'tcx> Borrow<$ty> for Interned<'tcx, $ty> {
($($name:ident: $method:ident($ty:ty): $ret_ctor:ident -> $ret_ty:ty,)+) => {
$(impl<'tcx> Borrow<$ty> for InternedInSet<'tcx, $ty> {
fn borrow<'a>(&'a self) -> &'a $ty {
&self.0
}
}
impl<'tcx> PartialEq for Interned<'tcx, $ty> {
impl<'tcx> PartialEq for InternedInSet<'tcx, $ty> {
fn eq(&self, other: &Self) -> bool {
// The `Borrow` trait requires that `x.borrow() == y.borrow()`
// equals `x == y`.
@ -2082,9 +2108,50 @@ macro_rules! direct_interners {
}
}
impl<'tcx> Eq for Interned<'tcx, $ty> {}
impl<'tcx> Eq for InternedInSet<'tcx, $ty> {}
impl<'tcx> Hash for Interned<'tcx, $ty> {
impl<'tcx> Hash for InternedInSet<'tcx, $ty> {
fn hash<H: Hasher>(&self, s: &mut H) {
// The `Borrow` trait requires that `x.borrow().hash(s) ==
// x.hash(s)`.
self.0.hash(s)
}
}
impl<'tcx> TyCtxt<'tcx> {
pub fn $method(self, v: $ty) -> $ret_ty {
$ret_ctor(Interned::new_unchecked(self.interners.$name.intern(v, |v| {
InternedInSet(self.interners.arena.alloc(v))
}).0))
}
})+
}
}
direct_interners! {
region: mk_region(RegionKind): Region -> Region<'tcx>,
const_: mk_const(ConstS<'tcx>): Const -> Const<'tcx>,
}
macro_rules! direct_interners_old {
($($name:ident: $method:ident($ty:ty),)+) => {
$(impl<'tcx> Borrow<$ty> for InternedInSet<'tcx, $ty> {
fn borrow<'a>(&'a self) -> &'a $ty {
&self.0
}
}
impl<'tcx> PartialEq for InternedInSet<'tcx, $ty> {
fn eq(&self, other: &Self) -> bool {
// The `Borrow` trait requires that `x.borrow() == y.borrow()`
// equals `x == y`.
self.0 == other.0
}
}
impl<'tcx> Eq for InternedInSet<'tcx, $ty> {}
impl<'tcx> Hash for InternedInSet<'tcx, $ty> {
fn hash<H: Hasher>(&self, s: &mut H) {
// The `Borrow` trait requires that `x.borrow().hash(s) ==
// x.hash(s)`.
@ -2095,16 +2162,15 @@ macro_rules! direct_interners {
impl<'tcx> TyCtxt<'tcx> {
pub fn $method(self, v: $ty) -> &'tcx $ty {
self.interners.$name.intern(v, |v| {
Interned(self.interners.arena.alloc(v))
InternedInSet(self.interners.arena.alloc(v))
}).0
}
})+
}
}
direct_interners! {
region: mk_region(RegionKind),
const_: mk_const(Const<'tcx>),
// FIXME: eventually these should all be converted to `direct_interners`.
direct_interners_old! {
const_allocation: intern_const_alloc(Allocation),
layout: intern_layout(Layout),
adt_def: intern_adt_def(AdtDef),
@ -2117,7 +2183,7 @@ macro_rules! slice_interners {
impl<'tcx> TyCtxt<'tcx> {
$(pub fn $method(self, v: &[$ty]) -> &'tcx List<$ty> {
self.interners.$field.intern_ref(v, || {
Interned(List::from_arena(&*self.arena, v))
InternedInSet(List::from_arena(&*self.arena, v))
}).0
})+
}
@ -2217,8 +2283,7 @@ impl<'tcx> TyCtxt<'tcx> {
#[inline]
pub fn mk_predicate(self, binder: Binder<'tcx, PredicateKind<'tcx>>) -> Predicate<'tcx> {
let inner = self.interners.intern_predicate(binder);
Predicate { inner }
self.interners.intern_predicate(binder)
}
#[inline]
@ -2429,8 +2494,8 @@ impl<'tcx> TyCtxt<'tcx> {
}
#[inline]
pub fn mk_const_var(self, v: ConstVid<'tcx>, ty: Ty<'tcx>) -> &'tcx Const<'tcx> {
self.mk_const(ty::Const { val: ty::ConstKind::Infer(InferConst::Var(v)), ty })
pub fn mk_const_var(self, v: ConstVid<'tcx>, ty: Ty<'tcx>) -> Const<'tcx> {
self.mk_const(ty::ConstS { val: ty::ConstKind::Infer(InferConst::Var(v)), ty })
}
#[inline]
@ -2449,8 +2514,8 @@ impl<'tcx> TyCtxt<'tcx> {
}
#[inline]
pub fn mk_const_infer(self, ic: InferConst<'tcx>, ty: Ty<'tcx>) -> &'tcx ty::Const<'tcx> {
self.mk_const(ty::Const { val: ty::ConstKind::Infer(ic), ty })
pub fn mk_const_infer(self, ic: InferConst<'tcx>, ty: Ty<'tcx>) -> ty::Const<'tcx> {
self.mk_const(ty::ConstS { val: ty::ConstKind::Infer(ic), ty })
}
#[inline]
@ -2459,8 +2524,8 @@ impl<'tcx> TyCtxt<'tcx> {
}
#[inline]
pub fn mk_const_param(self, index: u32, name: Symbol, ty: Ty<'tcx>) -> &'tcx Const<'tcx> {
self.mk_const(ty::Const { val: ty::ConstKind::Param(ParamConst { index, name }), ty })
pub fn mk_const_param(self, index: u32, name: Symbol, ty: Ty<'tcx>) -> Const<'tcx> {
self.mk_const(ty::ConstS { val: ty::ConstKind::Param(ParamConst { index, name }), ty })
}
pub fn mk_param_from_def(self, param: &ty::GenericParamDef) -> GenericArg<'tcx> {

View file

@ -1,10 +1,10 @@
//! Diagnostics related methods for `TyS`.
//! Diagnostics related methods for `Ty`.
use crate::ty::subst::{GenericArg, GenericArgKind};
use crate::ty::TyKind::*;
use crate::ty::{
ConstKind, ExistentialPredicate, ExistentialProjection, ExistentialTraitRef, InferTy,
ProjectionTy, Term, TyCtxt, TyS, TypeAndMut,
ProjectionTy, Term, Ty, TyCtxt, TypeAndMut,
};
use rustc_errors::{Applicability, DiagnosticBuilder};
@ -13,9 +13,9 @@ use rustc_hir::def_id::DefId;
use rustc_hir::{QPath, TyKind, WhereBoundPredicate, WherePredicate};
use rustc_span::Span;
impl<'tcx> TyS<'tcx> {
/// Similar to `TyS::is_primitive`, but also considers inferred numeric values to be primitive.
pub fn is_primitive_ty(&self) -> bool {
impl<'tcx> Ty<'tcx> {
/// Similar to `Ty::is_primitive`, but also considers inferred numeric values to be primitive.
pub fn is_primitive_ty(self) -> bool {
matches!(
self.kind(),
Bool | Char
@ -34,7 +34,7 @@ impl<'tcx> TyS<'tcx> {
/// Whether the type is succinctly representable as a type instead of just referred to with a
/// description in error messages. This is used in the main error message.
pub fn is_simple_ty(&self) -> bool {
pub fn is_simple_ty(self) -> bool {
match self.kind() {
Bool
| Char
@ -58,7 +58,7 @@ impl<'tcx> TyS<'tcx> {
/// description in error messages. This is used in the primary span label. Beyond what
/// `is_simple_ty` includes, it also accepts ADTs with no type arguments and references to
/// ADTs with no type arguments.
pub fn is_simple_text(&self) -> bool {
pub fn is_simple_text(self) -> bool {
match self.kind() {
Adt(_, substs) => substs.non_erasable_generics().next().is_none(),
Ref(_, ty, _) => ty.is_simple_text(),
@ -67,11 +67,11 @@ impl<'tcx> TyS<'tcx> {
}
/// Whether the type can be safely suggested during error recovery.
pub fn is_suggestable(&self) -> bool {
pub fn is_suggestable(self) -> bool {
fn generic_arg_is_suggestible(arg: GenericArg<'_>) -> bool {
match arg.unpack() {
GenericArgKind::Type(ty) => ty.is_suggestable(),
GenericArgKind::Const(c) => const_is_suggestable(c.val),
GenericArgKind::Const(c) => const_is_suggestable(c.val()),
_ => true,
}
}
@ -110,7 +110,7 @@ impl<'tcx> TyS<'tcx> {
}) => {
let term_is_suggestable = match term {
Term::Ty(ty) => ty.is_suggestable(),
Term::Const(c) => const_is_suggestable(c.val),
Term::Const(c) => const_is_suggestable(c.val()),
};
term_is_suggestable && substs.iter().all(generic_arg_is_suggestible)
}
@ -120,7 +120,7 @@ impl<'tcx> TyS<'tcx> {
args.iter().all(generic_arg_is_suggestible)
}
Slice(ty) | RawPtr(TypeAndMut { ty, .. }) | Ref(_, ty, _) => ty.is_suggestable(),
Array(ty, c) => ty.is_suggestable() && const_is_suggestable(c.val),
Array(ty, c) => ty.is_suggestable() && const_is_suggestable(c.val()),
_ => true,
}
}

View file

@ -60,13 +60,13 @@ pub enum TypeError<'tcx> {
/// created a cycle (because it appears somewhere within that
/// type).
CyclicTy(Ty<'tcx>),
CyclicConst(&'tcx ty::Const<'tcx>),
CyclicConst(ty::Const<'tcx>),
ProjectionMismatched(ExpectedFound<DefId>),
ExistentialMismatch(
ExpectedFound<&'tcx ty::List<ty::Binder<'tcx, ty::ExistentialPredicate<'tcx>>>>,
),
ObjectUnsafeCoercion(DefId),
ConstMismatch(ExpectedFound<&'tcx ty::Const<'tcx>>),
ConstMismatch(ExpectedFound<ty::Const<'tcx>>),
IntrinsicCast,
/// Safe `#[target_feature]` functions are not assignable to safe function pointers.
@ -239,8 +239,8 @@ impl<'tcx> TypeError<'tcx> {
}
}
impl<'tcx> ty::TyS<'tcx> {
pub fn sort_string(&self, tcx: TyCtxt<'_>) -> Cow<'static, str> {
impl<'tcx> Ty<'tcx> {
pub fn sort_string(self, tcx: TyCtxt<'_>) -> Cow<'static, str> {
match *self.kind() {
ty::Bool | ty::Char | ty::Int(_) | ty::Uint(_) | ty::Float(_) | ty::Str | ty::Never => {
format!("`{}`", self).into()
@ -255,7 +255,7 @@ impl<'tcx> ty::TyS<'tcx> {
}
let n = tcx.lift(n).unwrap();
if let ty::ConstKind::Value(v) = n.val {
if let ty::ConstKind::Value(v) = n.val() {
if let Some(n) = v.try_to_machine_usize(tcx) {
return format!("array of {} element{}", n, pluralize!(n)).into();
}
@ -306,7 +306,7 @@ impl<'tcx> ty::TyS<'tcx> {
}
}
pub fn prefix_string(&self, tcx: TyCtxt<'_>) -> Cow<'static, str> {
pub fn prefix_string(self, tcx: TyCtxt<'_>) -> Cow<'static, str> {
match *self.kind() {
ty::Infer(_)
| ty::Error(_)

View file

@ -6,7 +6,7 @@ use std::slice;
pub struct FlagComputation {
pub flags: TypeFlags,
// see `TyS::outer_exclusive_binder` for details
// see `Ty::outer_exclusive_binder` for details
pub outer_exclusive_binder: ty::DebruijnIndex,
}
@ -28,7 +28,7 @@ impl FlagComputation {
result
}
pub fn for_const(c: &ty::Const<'_>) -> TypeFlags {
pub fn for_const(c: ty::Const<'_>) -> TypeFlags {
let mut result = FlagComputation::new();
result.add_const(c);
result.flags
@ -270,7 +270,7 @@ impl FlagComputation {
fn add_ty(&mut self, ty: Ty<'_>) {
self.add_flags(ty.flags());
self.add_exclusive_binder(ty.outer_exclusive_binder);
self.add_exclusive_binder(ty.outer_exclusive_binder());
}
fn add_tys(&mut self, tys: &[Ty<'_>]) {
@ -286,9 +286,9 @@ impl FlagComputation {
}
}
fn add_const(&mut self, c: &ty::Const<'_>) {
self.add_ty(c.ty);
match c.val {
fn add_const(&mut self, c: ty::Const<'_>) {
self.add_ty(c.ty());
match c.val() {
ty::ConstKind::Unevaluated(unevaluated) => self.add_unevaluated_const(unevaluated),
ty::ConstKind::Infer(infer) => {
self.add_flags(TypeFlags::STILL_FURTHER_SPECIALIZABLE);

Some files were not shown because too many files have changed in this diff Show more