summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_hir_typeck/src/writeback.rs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_hir_typeck/src/writeback.rs')
-rw-r--r--compiler/rustc_hir_typeck/src/writeback.rs119
1 files changed, 55 insertions, 64 deletions
diff --git a/compiler/rustc_hir_typeck/src/writeback.rs b/compiler/rustc_hir_typeck/src/writeback.rs
index 0f21fc1e6..106457536 100644
--- a/compiler/rustc_hir_typeck/src/writeback.rs
+++ b/compiler/rustc_hir_typeck/src/writeback.rs
@@ -11,10 +11,9 @@ use rustc_hir::intravisit::{self, Visitor};
use rustc_infer::infer::error_reporting::TypeAnnotationNeeded::E0282;
use rustc_middle::hir::place::Place as HirPlace;
use rustc_middle::mir::FakeReadCause;
-use rustc_middle::ty::adjustment::{Adjust, Adjustment, PointerCast};
+use rustc_middle::ty::adjustment::{Adjust, Adjustment, PointerCoercion};
use rustc_middle::ty::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable};
use rustc_middle::ty::visit::{TypeSuperVisitable, TypeVisitable, TypeVisitableExt};
-use rustc_middle::ty::TypeckResults;
use rustc_middle::ty::{self, ClosureSizeProfileData, Ty, TyCtxt};
use rustc_span::symbol::sym;
use rustc_span::Span;
@@ -137,7 +136,10 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
fn write_ty_to_typeck_results(&mut self, hir_id: hir::HirId, ty: Ty<'tcx>) {
debug!("write_ty_to_typeck_results({:?}, {:?})", hir_id, ty);
- assert!(!ty.has_infer() && !ty.has_placeholders() && !ty.has_free_regions());
+ assert!(
+ !ty.has_infer() && !ty.has_placeholders() && !ty.has_free_regions(),
+ "{ty} can't be put into typeck results"
+ );
self.typeck_results.node_types_mut().insert(hir_id, ty);
}
@@ -148,31 +150,25 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
fn fix_scalar_builtin_expr(&mut self, e: &hir::Expr<'_>) {
match e.kind {
hir::ExprKind::Unary(hir::UnOp::Neg | hir::UnOp::Not, inner) => {
- let inner_ty = self.fcx.node_ty(inner.hir_id);
- let inner_ty = self.fcx.resolve_vars_if_possible(inner_ty);
+ let inner_ty = self.typeck_results.node_type(inner.hir_id);
if inner_ty.is_scalar() {
- let mut typeck_results = self.fcx.typeck_results.borrow_mut();
- typeck_results.type_dependent_defs_mut().remove(e.hir_id);
- typeck_results.node_substs_mut().remove(e.hir_id);
+ self.typeck_results.type_dependent_defs_mut().remove(e.hir_id);
+ self.typeck_results.node_substs_mut().remove(e.hir_id);
}
}
hir::ExprKind::Binary(ref op, lhs, rhs) | hir::ExprKind::AssignOp(ref op, lhs, rhs) => {
- let lhs_ty = self.fcx.node_ty(lhs.hir_id);
- let lhs_ty = self.fcx.resolve_vars_if_possible(lhs_ty);
-
- let rhs_ty = self.fcx.node_ty(rhs.hir_id);
- let rhs_ty = self.fcx.resolve_vars_if_possible(rhs_ty);
+ let lhs_ty = self.typeck_results.node_type(lhs.hir_id);
+ let rhs_ty = self.typeck_results.node_type(rhs.hir_id);
if lhs_ty.is_scalar() && rhs_ty.is_scalar() {
- let mut typeck_results = self.fcx.typeck_results.borrow_mut();
- typeck_results.type_dependent_defs_mut().remove(e.hir_id);
- typeck_results.node_substs_mut().remove(e.hir_id);
+ self.typeck_results.type_dependent_defs_mut().remove(e.hir_id);
+ self.typeck_results.node_substs_mut().remove(e.hir_id);
match e.kind {
hir::ExprKind::Binary(..) => {
if !op.node.is_by_value() {
- let mut adjustments = typeck_results.adjustments_mut();
+ let mut adjustments = self.typeck_results.adjustments_mut();
if let Some(a) = adjustments.get_mut(lhs.hir_id) {
a.pop();
}
@@ -182,7 +178,7 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
}
}
hir::ExprKind::AssignOp(..)
- if let Some(a) = typeck_results.adjustments_mut().get_mut(lhs.hir_id) =>
+ if let Some(a) = self.typeck_results.adjustments_mut().get_mut(lhs.hir_id) =>
{
a.pop();
}
@@ -200,16 +196,14 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
// if they are not we don't modify the expr, hence we bypass the ICE
fn is_builtin_index(
&mut self,
- typeck_results: &TypeckResults<'tcx>,
e: &hir::Expr<'_>,
base_ty: Ty<'tcx>,
index_ty: Ty<'tcx>,
) -> bool {
- if let Some(elem_ty) = base_ty.builtin_index() {
- let Some(exp_ty) = typeck_results.expr_ty_opt(e) else {return false;};
- let resolved_exp_ty = self.resolve(exp_ty, &e.span);
-
- elem_ty == resolved_exp_ty && index_ty == self.fcx.tcx.types.usize
+ if let Some(elem_ty) = base_ty.builtin_index()
+ && let Some(exp_ty) = self.typeck_results.expr_ty_opt(e)
+ {
+ elem_ty == exp_ty && index_ty == self.fcx.tcx.types.usize
} else {
false
}
@@ -221,38 +215,35 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
// usize-ish
fn fix_index_builtin_expr(&mut self, e: &hir::Expr<'_>) {
if let hir::ExprKind::Index(ref base, ref index) = e.kind {
- let mut typeck_results = self.fcx.typeck_results.borrow_mut();
-
// All valid indexing looks like this; might encounter non-valid indexes at this point.
- let base_ty = typeck_results
- .expr_ty_adjusted_opt(base)
- .map(|t| self.fcx.resolve_vars_if_possible(t).kind());
+ let base_ty = self.typeck_results.expr_ty_adjusted_opt(base);
if base_ty.is_none() {
// When encountering `return [0][0]` outside of a `fn` body we can encounter a base
// that isn't in the type table. We assume more relevant errors have already been
// emitted, so we delay an ICE if none have. (#64638)
self.tcx().sess.delay_span_bug(e.span, format!("bad base: `{:?}`", base));
}
- if let Some(ty::Ref(_, base_ty, _)) = base_ty {
- let index_ty = typeck_results.expr_ty_adjusted_opt(index).unwrap_or_else(|| {
- // When encountering `return [0][0]` outside of a `fn` body we would attempt
- // to access an nonexistent index. We assume that more relevant errors will
- // already have been emitted, so we only gate on this with an ICE if no
- // error has been emitted. (#64638)
- self.fcx.tcx.ty_error_with_message(
- e.span,
- format!("bad index {:?} for base: `{:?}`", index, base),
- )
- });
- let index_ty = self.fcx.resolve_vars_if_possible(index_ty);
- let resolved_base_ty = self.resolve(*base_ty, &base.span);
-
- if self.is_builtin_index(&typeck_results, e, resolved_base_ty, index_ty) {
+ if let Some(base_ty) = base_ty
+ && let ty::Ref(_, base_ty_inner, _) = *base_ty.kind()
+ {
+ let index_ty =
+ self.typeck_results.expr_ty_adjusted_opt(index).unwrap_or_else(|| {
+ // When encountering `return [0][0]` outside of a `fn` body we would attempt
+ // to access an nonexistent index. We assume that more relevant errors will
+ // already have been emitted, so we only gate on this with an ICE if no
+ // error has been emitted. (#64638)
+ Ty::new_error_with_message(
+ self.fcx.tcx,
+ e.span,
+ format!("bad index {:?} for base: `{:?}`", index, base),
+ )
+ });
+ if self.is_builtin_index(e, base_ty_inner, index_ty) {
// Remove the method call record
- typeck_results.type_dependent_defs_mut().remove(e.hir_id);
- typeck_results.node_substs_mut().remove(e.hir_id);
+ self.typeck_results.type_dependent_defs_mut().remove(e.hir_id);
+ self.typeck_results.node_substs_mut().remove(e.hir_id);
- if let Some(a) = typeck_results.adjustments_mut().get_mut(base.hir_id) {
+ if let Some(a) = self.typeck_results.adjustments_mut().get_mut(base.hir_id) {
// Discard the need for a mutable borrow
// Extra adjustment made when indexing causes a drop
@@ -260,7 +251,7 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
// Since this is "after" the other adjustment to be
// discarded, we do an extra `pop()`
if let Some(Adjustment {
- kind: Adjust::Pointer(PointerCast::Unsize), ..
+ kind: Adjust::Pointer(PointerCoercion::Unsize), ..
}) = a.pop()
{
// So the borrow discard actually happens here
@@ -283,9 +274,6 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
impl<'cx, 'tcx> Visitor<'tcx> for WritebackCx<'cx, 'tcx> {
fn visit_expr(&mut self, e: &'tcx hir::Expr<'tcx>) {
- self.fix_scalar_builtin_expr(e);
- self.fix_index_builtin_expr(e);
-
match e.kind {
hir::ExprKind::Closure(&hir::Closure { body, .. }) => {
let body = self.fcx.tcx.hir().body(body);
@@ -314,6 +302,9 @@ impl<'cx, 'tcx> Visitor<'tcx> for WritebackCx<'cx, 'tcx> {
self.visit_node_id(e.span, e.hir_id);
intravisit::walk_expr(self, e);
+
+ self.fix_scalar_builtin_expr(e);
+ self.fix_index_builtin_expr(e);
}
fn visit_generic_param(&mut self, p: &'tcx hir::GenericParam<'tcx>) {
@@ -358,7 +349,7 @@ impl<'cx, 'tcx> Visitor<'tcx> for WritebackCx<'cx, 'tcx> {
fn visit_local(&mut self, l: &'tcx hir::Local<'tcx>) {
intravisit::walk_local(self, l);
- let var_ty = self.fcx.local_ty(l.span, l.hir_id).decl_ty;
+ let var_ty = self.fcx.local_ty(l.span, l.hir_id);
let var_ty = self.resolve(var_ty, &l.span);
self.write_ty_to_typeck_results(l.hir_id, var_ty);
}
@@ -583,19 +574,15 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
continue;
}
- let hidden_type =
- self.tcx().erase_regions(hidden_type.remap_generic_params_to_declaration_params(
- opaque_type_key,
- self.tcx(),
- true,
- ));
-
+ // Here we only detect impl trait definition conflicts when they
+ // are equal modulo regions.
if let Some(last_opaque_ty) = self
.typeck_results
.concrete_opaque_types
- .insert(opaque_type_key.def_id, hidden_type)
+ .insert(opaque_type_key, hidden_type)
&& last_opaque_ty.ty != hidden_type.ty
{
+ assert!(!self.fcx.next_trait_solver());
hidden_type
.report_mismatch(&last_opaque_ty, opaque_type_key.def_id, self.tcx())
.stash(
@@ -816,11 +803,15 @@ impl<'cx, 'tcx> TypeFolder<TyCtxt<'tcx>> for Resolver<'cx, 'tcx> {
fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
match self.fcx.fully_resolve(t) {
- Ok(t) if self.fcx.tcx.trait_solver_next() => {
+ Ok(t) if self.fcx.next_trait_solver() => {
// We must normalize erasing regions here, since later lints
// expect that types that show up in the typeck are fully
// normalized.
- self.fcx.tcx.try_normalize_erasing_regions(self.fcx.param_env, t).unwrap_or(t)
+ if let Ok(t) = self.fcx.tcx.try_normalize_erasing_regions(self.fcx.param_env, t) {
+ t
+ } else {
+ EraseEarlyRegions { tcx: self.fcx.tcx }.fold_ty(t)
+ }
}
Ok(t) => {
// Do not anonymize late-bound regions
@@ -833,7 +824,7 @@ impl<'cx, 'tcx> TypeFolder<TyCtxt<'tcx>> for Resolver<'cx, 'tcx> {
debug!("Resolver::fold_ty: input type `{:?}` not fully resolvable", t);
let e = self.report_error(t);
self.replaced_with_error = Some(e);
- self.fcx.tcx.ty_error(e)
+ Ty::new_error(self.fcx.tcx, e)
}
}
}
@@ -850,7 +841,7 @@ impl<'cx, 'tcx> TypeFolder<TyCtxt<'tcx>> for Resolver<'cx, 'tcx> {
debug!("Resolver::fold_const: input const `{:?}` not fully resolvable", ct);
let e = self.report_error(ct);
self.replaced_with_error = Some(e);
- self.fcx.tcx.const_error(ct.ty(), e)
+ ty::Const::new_error(self.fcx.tcx, e, ct.ty())
}
}
}