Auto merge of #116885 - aliemjay:rollup-plbeppt, r=aliemjay
Rollup of 5 pull requests Successful merges: - #116812 (Disable missing_copy_implementations lint on non_exhaustive types) - #116856 (Disable effects in libcore again) - #116865 (Suggest constraining assoc types in more cases) - #116870 (Don't compare host param by name) - #116879 (revert #114586) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
e1de04ad4e
21 changed files with 271 additions and 139 deletions
|
@ -341,39 +341,48 @@ impl<T> Trait<T> for X {
|
|||
let tcx = self.tcx;
|
||||
let assoc = tcx.associated_item(proj_ty.def_id);
|
||||
let (trait_ref, assoc_args) = proj_ty.trait_ref_and_own_args(tcx);
|
||||
if let Some(item) = tcx.hir().get_if_local(body_owner_def_id) {
|
||||
if let Some(hir_generics) = item.generics() {
|
||||
// Get the `DefId` for the type parameter corresponding to `A` in `<A as T>::Foo`.
|
||||
// This will also work for `impl Trait`.
|
||||
let def_id = if let ty::Param(param_ty) = proj_ty.self_ty().kind() {
|
||||
let generics = tcx.generics_of(body_owner_def_id);
|
||||
generics.type_param(param_ty, tcx).def_id
|
||||
} else {
|
||||
return false;
|
||||
};
|
||||
let Some(def_id) = def_id.as_local() else {
|
||||
return false;
|
||||
};
|
||||
let Some(item) = tcx.hir().get_if_local(body_owner_def_id) else {
|
||||
return false;
|
||||
};
|
||||
let Some(hir_generics) = item.generics() else {
|
||||
return false;
|
||||
};
|
||||
// Get the `DefId` for the type parameter corresponding to `A` in `<A as T>::Foo`.
|
||||
// This will also work for `impl Trait`.
|
||||
let def_id = if let ty::Param(param_ty) = proj_ty.self_ty().kind() {
|
||||
let generics = tcx.generics_of(body_owner_def_id);
|
||||
generics.type_param(param_ty, tcx).def_id
|
||||
} else {
|
||||
return false;
|
||||
};
|
||||
let Some(def_id) = def_id.as_local() else {
|
||||
return false;
|
||||
};
|
||||
|
||||
// First look in the `where` clause, as this might be
|
||||
// `fn foo<T>(x: T) where T: Trait`.
|
||||
for pred in hir_generics.bounds_for_param(def_id) {
|
||||
if self.constrain_generic_bound_associated_type_structured_suggestion(
|
||||
diag,
|
||||
&trait_ref,
|
||||
pred.bounds,
|
||||
assoc,
|
||||
assoc_args,
|
||||
ty,
|
||||
&msg,
|
||||
false,
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
// First look in the `where` clause, as this might be
|
||||
// `fn foo<T>(x: T) where T: Trait`.
|
||||
for pred in hir_generics.bounds_for_param(def_id) {
|
||||
if self.constrain_generic_bound_associated_type_structured_suggestion(
|
||||
diag,
|
||||
&trait_ref,
|
||||
pred.bounds,
|
||||
assoc,
|
||||
assoc_args,
|
||||
ty,
|
||||
&msg,
|
||||
false,
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
false
|
||||
// If associated item, look to constrain the params of the trait/impl.
|
||||
let hir_id = match item {
|
||||
hir::Node::ImplItem(item) => item.hir_id(),
|
||||
hir::Node::TraitItem(item) => item.hir_id(),
|
||||
_ => return false,
|
||||
};
|
||||
let parent = tcx.hir().get_parent_item(hir_id).def_id;
|
||||
self.suggest_constraint(diag, msg, parent.into(), proj_ty, ty)
|
||||
}
|
||||
|
||||
/// An associated type was expected and a different type was found.
|
||||
|
@ -426,21 +435,26 @@ impl<T> Trait<T> for X {
|
|||
let impl_comparison =
|
||||
matches!(cause_code, ObligationCauseCode::CompareImplItemObligation { .. });
|
||||
let assoc = tcx.associated_item(proj_ty.def_id);
|
||||
if !callable_scope || impl_comparison {
|
||||
if impl_comparison {
|
||||
// We do not want to suggest calling functions when the reason of the
|
||||
// type error is a comparison of an `impl` with its `trait` or when the
|
||||
// scope is outside of a `Body`.
|
||||
// type error is a comparison of an `impl` with its `trait`.
|
||||
} else {
|
||||
// If we find a suitable associated function that returns the expected type, we don't
|
||||
// want the more general suggestion later in this method about "consider constraining
|
||||
// the associated type or calling a method that returns the associated type".
|
||||
let point_at_assoc_fn = self.point_at_methods_that_satisfy_associated_type(
|
||||
diag,
|
||||
assoc.container_id(tcx),
|
||||
current_method_ident,
|
||||
proj_ty.def_id,
|
||||
values.expected,
|
||||
);
|
||||
let point_at_assoc_fn = if callable_scope
|
||||
&& self.point_at_methods_that_satisfy_associated_type(
|
||||
diag,
|
||||
assoc.container_id(tcx),
|
||||
current_method_ident,
|
||||
proj_ty.def_id,
|
||||
values.expected,
|
||||
) {
|
||||
// If we find a suitable associated function that returns the expected type, we
|
||||
// don't want the more general suggestion later in this method about "consider
|
||||
// constraining the associated type or calling a method that returns the associated
|
||||
// type".
|
||||
true
|
||||
} else {
|
||||
false
|
||||
};
|
||||
// Possibly suggest constraining the associated type to conform to the
|
||||
// found type.
|
||||
if self.suggest_constraint(diag, &msg, body_owner_def_id, proj_ty, values.found)
|
||||
|
|
|
@ -145,25 +145,7 @@ impl<'tcx> InferCtxt<'tcx> {
|
|||
return None;
|
||||
}
|
||||
}
|
||||
DefiningAnchor::Bubble => {
|
||||
if let ty::Alias(ty::Opaque, _) = b.kind() {
|
||||
// In bubble mode we don't know which of the two opaque types is supposed to have the other
|
||||
// as a hidden type (both, none or either one of them could be in its defining scope).
|
||||
let predicate = ty::PredicateKind::AliasRelate(
|
||||
a.into(),
|
||||
b.into(),
|
||||
ty::AliasRelationDirection::Equate,
|
||||
);
|
||||
let obligation = traits::Obligation::new(
|
||||
self.tcx,
|
||||
cause.clone(),
|
||||
param_env,
|
||||
predicate,
|
||||
);
|
||||
let obligations = vec![obligation];
|
||||
return Some(Ok(InferOk { value: (), obligations }));
|
||||
}
|
||||
}
|
||||
DefiningAnchor::Bubble => {}
|
||||
DefiningAnchor::Error => return None,
|
||||
};
|
||||
if let ty::Alias(ty::Opaque, ty::AliasTy { def_id: b_def_id, .. }) = *b.kind() {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue