summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_hir_typeck/src/expr.rs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_hir_typeck/src/expr.rs')
-rw-r--r--compiler/rustc_hir_typeck/src/expr.rs83
1 files changed, 39 insertions, 44 deletions
diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs
index 7fc4ccb04..6ffa0134f 100644
--- a/compiler/rustc_hir_typeck/src/expr.rs
+++ b/compiler/rustc_hir_typeck/src/expr.rs
@@ -36,6 +36,7 @@ use rustc_hir_analysis::astconv::AstConv as _;
use rustc_hir_analysis::check::ty_kind_suggestion;
use rustc_infer::infer;
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
+use rustc_infer::infer::DefineOpaqueTypes;
use rustc_infer::infer::InferOk;
use rustc_infer::traits::ObligationCause;
use rustc_middle::middle::stability;
@@ -49,6 +50,7 @@ use rustc_span::edit_distance::find_best_match_for_name;
use rustc_span::hygiene::DesugaringKind;
use rustc_span::source_map::{Span, Spanned};
use rustc_span::symbol::{kw, sym, Ident, Symbol};
+use rustc_target::abi::FieldIdx;
use rustc_target::spec::abi::Abi::RustIntrinsic;
use rustc_trait_selection::infer::InferCtxtExt;
use rustc_trait_selection::traits::{self, ObligationCauseCode};
@@ -118,7 +120,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
ty
}
- pub(super) fn check_expr_coercable_to_type(
+ pub(super) fn check_expr_coercible_to_type(
&self,
expr: &'tcx hir::Expr<'tcx>,
expected: Ty<'tcx>,
@@ -230,7 +232,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let ty = ensure_sufficient_stack(|| match &expr.kind {
hir::ExprKind::Path(
- qpath @ hir::QPath::Resolved(..) | qpath @ hir::QPath::TypeRelative(..),
+ qpath @ (hir::QPath::Resolved(..) | hir::QPath::TypeRelative(..)),
) => self.check_expr_path(qpath, expr, args),
_ => self.check_expr_kind(expr, expected),
});
@@ -283,7 +285,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let tcx = self.tcx;
match expr.kind {
- ExprKind::Box(subexpr) => self.check_expr_box(subexpr, expected),
ExprKind::Lit(ref lit) => self.check_lit(&lit, expected),
ExprKind::Binary(op, lhs, rhs) => self.check_binop(expr, op, lhs, rhs, expected),
ExprKind::Assign(lhs, rhs, span) => {
@@ -358,16 +359,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
}
- fn check_expr_box(&self, expr: &'tcx hir::Expr<'tcx>, expected: Expectation<'tcx>) -> Ty<'tcx> {
- let expected_inner = expected.to_option(self).map_or(NoExpectation, |ty| match ty.kind() {
- ty::Adt(def, _) if def.is_box() => Expectation::rvalue_hint(self, ty.boxed_ty()),
- _ => NoExpectation,
- });
- let referent_ty = self.check_expr_with_expectation(expr, expected_inner);
- self.require_type_is_sized(referent_ty, expr.span, traits::SizedBoxType);
- self.tcx.mk_box(referent_ty)
- }
-
fn check_expr_unary(
&self,
unop: hir::UnOp,
@@ -798,7 +789,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
self.ret_coercion_span.set(Some(expr.span));
}
let cause = self.cause(expr.span, ObligationCauseCode::ReturnNoExpression);
- if let Some((fn_decl, _)) = self.get_fn_decl(expr.hir_id) {
+ if let Some((_, fn_decl, _)) = self.get_fn_decl(expr.hir_id) {
coercion.coerce_forced_unit(
self,
&cause,
@@ -1137,7 +1128,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
};
- // This is (basically) inlined `check_expr_coercable_to_type`, but we want
+ // This is (basically) inlined `check_expr_coercible_to_type`, but we want
// to suggest an additional fixup here in `suggest_deref_binop`.
let rhs_ty = self.check_expr_with_hint(&rhs, lhs_ty);
if let (_, Some(mut diag)) =
@@ -1410,7 +1401,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let (element_ty, t) = match uty {
Some(uty) => {
- self.check_expr_coercable_to_type(&element, uty, None);
+ self.check_expr_coercible_to_type(&element, uty, None);
(uty, uty)
}
None => {
@@ -1487,7 +1478,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let elt_ts_iter = elts.iter().enumerate().map(|(i, e)| match flds {
Some(fs) if i < fs.len() => {
let ety = fs[i];
- self.check_expr_coercable_to_type(&e, ety, None);
+ self.check_expr_coercible_to_type(&e, ety, None);
ety
}
_ => self.check_expr_with_expectation(&e, NoExpectation),
@@ -1571,8 +1562,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let mut remaining_fields = variant
.fields
- .iter()
- .enumerate()
+ .iter_enumerated()
.map(|(i, field)| (field.ident(tcx).normalize_to_macros_2_0(), (i, field)))
.collect::<FxHashMap<_, _>>();
@@ -1683,7 +1673,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
if let Some(_) = remaining_fields.remove(&ident) {
let target_ty = self.field_ty(base_expr.span, f, substs);
let cause = self.misc(base_expr.span);
- match self.at(&cause, self.param_env).sup(target_ty, fru_ty) {
+ match self.at(&cause, self.param_env).sup(
+ DefineOpaqueTypes::No,
+ target_ty,
+ fru_ty,
+ ) {
Ok(InferOk { obligations, value: () }) => {
self.register_predicates(obligations)
}
@@ -1821,7 +1815,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
&self,
adt_ty: Ty<'tcx>,
span: Span,
- remaining_fields: FxHashMap<Ident, (usize, &ty::FieldDef)>,
+ remaining_fields: FxHashMap<Ident, (FieldIdx, &ty::FieldDef)>,
variant: &'tcx ty::VariantDef,
ast_fields: &'tcx [hir::ExprField<'tcx>],
substs: SubstsRef<'tcx>,
@@ -2215,11 +2209,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let (ident, def_scope) =
self.tcx.adjust_ident_and_get_scope(field, base_def.did(), body_hir_id);
let fields = &base_def.non_enum_variant().fields;
- if let Some(index) = fields
- .iter()
- .position(|f| f.ident(self.tcx).normalize_to_macros_2_0() == ident)
+ if let Some((index, field)) = fields
+ .iter_enumerated()
+ .find(|(_, f)| f.ident(self.tcx).normalize_to_macros_2_0() == ident)
{
- let field = &fields[index];
let field_ty = self.field_ty(expr.span, field, substs);
// Save the index of all fields regardless of their visibility in case
// of error recovery.
@@ -2236,15 +2229,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
}
ty::Tuple(tys) => {
- let fstr = field.as_str();
- if let Ok(index) = fstr.parse::<usize>() {
- if fstr == index.to_string() {
+ if let Ok(index) = field.as_str().parse::<usize>() {
+ if field.name == sym::integer(index) {
if let Some(&field_ty) = tys.get(index) {
let adjustments = self.adjust_steps(&autoderef);
self.apply_adjustments(base, adjustments);
self.register_predicates(autoderef.into_obligations());
- self.write_field_index(expr.hir_id, index);
+ self.write_field_index(expr.hir_id, FieldIdx::from_usize(index));
return field_ty;
}
}
@@ -2818,23 +2810,26 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
"cannot index into a value of type `{base_t}`",
);
// Try to give some advice about indexing tuples.
- if let ty::Tuple(..) = base_t.kind() {
+ if let ty::Tuple(types) = base_t.kind() {
let mut needs_note = true;
// If the index is an integer, we can show the actual
// fixed expression:
- if let ExprKind::Lit(ref lit) = idx.kind {
- if let ast::LitKind::Int(i, ast::LitIntType::Unsuffixed) = lit.node {
- let snip = self.tcx.sess.source_map().span_to_snippet(base.span);
- if let Ok(snip) = snip {
- err.span_suggestion(
- expr.span,
- "to access tuple elements, use",
- format!("{snip}.{i}"),
- Applicability::MachineApplicable,
- );
- needs_note = false;
- }
+ if let ExprKind::Lit(ref lit) = idx.kind
+ && let ast::LitKind::Int(i, ast::LitIntType::Unsuffixed) = lit.node
+ && i < types.len().try_into().expect("expected tuple index to be < usize length")
+ {
+ let snip = self.tcx.sess.source_map().span_to_snippet(base.span);
+ if let Ok(snip) = snip {
+ err.span_suggestion(
+ expr.span,
+ "to access tuple elements, use",
+ format!("{snip}.{i}"),
+ Applicability::MachineApplicable,
+ );
+ needs_note = false;
}
+ } else if let ExprKind::Path(..) = idx.peel_borrows().kind {
+ err.span_label(idx.span, "cannot access tuple elements at a variable index");
}
if needs_note {
err.help(
@@ -2874,7 +2869,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
) -> Ty<'tcx> {
match self.resume_yield_tys {
Some((resume_ty, yield_ty)) => {
- self.check_expr_coercable_to_type(&value, yield_ty, None);
+ self.check_expr_coercible_to_type(&value, yield_ty, None);
resume_ty
}
@@ -2883,7 +2878,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// information. Hence, we check the source of the yield expression here and check its
// value's type against `()` (this check should always hold).
None if src.is_await() => {
- self.check_expr_coercable_to_type(&value, self.tcx.mk_unit(), None);
+ self.check_expr_coercible_to_type(&value, self.tcx.mk_unit(), None);
self.tcx.mk_unit()
}
_ => {