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:
commit
5569757491
252 changed files with 1927 additions and 1699 deletions
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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));
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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(
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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 },
|
||||||
)),
|
)),
|
||||||
);
|
);
|
||||||
|
|
|
@ -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(
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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());
|
||||||
|
|
|
@ -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(
|
||||||
|
|
|
@ -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!(
|
||||||
|
|
|
@ -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,
|
||||||
};
|
};
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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");
|
||||||
|
|
|
@ -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 })
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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),
|
||||||
}
|
}
|
||||||
|
|
|
@ -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))?
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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,
|
||||||
|
|
98
compiler/rustc_data_structures/src/intern.rs
Normal file
98
compiler/rustc_data_structures/src/intern.rs
Normal 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;
|
59
compiler/rustc_data_structures/src/intern/tests.rs
Normal file
59
compiler/rustc_data_structures/src/intern/tests.rs
Normal 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
|
||||||
|
}
|
|
@ -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;
|
||||||
|
|
|
@ -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
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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>,
|
||||||
|
|
|
@ -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()),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,
|
||||||
})
|
})
|
||||||
|
|
|
@ -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`"
|
||||||
|
|
|
@ -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 }),
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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(), ¶m.kind) {
|
.map(|(subst, param)| match &(subst.unpack(), ¶m.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
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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(
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)) => {
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 },
|
||||||
|
|
|
@ -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,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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(),
|
||||||
|
|
|
@ -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()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)));
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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()),
|
||||||
|
|
|
@ -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));
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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]`",
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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) }
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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(),
|
||||||
|
|
|
@ -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,
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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),
|
||||||
})
|
})
|
||||||
|
|
|
@ -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,
|
||||||
}
|
}
|
||||||
|
|
|
@ -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>) {
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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]),
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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)));
|
||||||
}
|
}
|
||||||
|
|
||||||
_ => {}
|
_ => {}
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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) },
|
||||||
|
|
|
@ -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> {
|
||||||
|
|
|
@ -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,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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(_)
|
||||||
|
|
|
@ -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
Loading…
Add table
Reference in a new issue