1
Fork 0

Use can_eq to compare types for default assoc type error

This works correctly with inference variables.
This commit is contained in:
Nilstrieb 2023-01-25 20:11:05 +01:00
parent b222f2e266
commit 943000fdcf
7 changed files with 49 additions and 17 deletions

View file

@ -1850,7 +1850,6 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
self.note_and_explain_type_err(diag, terr, cause, span, cause.body_id.to_def_id());
if let Some(ValuePairs::PolyTraitRefs(exp_found)) = values
&& let ty::Closure(def_id, _) = exp_found.expected.skip_binder().self_ty().kind()
&& let Some(def_id) = def_id.as_local()

View file

@ -515,7 +515,11 @@ fn foo(&tcx) -> Self::T { String::new() }
// `expected` and point at it.
let parent_id = tcx.hir().get_parent_item(hir_id);
let item = tcx.hir().find_by_def_id(parent_id.def_id);
debug!("expected_projection parent item {:?}", item);
let param_env = tcx.param_env(body_owner_def_id);
match item {
Some(hir::Node::Item(hir::Item { kind: hir::ItemKind::Trait(.., items), .. })) => {
// FIXME: account for `#![feature(specialization)]`
@ -527,7 +531,8 @@ fn foo(&tcx) -> Self::T { String::new() }
if let hir::Defaultness::Default { has_value: true } =
tcx.impl_defaultness(item.id.owner_id)
{
if tcx.type_of(item.id.owner_id) == found {
let assoc_ty = tcx.bound_type_of(item.id.owner_id).subst_identity();
if self.infcx.can_eq(param_env, assoc_ty, found).is_ok() {
diag.span_label(
item.span,
"associated type defaults can't be assumed inside the \
@ -547,7 +552,9 @@ fn foo(&tcx) -> Self::T { String::new() }
})) => {
for item in &items[..] {
if let hir::AssocItemKind::Type = item.kind {
if tcx.type_of(item.id.owner_id) == found {
let assoc_ty = tcx.bound_type_of(item.id.owner_id).subst_identity();
if self.infcx.can_eq(param_env, assoc_ty, found).is_ok() {
diag.span_label(item.span, "expected this associated type");
return true;
}

View file

@ -441,6 +441,10 @@ impl<'tcx> TyCtxt<'tcx> {
self.opt_def_kind(def_id)
.unwrap_or_else(|| bug!("def_kind: unsupported node: {:?}", def_id))
}
pub fn bound_type_of(self, def_id: impl IntoQueryParam<DefId>) -> ty::EarlyBinder<Ty<'tcx>> {
ty::EarlyBinder(self.type_of(def_id))
}
}
impl<'tcx> TyCtxtAt<'tcx> {
@ -449,4 +453,8 @@ impl<'tcx> TyCtxtAt<'tcx> {
self.opt_def_kind(def_id)
.unwrap_or_else(|| bug!("def_kind: unsupported node: {:?}", def_id))
}
pub fn bound_type_of(self, def_id: impl IntoQueryParam<DefId>) -> ty::EarlyBinder<Ty<'tcx>> {
ty::EarlyBinder(self.type_of(def_id))
}
}

View file

@ -3,7 +3,6 @@
use crate::middle::codegen_fn_attrs::CodegenFnAttrFlags;
use crate::mir;
use crate::ty::layout::IntegerExt;
use crate::ty::query::TyCtxtAt;
use crate::ty::{
self, DefIdTree, FallibleTypeFolder, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable,
TypeVisitable,
@ -637,10 +636,6 @@ impl<'tcx> TyCtxt<'tcx> {
if visitor.found_recursion { Err(expanded_type) } else { Ok(expanded_type) }
}
pub fn bound_type_of(self, def_id: DefId) -> ty::EarlyBinder<Ty<'tcx>> {
ty::EarlyBinder(self.type_of(def_id))
}
pub fn bound_return_position_impl_trait_in_trait_tys(
self,
def_id: DefId,
@ -738,12 +733,6 @@ impl<'tcx> TyCtxt<'tcx> {
}
}
impl<'tcx> TyCtxtAt<'tcx> {
pub fn bound_type_of(self, def_id: DefId) -> ty::EarlyBinder<Ty<'tcx>> {
ty::EarlyBinder(self.type_of(def_id))
}
}
struct OpaqueTypeExpander<'tcx> {
// Contains the DefIds of the opaque types that are currently being
// expanded. When we expand an opaque type we insert the DefId of