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 /// We sometimes have `region` within an rvalue, or within a
/// call. Make them live at the location where they appear. /// call. Make them live at the location where they appear.
fn visit_region(&mut self, region: &ty::Region<'tcx>, location: Location) { fn visit_region(&mut self, region: ty::Region<'tcx>, location: Location) {
self.add_regular_live_constraint(*region, location); self.add_regular_live_constraint(region, location);
self.super_region(region); self.super_region(region);
} }

View file

@ -356,8 +356,8 @@ fn try_extract_error_from_fulfill_cx<'tcx>(
})?; })?;
debug!(?sub_region, "cause = {:#?}", cause); debug!(?sub_region, "cause = {:#?}", cause);
let nice_error = match (error_region, sub_region) { let nice_error = match (error_region, *sub_region) {
(Some(error_region), &ty::ReVar(vid)) => NiceRegionError::new( (Some(error_region), ty::ReVar(vid)) => NiceRegionError::new(
infcx, infcx,
RegionResolutionError::SubSupConflict( RegionResolutionError::SubSupConflict(
vid, vid,
@ -374,7 +374,7 @@ fn try_extract_error_from_fulfill_cx<'tcx>(
RegionResolutionError::ConcreteFailure(cause.clone(), error_region, placeholder_region), RegionResolutionError::ConcreteFailure(cause.clone(), error_region, placeholder_region),
), ),
// Note universe here is wrong... // Note universe here is wrong...
(None, &ty::ReVar(vid)) => NiceRegionError::new( (None, ty::ReVar(vid)) => NiceRegionError::new(
infcx, infcx,
RegionResolutionError::UpperBoundUniverseConflict( RegionResolutionError::UpperBoundUniverseConflict(
vid, 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 // This is also case 2 from above but for functions, return type is still an
// anonymous reference so we select the first argument. // anonymous reference so we select the first argument.
let argument_span = fn_decl.inputs.first()?.span; 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_span = fn_decl.output.span();
let return_ty = sig.output().skip_binder(); let return_ty = sig.output().skip_binder();
@ -2379,27 +2379,27 @@ impl<'tcx> AnnotatedBorrowFnSignature<'tcx> {
diag: &mut DiagnosticBuilder<'_>, diag: &mut DiagnosticBuilder<'_>,
) -> String { ) -> String {
match self { match self {
AnnotatedBorrowFnSignature::Closure { argument_ty, argument_span } => { &AnnotatedBorrowFnSignature::Closure { argument_ty, argument_span } => {
diag.span_label( diag.span_label(
*argument_span, argument_span,
format!("has type `{}`", cx.get_name_for_ty(argument_ty, 0)), format!("has type `{}`", cx.get_name_for_ty(argument_ty, 0)),
); );
cx.get_region_name_for_ty(argument_ty, 0) cx.get_region_name_for_ty(argument_ty, 0)
} }
AnnotatedBorrowFnSignature::AnonymousFunction { &AnnotatedBorrowFnSignature::AnonymousFunction {
argument_ty, argument_ty,
argument_span, argument_span,
return_ty, return_ty,
return_span, return_span,
} => { } => {
let argument_ty_name = cx.get_name_for_ty(argument_ty, 0); 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 return_ty_name = cx.get_name_for_ty(return_ty, 0);
let types_equal = return_ty_name == argument_ty_name; let types_equal = return_ty_name == argument_ty_name;
diag.span_label( diag.span_label(
*return_span, return_span,
format!( format!(
"{}has type `{}`", "{}has type `{}`",
if types_equal { "also " } else { "" }, if types_equal { "also " } else { "" },
@ -2419,7 +2419,7 @@ impl<'tcx> AnnotatedBorrowFnSignature<'tcx> {
} }
AnnotatedBorrowFnSignature::NamedFunction { arguments, return_ty, return_span } => { AnnotatedBorrowFnSignature::NamedFunction { arguments, return_ty, return_span } => {
// Region of return type and arguments checked to be the same earlier. // 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 { for (_, argument_span) in arguments {
diag.span_label(*argument_span, format!("has lifetime `{}`", region_name)); diag.span_label(*argument_span, format!("has lifetime `{}`", region_name));
} }

View file

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

View file

@ -246,18 +246,18 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
); );
( (
match kind { match kind {
IllegalMoveOriginKind::BorrowedContent { target_place } => self &IllegalMoveOriginKind::BorrowedContent { target_place } => self
.report_cannot_move_from_borrowed_content( .report_cannot_move_from_borrowed_content(
original_path, original_path,
*target_place, target_place,
span, span,
use_spans, use_spans,
), ),
IllegalMoveOriginKind::InteriorOfTypeWithDestructor { container_ty: ty } => { &IllegalMoveOriginKind::InteriorOfTypeWithDestructor { container_ty: ty } => {
self.cannot_move_out_of_interior_of_drop(span, ty) self.cannot_move_out_of_interior_of_drop(span, ty)
} }
IllegalMoveOriginKind::InteriorOfSliceOrArray { ty, is_index } => { &IllegalMoveOriginKind::InteriorOfSliceOrArray { ty, is_index } => {
self.cannot_move_out_of_interior_noncopy(span, ty, Some(*is_index)) self.cannot_move_out_of_interior_noncopy(span, ty, Some(is_index))
} }
}, },
span, 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. /// Returns `true` if a closure is inferred to be an `FnMut` closure.
fn is_closure_fn_mut(&self, fr: RegionVid) -> bool { 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 ty::BoundRegionKind::BrEnv = free_region.bound_region {
if let DefiningTy::Closure(_, substs) = if let DefiningTy::Closure(_, substs) =
self.regioncx.universal_regions().defining_ty self.regioncx.universal_regions().defining_ty
@ -628,8 +628,8 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
fr_name: RegionName, fr_name: RegionName,
outlived_fr: RegionVid, outlived_fr: RegionVid,
) { ) {
if let (Some(f), Some(ty::RegionKind::ReStatic)) = if let (Some(f), Some(ty::ReStatic)) =
(self.to_error_region(fr), self.to_error_region(outlived_fr)) (self.to_error_region(fr), self.to_error_region(outlived_fr).as_deref())
{ {
if let Some(&ty::Opaque(did, substs)) = self if let Some(&ty::Opaque(did, substs)) = self
.infcx .infcx
@ -652,7 +652,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
bound.kind().skip_binder() bound.kind().skip_binder()
{ {
let r = r.subst(self.infcx.tcx, substs); let r = r.subst(self.infcx.tcx, substs);
if let ty::RegionKind::ReStatic = r { if r.is_static() {
found = true; found = true;
break; break;
} else { } else {

View file

@ -264,7 +264,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
let tcx = self.infcx.tcx; let tcx = self.infcx.tcx;
debug!("give_region_a_name: error_region = {:?}", error_region); debug!("give_region_a_name: error_region = {:?}", error_region);
match error_region { match *error_region {
ty::ReEarlyBound(ebr) => { ty::ReEarlyBound(ebr) => {
if ebr.has_name() { if ebr.has_name() {
let span = tcx.hir().span_if_local(ebr.def_id).unwrap_or(DUMMY_SP); let span = tcx.hir().span_if_local(ebr.def_id).unwrap_or(DUMMY_SP);
@ -433,7 +433,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
span: Span, span: Span,
counter: usize, counter: usize,
) -> RegionNameHighlight { ) -> RegionNameHighlight {
let mut highlight = RegionHighlightMode::default(); let mut highlight = RegionHighlightMode::new(self.infcx.tcx);
highlight.highlighting_region_vid(needle_fr, counter); highlight.highlighting_region_vid(needle_fr, counter);
let type_name = let type_name =
self.infcx.extract_inference_diagnostics_data(ty.into(), Some(highlight)).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. // 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>` // 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::Slice(elem_ty), hir::TyKind::Slice(elem_hir_ty))
| (ty::Array(elem_ty, _), hir::TyKind::Array(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)) => { (ty::RawPtr(mut_ty), hir::TyKind::Ptr(mut_hir_ty)) => {
@ -818,7 +818,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
return None; 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()); highlight.highlighting_region_vid(fr, *self.next_region_name.try_borrow().unwrap());
let type_name = let type_name =
self.infcx.extract_inference_diagnostics_data(yield_ty.into(), Some(highlight)).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, BasicBlock, Body, ClosureOutlivesSubject, ClosureRegionRequirements, LocalKind, Location,
Promoted, 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 rustc_span::symbol::sym;
use std::env; use std::env;
use std::fmt::Debug; use std::fmt::Debug;
@ -443,9 +443,9 @@ pub trait ToRegionVid {
fn to_region_vid(self) -> RegionVid; fn to_region_vid(self) -> RegionVid;
} }
impl<'tcx> ToRegionVid for &'tcx RegionKind { impl<'tcx> ToRegionVid for Region<'tcx> {
fn to_region_vid(self) -> RegionVid { 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 { match verify_bound {
VerifyBound::IfEq(test_ty, verify_bound1) => { 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 => { VerifyBound::IsEmpty => {
@ -1178,7 +1178,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
} }
VerifyBound::OutlivedBy(r) => { 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) 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) { for vid in self.rev_scc_graph.as_ref().unwrap().upper_bounds(scc) {
match self.definitions[vid].external_name { match self.definitions[vid].external_name {
None => {} None => {}
Some(&ty::ReStatic) => {} Some(region) if region.is_static() => {}
Some(region) => return region, Some(region) => return region,
} }
} }
@ -183,7 +183,7 @@ fn check_opaque_type_parameter_valid(
for (i, arg) in opaque_type_key.substs.iter().enumerate() { for (i, arg) in opaque_type_key.substs.iter().enumerate() {
let arg_is_param = match arg.unpack() { let arg_is_param = match arg.unpack() {
GenericArgKind::Type(ty) => matches!(ty.kind(), ty::Param(_)), GenericArgKind::Type(ty) => matches!(ty.kind(), ty::Param(_)),
GenericArgKind::Lifetime(ty::ReStatic) => { GenericArgKind::Lifetime(lt) if lt.is_static() => {
tcx.sess tcx.sess
.struct_span_err(span, "non-defining opaque type use in defining scope") .struct_span_err(span, "non-defining opaque type use in defining scope")
.span_label( .span_label(
@ -196,9 +196,9 @@ fn check_opaque_type_parameter_valid(
return false; return false;
} }
GenericArgKind::Lifetime(lt) => { 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 { if arg_is_param {

View file

@ -57,7 +57,7 @@ impl<'a, 'tcx> MutVisitor<'tcx> for NllVisitor<'a, 'tcx> {
#[instrument(skip(self), level = "debug")] #[instrument(skip(self), level = "debug")]
fn visit_ty(&mut self, ty: &mut Ty<'tcx>, ty_context: TyContext) { fn visit_ty(&mut self, ty: &mut Ty<'tcx>, ty_context: TyContext) {
*ty = self.renumber_regions(ty); *ty = self.renumber_regions(*ty);
debug!(?ty); debug!(?ty);
} }
@ -72,12 +72,12 @@ impl<'a, 'tcx> MutVisitor<'tcx> for NllVisitor<'a, 'tcx> {
#[instrument(skip(self), level = "debug")] #[instrument(skip(self), level = "debug")]
fn visit_region(&mut self, region: &mut ty::Region<'tcx>, location: Location) { fn visit_region(&mut self, region: &mut ty::Region<'tcx>, location: Location) {
let old_region = *region; let old_region = *region;
*region = self.renumber_regions(&old_region); *region = self.renumber_regions(old_region);
debug!(?region); debug!(?region);
} }
fn visit_const(&mut self, constant: &mut &'tcx ty::Const<'tcx>, _location: Location) { fn visit_const(&mut self, constant: &mut ty::Const<'tcx>, _location: Location) {
*constant = self.renumber_regions(&*constant); *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 // create new region variables, which can't be done later when
// verifying these bounds. // verifying these bounds.
if t1.has_placeholders() { if t1.has_placeholders() {
t1 = tcx.fold_regions(&t1, &mut false, |r, _| match *r { t1 = tcx.fold_regions(t1, &mut false, |r, _| match *r {
ty::RegionKind::RePlaceholder(placeholder) => { ty::RePlaceholder(placeholder) => {
self.constraints.placeholder_region(self.infcx, placeholder) self.constraints.placeholder_region(self.infcx, placeholder)
} }
_ => r, _ => r,
@ -142,8 +142,8 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> {
} }
fn to_region_vid(&mut self, r: ty::Region<'tcx>) -> ty::RegionVid { fn to_region_vid(&mut self, r: ty::Region<'tcx>) -> ty::RegionVid {
if let ty::RePlaceholder(placeholder) = r { if let ty::RePlaceholder(placeholder) = *r {
self.constraints.placeholder_region(self.infcx, *placeholder).to_region_vid() self.constraints.placeholder_region(self.infcx, placeholder).to_region_vid()
} else { } else {
self.universal_regions.to_region_vid(r) 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 // `where Type:` is lowered to `where Type: 'empty` so that
// we check `Type` is well formed, but there's no use for // we check `Type` is well formed, but there's no use for
// this bound here. // this bound here.
if let ty::ReEmpty(_) = r1 { if r1.is_empty() {
return; return;
} }

View file

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

View file

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

View file

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

View file

@ -79,7 +79,7 @@ pub(crate) fn codegen_fn<'tcx>(
let arg_uninhabited = fx let arg_uninhabited = fx
.mir .mir
.args_iter() .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) { if !crate::constant::check_constants(&mut fx) {
fx.bcx.append_block_params_for_function_params(fx.block_map[START_BLOCK]); fx.bcx.append_block_params_for_function_params(fx.block_map[START_BLOCK]);
@ -668,7 +668,7 @@ fn codegen_stmt<'tcx>(
let times = fx let times = fx
.monomorphize(times) .monomorphize(times)
.eval(fx.tcx, ParamEnv::reveal_all()) .eval(fx.tcx, ParamEnv::reveal_all())
.val .val()
.try_to_bits(fx.tcx.data_layout.pointer_size) .try_to_bits(fx.tcx.data_layout.pointer_size)
.unwrap(); .unwrap();
if operand.layout().size.bytes() == 0 { if operand.layout().size.bytes() == 0 {
@ -818,16 +818,16 @@ pub(crate) fn codegen_place<'tcx>(
match cplace.layout().ty.kind() { match cplace.layout().ty.kind() {
ty::Array(elem_ty, _len) => { ty::Array(elem_ty, _len) => {
assert!(!from_end, "array subslices are never `from_end`"); 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(); let ptr = cplace.to_ptr();
cplace = CPlace::for_ptr( cplace = CPlace::for_ptr(
ptr.offset_i64(fx, elem_layout.size.bytes() as i64 * (from as i64)), 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) => { ty::Slice(elem_ty) => {
assert!(from_end, "slice subslices should be `from_end`"); 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 (ptr, len) = cplace.to_ptr_maybe_unsized();
let len = len.unwrap(); let len = len.unwrap();
cplace = CPlace::for_ptr_with_extra( 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::FnPtr(_) => pointer_ty(tcx),
ty::RawPtr(TypeAndMut { ty: pointee_ty, mutbl: _ }) | ty::Ref(_, pointee_ty, _) => { 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; return None;
} else { } else {
pointer_ty(tcx) pointer_ty(tcx)
@ -100,7 +100,7 @@ fn clif_pair_type_from_ty<'tcx>(
(a, b) (a, b)
} }
ty::RawPtr(TypeAndMut { ty: pointee_ty, mutbl: _ }) | ty::Ref(_, pointee_ty, _) => { 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)) (pointer_ty(tcx), pointer_ty(tcx))
} else { } else {
return None; return None;

View file

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

View file

@ -114,7 +114,7 @@ impl<'tcx> DebugContext<'tcx> {
} }
fn dwarf_ty(&mut self, ty: Ty<'tcx>) -> UnitEntryId { 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; return *type_id;
} }
@ -143,7 +143,7 @@ impl<'tcx> DebugContext<'tcx> {
// Ensure that type is inserted before recursing to avoid duplicates // Ensure that type is inserted before recursing to avoid duplicates
self.types.insert(ty, type_id); 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); 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::Ref(_, b, _))
| (&ty::Ref(_, a, _), &ty::RawPtr(ty::TypeAndMut { ty: b, .. })) | (&ty::Ref(_, a, _), &ty::RawPtr(ty::TypeAndMut { ty: b, .. }))
| (&ty::RawPtr(ty::TypeAndMut { ty: 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() => { (&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()); 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 // Can only happen for vector types
let len = let len =
u16::try_from(len.eval_usize(fx.tcx, ParamEnv::reveal_all())).unwrap(); 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 { let data = match from.0 {
CValueInner::ByRef(ptr, None) => { CValueInner::ByRef(ptr, None) => {
@ -721,8 +721,8 @@ impl<'tcx> CPlace<'tcx> {
index: Value, index: Value,
) -> CPlace<'tcx> { ) -> CPlace<'tcx> {
let (elem_layout, ptr) = match self.layout().ty.kind() { let (elem_layout, ptr) = match self.layout().ty.kind() {
ty::Array(elem_ty, _) => (fx.layout_of(elem_ty), self.to_ptr()), 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::Slice(elem_ty) => (fx.layout_of(*elem_ty), self.to_ptr_maybe_unsized().0),
_ => bug!("place_index({:?})", self.layout().ty), _ => 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: a, mutbl: _ }),
ty::RawPtr(TypeAndMut { ty: b, 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::Ref(_, a, _), ty::RawPtr(TypeAndMut { ty: b, mutbl: _ }))
| (ty::RawPtr(TypeAndMut { ty: a, mutbl: _ }), ty::Ref(_, b, _)) => { | (ty::RawPtr(TypeAndMut { ty: a, mutbl: _ }), ty::Ref(_, b, _)) => {
assert_assignable(fx, a, b); assert_assignable(fx, *a, *b);
} }
(ty::FnPtr(_), ty::FnPtr(_)) => { (ty::FnPtr(_), ty::FnPtr(_)) => {
let from_sig = fx.tcx.normalize_erasing_late_bound_regions( 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 /// This function is used to remove the temporary metadata
/// mapping after we've computed the actual metadata. /// mapping after we've computed the actual metadata.
fn remove_type(&mut self, type_: Ty<'tcx>) { fn remove_type(&mut self, ty: Ty<'tcx>) {
if self.type_to_metadata.remove(type_).is_none() { if self.type_to_metadata.remove(&ty).is_none() {
bug!("type metadata `Ty` '{}' is not in the `TypeMap`!", type_); 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) 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); return_if_metadata_created_in_meantime!(cx, unique_type_id);
@ -546,7 +546,7 @@ fn subroutine_type_metadata<'ll, 'tcx>(
) )
.chain( .chain(
// regular arguments // 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(); .collect();
@ -601,7 +601,7 @@ fn slice_type_metadata<'ll, 'tcx>(
unique_type_id: UniqueTypeId, unique_type_id: UniqueTypeId,
) -> MetadataCreationResult<'ll> { ) -> MetadataCreationResult<'ll> {
let element_type = match slice_type.kind() { 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, ty::Str => cx.tcx.types.u8,
_ => { _ => {
bug!( bug!(

View file

@ -430,9 +430,9 @@ impl<'ll, 'tcx> DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
let t = arg.layout.ty; let t = arg.layout.ty;
let t = match t.kind() { let t = match t.kind() {
ty::Array(ct, _) 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, _ => t,
}; };

View file

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

View file

@ -146,7 +146,7 @@ fn push_debuginfo_type_name<'tcx>(
if cpp_like_debuginfo { if cpp_like_debuginfo {
output.push_str("array$<"); output.push_str("array$<");
push_debuginfo_type_name(tcx, inner_type, true, output, visited); 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(), ty::ConstKind::Param(param) => write!(output, ",{}>", param.name).unwrap(),
_ => write!(output, ",{}>", len.eval_usize(tcx, ty::ParamEnv::reveal_all())) _ => write!(output, ",{}>", len.eval_usize(tcx, ty::ParamEnv::reveal_all()))
.unwrap(), .unwrap(),
@ -154,7 +154,7 @@ fn push_debuginfo_type_name<'tcx>(
} else { } else {
output.push('['); output.push('[');
push_debuginfo_type_name(tcx, inner_type, true, output, visited); 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(), ty::ConstKind::Param(param) => write!(output, "; {}]", param.name).unwrap(),
_ => write!(output, "; {}]", len.eval_usize(tcx, ty::ParamEnv::reveal_all())) _ => write!(output, "; {}]", len.eval_usize(tcx, ty::ParamEnv::reveal_all()))
.unwrap(), .unwrap(),
@ -343,7 +343,7 @@ fn push_debuginfo_type_name<'tcx>(
// We only care about avoiding recursing // We only care about avoiding recursing
// directly back to the type we're currently // directly back to the type we're currently
// processing // processing
visited.remove(t); visited.remove(&t);
} }
ty::Closure(def_id, substs) | ty::Generator(def_id, substs, ..) => { ty::Closure(def_id, substs) | ty::Generator(def_id, substs, ..) => {
// Name will be "{closure_env#0}<T1, T2, ...>", "{generator_env#0}<T1, T2, ...>", or // 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 true
} }
fn push_const_param<'tcx>(tcx: TyCtxt<'tcx>, ct: &'tcx ty::Const<'tcx>, output: &mut String) { fn push_const_param<'tcx>(tcx: TyCtxt<'tcx>, ct: ty::Const<'tcx>, output: &mut String) {
match ct.val { match ct.val() {
ty::ConstKind::Param(param) => { ty::ConstKind::Param(param) => {
write!(output, "{}", param.name) write!(output, "{}", param.name)
} }
_ => match ct.ty.kind() { _ => match ct.ty().kind() {
ty::Int(ity) => { 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; let val = Integer::from_int_ty(&tcx, *ity).size().sign_extend(bits) as i128;
write!(output, "{}", val) write!(output, "{}", val)
} }
ty::Uint(_) => { 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) write!(output, "{}", val)
} }
ty::Bool => { 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(); let mut hasher = StableHasher::new();
hcx.while_hashing_spans(false, |hcx| { hcx.while_hashing_spans(false, |hcx| {
hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |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 // 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::Ty(ct) => ct,
mir::ConstantKind::Val(val, _) => return Ok(val), mir::ConstantKind::Val(val, _) => return Ok(val),
}; };
match ct.val { match ct.val() {
ty::ConstKind::Unevaluated(ct) => self ty::ConstKind::Unevaluated(ct) => self
.cx .cx
.tcx() .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 c = ty::Const::from_value(bx.tcx(), val, ty);
let values: Vec<_> = bx let values: Vec<_> = bx
.tcx() .tcx()
.destructure_const(ty::ParamEnv::reveal_all().and(&c)) .destructure_const(ty::ParamEnv::reveal_all().and(c))
.fields .fields
.iter() .iter()
.map(|field| { .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 layout = bx.layout_of(field_ty);
let scalar = match layout.abi { let scalar = match layout.abi {
Abi::Scalar(x) => x, Abi::Scalar(x) => x,
@ -78,7 +78,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
}) })
.collect(); .collect();
let llval = bx.const_struct(&values, false); let llval = bx.const_struct(&values, false);
(llval, c.ty) (llval, c.ty())
}) })
.unwrap_or_else(|_| { .unwrap_or_else(|_| {
bx.tcx().sess.span_err(span, "could not evaluate shuffle_indices at compile time"); 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>( pub(crate) fn destructure_const<'tcx>(
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
param_env: ty::ParamEnv<'tcx>, param_env: ty::ParamEnv<'tcx>,
val: &'tcx ty::Const<'tcx>, val: ty::Const<'tcx>,
) -> mir::DestructuredConst<'tcx> { ) -> mir::DestructuredConst<'tcx> {
trace!("destructure_const: {:?}", val); trace!("destructure_const: {:?}", val);
let ecx = mk_eval_cx(tcx, DUMMY_SP, param_env, false); let ecx = mk_eval_cx(tcx, DUMMY_SP, param_env, false);
let op = ecx.const_to_op(val, None).unwrap(); let op = ecx.const_to_op(val, None).unwrap();
// We go to `usize` as we cannot allocate anything bigger anyway. // 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::Array(_, len) => (usize::try_from(len.eval_usize(tcx, param_env)).unwrap(), None, op),
ty::Adt(def, _) if def.variants.is_empty() => { ty::Adt(def, _) if def.variants.is_empty() => {
return mir::DestructuredConst { variant: None, fields: &[] }; return mir::DestructuredConst { variant: None, fields: &[] };
@ -173,8 +173,8 @@ pub(crate) fn destructure_const<'tcx>(
pub(crate) fn deref_const<'tcx>( pub(crate) fn deref_const<'tcx>(
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
param_env: ty::ParamEnv<'tcx>, param_env: ty::ParamEnv<'tcx>,
val: &'tcx ty::Const<'tcx>, val: ty::Const<'tcx>,
) -> &'tcx ty::Const<'tcx> { ) -> ty::Const<'tcx> {
trace!("deref_const: {:?}", val); trace!("deref_const: {:?}", val);
let ecx = mk_eval_cx(tcx, DUMMY_SP, param_env, false); let ecx = mk_eval_cx(tcx, DUMMY_SP, param_env, false);
let op = ecx.const_to_op(val, None).unwrap(); 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. // In case of unsized types, figure out the real type behind.
MemPlaceMeta::Meta(scalar) => match mplace.layout.ty.kind() { MemPlaceMeta::Meta(scalar) => match mplace.layout.ty.kind() {
ty::Str => bug!("there's no sized equivalent of a `str`"), 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!( _ => bug!(
"type {} should not have metadata, but had {:?}", "type {} should not have metadata, but had {:?}",
mplace.layout.ty, 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()) { match (&src.layout.ty.kind(), &cast_ty.ty.kind()) {
(&ty::Ref(_, s, _), &ty::Ref(_, c, _) | &ty::RawPtr(TypeAndMut { ty: c, .. })) (&ty::Ref(_, s, _), &ty::Ref(_, c, _) | &ty::RawPtr(TypeAndMut { ty: c, .. }))
| (&ty::RawPtr(TypeAndMut { ty: s, .. }), &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, _)) => { (&ty::Adt(def_a, _), &ty::Adt(def_b, _)) => {
assert_eq!(def_a, 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) 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). /// "universe" (param_env).
pub fn const_to_op( pub fn const_to_op(
&self, &self,
val: &ty::Const<'tcx>, val: ty::Const<'tcx>,
layout: Option<TyAndLayout<'tcx>>, layout: Option<TyAndLayout<'tcx>>,
) -> InterpResult<'tcx, OpTy<'tcx, M::PointerTag>> { ) -> InterpResult<'tcx, OpTy<'tcx, M::PointerTag>> {
match val.val { match val.val() {
ty::ConstKind::Param(_) | ty::ConstKind::Bound(..) => throw_inval!(TooGeneric), ty::ConstKind::Param(_) | ty::ConstKind::Bound(..) => throw_inval!(TooGeneric),
ty::ConstKind::Error(_) => throw_inval!(AlreadyReported(ErrorReported)), ty::ConstKind::Error(_) => throw_inval!(AlreadyReported(ErrorReported)),
ty::ConstKind::Unevaluated(uv) => { 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(..) => { ty::ConstKind::Infer(..) | ty::ConstKind::Placeholder(..) => {
span_bug!(self.cur_span(), "const_to_op: Unexpected ConstKind {:?}", val) 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>>, layout: Option<TyAndLayout<'tcx>>,
) -> InterpResult<'tcx, OpTy<'tcx, M::PointerTag>> { ) -> InterpResult<'tcx, OpTy<'tcx, M::PointerTag>> {
match val { match val {
mir::ConstantKind::Ty(ct) => self.const_to_op(ct, layout), 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::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() { 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 // It is not nice to match on the type, but that seems to be the only way to
// implement this. // 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(..) => { ty::Slice(..) => {
let len = Scalar::from_machine_usize(inner_len, self); let len = Scalar::from_machine_usize(inner_len, self);
(MemPlaceMeta::Meta(len), base.layout.ty) (MemPlaceMeta::Meta(len), base.layout.ty)

View file

@ -55,7 +55,7 @@ where
assert!(matches!(ty.kind(), ty::Param(_))) assert!(matches!(ty.kind(), ty::Param(_)))
} }
ty::subst::GenericArgKind::Const(ct) => { ty::subst::GenericArgKind::Const(ct) => {
assert!(matches!(ct.val, ty::ConstKind::Param(_))) assert!(matches!(ct.val(), ty::ConstKind::Param(_)))
} }
ty::subst::GenericArgKind::Lifetime(..) => (), ty::subst::GenericArgKind::Lifetime(..) => (),
}, },
@ -68,8 +68,8 @@ where
} }
} }
fn visit_const(&mut self, c: &'tcx ty::Const<'tcx>) -> ControlFlow<Self::BreakTy> { fn visit_const(&mut self, c: ty::Const<'tcx>) -> ControlFlow<Self::BreakTy> {
match c.val { match c.val() {
ty::ConstKind::Param(..) => ControlFlow::Break(FoundParam), ty::ConstKind::Param(..) => ControlFlow::Break(FoundParam),
_ => c.super_visit_with(self), _ => 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 mutable reference inside a const? That does not seem right (except if it is
// a ZST). // a ZST).
let layout = self.ecx.layout_of(ty)?; let layout = self.ecx.layout_of(*ty)?;
if !layout.is_zst() { if !layout.is_zst() {
throw_validation_failure!(self.path, { "mutable reference in a `const`" }); 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. // This is the length of the array/slice.
let len = mplace.len(self.ecx)?; let len = mplace.len(self.ecx)?;
// This is the element type size. // 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.) // This is the size in bytes of the whole array. (This checks for overflow.)
let size = layout.size * len; 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 // 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 // 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. // 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). // Validate just the first element (if any).
self.walk_aggregate(op, fields.take(1))? 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; let mut tmp_ty = self_ty;
while let rustc_middle::ty::Ref(_, inner_ty, _) = tmp_ty.kind() { while let rustc_middle::ty::Ref(_, inner_ty, _) = tmp_ty.kind() {
num_refs += 1; num_refs += 1;
tmp_ty = inner_ty; tmp_ty = *inner_ty;
} }
let deref = "*".repeat(num_refs); let deref = "*".repeat(num_refs);

View file

@ -355,7 +355,7 @@ where
// Check the qualifs of the value of `const` items. // Check the qualifs of the value of `const` items.
if let Some(ct) = constant.literal.const_for_ty() { 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 // 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 // only for `NeedsNonConstDrop` with precise drop checking. This is the only const
// check performed after the promotion. Verify that with an assertion. // 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) { if matches!(kind, CastKind::Misc) {
let operand_ty = operand.ty(self.body, self.tcx); 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_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) { 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 // ptr-to-int casts are not possible in consts and thus not promotable
return Err(Unpromotable); return Err(Unpromotable);
@ -839,7 +839,7 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> {
span, span,
user_ty: None, user_ty: None,
literal: tcx literal: tcx
.mk_const(ty::Const { .mk_const(ty::ConstS {
ty, ty,
val: ty::ConstKind::Unevaluated(ty::Unevaluated { val: ty::ConstKind::Unevaluated(ty::Unevaluated {
def, 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(type_alias_impl_trait)]
#![feature(new_uninit)] #![feature(new_uninit)]
#![feature(once_cell)] #![feature(once_cell)]
#![feature(rustc_attrs)]
#![feature(test)] #![feature(test)]
#![feature(thread_id_value)] #![feature(thread_id_value)]
#![feature(vec_into_raw_parts)] #![feature(vec_into_raw_parts)]
@ -68,12 +69,12 @@ pub mod flock;
pub mod functor; pub mod functor;
pub mod fx; pub mod fx;
pub mod graph; pub mod graph;
pub mod intern;
pub mod jobserver; pub mod jobserver;
pub mod macros; pub mod macros;
pub mod map_in_place; pub mod map_in_place;
pub mod obligation_forest; pub mod obligation_forest;
pub mod owning_ref; pub mod owning_ref;
pub mod ptr_key;
pub mod sip128; pub mod sip128;
pub mod small_c_str; pub mod small_c_str;
pub mod snapshot_map; 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( fn to_trace(
_: TyCtxt<'tcx>, _: TyCtxt<'tcx>,
cause: &ObligationCause<'tcx>, cause: &ObligationCause<'tcx>,

View file

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

View file

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

View file

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

View file

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

View file

@ -369,7 +369,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
pub fn extract_inference_diagnostics_data( pub fn extract_inference_diagnostics_data(
&self, &self,
arg: GenericArg<'tcx>, arg: GenericArg<'tcx>,
highlight: Option<ty::print::RegionHighlightMode>, highlight: Option<ty::print::RegionHighlightMode<'tcx>>,
) -> InferenceDiagnosticsData { ) -> InferenceDiagnosticsData {
match arg.unpack() { match arg.unpack() {
GenericArgKind::Type(ty) => { GenericArgKind::Type(ty) => {
@ -409,7 +409,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
} }
} }
GenericArgKind::Const(ct) => { GenericArgKind::Const(ct) => {
match ct.val { match ct.val() {
ty::ConstKind::Infer(InferConst::Var(vid)) => { ty::ConstKind::Infer(InferConst::Var(vid)) => {
let origin = self let origin = self
.inner .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(_)) => { ty::ConstKind::Infer(InferConst::Var(_)) => {
return self.extract_inference_diagnostics_data(s, None); 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. /// 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> { fn replace_infers(&self, c: Const<'tcx>, index: u32, name: Symbol) -> Const<'tcx> {
match c.val { match c.val() {
ty::ConstKind::Infer(..) => self.tcx().mk_const_param(index, name, c.ty), ty::ConstKind::Infer(..) => self.tcx().mk_const_param(index, name, c.ty()),
_ => c, _ => c,
} }
} }
@ -962,7 +962,7 @@ impl<'tcx> TypeFolder<'tcx> for ResolvedTypeParamEraser<'tcx> {
.map(|(subst, param)| match &(subst.unpack(), &param.kind) { .map(|(subst, param)| match &(subst.unpack(), &param.kind) {
(_, ty::GenericParamDefKind::Type { has_default: true, .. }) => subst, (_, ty::GenericParamDefKind::Type { has_default: true, .. }) => subst,
(crate::infer::GenericArgKind::Const(c), _) => { (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), _ => subst.super_fold_with(self),
}) })
@ -985,7 +985,7 @@ impl<'tcx> TypeFolder<'tcx> for ResolvedTypeParamEraser<'tcx> {
} }
} }
ty::Ref(_, ty, _) => { ty::Ref(_, ty, _) => {
let ty = self.fold_ty(ty); let ty = self.fold_ty(*ty);
match ty.kind() { match ty.kind() {
// Avoid `&_`, these can be safely presented as `_`. // Avoid `&_`, these can be safely presented as `_`.
ty::Error(_) => self.tcx().ty_error(), ty::Error(_) => self.tcx().ty_error(),
@ -1002,7 +1002,7 @@ impl<'tcx> TypeFolder<'tcx> for ResolvedTypeParamEraser<'tcx> {
| ty::Projection(_) | ty::Projection(_)
| ty::Never => t.super_fold_with(self), | ty::Never => t.super_fold_with(self),
ty::Array(ty, c) => { 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. // 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 // 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_errors::{Applicability, ErrorReported};
use rustc_hir as hir; use rustc_hir as hir;
use rustc_hir::intravisit::Visitor; use rustc_hir::intravisit::Visitor;
use rustc_middle::ty::{self, TypeVisitor}; use rustc_middle::ty::TypeVisitor;
use rustc_span::MultiSpan; use rustc_span::MultiSpan;
impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
@ -22,7 +22,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
RegionResolutionError::ConcreteFailure(origin, sub, sup) => (origin, sub, sup), RegionResolutionError::ConcreteFailure(origin, sub, sup) => (origin, sub, sup),
_ => return None, _ => return None,
}; };
if *sub != ty::RegionKind::ReStatic { if !sub.is_static() {
return None; return None;
} }
let cause = match origin { 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>)> { pub fn regions(&self) -> Option<(Span, ty::Region<'tcx>, ty::Region<'tcx>)> {
match (&self.error, self.regions) { 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(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, Some((span, sub, sup))) => Some((span, sub, sup)),
_ => None, _ => 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, // Suggesting to add a `'static` lifetime to a parameter is nearly always incorrect,
// and can steer users down the wrong path. // and can steer users down the wrong path.
if *named == ty::ReStatic { if named.is_static() {
return None; return None;
} }

View file

@ -3,13 +3,14 @@ use crate::infer::lexical_region_resolve::RegionResolutionError;
use crate::infer::ValuePairs; use crate::infer::ValuePairs;
use crate::infer::{SubregionOrigin, TypeTrace}; use crate::infer::{SubregionOrigin, TypeTrace};
use crate::traits::{ObligationCause, ObligationCauseCode}; use crate::traits::{ObligationCause, ObligationCauseCode};
use rustc_data_structures::intern::Interned;
use rustc_errors::DiagnosticBuilder; use rustc_errors::DiagnosticBuilder;
use rustc_hir::def::Namespace; use rustc_hir::def::Namespace;
use rustc_hir::def_id::DefId; use rustc_hir::def_id::DefId;
use rustc_middle::ty::error::ExpectedFound; use rustc_middle::ty::error::ExpectedFound;
use rustc_middle::ty::print::{FmtPrinter, Print, RegionHighlightMode}; use rustc_middle::ty::print::{FmtPrinter, Print, RegionHighlightMode};
use rustc_middle::ty::subst::SubstsRef; 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}; use std::fmt::{self, Write};
@ -31,15 +32,15 @@ impl<'tcx> NiceRegionError<'_, 'tcx> {
vid, vid,
_, _,
SubregionOrigin::Subtype(box TypeTrace { cause, values }), 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( )) => self.try_report_trait_placeholder_mismatch(
Some(self.tcx().mk_region(ty::ReVar(*vid))), Some(self.tcx().mk_region(ReVar(*vid))),
cause, cause,
Some(sub_placeholder), Some(*sub_placeholder),
Some(sup_placeholder), Some(*sup_placeholder),
values, values,
), ),
@ -47,14 +48,14 @@ impl<'tcx> NiceRegionError<'_, 'tcx> {
vid, vid,
_, _,
SubregionOrigin::Subtype(box TypeTrace { cause, values }), SubregionOrigin::Subtype(box TypeTrace { cause, values }),
sub_placeholder @ ty::RePlaceholder(_), sub_placeholder @ Region(Interned(RePlaceholder(_), _)),
_, _,
_, _,
_, _,
)) => self.try_report_trait_placeholder_mismatch( )) => self.try_report_trait_placeholder_mismatch(
Some(self.tcx().mk_region(ty::ReVar(*vid))), Some(self.tcx().mk_region(ReVar(*vid))),
cause, cause,
Some(sub_placeholder), Some(*sub_placeholder),
None, None,
values, values,
), ),
@ -65,10 +66,10 @@ impl<'tcx> NiceRegionError<'_, 'tcx> {
SubregionOrigin::Subtype(box TypeTrace { cause, values }), SubregionOrigin::Subtype(box TypeTrace { cause, values }),
_, _,
_, _,
sup_placeholder @ ty::RePlaceholder(_), sup_placeholder @ Region(Interned(RePlaceholder(_), _)),
_, _,
)) => self.try_report_trait_placeholder_mismatch( )) => self.try_report_trait_placeholder_mismatch(
Some(self.tcx().mk_region(ty::ReVar(*vid))), Some(self.tcx().mk_region(ReVar(*vid))),
cause, cause,
None, None,
Some(*sup_placeholder), Some(*sup_placeholder),
@ -81,10 +82,10 @@ impl<'tcx> NiceRegionError<'_, 'tcx> {
_, _,
_, _,
SubregionOrigin::Subtype(box TypeTrace { cause, values }), SubregionOrigin::Subtype(box TypeTrace { cause, values }),
sup_placeholder @ ty::RePlaceholder(_), sup_placeholder @ Region(Interned(RePlaceholder(_), _)),
_, _,
)) => self.try_report_trait_placeholder_mismatch( )) => self.try_report_trait_placeholder_mismatch(
Some(self.tcx().mk_region(ty::ReVar(*vid))), Some(self.tcx().mk_region(ReVar(*vid))),
cause, cause,
None, None,
Some(*sup_placeholder), Some(*sup_placeholder),
@ -96,9 +97,9 @@ impl<'tcx> NiceRegionError<'_, 'tcx> {
_, _,
_, _,
SubregionOrigin::Subtype(box TypeTrace { cause, values }), SubregionOrigin::Subtype(box TypeTrace { cause, values }),
sup_placeholder @ ty::RePlaceholder(_), sup_placeholder @ Region(Interned(RePlaceholder(_), _)),
)) => self.try_report_trait_placeholder_mismatch( )) => self.try_report_trait_placeholder_mismatch(
Some(self.tcx().mk_region(ty::ReVar(*vid))), Some(self.tcx().mk_region(ReVar(*vid))),
cause, cause,
None, None,
Some(*sup_placeholder), Some(*sup_placeholder),
@ -107,8 +108,8 @@ impl<'tcx> NiceRegionError<'_, 'tcx> {
Some(RegionResolutionError::ConcreteFailure( Some(RegionResolutionError::ConcreteFailure(
SubregionOrigin::Subtype(box TypeTrace { cause, values }), SubregionOrigin::Subtype(box TypeTrace { cause, values }),
sub_region @ ty::RePlaceholder(_), sub_region @ Region(Interned(RePlaceholder(_), _)),
sup_region @ ty::RePlaceholder(_), sup_region @ Region(Interned(RePlaceholder(_), _)),
)) => self.try_report_trait_placeholder_mismatch( )) => self.try_report_trait_placeholder_mismatch(
None, None,
cause, cause,
@ -119,12 +120,12 @@ impl<'tcx> NiceRegionError<'_, 'tcx> {
Some(RegionResolutionError::ConcreteFailure( Some(RegionResolutionError::ConcreteFailure(
SubregionOrigin::Subtype(box TypeTrace { cause, values }), SubregionOrigin::Subtype(box TypeTrace { cause, values }),
sub_region @ ty::RePlaceholder(_), sub_region @ Region(Interned(RePlaceholder(_), _)),
sup_region, sup_region,
)) => self.try_report_trait_placeholder_mismatch( )) => self.try_report_trait_placeholder_mismatch(
(!sup_region.has_name()).then_some(sup_region), (!sup_region.has_name()).then_some(*sup_region),
cause, cause,
Some(sub_region), Some(*sub_region),
None, None,
values, values,
), ),
@ -132,12 +133,12 @@ impl<'tcx> NiceRegionError<'_, 'tcx> {
Some(RegionResolutionError::ConcreteFailure( Some(RegionResolutionError::ConcreteFailure(
SubregionOrigin::Subtype(box TypeTrace { cause, values }), SubregionOrigin::Subtype(box TypeTrace { cause, values }),
sub_region, sub_region,
sup_region @ ty::RePlaceholder(_), sup_region @ Region(Interned(RePlaceholder(_), _)),
)) => self.try_report_trait_placeholder_mismatch( )) => self.try_report_trait_placeholder_mismatch(
(!sub_region.has_name()).then_some(sub_region), (!sub_region.has_name()).then_some(*sub_region),
cause, cause,
None, None,
Some(sup_region), Some(*sup_region),
values, values,
), ),
@ -147,10 +148,10 @@ impl<'tcx> NiceRegionError<'_, 'tcx> {
fn try_report_trait_placeholder_mismatch( fn try_report_trait_placeholder_mismatch(
&self, &self,
vid: Option<ty::Region<'tcx>>, vid: Option<Region<'tcx>>,
cause: &ObligationCause<'tcx>, cause: &ObligationCause<'tcx>,
sub_placeholder: Option<ty::Region<'tcx>>, sub_placeholder: Option<Region<'tcx>>,
sup_placeholder: Option<ty::Region<'tcx>>, sup_placeholder: Option<Region<'tcx>>,
value_pairs: &ValuePairs<'tcx>, value_pairs: &ValuePairs<'tcx>,
) -> Option<DiagnosticBuilder<'tcx>> { ) -> Option<DiagnosticBuilder<'tcx>> {
let (expected_substs, found_substs, trait_def_id) = match value_pairs { let (expected_substs, found_substs, trait_def_id) = match value_pairs {
@ -193,10 +194,10 @@ impl<'tcx> NiceRegionError<'_, 'tcx> {
#[instrument(level = "debug", skip(self))] #[instrument(level = "debug", skip(self))]
fn report_trait_placeholder_mismatch( fn report_trait_placeholder_mismatch(
&self, &self,
vid: Option<ty::Region<'tcx>>, vid: Option<Region<'tcx>>,
cause: &ObligationCause<'tcx>, cause: &ObligationCause<'tcx>,
sub_placeholder: Option<ty::Region<'tcx>>, sub_placeholder: Option<Region<'tcx>>,
sup_placeholder: Option<ty::Region<'tcx>>, sup_placeholder: Option<Region<'tcx>>,
trait_def_id: DefId, trait_def_id: DefId,
expected_substs: SubstsRef<'tcx>, expected_substs: SubstsRef<'tcx>,
actual_substs: SubstsRef<'tcx>, actual_substs: SubstsRef<'tcx>,
@ -306,13 +307,13 @@ impl<'tcx> NiceRegionError<'_, 'tcx> {
fn explain_actual_impl_that_was_found( fn explain_actual_impl_that_was_found(
&self, &self,
err: &mut DiagnosticBuilder<'_>, err: &mut DiagnosticBuilder<'_>,
sub_placeholder: Option<ty::Region<'tcx>>, sub_placeholder: Option<Region<'tcx>>,
sup_placeholder: Option<ty::Region<'tcx>>, sup_placeholder: Option<Region<'tcx>>,
has_sub: Option<usize>, has_sub: Option<usize>,
has_sup: Option<usize>, has_sup: Option<usize>,
expected_trait_ref: ty::TraitRef<'tcx>, expected_trait_ref: ty::TraitRef<'tcx>,
actual_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>, expected_has_vid: Option<usize>,
actual_has_vid: Option<usize>, actual_has_vid: Option<usize>,
any_self_ty_has_vid: bool, any_self_ty_has_vid: bool,
@ -322,7 +323,7 @@ impl<'tcx> NiceRegionError<'_, 'tcx> {
#[derive(Copy, Clone)] #[derive(Copy, Clone)]
struct Highlighted<'tcx, T> { struct Highlighted<'tcx, T> {
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
highlight: RegionHighlightMode, highlight: RegionHighlightMode<'tcx>,
value: T, value: T,
} }
@ -366,7 +367,7 @@ impl<'tcx> NiceRegionError<'_, 'tcx> {
let highlight_trait_ref = |trait_ref| Highlighted { let highlight_trait_ref = |trait_ref| Highlighted {
tcx: self.tcx(), tcx: self.tcx(),
highlight: RegionHighlightMode::default(), highlight: RegionHighlightMode::new(self.tcx()),
value: trait_ref, 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::intravisit::{walk_ty, Visitor};
use rustc_hir::{self as hir, GenericBound, Item, ItemKind, Lifetime, LifetimeName, Node, TyKind}; use rustc_hir::{self as hir, GenericBound, Item, ItemKind, Lifetime, LifetimeName, Node, TyKind};
use rustc_middle::ty::{ use rustc_middle::ty::{
self, AssocItemContainer, RegionKind, StaticLifetimeVisitor, Ty, TyCtxt, TypeFoldable, self, AssocItemContainer, StaticLifetimeVisitor, Ty, TyCtxt, TypeFoldable, TypeVisitor,
TypeVisitor,
}; };
use rustc_span::symbol::Ident; use rustc_span::symbol::Ident;
use rustc_span::{MultiSpan, Span}; use rustc_span::{MultiSpan, Span};
@ -33,25 +32,23 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
sup_origin, sup_origin,
sup_r, sup_r,
spans, spans,
) if **sub_r == RegionKind::ReStatic => { ) if sub_r.is_static() => (var_origin, sub_origin, sub_r, sup_origin, sup_r, spans),
(var_origin, sub_origin, sub_r, sup_origin, sup_r, spans)
}
RegionResolutionError::ConcreteFailure( RegionResolutionError::ConcreteFailure(
SubregionOrigin::Subtype(box TypeTrace { cause, .. }), SubregionOrigin::Subtype(box TypeTrace { cause, .. }),
sub_r, sub_r,
sup_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 {}`. // This is for an implicit `'static` requirement coming from `impl dyn Trait {}`.
if let ObligationCauseCode::UnifyReceiver(ctxt) = cause.code() { if let ObligationCauseCode::UnifyReceiver(ctxt) = cause.code() {
// This may have a closure and it would cause ICE // This may have a closure and it would cause ICE
// through `find_param_with_region` (#78262). // 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); let fn_returns = tcx.return_type_impl_or_dyn_traits(anon_reg_sup.def_id);
if fn_returns.is_empty() { if fn_returns.is_empty() {
return None; 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() { let lifetime = if sup_r.has_name() {
format!("lifetime `{}`", sup_r) format!("lifetime `{}`", sup_r)
} else { } else {
@ -101,11 +98,11 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
"try_report_static_impl_trait(var={:?}, sub={:?} {:?} sup={:?} {:?})", "try_report_static_impl_trait(var={:?}, sub={:?} {:?} sup={:?} {:?})",
var_origin, sub_origin, sub_r, sup_origin, sup_r 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); debug!("try_report_static_impl_trait: anon_reg_sup={:?}", anon_reg_sup);
let sp = var_origin.span(); let sp = var_origin.span();
let return_sp = sub_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() { let (lifetime_name, lifetime) = if sup_r.has_name() {
(sup_r.to_string(), format!("lifetime `{}`", sup_r)) (sup_r.to_string(), format!("lifetime `{}`", sup_r))
} else { } else {
@ -560,7 +557,7 @@ pub(super) struct TraitObjectVisitor(pub(super) FxHashSet<DefId>);
impl<'tcx> TypeVisitor<'tcx> for TraitObjectVisitor { impl<'tcx> TypeVisitor<'tcx> for TraitObjectVisitor {
fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> { fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
match t.kind() { 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() { if let Some(def_id) = preds.principal_def_id() {
self.0.insert(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 { if sup_expected_found == sub_expected_found {
self.emit_err( self.emit_err(
var_origin.span(), var_origin.span(),
sub_expected, *sub_expected,
sub_found, *sub_found,
*trait_item_def_id, *trait_item_def_id,
); );
return Some(ErrorReported); return Some(ErrorReported);
@ -81,21 +81,21 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
// Mark all unnamed regions in the type with a number. // Mark all unnamed regions in the type with a number.
// This diagnostic is called in response to lifetime errors, so be informative. // This diagnostic is called in response to lifetime errors, so be informative.
struct HighlightBuilder { struct HighlightBuilder<'tcx> {
highlight: RegionHighlightMode, highlight: RegionHighlightMode<'tcx>,
counter: usize, counter: usize,
} }
impl HighlightBuilder { impl<'tcx> HighlightBuilder<'tcx> {
fn build(ty: Ty<'_>) -> RegionHighlightMode { fn build(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> RegionHighlightMode<'tcx> {
let mut builder = let mut builder =
HighlightBuilder { highlight: RegionHighlightMode::default(), counter: 1 }; HighlightBuilder { highlight: RegionHighlightMode::new(tcx), counter: 1 };
builder.visit_ty(ty); builder.visit_ty(ty);
builder.highlight 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> { fn visit_region(&mut self, r: ty::Region<'tcx>) -> ControlFlow<Self::BreakTy> {
if !r.has_name() && self.counter <= 3 { if !r.has_name() && self.counter <= 3 {
self.highlight.highlighting_region(r, self.counter); 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 let expected = self
.infcx .infcx
.extract_inference_diagnostics_data(expected.into(), Some(expected_highlight)) .extract_inference_diagnostics_data(expected.into(), Some(expected_highlight))
.name; .name;
let found_highlight = HighlightBuilder::build(found); let found_highlight = HighlightBuilder::build(self.tcx(), found);
let found = let found =
self.infcx.extract_inference_diagnostics_data(found.into(), Some(found_highlight)).name; 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 ty = fn_sig.inputs()[index];
let mut found_anon_region = false; let mut found_anon_region = false;
let new_param_ty = self.tcx().fold_regions(ty, &mut false, |r, _| { let new_param_ty = self.tcx().fold_regions(ty, &mut false, |r, _| {
if *r == *anon_region { if r == anon_region {
found_anon_region = true; found_anon_region = true;
replace_region replace_region
} else { } else {

View file

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

View file

@ -41,8 +41,8 @@ pub struct FreeRegionMap<'tcx> {
} }
impl<'tcx> FreeRegionMap<'tcx> { impl<'tcx> FreeRegionMap<'tcx> {
pub fn elements(&self) -> impl Iterator<Item = &Region<'tcx>> { pub fn elements(&self) -> impl Iterator<Item = Region<'tcx>> + '_ {
self.relation.elements() self.relation.elements().copied()
} }
pub fn is_empty(&self) -> bool { pub fn is_empty(&self) -> bool {
@ -91,7 +91,7 @@ impl<'tcx> FreeRegionMap<'tcx> {
/// True for free regions other than `'static`. /// True for free regions other than `'static`.
pub fn is_free(&self, r: Region<'_>) -> bool { 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 /// 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, ty_freshen_count: u32,
const_freshen_count: u32, const_freshen_count: u32,
ty_freshen_map: FxHashMap<ty::InferTy, Ty<'tcx>>, 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, keep_static: bool,
} }
@ -89,11 +89,11 @@ impl<'a, 'tcx> TypeFreshener<'a, 'tcx> {
fn freshen_const<F>( fn freshen_const<F>(
&mut self, &mut self,
opt_ct: Option<&'tcx ty::Const<'tcx>>, opt_ct: Option<ty::Const<'tcx>>,
key: ty::InferConst<'tcx>, key: ty::InferConst<'tcx>,
freshener: F, freshener: F,
ty: Ty<'tcx>, ty: Ty<'tcx>,
) -> &'tcx ty::Const<'tcx> ) -> ty::Const<'tcx>
where where
F: FnOnce(u32) -> ty::InferConst<'tcx>, 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> { fn fold_const(&mut self, ct: ty::Const<'tcx>) -> ty::Const<'tcx> {
match ct.val { match ct.val() {
ty::ConstKind::Infer(ty::InferConst::Var(v)) => { ty::ConstKind::Infer(ty::InferConst::Var(v)) => {
let opt_ct = self let opt_ct = self
.infcx .infcx
@ -236,7 +236,7 @@ impl<'a, 'tcx> TypeFolder<'tcx> for TypeFreshener<'a, 'tcx> {
opt_ct, opt_ct,
ty::InferConst::Var(v), ty::InferConst::Var(v),
ty::InferConst::Fresh, ty::InferConst::Fresh,
ct.ty, ct.ty(),
); );
} }
ty::ConstKind::Infer(ty::InferConst::Fresh(i)) => { ty::ConstKind::Infer(ty::InferConst::Fresh(i)) => {

View file

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

View file

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

View file

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

View file

@ -87,7 +87,7 @@ pub trait TypeRelatingDelegate<'tcx> {
info: ty::VarianceDiagInfo<'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. /// Creates a new universe index. Used when instantiating placeholders.
fn create_next_universe(&mut self) -> ty::UniverseIndex; fn create_next_universe(&mut self) -> ty::UniverseIndex;
@ -244,8 +244,8 @@ where
scopes: &[BoundRegionScope<'tcx>], scopes: &[BoundRegionScope<'tcx>],
) -> ty::Region<'tcx> { ) -> ty::Region<'tcx> {
debug!("replace_bound_regions(scopes={:?})", scopes); debug!("replace_bound_regions(scopes={:?})", scopes);
if let ty::ReLateBound(debruijn, br) = r { if let ty::ReLateBound(debruijn, br) = *r {
Self::lookup_bound_region(*debruijn, br, first_free_index, scopes) Self::lookup_bound_region(debruijn, &br, first_free_index, scopes)
} else { } else {
r r
} }
@ -450,7 +450,7 @@ impl<'tcx> VidValuePair<'tcx> for (ty::TyVid, Ty<'tcx>) {
where where
D: TypeRelatingDelegate<'tcx>, 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 where
D: TypeRelatingDelegate<'tcx>, D: TypeRelatingDelegate<'tcx>,
{ {
relate.relate(&self.value_ty(), &generalized_ty) relate.relate(self.value_ty(), generalized_ty)
} }
} }
@ -609,16 +609,16 @@ where
fn consts( fn consts(
&mut self, &mut self,
a: &'tcx ty::Const<'tcx>, a: ty::Const<'tcx>,
mut b: &'tcx ty::Const<'tcx>, mut b: ty::Const<'tcx>,
) -> RelateResult<'tcx, &'tcx ty::Const<'tcx>> { ) -> RelateResult<'tcx, ty::Const<'tcx>> {
let a = self.infcx.shallow_resolve(a); let a = self.infcx.shallow_resolve(a);
if !D::forbid_inference_vars() { if !D::forbid_inference_vars() {
b = self.infcx.shallow_resolve(b); b = self.infcx.shallow_resolve(b);
} }
match b.val { match b.val() {
ty::ConstKind::Infer(InferConst::Var(_)) if D::forbid_inference_vars() => { ty::ConstKind::Infer(InferConst::Var(_)) if D::forbid_inference_vars() => {
// Forbid inference variables in the RHS. // Forbid inference variables in the RHS.
bug!("unexpected inference var {:?}", b) bug!("unexpected inference var {:?}", b)
@ -745,7 +745,7 @@ impl<'tcx, D> ConstEquateRelation<'tcx> for TypeRelating<'_, 'tcx, D>
where where
D: TypeRelatingDelegate<'tcx>, 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); 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> { fn visit_region(&mut self, r: ty::Region<'tcx>) -> ControlFlow<Self::BreakTy> {
let ScopeInstantiator { bound_region_scope, next_region, .. } = self; let ScopeInstantiator { bound_region_scope, next_region, .. } = self;
match r { match *r {
ty::ReLateBound(debruijn, br) if *debruijn == self.target_index => { ty::ReLateBound(debruijn, br) if debruijn == self.target_index => {
bound_region_scope.map.entry(*br).or_insert_with(|| next_region(*br)); bound_region_scope.map.entry(br).or_insert_with(|| next_region(br));
} }
_ => {} _ => {}
@ -963,8 +963,8 @@ where
) -> RelateResult<'tcx, ty::Region<'tcx>> { ) -> RelateResult<'tcx, ty::Region<'tcx>> {
debug!("TypeGeneralizer::regions(a={:?})", a); debug!("TypeGeneralizer::regions(a={:?})", a);
if let ty::ReLateBound(debruijn, _) = a { if let ty::ReLateBound(debruijn, _) = *a {
if *debruijn < self.first_free_index { if debruijn < self.first_free_index {
return Ok(a); return Ok(a);
} }
} }
@ -992,10 +992,10 @@ where
fn consts( fn consts(
&mut self, &mut self,
a: &'tcx ty::Const<'tcx>, a: ty::Const<'tcx>,
_: &'tcx ty::Const<'tcx>, _: ty::Const<'tcx>,
) -> RelateResult<'tcx, &'tcx ty::Const<'tcx>> { ) -> RelateResult<'tcx, ty::Const<'tcx>> {
match a.val { match a.val() {
ty::ConstKind::Infer(InferConst::Var(_)) if D::forbid_inference_vars() => { ty::ConstKind::Infer(InferConst::Var(_)) if D::forbid_inference_vars() => {
bug!("unexpected inference variable encountered in NLL generalization: {:?}", a); bug!("unexpected inference variable encountered in NLL generalization: {:?}", a);
} }
@ -1010,7 +1010,7 @@ where
origin: var_value.origin, origin: var_value.origin,
val: ConstVariableValue::Unknown { universe: self.universe }, 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::infer::{GenericKind, InferCtxt};
use crate::traits::query::OutlivesBound; use crate::traits::query::OutlivesBound;
use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::intern::Interned;
use rustc_hir as hir; use rustc_hir as hir;
use rustc_middle::ty; use rustc_middle::ty::{self, ReEarlyBound, ReFree, ReVar, Region};
use super::explicit_outlives_bounds; use super::explicit_outlives_bounds;
@ -66,7 +67,7 @@ pub struct OutlivesEnvironment<'tcx> {
/// "Region-bound pairs" tracks outlives relations that are known to /// "Region-bound pairs" tracks outlives relations that are known to
/// be true, either because of explicit where-clauses like `T: 'a` or /// be true, either because of explicit where-clauses like `T: 'a` or
/// because of implied bounds. /// 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> { impl<'a, 'tcx> OutlivesEnvironment<'tcx> {
pub fn new(param_env: ty::ParamEnv<'tcx>) -> Self { 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); debug!("add_outlives_bounds: outlives_bound={:?}", outlives_bound);
match outlives_bound { match outlives_bound {
OutlivesBound::RegionSubRegion( OutlivesBound::RegionSubRegion(
r_a @ (&ty::ReEarlyBound(_) | &ty::ReFree(_)), r_a @ (Region(Interned(ReEarlyBound(_), _)) | Region(Interned(ReFree(_), _))),
&ty::ReVar(vid_b), 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) => { OutlivesBound::RegionSubParam(r_a, param_b) => {
self.region_bound_pairs_accum.push((r_a, GenericKind::Param(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(); let origin = origin.clone();
match component { match component {
Component::Region(region1) => { 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) => { Component::Param(param_ty) => {
self.param_ty_must_outlive(origin, region, *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); let scc = self.mini_graph.sccs.scc(*leak_check_node);
// Set the universe of each SCC to be the minimum of its constituent universes // 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!( debug!(
"assign_placeholder_values: scc={:?} universe={:?} region={:?}", "assign_placeholder_values: scc={:?} universe={:?} region={:?}",
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 // 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) { 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::fx::{FxHashMap, FxHashSet};
use rustc_data_structures::intern::Interned;
use rustc_data_structures::sync::Lrc; use rustc_data_structures::sync::Lrc;
use rustc_data_structures::undo_log::UndoLogs; use rustc_data_structures::undo_log::UndoLogs;
use rustc_data_structures::unify as ut; use rustc_data_structures::unify as ut;
@ -502,14 +503,15 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> {
self.make_subregion(origin, sup, sub); self.make_subregion(origin, sup, sub);
match (sub, sup) { match (sub, sup) {
(&ty::ReVar(sub), &ty::ReVar(sup)) => { (Region(Interned(ReVar(sub), _)), Region(Interned(ReVar(sup), _))) => {
debug!("make_eqregion: unifying {:?} with {:?}", sub, sup); debug!("make_eqregion: unifying {:?} with {:?}", sub, sup);
self.unification_table().union(sub, sup); self.unification_table().union(*sub, *sup);
self.any_unifications = true; 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); 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; self.any_unifications = true;
} }
(_, _) => {} (_, _) => {}
@ -550,20 +552,20 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> {
// cannot add constraints once regions are resolved // cannot add constraints once regions are resolved
debug!("origin = {:#?}", origin); debug!("origin = {:#?}", origin);
match (sub, sup) { match (*sub, *sup) {
(&ReLateBound(..), _) | (_, &ReLateBound(..)) => { (ReLateBound(..), _) | (_, ReLateBound(..)) => {
span_bug!(origin.span(), "cannot relate bound region: {:?} <= {:?}", sub, sup); span_bug!(origin.span(), "cannot relate bound region: {:?} <= {:?}", sub, sup);
} }
(_, &ReStatic) => { (_, ReStatic) => {
// all regions are subregions of static, so we can ignore this // 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); 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); self.add_constraint(Constraint::RegSubVar(sub, sup_id), origin);
} }
(&ReVar(sub_id), _) => { (ReVar(sub_id), _) => {
self.add_constraint(Constraint::VarSubReg(sub_id, sup), origin); self.add_constraint(Constraint::VarSubReg(sub_id, sup), origin);
} }
_ => { _ => {
@ -591,16 +593,12 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> {
) -> Region<'tcx> { ) -> Region<'tcx> {
// cannot add constraints once regions are resolved // cannot add constraints once regions are resolved
debug!("RegionConstraintCollector: lub_regions({:?}, {:?})", a, b); debug!("RegionConstraintCollector: lub_regions({:?}, {:?})", a, b);
match (a, b) { if a.is_static() || b.is_static() {
(r @ &ReStatic, _) | (_, r @ &ReStatic) => { a // nothing lives longer than static
r // nothing lives longer than static } else if a == b {
} a // LUB(a,a) = a
} else {
_ if a == b => { self.combine_vars(tcx, Lub, a, b, origin)
a // LUB(a,a) = a
}
_ => self.combine_vars(tcx, Lub, a, b, origin),
} }
} }
@ -613,16 +611,14 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> {
) -> Region<'tcx> { ) -> Region<'tcx> {
// cannot add constraints once regions are resolved // cannot add constraints once regions are resolved
debug!("RegionConstraintCollector: glb_regions({:?}, {:?})", a, b); debug!("RegionConstraintCollector: glb_regions({:?}, {:?})", a, b);
match (a, b) { if a.is_static() {
(&ReStatic, r) | (r, &ReStatic) => { b // static lives longer than everything else
r // static lives longer than everything else } else if b.is_static() {
} a // static lives longer than everything else
} else if a == b {
_ if a == b => { a // GLB(a,a) = a
a // GLB(a,a) = a } else {
} self.combine_vars(tcx, Glb, a, b, origin)
_ => self.combine_vars(tcx, Glb, a, b, origin),
} }
} }
@ -639,11 +635,11 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> {
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
region: ty::Region<'tcx>, region: ty::Region<'tcx>,
) -> ty::Region<'tcx> { ) -> ty::Region<'tcx> {
match region { match *region {
ty::ReVar(rid) => { 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(|| { 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)) tcx.reuse_or_mk_region(region, ty::ReVar(root))
}) })
} }
@ -767,8 +763,7 @@ impl<'tcx> VerifyBound<'tcx> {
pub fn must_hold(&self) -> bool { pub fn must_hold(&self) -> bool {
match self { match self {
VerifyBound::IfEq(..) => false, VerifyBound::IfEq(..) => false,
VerifyBound::OutlivedBy(ty::ReStatic) => true, VerifyBound::OutlivedBy(re) => re.is_static(),
VerifyBound::OutlivedBy(_) => false,
VerifyBound::IsEmpty => false, VerifyBound::IsEmpty => false,
VerifyBound::AnyBound(bs) => bs.iter().any(|b| b.must_hold()), VerifyBound::AnyBound(bs) => bs.iter().any(|b| b.must_hold()),
VerifyBound::AllBounds(bs) => bs.iter().all(|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() { if !ct.has_infer_types_or_consts() {
ct // micro-optimize -- if there is nothing in this const that this fold affects... ct // micro-optimize -- if there is nothing in this const that this fold affects...
} else { } 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() { if !ct.has_infer_regions() {
ct // micro-optimize -- if there is nothing in this const that this fold affects... ct // micro-optimize -- if there is nothing in this const that this fold affects...
} else { } else {
@ -218,15 +218,12 @@ impl<'a, 'tcx> FallibleTypeFolder<'tcx> for FullTypeResolver<'a, 'tcx> {
} }
} }
fn try_fold_const( fn try_fold_const(&mut self, c: ty::Const<'tcx>) -> Result<ty::Const<'tcx>, Self::Error> {
&mut self,
c: &'tcx ty::Const<'tcx>,
) -> Result<&'tcx ty::Const<'tcx>, Self::Error> {
if !c.needs_infer() { if !c.needs_infer() {
Ok(c) // micro-optimize -- if there is nothing in this const that this fold affects... Ok(c) // micro-optimize -- if there is nothing in this const that this fold affects...
} else { } else {
let c = self.infcx.shallow_resolve(c); let c = self.infcx.shallow_resolve(c);
match c.val { match c.val() {
ty::ConstKind::Infer(InferConst::Var(vid)) => { ty::ConstKind::Infer(InferConst::Var(vid)) => {
return Err(FixupError::UnresolvedConst(vid)); return Err(FixupError::UnresolvedConst(vid));
} }

View file

@ -151,9 +151,9 @@ impl<'tcx> TypeRelation<'tcx> for Sub<'_, '_, 'tcx> {
fn consts( fn consts(
&mut self, &mut self,
a: &'tcx ty::Const<'tcx>, a: ty::Const<'tcx>,
b: &'tcx ty::Const<'tcx>, b: ty::Const<'tcx>,
) -> RelateResult<'tcx, &'tcx ty::Const<'tcx>> { ) -> RelateResult<'tcx, ty::Const<'tcx>> {
self.fields.infcx.super_combine_consts(self, a, b) 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> { 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); 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>), CodeSelectionError(SelectionError<'tcx>),
CodeProjectionError(MismatchedProjectionTypes<'tcx>), CodeProjectionError(MismatchedProjectionTypes<'tcx>),
CodeSubtypeError(ExpectedFound<Ty<'tcx>>, TypeError<'tcx>), // always comes from a SubtypePredicate 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, CodeAmbiguity,
} }

View file

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

View file

@ -974,7 +974,7 @@ impl<'tcx> LateContext<'tcx> {
Ok(()) 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(()) Ok(())
} }

View file

@ -7,9 +7,10 @@ use rustc_middle::ty;
use rustc_span::symbol::sym; use rustc_span::symbol::sym;
declare_tool_lint! { 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. /// The `rustc_pass_by_value` lint marks a type with `#[rustc_pass_by_value]` requiring it to
/// This is usually used for types that are thin wrappers around references, so there is no benefit to an extra /// always be passed by value. This is usually used for types that are thin wrappers around
/// layer of indirection. (Example: `Ty` which is a reference to a `TyS`) /// 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, pub rustc::PASS_BY_VALUE,
Warn, Warn,
"pass by reference of a type flagged as `#[rustc_pass_by_value]`", "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) = 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') { if let Some(pos) = repr_str.chars().position(|c| c == 'i' || c == 'u') {
let (sans_suffix, _) = repr_str.split_at(pos); let (sans_suffix, _) = repr_str.split_at(pos);
@ -367,7 +367,7 @@ fn lint_int_literal<'tcx>(
max, max,
)); ));
if let Some(sugg_ty) = 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)); 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() { 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 { match r {
FfiSafe => {} FfiSafe => {}
_ => { _ => {
@ -1257,7 +1257,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
let sig = self.cx.tcx.erase_late_bound_regions(sig); let sig = self.cx.tcx.erase_late_bound_regions(sig);
for (input_ty, input_hir) in iter::zip(sig.inputs(), decl.inputs) { 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 { 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)) } 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) } thir_abstract_const => { cdata.get_thir_abstract_const(tcx, def_id.index) }
unused_generic_params => { cdata.get_unused_generic_params(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) } mir_const_qualif => { cdata.mir_const_qualif(def_id.index) }
fn_sig => { cdata.fn_sig(def_id.index, tcx) } fn_sig => { cdata.fn_sig(def_id.index, tcx) }
inherent_impls => { cdata.get_inherent_implementations_for_type(tcx, def_id.index) } inherent_impls => { cdata.get_inherent_implementations_for_type(tcx, def_id.index) }

View file

@ -88,7 +88,8 @@ macro_rules! arena_types {
// Interned types // Interned types
[] tys: rustc_middle::ty::TyS<'tcx>, [] 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`, // Note that this deliberately duplicates items in the `rustc_hir::arena`,
// since we need to allocate this type on both 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() tcx.mk_region(ty::ReLateBound(ty::INNERMOST, br)).into()
} }
GenericArgKind::Const(ct) => tcx GenericArgKind::Const(ct) => tcx
.mk_const(ty::Const { .mk_const(ty::ConstS {
ty: ct.ty, ty: ct.ty(),
val: ty::ConstKind::Bound(ty::INNERMOST, ty::BoundVar::from_u32(i)), val: ty::ConstKind::Bound(ty::INNERMOST, ty::BoundVar::from_u32(i)),
}) })
.into(), .into(),

View file

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

View file

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

View file

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

View file

@ -387,7 +387,7 @@ pub enum ClosureOutlivesSubject<'tcx> {
#[derive(Copy, Clone, Debug, HashStable)] #[derive(Copy, Clone, Debug, HashStable)]
pub struct DestructuredConst<'tcx> { pub struct DestructuredConst<'tcx> {
pub variant: Option<VariantIdx>, 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 /// 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 /// `PlaceElem`, where we can just use the `Ty` that is already
/// stored inline on field projection elems. /// stored inline on field projection elems.
pub fn projection_ty(self, tcx: TyCtxt<'tcx>, elem: PlaceElem<'tcx>) -> PlaceTy<'tcx> { 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, |...| { ... })` /// `place_ty.projection_ty_core(tcx, elem, |...| { ... })`
@ -93,11 +93,11 @@ impl<'tcx> PlaceTy<'tcx> {
ProjectionElem::Subslice { from, to, from_end } => { ProjectionElem::Subslice { from, to, from_end } => {
PlaceTy::from_ty(match self.ty.kind() { PlaceTy::from_ty(match self.ty.kind() {
ty::Slice(..) => self.ty, 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 => { ty::Array(inner, size) if from_end => {
let size = size.eval_usize(tcx, param_env); let size = size.eval_usize(tcx, param_env);
let len = size - (from as u64) - (to as u64); 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), _ => 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)> { pub fn as_switch(&self) -> Option<(&Operand<'tcx>, Ty<'tcx>, &SwitchTargets)> {
match self { match self {
TerminatorKind::SwitchInt { discr, switch_ty, targets } => { TerminatorKind::SwitchInt { discr, switch_ty, targets } => {
Some((discr, switch_ty, targets)) Some((discr, *switch_ty, targets))
} }
_ => None, _ => None,
} }

View file

@ -194,13 +194,13 @@ macro_rules! make_mir_visitor {
} }
fn visit_region(&mut self, fn visit_region(&mut self,
region: & $($mutability)? ty::Region<'tcx>, region: $(& $mutability)? ty::Region<'tcx>,
_: Location) { _: Location) {
self.super_region(region); self.super_region(region);
} }
fn visit_const(&mut self, fn visit_const(&mut self,
constant: & $($mutability)? &'tcx ty::Const<'tcx>, constant: $(& $mutability)? ty::Const<'tcx>,
_: Location) { _: Location) {
self.super_const(constant); self.super_const(constant);
} }
@ -242,7 +242,7 @@ macro_rules! make_mir_visitor {
) { ) {
let span = body.span; let span = body.span;
if let Some(gen) = &$($mutability)? body.generator { 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( self.visit_ty(
yield_ty, yield_ty,
TyContext::YieldTy(SourceInfo::outermost(span)) TyContext::YieldTy(SourceInfo::outermost(span))
@ -266,7 +266,7 @@ macro_rules! make_mir_visitor {
} }
self.visit_ty( self.visit_ty(
&$($mutability)? body.return_ty(), $(& $mutability)? body.return_ty(),
TyContext::ReturnTy(SourceInfo::outermost(body.span)) TyContext::ReturnTy(SourceInfo::outermost(body.span))
); );
@ -355,7 +355,7 @@ macro_rules! make_mir_visitor {
ty::InstanceDef::DropGlue(_def_id, Some(ty)) | ty::InstanceDef::DropGlue(_def_id, Some(ty)) |
ty::InstanceDef::CloneShim(_def_id, ty) => { ty::InstanceDef::CloneShim(_def_id, ty) => {
// FIXME(eddyb) use a better `TyContext` here. // 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); self.visit_substs(callee_substs, location);
@ -487,7 +487,7 @@ macro_rules! make_mir_visitor {
targets: _ targets: _
} => { } => {
self.visit_operand(discr, location); self.visit_operand(discr, location);
self.visit_ty(switch_ty, TyContext::Location(location)); self.visit_ty($(& $mutability)? *switch_ty, TyContext::Location(location));
} }
TerminatorKind::Drop { TerminatorKind::Drop {
@ -641,7 +641,7 @@ macro_rules! make_mir_visitor {
Rvalue::ThreadLocalRef(_) => {} Rvalue::ThreadLocalRef(_) => {}
Rvalue::Ref(r, bk, path) => { Rvalue::Ref(r, bk, path) => {
self.visit_region(r, location); self.visit_region($(& $mutability)? *r, location);
let ctx = match bk { let ctx = match bk {
BorrowKind::Shared => PlaceContext::NonMutatingUse( BorrowKind::Shared => PlaceContext::NonMutatingUse(
NonMutatingUseContext::SharedBorrow NonMutatingUseContext::SharedBorrow
@ -680,7 +680,7 @@ macro_rules! make_mir_visitor {
Rvalue::Cast(_cast_kind, operand, ty) => { Rvalue::Cast(_cast_kind, operand, ty) => {
self.visit_operand(operand, location); 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)) Rvalue::BinaryOp(_bin_op, box(lhs, rhs))
@ -702,14 +702,14 @@ macro_rules! make_mir_visitor {
} }
Rvalue::NullaryOp(_op, ty) => { Rvalue::NullaryOp(_op, ty) => {
self.visit_ty(ty, TyContext::Location(location)); self.visit_ty($(& $mutability)? *ty, TyContext::Location(location));
} }
Rvalue::Aggregate(kind, operands) => { Rvalue::Aggregate(kind, operands) => {
let kind = &$($mutability)? **kind; let kind = &$($mutability)? **kind;
match kind { match kind {
AggregateKind::Array(ty) => { AggregateKind::Array(ty) => {
self.visit_ty(ty, TyContext::Location(location)); self.visit_ty($(& $mutability)? *ty, TyContext::Location(location));
} }
AggregateKind::Tuple => { AggregateKind::Tuple => {
} }
@ -744,7 +744,7 @@ macro_rules! make_mir_visitor {
Rvalue::ShallowInitBox(operand, ty) => { Rvalue::ShallowInitBox(operand, ty) => {
self.visit_operand(operand, location); 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: _, is_block_tail: _,
} = local_decl; } = local_decl;
self.visit_ty(ty, TyContext::LocalDecl { self.visit_ty($(& $mutability)? *ty, TyContext::LocalDecl {
local, local,
source_info: *source_info, source_info: *source_info,
}); });
@ -864,8 +864,8 @@ macro_rules! make_mir_visitor {
self.visit_span(span); self.visit_span(span);
drop(user_ty); // no visit method for this drop(user_ty); // no visit method for this
match literal { match literal {
ConstantKind::Ty(ct) => self.visit_const(ct, location), ConstantKind::Ty(ct) => self.visit_const($(& $mutability)? *ct, location),
ConstantKind::Val(_, t) => self.visit_ty(t, TyContext::Location(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>, ty: & $($mutability)? CanonicalUserTypeAnnotation<'tcx>,
) { ) {
self.visit_span(& $($mutability)? ty.span); 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_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>) { 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 /// 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`. /// 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) } desc { |tcx| "compute const default for a given parameter `{}`", tcx.def_path_str(param) }
separate_provide_extern separate_provide_extern
} }
@ -926,7 +926,7 @@ rustc_queries! {
/// Destructure a constant ADT or array into its variant index and its /// Destructure a constant ADT or array into its variant index and its
/// field values. /// field values.
query destructure_const( query destructure_const(
key: ty::ParamEnvAnd<'tcx, &'tcx ty::Const<'tcx>> key: ty::ParamEnvAnd<'tcx, ty::Const<'tcx>>
) -> mir::DestructuredConst<'tcx> { ) -> mir::DestructuredConst<'tcx> {
desc { "destructure constant" } desc { "destructure constant" }
remap_env_constness remap_env_constness
@ -935,8 +935,8 @@ rustc_queries! {
/// Dereference a constant reference or raw pointer and turn the result into a constant /// Dereference a constant reference or raw pointer and turn the result into a constant
/// again. /// again.
query deref_const( query deref_const(
key: ty::ParamEnvAnd<'tcx, &'tcx ty::Const<'tcx>> key: ty::ParamEnvAnd<'tcx, ty::Const<'tcx>>
) -> &'tcx ty::Const<'tcx> { ) -> ty::Const<'tcx> {
desc { "deref constant" } desc { "deref constant" }
remap_env_constness remap_env_constness
} }
@ -947,7 +947,7 @@ rustc_queries! {
query lit_to_const( query lit_to_const(
key: LitToConstInput<'tcx> key: LitToConstInput<'tcx>
) -> Result<&'tcx ty::Const<'tcx>, LitToConstError> { ) -> Result<ty::Const<'tcx>, LitToConstError> {
desc { "converting literal to const" } desc { "converting literal to const" }
} }
@ -1146,33 +1146,33 @@ rustc_queries! {
desc { "computing whether `{}` is `Copy`", env.value } desc { "computing whether `{}` is `Copy`", env.value }
remap_env_constness remap_env_constness
} }
/// Query backing `TyS::is_sized`. /// Query backing `Ty::is_sized`.
query is_sized_raw(env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool { query is_sized_raw(env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool {
desc { "computing whether `{}` is `Sized`", env.value } desc { "computing whether `{}` is `Sized`", env.value }
remap_env_constness remap_env_constness
} }
/// Query backing `TyS::is_freeze`. /// Query backing `Ty::is_freeze`.
query is_freeze_raw(env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool { query is_freeze_raw(env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool {
desc { "computing whether `{}` is freeze", env.value } desc { "computing whether `{}` is freeze", env.value }
remap_env_constness remap_env_constness
} }
/// Query backing `TyS::is_unpin`. /// Query backing `Ty::is_unpin`.
query is_unpin_raw(env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool { query is_unpin_raw(env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool {
desc { "computing whether `{}` is `Unpin`", env.value } desc { "computing whether `{}` is `Unpin`", env.value }
remap_env_constness remap_env_constness
} }
/// Query backing `TyS::needs_drop`. /// Query backing `Ty::needs_drop`.
query needs_drop_raw(env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool { query needs_drop_raw(env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool {
desc { "computing whether `{}` needs drop", env.value } desc { "computing whether `{}` needs drop", env.value }
remap_env_constness 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 { query has_significant_drop_raw(env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool {
desc { "computing whether `{}` has a significant drop", env.value } desc { "computing whether `{}` has a significant drop", env.value }
remap_env_constness 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 /// This is only correct for ADTs. Call `is_structural_eq_shallow` to handle all types
/// correctly. /// correctly.

View file

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

View file

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

View file

@ -26,7 +26,7 @@ pub trait Visitor<'a, 'tcx: 'a>: Sized {
walk_pat(self, pat); 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>) { 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); visitor.visit_pat(&subpattern.pattern);
} }
} }
Constant { value } => visitor.visit_const(value), Constant { value } => visitor.visit_const(*value),
Range(range) => { Range(range) => {
visitor.visit_const(range.lo); visitor.visit_const(range.lo);
visitor.visit_const(range.hi); visitor.visit_const(range.hi);

View file

@ -77,7 +77,7 @@ impl<'tcx> TypeRelation<'tcx> for Match<'tcx> {
) => Ok(a), ) => Ok(a),
(&ty::Infer(_), _) | (_, &ty::Infer(_)) => { (&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()), (&ty::Error(_), _) | (_, &ty::Error(_)) => Ok(self.tcx().ty_error()),
@ -88,21 +88,21 @@ impl<'tcx> TypeRelation<'tcx> for Match<'tcx> {
fn consts( fn consts(
&mut self, &mut self,
a: &'tcx ty::Const<'tcx>, a: ty::Const<'tcx>,
b: &'tcx ty::Const<'tcx>, b: ty::Const<'tcx>,
) -> RelateResult<'tcx, &'tcx ty::Const<'tcx>> { ) -> RelateResult<'tcx, ty::Const<'tcx>> {
debug!("{}.consts({:?}, {:?})", self.tag(), a, b); debug!("{}.consts({:?}, {:?})", self.tag(), a, b);
if a == b { if a == b {
return Ok(a); return Ok(a);
} }
match (a.val, b.val) { match (a.val(), b.val()) {
(_, ty::ConstKind::Infer(InferConst::Fresh(_))) => { (_, ty::ConstKind::Infer(InferConst::Fresh(_))) => {
return Ok(a); return Ok(a);
} }
(ty::ConstKind::Infer(_), _) | (_, ty::ConstKind::Infer(_)) => { (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. /// 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> { pub fn to_ty(self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
match self { match self {
ty::ClosureKind::Fn => tcx.types.i8, 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 { impl<'tcx, E: TyEncoder<'tcx>> Encodable<E> for AllocId {
fn encode(&self, e: &mut E) -> Result<(), E::Error> { fn encode(&self, e: &mut E) -> Result<(), E::Error> {
e.encode_alloc_id(self) e.encode_alloc_id(self)
@ -156,7 +168,6 @@ macro_rules! encodable_via_deref {
encodable_via_deref! { encodable_via_deref! {
&'tcx ty::TypeckResults<'tcx>, &'tcx ty::TypeckResults<'tcx>,
ty::Region<'tcx>,
&'tcx traits::ImplSource<'tcx, ()>, &'tcx traits::ImplSource<'tcx, ()>,
&'tcx mir::Body<'tcx>, &'tcx mir::Body<'tcx>,
&'tcx mir::UnsafetyCheckResult, &'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> { impl<'tcx, D: TyDecoder<'tcx>> Decodable<D> for ty::Const<'tcx> {
fn decode(decoder: &mut D) -> &'tcx Self { fn decode(decoder: &mut D) -> Self {
decoder.tcx().mk_const(Decodable::decode(decoder)) decoder.tcx().mk_const(Decodable::decode(decoder))
} }
} }

View file

@ -4,10 +4,12 @@ use crate::ty::{
self, InlineConstSubsts, InlineConstSubstsParts, InternalSubsts, ParamEnv, ParamEnvAnd, Ty, self, InlineConstSubsts, InlineConstSubstsParts, InternalSubsts, ParamEnv, ParamEnvAnd, Ty,
TyCtxt, TypeFoldable, TyCtxt, TypeFoldable,
}; };
use rustc_data_structures::intern::Interned;
use rustc_errors::ErrorReported; use rustc_errors::ErrorReported;
use rustc_hir as hir; use rustc_hir as hir;
use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_macros::HashStable; use rustc_macros::HashStable;
use std::fmt;
mod int; mod int;
mod kind; mod kind;
@ -17,22 +19,42 @@ pub use int::*;
pub use kind::*; pub use kind::*;
pub use valtree::*; pub use valtree::*;
/// Typed constant value. /// Use this rather than `ConstS`, whenever possible.
#[derive(Copy, Clone, Debug, Hash, TyEncodable, TyDecodable, Eq, PartialEq, Ord, PartialOrd)] #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, HashStable)]
#[derive(HashStable)] #[cfg_attr(not(bootstrap), rustc_pass_by_value)]
pub struct Const<'tcx> { pub struct Const<'tcx>(pub Interned<'tcx, ConstS<'tcx>>);
pub ty: Ty<'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>, pub val: ConstKind<'tcx>,
} }
#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))] #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
static_assert_size!(Const<'_>, 48); static_assert_size!(ConstS<'_>, 48);
impl<'tcx> Const<'tcx> { 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 /// Literals and const generic parameters are eagerly converted to a constant, everything else
/// becomes `Unevaluated`. /// 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)) 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( pub fn from_opt_const_arg_anon_const(
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
def: ty::WithOptConstParam<LocalDefId>, def: ty::WithOptConstParam<LocalDefId>,
) -> &'tcx Self { ) -> Self {
debug!("Const::from_anon_const(def={:?})", def); debug!("Const::from_anon_const(def={:?})", def);
let body_id = match tcx.hir().get_by_def_id(def.did) { 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) { match Self::try_eval_lit_or_param(tcx, ty, expr) {
Some(v) => v, Some(v) => v,
None => tcx.mk_const(ty::Const { None => tcx.mk_const(ty::ConstS {
val: ty::ConstKind::Unevaluated(ty::Unevaluated { val: ty::ConstKind::Unevaluated(ty::Unevaluated {
def: def.to_global(), def: def.to_global(),
substs: InternalSubsts::identity_for_item(tcx, def.did.to_def_id()), substs: InternalSubsts::identity_for_item(tcx, def.did.to_def_id()),
@ -74,7 +96,7 @@ impl<'tcx> Const<'tcx> {
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
ty: Ty<'tcx>, ty: Ty<'tcx>,
expr: &'tcx hir::Expr<'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 // 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. // currently have to be wrapped in curly brackets, so it's necessary to special-case.
let expr = match &expr.kind { 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 generics = tcx.generics_of(item_def_id.to_def_id());
let index = generics.param_def_id_to_index[&def_id]; let index = generics.param_def_id_to_index[&def_id];
let name = tcx.hir().name(hir_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)), val: ty::ConstKind::Param(ty::ParamConst::new(index, name)),
ty, 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); debug!("Const::from_inline_const(def_id={:?})", def_id);
let hir_id = tcx.hir().local_def_id_to_hir_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 = let substs =
InlineConstSubsts::new(tcx, InlineConstSubstsParts { parent_substs, ty }) InlineConstSubsts::new(tcx, InlineConstSubstsParts { parent_substs, ty })
.substs; .substs;
tcx.mk_const(ty::Const { tcx.mk_const(ty::ConstS {
val: ty::ConstKind::Unevaluated(ty::Unevaluated { val: ty::ConstKind::Unevaluated(ty::Unevaluated {
def: ty::WithOptConstParam::unknown(def_id).to_global(), def: ty::WithOptConstParam::unknown(def_id).to_global(),
substs, substs,
@ -171,19 +193,19 @@ impl<'tcx> Const<'tcx> {
/// Interns the given value as a constant. /// Interns the given value as a constant.
#[inline] #[inline]
pub fn from_value(tcx: TyCtxt<'tcx>, val: ConstValue<'tcx>, ty: Ty<'tcx>) -> &'tcx Self { pub fn from_value(tcx: TyCtxt<'tcx>, val: ConstValue<'tcx>, ty: Ty<'tcx>) -> Self {
tcx.mk_const(Self { val: ConstKind::Value(val), ty }) tcx.mk_const(ConstS { val: ConstKind::Value(val), ty })
} }
#[inline] #[inline]
/// Interns the given scalar as a constant. /// 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) Self::from_value(tcx, ConstValue::Scalar(val), ty)
} }
#[inline] #[inline]
/// Creates a constant with the given integer value and interns it. /// 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 let size = tcx
.layout_of(ty) .layout_of(ty)
.unwrap_or_else(|e| panic!("could not compute layout for {:?}: {:?}", ty, e)) .unwrap_or_else(|e| panic!("could not compute layout for {:?}: {:?}", ty, e))
@ -193,19 +215,19 @@ impl<'tcx> Const<'tcx> {
#[inline] #[inline]
/// Creates an interned zst constant. /// 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) Self::from_scalar(tcx, Scalar::ZST, ty)
} }
#[inline] #[inline]
/// Creates an interned bool constant. /// 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)) Self::from_bits(tcx, v as u128, ParamEnv::empty().and(tcx.types.bool))
} }
#[inline] #[inline]
/// Creates an interned usize constant. /// 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)) 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 /// generics (or erroneous code) or if the value can't be represented as bits (e.g. because it
/// contains const generic parameters or pointers). /// contains const generic parameters or pointers).
pub fn try_eval_bits( pub fn try_eval_bits(
&self, self,
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
param_env: ParamEnv<'tcx>, param_env: ParamEnv<'tcx>,
ty: Ty<'tcx>, ty: Ty<'tcx>,
) -> Option<u128> { ) -> 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; 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 // 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] #[inline]
pub fn try_eval_bool(&self, tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>) -> Option<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() self.val().eval(tcx, param_env).try_to_bool()
} }
#[inline] #[inline]
pub fn try_eval_usize(&self, tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>) -> Option<u64> { 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) self.val().eval(tcx, param_env).try_to_machine_usize(tcx)
} }
#[inline] #[inline]
/// Tries to evaluate the constant if it is `Unevaluated`. If that doesn't succeed, return the /// Tries to evaluate the constant if it is `Unevaluated`. If that doesn't succeed, return the
/// unevaluated constant. /// unevaluated constant.
pub fn eval(&self, tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>) -> &Const<'tcx> { pub fn eval(self, tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>) -> Const<'tcx> {
if let Some(val) = self.val.try_eval(tcx, param_env) { if let Some(val) = self.val().try_eval(tcx, param_env) {
match val { match val {
Ok(val) => Const::from_value(tcx, val, self.ty), Ok(val) => Const::from_value(tcx, val, self.ty()),
Err(ErrorReported) => tcx.const_error(self.ty), Err(ErrorReported) => tcx.const_error(self.ty()),
} }
} else { } else {
self self
@ -251,20 +273,20 @@ impl<'tcx> Const<'tcx> {
#[inline] #[inline]
/// Panics if the value cannot be evaluated or doesn't contain a valid integer of the given type. /// 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) self.try_eval_bits(tcx, param_env, ty)
.unwrap_or_else(|| bug!("expected bits of {:#?}, got {:#?}", ty, self)) .unwrap_or_else(|| bug!("expected bits of {:#?}, got {:#?}", ty, self))
} }
#[inline] #[inline]
/// Panics if the value cannot be evaluated or doesn't contain a valid `usize`. /// 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) self.try_eval_usize(tcx, param_env)
.unwrap_or_else(|| bug!("expected usize, got {:#?}", self)) .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()) { let default_def_id = match tcx.hir().get_by_def_id(def_id.expect_local()) {
hir::Node::GenericParam(hir::GenericParam { hir::Node::GenericParam(hir::GenericParam {
kind: hir::GenericParamKind::Const { ty: _, default: Some(ac) }, 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::TyKind::*;
use crate::ty::{ use crate::ty::{
self, AdtDef, AdtKind, Binder, BindingMode, BoundVar, CanonicalPolyFnSig, self, AdtDef, AdtKind, Binder, BindingMode, BoundVar, CanonicalPolyFnSig,
ClosureSizeProfileData, Const, ConstVid, DefIdTree, ExistentialPredicate, FloatTy, FloatVar, ClosureSizeProfileData, Const, ConstS, ConstVid, DefIdTree, ExistentialPredicate, FloatTy,
FloatVid, GenericParamDefKind, InferConst, InferTy, IntTy, IntVar, IntVid, List, ParamConst, FloatVar, FloatVid, GenericParamDefKind, InferConst, InferTy, IntTy, IntVar, IntVid, List,
ParamTy, PolyFnSig, Predicate, PredicateInner, PredicateKind, ProjectionTy, Region, RegionKind, ParamConst, ParamTy, PolyFnSig, Predicate, PredicateKind, PredicateS, ProjectionTy, Region,
ReprOptions, TraitObjectVisitor, Ty, TyKind, TyS, TyVar, TyVid, TypeAndMut, UintTy, RegionKind, ReprOptions, TraitObjectVisitor, Ty, TyKind, TyS, TyVar, TyVid, TypeAndMut, UintTy,
}; };
use rustc_ast as ast; use rustc_ast as ast;
use rustc_attr as attr; use rustc_attr as attr;
use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_data_structures::intern::Interned;
use rustc_data_structures::memmap::Mmap; use rustc_data_structures::memmap::Mmap;
use rustc_data_structures::profiling::SelfProfilerRef; use rustc_data_structures::profiling::SelfProfilerRef;
use rustc_data_structures::sharded::{IntoPointer, ShardedHashMap}; use rustc_data_structures::sharded::{IntoPointer, ShardedHashMap};
@ -91,7 +92,7 @@ pub trait OnDiskCache<'tcx>: rustc_data_structures::sync::Sync {
#[derive(TyEncodable, TyDecodable, HashStable)] #[derive(TyEncodable, TyDecodable, HashStable)]
pub struct DelaySpanBugEmitted(()); pub struct DelaySpanBugEmitted(());
type InternedSet<'tcx, T> = ShardedHashMap<Interned<'tcx, T>, ()>; type InternedSet<'tcx, T> = ShardedHashMap<InternedInSet<'tcx, T>, ()>;
pub struct CtxtInterners<'tcx> { pub struct CtxtInterners<'tcx> {
/// The arena that types, regions, etc. are allocated from. /// The arena that types, regions, etc. are allocated from.
@ -106,11 +107,11 @@ pub struct CtxtInterners<'tcx> {
region: InternedSet<'tcx, RegionKind>, region: InternedSet<'tcx, RegionKind>,
poly_existential_predicates: poly_existential_predicates:
InternedSet<'tcx, List<ty::Binder<'tcx, ExistentialPredicate<'tcx>>>>, InternedSet<'tcx, List<ty::Binder<'tcx, ExistentialPredicate<'tcx>>>>,
predicate: InternedSet<'tcx, PredicateInner<'tcx>>, predicate: InternedSet<'tcx, PredicateS<'tcx>>,
predicates: InternedSet<'tcx, List<Predicate<'tcx>>>, predicates: InternedSet<'tcx, List<Predicate<'tcx>>>,
projs: InternedSet<'tcx, List<ProjectionKind>>, projs: InternedSet<'tcx, List<ProjectionKind>>,
place_elems: InternedSet<'tcx, List<PlaceElem<'tcx>>>, place_elems: InternedSet<'tcx, List<PlaceElem<'tcx>>>,
const_: InternedSet<'tcx, Const<'tcx>>, const_: InternedSet<'tcx, ConstS<'tcx>>,
const_allocation: InternedSet<'tcx, Allocation>, const_allocation: InternedSet<'tcx, Allocation>,
bound_variable_kinds: InternedSet<'tcx, List<ty::BoundVariableKind>>, bound_variable_kinds: InternedSet<'tcx, List<ty::BoundVariableKind>>,
layout: InternedSet<'tcx, Layout>, layout: InternedSet<'tcx, Layout>,
@ -151,39 +152,40 @@ impl<'tcx> CtxtInterners<'tcx> {
#[allow(rustc::usage_of_ty_tykind)] #[allow(rustc::usage_of_ty_tykind)]
#[inline(never)] #[inline(never)]
fn intern_ty(&self, kind: TyKind<'tcx>) -> Ty<'tcx> { fn intern_ty(&self, kind: TyKind<'tcx>) -> Ty<'tcx> {
self.type_ Ty(Interned::new_unchecked(
.intern(kind, |kind| { self.type_
let flags = super::flags::FlagComputation::for_kind(&kind); .intern(kind, |kind| {
let flags = super::flags::FlagComputation::for_kind(&kind);
let ty_struct = TyS { let ty_struct = TyS {
kind, kind,
flags: flags.flags, flags: flags.flags,
outer_exclusive_binder: flags.outer_exclusive_binder, outer_exclusive_binder: flags.outer_exclusive_binder,
}; };
Interned(self.arena.alloc(ty_struct)) InternedInSet(self.arena.alloc(ty_struct))
}) })
.0 .0,
))
} }
#[inline(never)] #[inline(never)]
fn intern_predicate( fn intern_predicate(&self, kind: Binder<'tcx, PredicateKind<'tcx>>) -> Predicate<'tcx> {
&self, Predicate(Interned::new_unchecked(
kind: Binder<'tcx, PredicateKind<'tcx>>, self.predicate
) -> &'tcx PredicateInner<'tcx> { .intern(kind, |kind| {
self.predicate let flags = super::flags::FlagComputation::for_predicate(kind);
.intern(kind, |kind| {
let flags = super::flags::FlagComputation::for_predicate(kind);
let predicate_struct = PredicateInner { let predicate_struct = PredicateS {
kind, kind,
flags: flags.flags, flags: flags.flags,
outer_exclusive_binder: flags.outer_exclusive_binder, outer_exclusive_binder: flags.outer_exclusive_binder,
}; };
Interned(self.arena.alloc(predicate_struct)) InternedInSet(self.arena.alloc(predicate_struct))
}) })
.0 .0,
))
} }
} }
@ -227,7 +229,7 @@ pub struct CommonLifetimes<'tcx> {
} }
pub struct CommonConsts<'tcx> { pub struct CommonConsts<'tcx> {
pub unit: &'tcx Const<'tcx>, pub unit: Const<'tcx>,
} }
pub struct LocalTableInContext<'a, V> { pub struct LocalTableInContext<'a, V> {
@ -858,16 +860,16 @@ impl<'tcx> CanonicalUserType<'tcx> {
_ => false, _ => false,
}, },
GenericArgKind::Lifetime(r) => match r { GenericArgKind::Lifetime(r) => match *r {
ty::ReLateBound(debruijn, br) => { ty::ReLateBound(debruijn, br) => {
// We only allow a `ty::INNERMOST` index in substitutions. // We only allow a `ty::INNERMOST` index in substitutions.
assert_eq!(*debruijn, ty::INNERMOST); assert_eq!(debruijn, ty::INNERMOST);
cvar == br.var cvar == br.var
} }
_ => false, _ => false,
}, },
GenericArgKind::Const(ct) => match ct.val { GenericArgKind::Const(ct) => match ct.val() {
ty::ConstKind::Bound(debruijn, b) => { ty::ConstKind::Bound(debruijn, b) => {
// We only allow a `ty::INNERMOST` index in substitutions. // We only allow a `ty::INNERMOST` index in substitutions.
assert_eq!(debruijn, ty::INNERMOST); assert_eq!(debruijn, ty::INNERMOST);
@ -928,22 +930,30 @@ impl<'tcx> CommonTypes<'tcx> {
impl<'tcx> CommonLifetimes<'tcx> { impl<'tcx> CommonLifetimes<'tcx> {
fn new(interners: &CtxtInterners<'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 { CommonLifetimes {
re_root_empty: mk(RegionKind::ReEmpty(ty::UniverseIndex::ROOT)), re_root_empty: mk(ty::ReEmpty(ty::UniverseIndex::ROOT)),
re_static: mk(RegionKind::ReStatic), re_static: mk(ty::ReStatic),
re_erased: mk(RegionKind::ReErased), re_erased: mk(ty::ReErased),
} }
} }
} }
impl<'tcx> CommonConsts<'tcx> { impl<'tcx> CommonConsts<'tcx> {
fn new(interners: &CtxtInterners<'tcx>, types: &CommonTypes<'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 { CommonConsts {
unit: mk_const(ty::Const { unit: mk_const(ty::ConstS {
val: ty::ConstKind::Value(ConstValue::Scalar(Scalar::ZST)), val: ty::ConstKind::Value(ConstValue::Scalar(Scalar::ZST)),
ty: types.unit, ty: types.unit,
}), }),
@ -1215,7 +1225,7 @@ impl<'tcx> TyCtxt<'tcx> {
/// Like [TyCtxt::ty_error] but for constants. /// Like [TyCtxt::ty_error] but for constants.
#[track_caller] #[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( self.const_error_with_message(
ty, ty,
DUMMY_SP, DUMMY_SP,
@ -1230,9 +1240,9 @@ impl<'tcx> TyCtxt<'tcx> {
ty: Ty<'tcx>, ty: Ty<'tcx>,
span: S, span: S,
msg: &str, msg: &str,
) -> &'tcx Const<'tcx> { ) -> Const<'tcx> {
self.sess.delay_span_bug(span, msg); 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 { 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>; 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 { macro_rules! nop_lift {
($set:ident; $ty:ty => $lifted:ty) => { ($set:ident; $ty:ty => $lifted:ty) => {
impl<'a, 'tcx> Lift<'tcx> for $ty { impl<'a, 'tcx> Lift<'tcx> for $ty {
type Lifted = $lifted; type Lifted = $lifted;
fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::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) }) Some(unsafe { mem::transmute(self) })
} else { } else {
None None
@ -1650,7 +1676,7 @@ macro_rules! nop_list_lift {
if self.is_empty() { if self.is_empty() {
return Some(List::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) }) Some(unsafe { mem::transmute(self) })
} else { } else {
None None
@ -1662,9 +1688,9 @@ macro_rules! nop_list_lift {
nop_lift! {type_; Ty<'a> => Ty<'tcx>} nop_lift! {type_; Ty<'a> => Ty<'tcx>}
nop_lift! {region; Region<'a> => Region<'tcx>} nop_lift! {region; Region<'a> => Region<'tcx>}
nop_lift! {const_; &'a Const<'a> => &'tcx Const<'tcx>} nop_lift! {const_; Const<'a> => Const<'tcx>}
nop_lift! {const_allocation; &'a Allocation => &'tcx Allocation} nop_lift_old! {const_allocation; &'a Allocation => &'tcx Allocation}
nop_lift! {predicate; &'a PredicateInner<'a> => &'tcx PredicateInner<'tcx>} nop_lift! {predicate; Predicate<'a> => Predicate<'tcx>}
nop_list_lift! {type_list; Ty<'a> => Ty<'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>>} 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)] #[allow(non_snake_case)]
mod inner { mod inner {
use crate::ty::{self, TyCtxt}; use crate::ty::{self, TyCtxt};
use crate::ty::context::Interned; use crate::ty::context::InternedInSet;
#[derive(Copy, Clone)] #[derive(Copy, Clone)]
struct DebugStat { struct DebugStat {
@ -1880,16 +1906,16 @@ macro_rules! sty_debug_print {
let shards = tcx.interners.type_.lock_shards(); let shards = tcx.interners.type_.lock_shards();
let types = shards.iter().flat_map(|shard| shard.keys()); let types = shards.iter().flat_map(|shard| shard.keys());
for &Interned(t) in types { for &InternedInSet(t) in types {
let variant = match t.kind() { let variant = match t.kind {
ty::Bool | ty::Char | ty::Int(..) | ty::Uint(..) | ty::Bool | ty::Char | ty::Int(..) | ty::Uint(..) |
ty::Float(..) | ty::Str | ty::Never => continue, ty::Float(..) | ty::Str | ty::Never => continue,
ty::Error(_) => /* unimportant */ continue, ty::Error(_) => /* unimportant */ continue,
$(ty::$variant(..) => &mut $variant,)* $(ty::$variant(..) => &mut $variant,)*
}; };
let lt = t.flags().intersects(ty::TypeFlags::HAS_RE_INFER); let lt = t.flags.intersects(ty::TypeFlags::HAS_RE_INFER);
let ty = t.flags().intersects(ty::TypeFlags::HAS_TY_INFER); let ty = t.flags.intersects(ty::TypeFlags::HAS_TY_INFER);
let ct = t.flags().intersects(ty::TypeFlags::HAS_CT_INFER); let ct = t.flags.intersects(ty::TypeFlags::HAS_CT_INFER);
variant.total += 1; variant.total += 1;
total.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 // 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 // impls `Borrow` so that it can be looked up using the original
// (non-arena-memory-owning) types. // (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 { 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 () { fn into_pointer(&self) -> *const () {
self.0 as *const _ as *const () self.0 as *const _ as *const ()
} }
} }
#[allow(rustc::usage_of_ty_tykind)] #[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> { 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 &self.0.kind
} }
} }
impl<'tcx> PartialEq for Interned<'tcx, PredicateInner<'tcx>> { impl<'tcx> PartialEq for InternedInSet<'tcx, TyS<'tcx>> {
fn eq(&self, other: &Interned<'tcx, PredicateInner<'tcx>>) -> bool { fn eq(&self, other: &InternedInSet<'tcx, TyS<'tcx>>) -> bool {
// The `Borrow` trait requires that `x.borrow() == y.borrow()` equals // The `Borrow` trait requires that `x.borrow() == y.borrow()` equals
// `x == y`. // `x == y`.
self.0.kind == other.0.kind 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) { fn hash<H: Hasher>(&self, s: &mut H) {
// The `Borrow` trait requires that `x.borrow().hash(s) == x.hash(s)`. // The `Borrow` trait requires that `x.borrow().hash(s) == x.hash(s)`.
self.0.kind.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] { fn borrow<'a>(&'a self) -> &'a [T] {
&self.0[..] &self.0[..]
} }
} }
impl<'tcx, T: PartialEq> PartialEq for Interned<'tcx, List<T>> { impl<'tcx, T: PartialEq> PartialEq for InternedInSet<'tcx, List<T>> {
fn eq(&self, other: &Interned<'tcx, List<T>>) -> bool { fn eq(&self, other: &InternedInSet<'tcx, List<T>>) -> bool {
// The `Borrow` trait requires that `x.borrow() == y.borrow()` equals // The `Borrow` trait requires that `x.borrow() == y.borrow()` equals
// `x == y`. // `x == y`.
self.0[..] == other.0[..] 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) { fn hash<H: Hasher>(&self, s: &mut H) {
// The `Borrow` trait requires that `x.borrow().hash(s) == x.hash(s)`. // The `Borrow` trait requires that `x.borrow().hash(s) == x.hash(s)`.
self.0[..].hash(s) self.0[..].hash(s)
@ -2067,14 +2093,14 @@ impl<'tcx, T: Hash> Hash for Interned<'tcx, List<T>> {
} }
macro_rules! direct_interners { macro_rules! direct_interners {
($($name:ident: $method:ident($ty:ty),)+) => { ($($name:ident: $method:ident($ty:ty): $ret_ctor:ident -> $ret_ty:ty,)+) => {
$(impl<'tcx> Borrow<$ty> for Interned<'tcx, $ty> { $(impl<'tcx> Borrow<$ty> for InternedInSet<'tcx, $ty> {
fn borrow<'a>(&'a self) -> &'a $ty { fn borrow<'a>(&'a self) -> &'a $ty {
&self.0 &self.0
} }
} }
impl<'tcx> PartialEq for Interned<'tcx, $ty> { impl<'tcx> PartialEq for InternedInSet<'tcx, $ty> {
fn eq(&self, other: &Self) -> bool { fn eq(&self, other: &Self) -> bool {
// The `Borrow` trait requires that `x.borrow() == y.borrow()` // The `Borrow` trait requires that `x.borrow() == y.borrow()`
// equals `x == y`. // 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) { fn hash<H: Hasher>(&self, s: &mut H) {
// The `Borrow` trait requires that `x.borrow().hash(s) == // The `Borrow` trait requires that `x.borrow().hash(s) ==
// x.hash(s)`. // x.hash(s)`.
@ -2095,16 +2162,15 @@ macro_rules! direct_interners {
impl<'tcx> TyCtxt<'tcx> { impl<'tcx> TyCtxt<'tcx> {
pub fn $method(self, v: $ty) -> &'tcx $ty { pub fn $method(self, v: $ty) -> &'tcx $ty {
self.interners.$name.intern(v, |v| { self.interners.$name.intern(v, |v| {
Interned(self.interners.arena.alloc(v)) InternedInSet(self.interners.arena.alloc(v))
}).0 }).0
} }
})+ })+
} }
} }
direct_interners! { // FIXME: eventually these should all be converted to `direct_interners`.
region: mk_region(RegionKind), direct_interners_old! {
const_: mk_const(Const<'tcx>),
const_allocation: intern_const_alloc(Allocation), const_allocation: intern_const_alloc(Allocation),
layout: intern_layout(Layout), layout: intern_layout(Layout),
adt_def: intern_adt_def(AdtDef), adt_def: intern_adt_def(AdtDef),
@ -2117,7 +2183,7 @@ macro_rules! slice_interners {
impl<'tcx> TyCtxt<'tcx> { impl<'tcx> TyCtxt<'tcx> {
$(pub fn $method(self, v: &[$ty]) -> &'tcx List<$ty> { $(pub fn $method(self, v: &[$ty]) -> &'tcx List<$ty> {
self.interners.$field.intern_ref(v, || { self.interners.$field.intern_ref(v, || {
Interned(List::from_arena(&*self.arena, v)) InternedInSet(List::from_arena(&*self.arena, v))
}).0 }).0
})+ })+
} }
@ -2217,8 +2283,7 @@ impl<'tcx> TyCtxt<'tcx> {
#[inline] #[inline]
pub fn mk_predicate(self, binder: Binder<'tcx, PredicateKind<'tcx>>) -> Predicate<'tcx> { pub fn mk_predicate(self, binder: Binder<'tcx, PredicateKind<'tcx>>) -> Predicate<'tcx> {
let inner = self.interners.intern_predicate(binder); self.interners.intern_predicate(binder)
Predicate { inner }
} }
#[inline] #[inline]
@ -2429,8 +2494,8 @@ impl<'tcx> TyCtxt<'tcx> {
} }
#[inline] #[inline]
pub fn mk_const_var(self, v: ConstVid<'tcx>, ty: Ty<'tcx>) -> &'tcx Const<'tcx> { pub fn mk_const_var(self, v: ConstVid<'tcx>, ty: Ty<'tcx>) -> Const<'tcx> {
self.mk_const(ty::Const { val: ty::ConstKind::Infer(InferConst::Var(v)), ty }) self.mk_const(ty::ConstS { val: ty::ConstKind::Infer(InferConst::Var(v)), ty })
} }
#[inline] #[inline]
@ -2449,8 +2514,8 @@ impl<'tcx> TyCtxt<'tcx> {
} }
#[inline] #[inline]
pub fn mk_const_infer(self, ic: InferConst<'tcx>, ty: Ty<'tcx>) -> &'tcx ty::Const<'tcx> { pub fn mk_const_infer(self, ic: InferConst<'tcx>, ty: Ty<'tcx>) -> ty::Const<'tcx> {
self.mk_const(ty::Const { val: ty::ConstKind::Infer(ic), ty }) self.mk_const(ty::ConstS { val: ty::ConstKind::Infer(ic), ty })
} }
#[inline] #[inline]
@ -2459,8 +2524,8 @@ impl<'tcx> TyCtxt<'tcx> {
} }
#[inline] #[inline]
pub fn mk_const_param(self, index: u32, name: Symbol, ty: Ty<'tcx>) -> &'tcx Const<'tcx> { pub fn mk_const_param(self, index: u32, name: Symbol, ty: Ty<'tcx>) -> Const<'tcx> {
self.mk_const(ty::Const { val: ty::ConstKind::Param(ParamConst { index, name }), ty }) 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> { 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::subst::{GenericArg, GenericArgKind};
use crate::ty::TyKind::*; use crate::ty::TyKind::*;
use crate::ty::{ use crate::ty::{
ConstKind, ExistentialPredicate, ExistentialProjection, ExistentialTraitRef, InferTy, ConstKind, ExistentialPredicate, ExistentialProjection, ExistentialTraitRef, InferTy,
ProjectionTy, Term, TyCtxt, TyS, TypeAndMut, ProjectionTy, Term, Ty, TyCtxt, TypeAndMut,
}; };
use rustc_errors::{Applicability, DiagnosticBuilder}; use rustc_errors::{Applicability, DiagnosticBuilder};
@ -13,9 +13,9 @@ use rustc_hir::def_id::DefId;
use rustc_hir::{QPath, TyKind, WhereBoundPredicate, WherePredicate}; use rustc_hir::{QPath, TyKind, WhereBoundPredicate, WherePredicate};
use rustc_span::Span; use rustc_span::Span;
impl<'tcx> TyS<'tcx> { impl<'tcx> Ty<'tcx> {
/// Similar to `TyS::is_primitive`, but also considers inferred numeric values to be primitive. /// Similar to `Ty::is_primitive`, but also considers inferred numeric values to be primitive.
pub fn is_primitive_ty(&self) -> bool { pub fn is_primitive_ty(self) -> bool {
matches!( matches!(
self.kind(), self.kind(),
Bool | Char 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 /// 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. /// 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() { match self.kind() {
Bool Bool
| Char | Char
@ -58,7 +58,7 @@ impl<'tcx> TyS<'tcx> {
/// description in error messages. This is used in the primary span label. Beyond what /// 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 /// `is_simple_ty` includes, it also accepts ADTs with no type arguments and references to
/// ADTs with no type arguments. /// ADTs with no type arguments.
pub fn is_simple_text(&self) -> bool { pub fn is_simple_text(self) -> bool {
match self.kind() { match self.kind() {
Adt(_, substs) => substs.non_erasable_generics().next().is_none(), Adt(_, substs) => substs.non_erasable_generics().next().is_none(),
Ref(_, ty, _) => ty.is_simple_text(), Ref(_, ty, _) => ty.is_simple_text(),
@ -67,11 +67,11 @@ impl<'tcx> TyS<'tcx> {
} }
/// Whether the type can be safely suggested during error recovery. /// 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 { fn generic_arg_is_suggestible(arg: GenericArg<'_>) -> bool {
match arg.unpack() { match arg.unpack() {
GenericArgKind::Type(ty) => ty.is_suggestable(), GenericArgKind::Type(ty) => ty.is_suggestable(),
GenericArgKind::Const(c) => const_is_suggestable(c.val), GenericArgKind::Const(c) => const_is_suggestable(c.val()),
_ => true, _ => true,
} }
} }
@ -110,7 +110,7 @@ impl<'tcx> TyS<'tcx> {
}) => { }) => {
let term_is_suggestable = match term { let term_is_suggestable = match term {
Term::Ty(ty) => ty.is_suggestable(), 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) 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) args.iter().all(generic_arg_is_suggestible)
} }
Slice(ty) | RawPtr(TypeAndMut { ty, .. }) | Ref(_, ty, _) => ty.is_suggestable(), 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, _ => true,
} }
} }

View file

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

View file

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

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