Register const preds for Deref adjustments in HIR typeck

This commit is contained in:
Michael Goulet 2024-11-03 04:39:08 +00:00
parent 43c78051ea
commit e03e9abe3c
3 changed files with 42 additions and 12 deletions

View File

@ -254,12 +254,34 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
} }
for a in &adj { for a in &adj {
if let Adjust::NeverToAny = a.kind { match a.kind {
Adjust::NeverToAny => {
if a.target.is_ty_var() { if a.target.is_ty_var() {
self.diverging_type_vars.borrow_mut().insert(a.target); self.diverging_type_vars.borrow_mut().insert(a.target);
debug!("apply_adjustments: adding `{:?}` as diverging type var", a.target); debug!("apply_adjustments: adding `{:?}` as diverging type var", a.target);
} }
} }
Adjust::Deref(Some(overloaded_deref)) => {
self.enforce_context_effects(
expr.span,
overloaded_deref.method_call(self.tcx),
self.tcx.mk_args(&[a.target.into()]),
);
}
Adjust::Deref(None) => {
// FIXME(effects): We *could* enforce `&T: ~const Deref` here.
}
Adjust::Pointer(_pointer_coercion) => {
// FIXME(effects): We should probably enforce these.
}
Adjust::ReborrowPin(_mutability) => {
// FIXME(effects): We could enforce these; they correspond to
// `&mut T: DerefMut` tho, so it's kinda moot.
}
Adjust::Borrow(_) => {
// No effects to enforce here.
}
}
} }
let autoborrow_mut = adj.iter().any(|adj| { let autoborrow_mut = adj.iter().any(|adj| {

View File

@ -1,5 +1,6 @@
use rustc_abi::FieldIdx; use rustc_abi::FieldIdx;
use rustc_hir as hir; use rustc_hir as hir;
use rustc_hir::def_id::DefId;
use rustc_hir::lang_items::LangItem; use rustc_hir::lang_items::LangItem;
use rustc_macros::{HashStable, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable}; use rustc_macros::{HashStable, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable};
use rustc_span::Span; use rustc_span::Span;
@ -123,19 +124,18 @@ pub struct OverloadedDeref {
} }
impl OverloadedDeref { impl OverloadedDeref {
/// Get the zst function item type for this method call. /// Get the [`DefId`] of the method call for the given `Deref`/`DerefMut` trait
pub fn method_call<'tcx>(&self, tcx: TyCtxt<'tcx>, source: Ty<'tcx>) -> Ty<'tcx> { /// for this overloaded deref's mutability.
pub fn method_call<'tcx>(&self, tcx: TyCtxt<'tcx>) -> DefId {
let trait_def_id = match self.mutbl { let trait_def_id = match self.mutbl {
hir::Mutability::Not => tcx.require_lang_item(LangItem::Deref, None), hir::Mutability::Not => tcx.require_lang_item(LangItem::Deref, None),
hir::Mutability::Mut => tcx.require_lang_item(LangItem::DerefMut, None), hir::Mutability::Mut => tcx.require_lang_item(LangItem::DerefMut, None),
}; };
let method_def_id = tcx tcx.associated_items(trait_def_id)
.associated_items(trait_def_id)
.in_definition_order() .in_definition_order()
.find(|m| m.kind == ty::AssocKind::Fn) .find(|m| m.kind == ty::AssocKind::Fn)
.unwrap() .unwrap()
.def_id; .def_id
Ty::new_fn_def(tcx, method_def_id, [source])
} }
} }

View File

@ -136,7 +136,9 @@ impl<'tcx> Cx<'tcx> {
Adjust::Deref(Some(deref)) => { Adjust::Deref(Some(deref)) => {
// We don't need to do call adjust_span here since // We don't need to do call adjust_span here since
// deref coercions always start with a built-in deref. // deref coercions always start with a built-in deref.
let call = deref.method_call(self.tcx(), expr.ty); let call_def_id = deref.method_call(self.tcx());
let overloaded_callee =
Ty::new_fn_def(self.tcx(), call_def_id, self.tcx().mk_args(&[expr.ty.into()]));
expr = Expr { expr = Expr {
temp_lifetime, temp_lifetime,
@ -150,7 +152,13 @@ impl<'tcx> Cx<'tcx> {
let expr = Box::new([self.thir.exprs.push(expr)]); let expr = Box::new([self.thir.exprs.push(expr)]);
self.overloaded_place(hir_expr, adjustment.target, Some(call), expr, deref.span) self.overloaded_place(
hir_expr,
adjustment.target,
Some(overloaded_callee),
expr,
deref.span,
)
} }
Adjust::Borrow(AutoBorrow::Ref(m)) => ExprKind::Borrow { Adjust::Borrow(AutoBorrow::Ref(m)) => ExprKind::Borrow {
borrow_kind: m.to_borrow_kind(), borrow_kind: m.to_borrow_kind(),