Rollup merge of #136281 - nnethercote:rustc_hir_analysis, r=lcnr
`rustc_hir_analysis` cleanups Just some improvements I found while looking through this code. r? `@lcnr`
This commit is contained in:
commit
940b45f27c
22 changed files with 223 additions and 314 deletions
|
@ -424,12 +424,12 @@ fn compare_method_predicate_entailment<'tcx>(
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
struct RemapLateParam<'a, 'tcx> {
|
struct RemapLateParam<'tcx> {
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
mapping: &'a FxIndexMap<ty::LateParamRegionKind, ty::LateParamRegionKind>,
|
mapping: FxIndexMap<ty::LateParamRegionKind, ty::LateParamRegionKind>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> TypeFolder<TyCtxt<'tcx>> for RemapLateParam<'_, 'tcx> {
|
impl<'tcx> TypeFolder<TyCtxt<'tcx>> for RemapLateParam<'tcx> {
|
||||||
fn cx(&self) -> TyCtxt<'tcx> {
|
fn cx(&self) -> TyCtxt<'tcx> {
|
||||||
self.tcx
|
self.tcx
|
||||||
}
|
}
|
||||||
|
|
|
@ -299,8 +299,7 @@ fn report_mismatched_rpitit_signature<'tcx>(
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let mut return_ty =
|
let mut return_ty = trait_m_sig.output().fold_with(&mut super::RemapLateParam { tcx, mapping });
|
||||||
trait_m_sig.output().fold_with(&mut super::RemapLateParam { tcx, mapping: &mapping });
|
|
||||||
|
|
||||||
if tcx.asyncness(impl_m_def_id).is_async() && tcx.asyncness(trait_m_def_id).is_async() {
|
if tcx.asyncness(impl_m_def_id).is_async() && tcx.asyncness(trait_m_def_id).is_async() {
|
||||||
let ty::Alias(ty::Projection, future_ty) = return_ty.kind() else {
|
let ty::Alias(ty::Projection, future_ty) = return_ty.kind() else {
|
||||||
|
|
|
@ -1,7 +1,3 @@
|
||||||
// FIXME(@lcnr): Move this module out of `rustc_hir_analysis`.
|
|
||||||
//
|
|
||||||
// We don't do any drop checking during hir typeck.
|
|
||||||
|
|
||||||
use rustc_data_structures::fx::FxHashSet;
|
use rustc_data_structures::fx::FxHashSet;
|
||||||
use rustc_errors::codes::*;
|
use rustc_errors::codes::*;
|
||||||
use rustc_errors::{ErrorGuaranteed, struct_span_code_err};
|
use rustc_errors::{ErrorGuaranteed, struct_span_code_err};
|
||||||
|
@ -32,7 +28,10 @@ use crate::hir::def_id::{DefId, LocalDefId};
|
||||||
/// struct/enum definition for the nominal type itself (i.e.
|
/// struct/enum definition for the nominal type itself (i.e.
|
||||||
/// cannot do `struct S<T>; impl<T:Clone> Drop for S<T> { ... }`).
|
/// cannot do `struct S<T>; impl<T:Clone> Drop for S<T> { ... }`).
|
||||||
///
|
///
|
||||||
pub fn check_drop_impl(tcx: TyCtxt<'_>, drop_impl_did: DefId) -> Result<(), ErrorGuaranteed> {
|
pub(crate) fn check_drop_impl(
|
||||||
|
tcx: TyCtxt<'_>,
|
||||||
|
drop_impl_did: DefId,
|
||||||
|
) -> Result<(), ErrorGuaranteed> {
|
||||||
match tcx.impl_polarity(drop_impl_did) {
|
match tcx.impl_polarity(drop_impl_did) {
|
||||||
ty::ImplPolarity::Positive => {}
|
ty::ImplPolarity::Positive => {}
|
||||||
ty::ImplPolarity::Negative => {
|
ty::ImplPolarity::Negative => {
|
||||||
|
|
|
@ -199,7 +199,8 @@ pub fn check_intrinsic_type(
|
||||||
let split: Vec<&str> = name_str.split('_').collect();
|
let split: Vec<&str> = name_str.split('_').collect();
|
||||||
assert!(split.len() >= 2, "Atomic intrinsic in an incorrect format");
|
assert!(split.len() >= 2, "Atomic intrinsic in an incorrect format");
|
||||||
|
|
||||||
//We only care about the operation here
|
// Each atomic op has variants with different suffixes (`_seq_cst`, `_acquire`, etc.). Use
|
||||||
|
// string ops to strip the suffixes, because the variants all get the same treatment here.
|
||||||
let (n_tps, inputs, output) = match split[1] {
|
let (n_tps, inputs, output) = match split[1] {
|
||||||
"cxchg" | "cxchgweak" => (
|
"cxchg" | "cxchgweak" => (
|
||||||
1,
|
1,
|
||||||
|
|
|
@ -455,18 +455,14 @@ fn fn_sig_suggestion<'tcx>(
|
||||||
let mut output = sig.output();
|
let mut output = sig.output();
|
||||||
|
|
||||||
let asyncness = if tcx.asyncness(assoc.def_id).is_async() {
|
let asyncness = if tcx.asyncness(assoc.def_id).is_async() {
|
||||||
output = if let ty::Alias(_, alias_ty) = *output.kind() {
|
output = if let ty::Alias(_, alias_ty) = *output.kind()
|
||||||
tcx.explicit_item_self_bounds(alias_ty.def_id)
|
&& let Some(output) = tcx
|
||||||
|
.explicit_item_self_bounds(alias_ty.def_id)
|
||||||
.iter_instantiated_copied(tcx, alias_ty.args)
|
.iter_instantiated_copied(tcx, alias_ty.args)
|
||||||
.find_map(|(bound, _)| {
|
.find_map(|(bound, _)| {
|
||||||
bound.as_projection_clause()?.no_bound_vars()?.term.as_type()
|
bound.as_projection_clause()?.no_bound_vars()?.term.as_type()
|
||||||
})
|
}) {
|
||||||
.unwrap_or_else(|| {
|
output
|
||||||
span_bug!(
|
|
||||||
ident.span,
|
|
||||||
"expected async fn to have `impl Future` output, but it returns {output}"
|
|
||||||
)
|
|
||||||
})
|
|
||||||
} else {
|
} else {
|
||||||
span_bug!(
|
span_bug!(
|
||||||
ident.span,
|
ident.span,
|
||||||
|
|
|
@ -2267,14 +2267,12 @@ impl<'tcx> WfCheckingCtxt<'_, 'tcx> {
|
||||||
|
|
||||||
fn check_mod_type_wf(tcx: TyCtxt<'_>, module: LocalModDefId) -> Result<(), ErrorGuaranteed> {
|
fn check_mod_type_wf(tcx: TyCtxt<'_>, module: LocalModDefId) -> Result<(), ErrorGuaranteed> {
|
||||||
let items = tcx.hir_module_items(module);
|
let items = tcx.hir_module_items(module);
|
||||||
let mut res = items.par_items(|item| tcx.ensure().check_well_formed(item.owner_id.def_id));
|
let res = items
|
||||||
res =
|
.par_items(|item| tcx.ensure().check_well_formed(item.owner_id.def_id))
|
||||||
res.and(items.par_impl_items(|item| tcx.ensure().check_well_formed(item.owner_id.def_id)));
|
.and(items.par_impl_items(|item| tcx.ensure().check_well_formed(item.owner_id.def_id)))
|
||||||
res =
|
.and(items.par_trait_items(|item| tcx.ensure().check_well_formed(item.owner_id.def_id)))
|
||||||
res.and(items.par_trait_items(|item| tcx.ensure().check_well_formed(item.owner_id.def_id)));
|
.and(items.par_foreign_items(|item| tcx.ensure().check_well_formed(item.owner_id.def_id)))
|
||||||
res = res
|
.and(items.par_opaques(|item| tcx.ensure().check_well_formed(item)));
|
||||||
.and(items.par_foreign_items(|item| tcx.ensure().check_well_formed(item.owner_id.def_id)));
|
|
||||||
res = res.and(items.par_opaques(|item| tcx.ensure().check_well_formed(item)));
|
|
||||||
if module == LocalModDefId::CRATE_DEF_ID {
|
if module == LocalModDefId::CRATE_DEF_ID {
|
||||||
super::entry::check_for_entry_fn(tcx);
|
super::entry::check_for_entry_fn(tcx);
|
||||||
}
|
}
|
||||||
|
|
|
@ -404,17 +404,12 @@ pub(crate) fn coerce_unsized_info<'tcx>(
|
||||||
check_mutbl(mt_a, mt_b, &|ty| Ty::new_imm_ref(tcx, r_b, ty))
|
check_mutbl(mt_a, mt_b, &|ty| Ty::new_imm_ref(tcx, r_b, ty))
|
||||||
}
|
}
|
||||||
|
|
||||||
(&ty::Ref(_, ty_a, mutbl_a), &ty::RawPtr(ty_b, mutbl_b)) => check_mutbl(
|
(&ty::Ref(_, ty_a, mutbl_a), &ty::RawPtr(ty_b, mutbl_b))
|
||||||
ty::TypeAndMut { ty: ty_a, mutbl: mutbl_a },
|
| (&ty::RawPtr(ty_a, mutbl_a), &ty::RawPtr(ty_b, mutbl_b)) => {
|
||||||
ty::TypeAndMut { ty: ty_b, mutbl: mutbl_b },
|
let mt_a = ty::TypeAndMut { ty: ty_a, mutbl: mutbl_a };
|
||||||
&|ty| Ty::new_imm_ptr(tcx, ty),
|
let mt_b = ty::TypeAndMut { ty: ty_b, mutbl: mutbl_b };
|
||||||
),
|
check_mutbl(mt_a, mt_b, &|ty| Ty::new_imm_ptr(tcx, ty))
|
||||||
|
}
|
||||||
(&ty::RawPtr(ty_a, mutbl_a), &ty::RawPtr(ty_b, mutbl_b)) => check_mutbl(
|
|
||||||
ty::TypeAndMut { ty: ty_a, mutbl: mutbl_a },
|
|
||||||
ty::TypeAndMut { ty: ty_b, mutbl: mutbl_b },
|
|
||||||
&|ty| Ty::new_imm_ptr(tcx, ty),
|
|
||||||
),
|
|
||||||
|
|
||||||
(&ty::Adt(def_a, args_a), &ty::Adt(def_b, args_b))
|
(&ty::Adt(def_a, args_a), &ty::Adt(def_b, args_b))
|
||||||
if def_a.is_struct() && def_b.is_struct() =>
|
if def_a.is_struct() && def_b.is_struct() =>
|
||||||
|
|
|
@ -158,12 +158,12 @@ fn coherent_trait(tcx: TyCtxt<'_>, def_id: DefId) -> Result<(), ErrorGuaranteed>
|
||||||
let trait_ref = trait_header.trait_ref.instantiate_identity();
|
let trait_ref = trait_header.trait_ref.instantiate_identity();
|
||||||
let trait_def = tcx.trait_def(trait_ref.def_id);
|
let trait_def = tcx.trait_def(trait_ref.def_id);
|
||||||
|
|
||||||
res = res.and(check_impl(tcx, impl_def_id, trait_ref, trait_def));
|
res = res
|
||||||
res = res.and(check_object_overlap(tcx, impl_def_id, trait_ref));
|
.and(check_impl(tcx, impl_def_id, trait_ref, trait_def))
|
||||||
|
.and(check_object_overlap(tcx, impl_def_id, trait_ref))
|
||||||
res = res.and(unsafety::check_item(tcx, impl_def_id, trait_header, trait_def));
|
.and(unsafety::check_item(tcx, impl_def_id, trait_header, trait_def))
|
||||||
res = res.and(tcx.ensure().orphan_check_impl(impl_def_id));
|
.and(tcx.ensure().orphan_check_impl(impl_def_id))
|
||||||
res = res.and(builtin::check_trait(tcx, def_id, impl_def_id, trait_header));
|
.and(builtin::check_trait(tcx, def_id, impl_def_id, trait_header));
|
||||||
}
|
}
|
||||||
|
|
||||||
res
|
res
|
||||||
|
|
|
@ -57,7 +57,7 @@ mod type_of;
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
pub fn provide(providers: &mut Providers) {
|
pub(crate) fn provide(providers: &mut Providers) {
|
||||||
resolve_bound_vars::provide(providers);
|
resolve_bound_vars::provide(providers);
|
||||||
*providers = Providers {
|
*providers = Providers {
|
||||||
type_of: type_of::type_of,
|
type_of: type_of::type_of,
|
||||||
|
@ -122,7 +122,7 @@ pub fn provide(providers: &mut Providers) {
|
||||||
/// `ItemCtxt` is parameterized by a `DefId` that it uses to satisfy
|
/// `ItemCtxt` is parameterized by a `DefId` that it uses to satisfy
|
||||||
/// `probe_ty_param_bounds` requests, drawing the information from
|
/// `probe_ty_param_bounds` requests, drawing the information from
|
||||||
/// the HIR (`hir::Generics`), recursively.
|
/// the HIR (`hir::Generics`), recursively.
|
||||||
pub struct ItemCtxt<'tcx> {
|
pub(crate) struct ItemCtxt<'tcx> {
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
item_def_id: LocalDefId,
|
item_def_id: LocalDefId,
|
||||||
tainted_by_errors: Cell<Option<ErrorGuaranteed>>,
|
tainted_by_errors: Cell<Option<ErrorGuaranteed>>,
|
||||||
|
@ -148,7 +148,7 @@ impl<'v> Visitor<'v> for HirPlaceholderCollector {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct CollectItemTypesVisitor<'tcx> {
|
pub(crate) struct CollectItemTypesVisitor<'tcx> {
|
||||||
pub tcx: TyCtxt<'tcx>,
|
pub tcx: TyCtxt<'tcx>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -364,19 +364,19 @@ fn bad_placeholder<'cx, 'tcx>(
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> ItemCtxt<'tcx> {
|
impl<'tcx> ItemCtxt<'tcx> {
|
||||||
pub fn new(tcx: TyCtxt<'tcx>, item_def_id: LocalDefId) -> ItemCtxt<'tcx> {
|
pub(crate) fn new(tcx: TyCtxt<'tcx>, item_def_id: LocalDefId) -> ItemCtxt<'tcx> {
|
||||||
ItemCtxt { tcx, item_def_id, tainted_by_errors: Cell::new(None) }
|
ItemCtxt { tcx, item_def_id, tainted_by_errors: Cell::new(None) }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn lower_ty(&self, hir_ty: &hir::Ty<'tcx>) -> Ty<'tcx> {
|
pub(crate) fn lower_ty(&self, hir_ty: &hir::Ty<'tcx>) -> Ty<'tcx> {
|
||||||
self.lowerer().lower_ty(hir_ty)
|
self.lowerer().lower_ty(hir_ty)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn hir_id(&self) -> hir::HirId {
|
pub(crate) fn hir_id(&self) -> hir::HirId {
|
||||||
self.tcx.local_def_id_to_hir_id(self.item_def_id)
|
self.tcx.local_def_id_to_hir_id(self.item_def_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn node(&self) -> hir::Node<'tcx> {
|
pub(crate) fn node(&self) -> hir::Node<'tcx> {
|
||||||
self.tcx.hir_node(self.hir_id())
|
self.tcx.hir_node(self.hir_id())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -100,36 +100,19 @@ enum InheritanceKind {
|
||||||
Own,
|
Own,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct GenericsBuilder<'tcx> {
|
fn build_generics<'tcx>(
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
sig_id: DefId,
|
sig_id: DefId,
|
||||||
parent: Option<DefId>,
|
parent: Option<DefId>,
|
||||||
inh_kind: InheritanceKind,
|
inh_kind: InheritanceKind,
|
||||||
}
|
) -> ty::Generics {
|
||||||
|
|
||||||
impl<'tcx> GenericsBuilder<'tcx> {
|
|
||||||
fn new(tcx: TyCtxt<'tcx>, sig_id: DefId) -> GenericsBuilder<'tcx> {
|
|
||||||
GenericsBuilder { tcx, sig_id, parent: None, inh_kind: InheritanceKind::WithParent(false) }
|
|
||||||
}
|
|
||||||
|
|
||||||
fn with_parent(mut self, parent: DefId) -> Self {
|
|
||||||
self.parent = Some(parent);
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
fn with_inheritance_kind(mut self, inh_kind: InheritanceKind) -> Self {
|
|
||||||
self.inh_kind = inh_kind;
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
fn build(self) -> ty::Generics {
|
|
||||||
let mut own_params = vec![];
|
let mut own_params = vec![];
|
||||||
|
|
||||||
let sig_generics = self.tcx.generics_of(self.sig_id);
|
let sig_generics = tcx.generics_of(sig_id);
|
||||||
if let InheritanceKind::WithParent(has_self) = self.inh_kind
|
if let InheritanceKind::WithParent(has_self) = inh_kind
|
||||||
&& let Some(parent_def_id) = sig_generics.parent
|
&& let Some(parent_def_id) = sig_generics.parent
|
||||||
{
|
{
|
||||||
let sig_parent_generics = self.tcx.generics_of(parent_def_id);
|
let sig_parent_generics = tcx.generics_of(parent_def_id);
|
||||||
own_params.append(&mut sig_parent_generics.own_params.clone());
|
own_params.append(&mut sig_parent_generics.own_params.clone());
|
||||||
if !has_self {
|
if !has_self {
|
||||||
own_params.remove(0);
|
own_params.remove(0);
|
||||||
|
@ -155,9 +138,9 @@ impl<'tcx> GenericsBuilder<'tcx> {
|
||||||
let param_def_id_to_index =
|
let param_def_id_to_index =
|
||||||
own_params.iter().map(|param| (param.def_id, param.index)).collect();
|
own_params.iter().map(|param| (param.def_id, param.index)).collect();
|
||||||
|
|
||||||
let (parent_count, has_self) = if let Some(def_id) = self.parent {
|
let (parent_count, has_self) = if let Some(def_id) = parent {
|
||||||
let parent_generics = self.tcx.generics_of(def_id);
|
let parent_generics = tcx.generics_of(def_id);
|
||||||
let parent_kind = self.tcx.def_kind(def_id);
|
let parent_kind = tcx.def_kind(def_id);
|
||||||
(parent_generics.count(), parent_kind == DefKind::Trait)
|
(parent_generics.count(), parent_kind == DefKind::Trait)
|
||||||
} else {
|
} else {
|
||||||
(0, false)
|
(0, false)
|
||||||
|
@ -180,50 +163,22 @@ impl<'tcx> GenericsBuilder<'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
ty::Generics {
|
ty::Generics {
|
||||||
parent: self.parent,
|
parent,
|
||||||
parent_count,
|
parent_count,
|
||||||
own_params,
|
own_params,
|
||||||
param_def_id_to_index,
|
param_def_id_to_index,
|
||||||
has_self,
|
has_self,
|
||||||
has_late_bound_regions: sig_generics.has_late_bound_regions,
|
has_late_bound_regions: sig_generics.has_late_bound_regions,
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct PredicatesBuilder<'tcx> {
|
fn build_predicates<'tcx>(
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
sig_id: DefId,
|
sig_id: DefId,
|
||||||
parent: Option<DefId>,
|
parent: Option<DefId>,
|
||||||
inh_kind: InheritanceKind,
|
inh_kind: InheritanceKind,
|
||||||
args: ty::GenericArgsRef<'tcx>,
|
args: ty::GenericArgsRef<'tcx>,
|
||||||
}
|
) -> ty::GenericPredicates<'tcx> {
|
||||||
|
|
||||||
impl<'tcx> PredicatesBuilder<'tcx> {
|
|
||||||
fn new(
|
|
||||||
tcx: TyCtxt<'tcx>,
|
|
||||||
args: ty::GenericArgsRef<'tcx>,
|
|
||||||
sig_id: DefId,
|
|
||||||
) -> PredicatesBuilder<'tcx> {
|
|
||||||
PredicatesBuilder {
|
|
||||||
tcx,
|
|
||||||
sig_id,
|
|
||||||
parent: None,
|
|
||||||
inh_kind: InheritanceKind::WithParent(false),
|
|
||||||
args,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn with_parent(mut self, parent: DefId) -> Self {
|
|
||||||
self.parent = Some(parent);
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
fn with_inheritance_kind(mut self, inh_kind: InheritanceKind) -> Self {
|
|
||||||
self.inh_kind = inh_kind;
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
fn build(self) -> ty::GenericPredicates<'tcx> {
|
|
||||||
struct PredicatesCollector<'tcx> {
|
struct PredicatesCollector<'tcx> {
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
preds: Vec<(ty::Clause<'tcx>, Span)>,
|
preds: Vec<(ty::Clause<'tcx>, Span)>,
|
||||||
|
@ -257,56 +212,44 @@ impl<'tcx> PredicatesBuilder<'tcx> {
|
||||||
self.with_own_preds(f, def_id)
|
self.with_own_preds(f, def_id)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let collector = PredicatesCollector::new(self.tcx, self.args);
|
let collector = PredicatesCollector::new(tcx, args);
|
||||||
|
|
||||||
// `explicit_predicates_of` is used here to avoid copying `Self: Trait` predicate.
|
// `explicit_predicates_of` is used here to avoid copying `Self: Trait` predicate.
|
||||||
// Note: `predicates_of` query can also add inferred outlives predicates, but that
|
// Note: `predicates_of` query can also add inferred outlives predicates, but that
|
||||||
// is not the case here as `sig_id` is either a trait or a function.
|
// is not the case here as `sig_id` is either a trait or a function.
|
||||||
let preds = match self.inh_kind {
|
let preds = match inh_kind {
|
||||||
InheritanceKind::WithParent(false) => {
|
InheritanceKind::WithParent(false) => {
|
||||||
collector.with_preds(|def_id| self.tcx.explicit_predicates_of(def_id), self.sig_id)
|
collector.with_preds(|def_id| tcx.explicit_predicates_of(def_id), sig_id)
|
||||||
}
|
}
|
||||||
InheritanceKind::WithParent(true) => {
|
InheritanceKind::WithParent(true) => {
|
||||||
collector.with_preds(|def_id| self.tcx.predicates_of(def_id), self.sig_id)
|
collector.with_preds(|def_id| tcx.predicates_of(def_id), sig_id)
|
||||||
}
|
}
|
||||||
InheritanceKind::Own => {
|
InheritanceKind::Own => {
|
||||||
collector.with_own_preds(|def_id| self.tcx.predicates_of(def_id), self.sig_id)
|
collector.with_own_preds(|def_id| tcx.predicates_of(def_id), sig_id)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.preds;
|
.preds;
|
||||||
|
|
||||||
ty::GenericPredicates {
|
ty::GenericPredicates { parent, predicates: tcx.arena.alloc_from_iter(preds) }
|
||||||
parent: self.parent,
|
|
||||||
predicates: self.tcx.arena.alloc_from_iter(preds),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct GenericArgsBuilder<'tcx> {
|
fn build_generic_args<'tcx>(
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
remap_table: RemapTable,
|
|
||||||
sig_id: DefId,
|
sig_id: DefId,
|
||||||
def_id: LocalDefId,
|
def_id: LocalDefId,
|
||||||
}
|
args: ty::GenericArgsRef<'tcx>,
|
||||||
|
) -> ty::GenericArgsRef<'tcx> {
|
||||||
impl<'tcx> GenericArgsBuilder<'tcx> {
|
let caller_generics = tcx.generics_of(def_id);
|
||||||
fn new(tcx: TyCtxt<'tcx>, sig_id: DefId, def_id: LocalDefId) -> GenericArgsBuilder<'tcx> {
|
let callee_generics = tcx.generics_of(sig_id);
|
||||||
GenericArgsBuilder { tcx, remap_table: FxHashMap::default(), sig_id, def_id }
|
|
||||||
}
|
|
||||||
|
|
||||||
fn build_from_args(mut self, args: ty::GenericArgsRef<'tcx>) -> ty::GenericArgsRef<'tcx> {
|
|
||||||
let caller_generics = self.tcx.generics_of(self.def_id);
|
|
||||||
let callee_generics = self.tcx.generics_of(self.sig_id);
|
|
||||||
|
|
||||||
|
let mut remap_table = FxHashMap::default();
|
||||||
for caller_param in &caller_generics.own_params {
|
for caller_param in &caller_generics.own_params {
|
||||||
let callee_index =
|
let callee_index = callee_generics.param_def_id_to_index(tcx, caller_param.def_id).unwrap();
|
||||||
callee_generics.param_def_id_to_index(self.tcx, caller_param.def_id).unwrap();
|
remap_table.insert(callee_index, caller_param.index);
|
||||||
self.remap_table.insert(callee_index, caller_param.index);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut folder = ParamIndexRemapper { tcx: self.tcx, remap_table: self.remap_table };
|
let mut folder = ParamIndexRemapper { tcx, remap_table };
|
||||||
args.fold_with(&mut folder)
|
args.fold_with(&mut folder)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_generic_args<'tcx>(
|
fn create_generic_args<'tcx>(
|
||||||
|
@ -314,8 +257,6 @@ fn create_generic_args<'tcx>(
|
||||||
def_id: LocalDefId,
|
def_id: LocalDefId,
|
||||||
sig_id: DefId,
|
sig_id: DefId,
|
||||||
) -> ty::GenericArgsRef<'tcx> {
|
) -> ty::GenericArgsRef<'tcx> {
|
||||||
let builder = GenericArgsBuilder::new(tcx, sig_id, def_id);
|
|
||||||
|
|
||||||
let caller_kind = fn_kind(tcx, def_id.into());
|
let caller_kind = fn_kind(tcx, def_id.into());
|
||||||
let callee_kind = fn_kind(tcx, sig_id);
|
let callee_kind = fn_kind(tcx, sig_id);
|
||||||
match (caller_kind, callee_kind) {
|
match (caller_kind, callee_kind) {
|
||||||
|
@ -325,7 +266,7 @@ fn create_generic_args<'tcx>(
|
||||||
| (FnKind::AssocTrait, FnKind::Free)
|
| (FnKind::AssocTrait, FnKind::Free)
|
||||||
| (FnKind::AssocTrait, FnKind::AssocTrait) => {
|
| (FnKind::AssocTrait, FnKind::AssocTrait) => {
|
||||||
let args = ty::GenericArgs::identity_for_item(tcx, sig_id);
|
let args = ty::GenericArgs::identity_for_item(tcx, sig_id);
|
||||||
builder.build_from_args(args)
|
build_generic_args(tcx, sig_id, def_id, args)
|
||||||
}
|
}
|
||||||
|
|
||||||
(FnKind::AssocTraitImpl, FnKind::AssocTrait) => {
|
(FnKind::AssocTraitImpl, FnKind::AssocTrait) => {
|
||||||
|
@ -335,8 +276,9 @@ fn create_generic_args<'tcx>(
|
||||||
tcx.impl_trait_header(parent).unwrap().trait_ref.instantiate_identity().args;
|
tcx.impl_trait_header(parent).unwrap().trait_ref.instantiate_identity().args;
|
||||||
|
|
||||||
let trait_args = ty::GenericArgs::identity_for_item(tcx, sig_id);
|
let trait_args = ty::GenericArgs::identity_for_item(tcx, sig_id);
|
||||||
let method_args = tcx.mk_args_from_iter(trait_args.iter().skip(callee_generics.parent_count));
|
let method_args =
|
||||||
let method_args = builder.build_from_args(method_args);
|
tcx.mk_args_from_iter(trait_args.iter().skip(callee_generics.parent_count));
|
||||||
|
let method_args = build_generic_args(tcx, sig_id, def_id, method_args);
|
||||||
|
|
||||||
tcx.mk_args_from_iter(parent_args.iter().chain(method_args))
|
tcx.mk_args_from_iter(parent_args.iter().chain(method_args))
|
||||||
}
|
}
|
||||||
|
@ -347,16 +289,16 @@ fn create_generic_args<'tcx>(
|
||||||
let generic_self_ty = ty::GenericArg::from(self_ty);
|
let generic_self_ty = ty::GenericArg::from(self_ty);
|
||||||
|
|
||||||
let trait_args = ty::GenericArgs::identity_for_item(tcx, sig_id);
|
let trait_args = ty::GenericArgs::identity_for_item(tcx, sig_id);
|
||||||
let trait_args = builder.build_from_args(trait_args);
|
let trait_args = build_generic_args(tcx, sig_id, def_id, trait_args);
|
||||||
|
|
||||||
let args = std::iter::once(generic_self_ty).chain(trait_args.iter().skip(1));
|
let args = std::iter::once(generic_self_ty).chain(trait_args.iter().skip(1));
|
||||||
tcx.mk_args_from_iter(args)
|
tcx.mk_args_from_iter(args)
|
||||||
}
|
}
|
||||||
|
|
||||||
// For trait impl's `sig_id` is always equal to the corresponding trait method.
|
// For trait impl's `sig_id` is always equal to the corresponding trait method.
|
||||||
|
// For inherent methods delegation is not yet supported.
|
||||||
(FnKind::AssocTraitImpl, _)
|
(FnKind::AssocTraitImpl, _)
|
||||||
| (_, FnKind::AssocTraitImpl)
|
| (_, FnKind::AssocTraitImpl)
|
||||||
// Delegation to inherent methods is not yet supported.
|
|
||||||
| (_, FnKind::AssocInherentImpl) => unreachable!(),
|
| (_, FnKind::AssocInherentImpl) => unreachable!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -377,39 +319,31 @@ pub(crate) fn inherit_generics_for_delegation_item<'tcx>(
|
||||||
def_id: LocalDefId,
|
def_id: LocalDefId,
|
||||||
sig_id: DefId,
|
sig_id: DefId,
|
||||||
) -> ty::Generics {
|
) -> ty::Generics {
|
||||||
let builder = GenericsBuilder::new(tcx, sig_id);
|
|
||||||
|
|
||||||
let caller_kind = fn_kind(tcx, def_id.into());
|
let caller_kind = fn_kind(tcx, def_id.into());
|
||||||
let callee_kind = fn_kind(tcx, sig_id);
|
let callee_kind = fn_kind(tcx, sig_id);
|
||||||
match (caller_kind, callee_kind) {
|
match (caller_kind, callee_kind) {
|
||||||
(FnKind::Free, FnKind::Free)
|
(FnKind::Free, FnKind::Free) | (FnKind::Free, FnKind::AssocTrait) => {
|
||||||
| (FnKind::Free, FnKind::AssocTrait) => builder.with_inheritance_kind(InheritanceKind::WithParent(true)).build(),
|
build_generics(tcx, sig_id, None, InheritanceKind::WithParent(true))
|
||||||
|
}
|
||||||
|
|
||||||
(FnKind::AssocTraitImpl, FnKind::AssocTrait) => {
|
(FnKind::AssocTraitImpl, FnKind::AssocTrait) => {
|
||||||
builder
|
build_generics(tcx, sig_id, Some(tcx.parent(def_id.into())), InheritanceKind::Own)
|
||||||
.with_parent(tcx.parent(def_id.into()))
|
|
||||||
.with_inheritance_kind(InheritanceKind::Own)
|
|
||||||
.build()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
(FnKind::AssocInherentImpl, FnKind::AssocTrait)
|
(FnKind::AssocInherentImpl, FnKind::AssocTrait)
|
||||||
| (FnKind::AssocTrait, FnKind::AssocTrait) => {
|
| (FnKind::AssocTrait, FnKind::AssocTrait)
|
||||||
builder
|
| (FnKind::AssocInherentImpl, FnKind::Free)
|
||||||
.with_parent(tcx.parent(def_id.into()))
|
| (FnKind::AssocTrait, FnKind::Free) => build_generics(
|
||||||
.build()
|
tcx,
|
||||||
}
|
sig_id,
|
||||||
|
Some(tcx.parent(def_id.into())),
|
||||||
(FnKind::AssocInherentImpl, FnKind::Free)
|
InheritanceKind::WithParent(false),
|
||||||
| (FnKind::AssocTrait, FnKind::Free) => {
|
),
|
||||||
builder
|
|
||||||
.with_parent(tcx.parent(def_id.into()))
|
|
||||||
.build()
|
|
||||||
}
|
|
||||||
|
|
||||||
// For trait impl's `sig_id` is always equal to the corresponding trait method.
|
// For trait impl's `sig_id` is always equal to the corresponding trait method.
|
||||||
|
// For inherent methods delegation is not yet supported.
|
||||||
(FnKind::AssocTraitImpl, _)
|
(FnKind::AssocTraitImpl, _)
|
||||||
| (_, FnKind::AssocTraitImpl)
|
| (_, FnKind::AssocTraitImpl)
|
||||||
// Delegation to inherent methods is not yet supported.
|
|
||||||
| (_, FnKind::AssocInherentImpl) => unreachable!(),
|
| (_, FnKind::AssocInherentImpl) => unreachable!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -420,36 +354,36 @@ pub(crate) fn inherit_predicates_for_delegation_item<'tcx>(
|
||||||
sig_id: DefId,
|
sig_id: DefId,
|
||||||
) -> ty::GenericPredicates<'tcx> {
|
) -> ty::GenericPredicates<'tcx> {
|
||||||
let args = create_generic_args(tcx, def_id, sig_id);
|
let args = create_generic_args(tcx, def_id, sig_id);
|
||||||
let builder = PredicatesBuilder::new(tcx, args, sig_id);
|
|
||||||
|
|
||||||
let caller_kind = fn_kind(tcx, def_id.into());
|
let caller_kind = fn_kind(tcx, def_id.into());
|
||||||
let callee_kind = fn_kind(tcx, sig_id);
|
let callee_kind = fn_kind(tcx, sig_id);
|
||||||
match (caller_kind, callee_kind) {
|
match (caller_kind, callee_kind) {
|
||||||
(FnKind::Free, FnKind::Free)
|
(FnKind::Free, FnKind::Free) | (FnKind::Free, FnKind::AssocTrait) => {
|
||||||
| (FnKind::Free, FnKind::AssocTrait) => {
|
build_predicates(tcx, sig_id, None, InheritanceKind::WithParent(true), args)
|
||||||
builder.with_inheritance_kind(InheritanceKind::WithParent(true)).build()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
(FnKind::AssocTraitImpl, FnKind::AssocTrait) => {
|
(FnKind::AssocTraitImpl, FnKind::AssocTrait) => build_predicates(
|
||||||
builder
|
tcx,
|
||||||
.with_parent(tcx.parent(def_id.into()))
|
sig_id,
|
||||||
.with_inheritance_kind(InheritanceKind::Own)
|
Some(tcx.parent(def_id.into())),
|
||||||
.build()
|
InheritanceKind::Own,
|
||||||
}
|
args,
|
||||||
|
),
|
||||||
|
|
||||||
(FnKind::AssocInherentImpl, FnKind::AssocTrait)
|
(FnKind::AssocInherentImpl, FnKind::AssocTrait)
|
||||||
| (FnKind::AssocTrait, FnKind::AssocTrait)
|
| (FnKind::AssocTrait, FnKind::AssocTrait)
|
||||||
| (FnKind::AssocInherentImpl, FnKind::Free)
|
| (FnKind::AssocInherentImpl, FnKind::Free)
|
||||||
| (FnKind::AssocTrait, FnKind::Free) => {
|
| (FnKind::AssocTrait, FnKind::Free) => build_predicates(
|
||||||
builder
|
tcx,
|
||||||
.with_parent(tcx.parent(def_id.into()))
|
sig_id,
|
||||||
.build()
|
Some(tcx.parent(def_id.into())),
|
||||||
}
|
InheritanceKind::WithParent(false),
|
||||||
|
args,
|
||||||
|
),
|
||||||
|
|
||||||
// For trait impl's `sig_id` is always equal to the corresponding trait method.
|
// For trait impl's `sig_id` is always equal to the corresponding trait method.
|
||||||
|
// For inherent methods delegation is not yet supported.
|
||||||
(FnKind::AssocTraitImpl, _)
|
(FnKind::AssocTraitImpl, _)
|
||||||
| (_, FnKind::AssocTraitImpl)
|
| (_, FnKind::AssocTraitImpl)
|
||||||
// Delegation to inherent methods is not yet supported.
|
|
||||||
| (_, FnKind::AssocInherentImpl) => unreachable!(),
|
| (_, FnKind::AssocInherentImpl) => unreachable!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -273,7 +273,7 @@ pub fn lower_generic_args<'tcx: 'a, 'a>(
|
||||||
|
|
||||||
// We lower to an infer even when the feature gate is not enabled
|
// We lower to an infer even when the feature gate is not enabled
|
||||||
// as it is useful for diagnostics to be able to see a `ConstKind::Infer`
|
// as it is useful for diagnostics to be able to see a `ConstKind::Infer`
|
||||||
args.push(ctx.provided_kind(&args, param, arg));
|
args.push(ctx.provided_kind(param, arg));
|
||||||
args_iter.next();
|
args_iter.next();
|
||||||
params.next();
|
params.next();
|
||||||
}
|
}
|
||||||
|
|
|
@ -296,7 +296,6 @@ pub trait GenericArgsLowerer<'a, 'tcx> {
|
||||||
|
|
||||||
fn provided_kind(
|
fn provided_kind(
|
||||||
&mut self,
|
&mut self,
|
||||||
preceding_args: &[ty::GenericArg<'tcx>],
|
|
||||||
param: &ty::GenericParamDef,
|
param: &ty::GenericParamDef,
|
||||||
arg: &GenericArg<'tcx>,
|
arg: &GenericArg<'tcx>,
|
||||||
) -> ty::GenericArg<'tcx>;
|
) -> ty::GenericArg<'tcx>;
|
||||||
|
@ -480,7 +479,6 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||||
|
|
||||||
fn provided_kind(
|
fn provided_kind(
|
||||||
&mut self,
|
&mut self,
|
||||||
_preceding_args: &[ty::GenericArg<'tcx>],
|
|
||||||
param: &ty::GenericParamDef,
|
param: &ty::GenericParamDef,
|
||||||
arg: &GenericArg<'tcx>,
|
arg: &GenericArg<'tcx>,
|
||||||
) -> ty::GenericArg<'tcx> {
|
) -> ty::GenericArg<'tcx> {
|
||||||
|
|
|
@ -34,7 +34,7 @@
|
||||||
//! impl<T, I: Iterator<Item=T>> SpecExtend<T> for I { /* default impl */ }
|
//! impl<T, I: Iterator<Item=T>> SpecExtend<T> for I { /* default impl */ }
|
||||||
//! ```
|
//! ```
|
||||||
//!
|
//!
|
||||||
//! We get that the generic pamameters for `impl2` are `[T, std::vec::IntoIter<T>]`.
|
//! We get that the generic parameters for `impl2` are `[T, std::vec::IntoIter<T>]`.
|
||||||
//! `T` is constrained to be `<I as Iterator>::Item`, so we check only
|
//! `T` is constrained to be `<I as Iterator>::Item`, so we check only
|
||||||
//! `std::vec::IntoIter<T>` for repeated parameters, which it doesn't have. The
|
//! `std::vec::IntoIter<T>` for repeated parameters, which it doesn't have. The
|
||||||
//! predicates of `impl1` are only `T: Sized`, which is also a predicate of
|
//! predicates of `impl1` are only `T: Sized`, which is also a predicate of
|
||||||
|
@ -119,7 +119,6 @@ fn check_always_applicable(
|
||||||
impl2_node: Node,
|
impl2_node: Node,
|
||||||
) -> Result<(), ErrorGuaranteed> {
|
) -> Result<(), ErrorGuaranteed> {
|
||||||
let span = tcx.def_span(impl1_def_id);
|
let span = tcx.def_span(impl1_def_id);
|
||||||
let mut res = check_has_items(tcx, impl1_def_id, impl2_node, span);
|
|
||||||
|
|
||||||
let (impl1_args, impl2_args) = get_impl_args(tcx, impl1_def_id, impl2_node)?;
|
let (impl1_args, impl2_args) = get_impl_args(tcx, impl1_def_id, impl2_node)?;
|
||||||
let impl2_def_id = impl2_node.def_id();
|
let impl2_def_id = impl2_node.def_id();
|
||||||
|
@ -131,11 +130,10 @@ fn check_always_applicable(
|
||||||
unconstrained_parent_impl_args(tcx, impl2_def_id, impl2_args)
|
unconstrained_parent_impl_args(tcx, impl2_def_id, impl2_args)
|
||||||
};
|
};
|
||||||
|
|
||||||
res = res.and(check_static_lifetimes(tcx, &parent_args, span));
|
check_has_items(tcx, impl1_def_id, impl2_node, span)
|
||||||
res = res.and(check_duplicate_params(tcx, impl1_args, parent_args, span));
|
.and(check_static_lifetimes(tcx, &parent_args, span))
|
||||||
res = res.and(check_predicates(tcx, impl1_def_id, impl1_args, impl2_node, impl2_args, span));
|
.and(check_duplicate_params(tcx, impl1_args, parent_args, span))
|
||||||
|
.and(check_predicates(tcx, impl1_def_id, impl1_args, impl2_node, impl2_args, span))
|
||||||
res
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_has_items(
|
fn check_has_items(
|
||||||
|
|
|
@ -83,12 +83,11 @@ pub mod autoderef;
|
||||||
mod bounds;
|
mod bounds;
|
||||||
mod check_unused;
|
mod check_unused;
|
||||||
mod coherence;
|
mod coherence;
|
||||||
mod delegation;
|
mod collect;
|
||||||
pub mod hir_ty_lowering;
|
|
||||||
// FIXME: This module shouldn't be public.
|
|
||||||
pub mod collect;
|
|
||||||
mod constrained_generic_params;
|
mod constrained_generic_params;
|
||||||
|
mod delegation;
|
||||||
mod errors;
|
mod errors;
|
||||||
|
pub mod hir_ty_lowering;
|
||||||
pub mod hir_wf_check;
|
pub mod hir_wf_check;
|
||||||
mod impl_wf_check;
|
mod impl_wf_check;
|
||||||
mod outlives;
|
mod outlives;
|
||||||
|
@ -104,7 +103,8 @@ use rustc_middle::ty::{self, Const, Ty, TyCtxt};
|
||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
use rustc_trait_selection::traits;
|
use rustc_trait_selection::traits;
|
||||||
|
|
||||||
use self::hir_ty_lowering::{FeedConstTy, HirTyLowerer};
|
pub use crate::collect::suggest_impl_trait;
|
||||||
|
use crate::hir_ty_lowering::{FeedConstTy, HirTyLowerer};
|
||||||
|
|
||||||
rustc_fluent_macro::fluent_messages! { "../messages.ftl" }
|
rustc_fluent_macro::fluent_messages! { "../messages.ftl" }
|
||||||
|
|
||||||
|
|
|
@ -24,7 +24,7 @@ pub(super) fn infer_predicates(
|
||||||
|
|
||||||
// If new predicates were added then we need to re-calculate
|
// If new predicates were added then we need to re-calculate
|
||||||
// all crates since there could be new implied predicates.
|
// all crates since there could be new implied predicates.
|
||||||
'outer: loop {
|
loop {
|
||||||
let mut predicates_added = false;
|
let mut predicates_added = false;
|
||||||
|
|
||||||
// Visit all the crates and infer predicates
|
// Visit all the crates and infer predicates
|
||||||
|
@ -90,7 +90,7 @@ pub(super) fn infer_predicates(
|
||||||
}
|
}
|
||||||
|
|
||||||
if !predicates_added {
|
if !predicates_added {
|
||||||
break 'outer;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,9 +27,6 @@ mod solve;
|
||||||
|
|
||||||
pub(crate) mod dump;
|
pub(crate) mod dump;
|
||||||
|
|
||||||
/// Code for transforming variances.
|
|
||||||
mod xform;
|
|
||||||
|
|
||||||
pub(crate) fn provide(providers: &mut Providers) {
|
pub(crate) fn provide(providers: &mut Providers) {
|
||||||
*providers = Providers { variances_of, crate_variances, ..*providers };
|
*providers = Providers { variances_of, crate_variances, ..*providers };
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,8 +12,26 @@ use tracing::debug;
|
||||||
use super::constraints::*;
|
use super::constraints::*;
|
||||||
use super::terms::VarianceTerm::*;
|
use super::terms::VarianceTerm::*;
|
||||||
use super::terms::*;
|
use super::terms::*;
|
||||||
use super::xform::*;
|
|
||||||
|
|
||||||
|
fn glb(v1: ty::Variance, v2: ty::Variance) -> ty::Variance {
|
||||||
|
// Greatest lower bound of the variance lattice as defined in The Paper:
|
||||||
|
//
|
||||||
|
// *
|
||||||
|
// - +
|
||||||
|
// o
|
||||||
|
match (v1, v2) {
|
||||||
|
(ty::Invariant, _) | (_, ty::Invariant) => ty::Invariant,
|
||||||
|
|
||||||
|
(ty::Covariant, ty::Contravariant) => ty::Invariant,
|
||||||
|
(ty::Contravariant, ty::Covariant) => ty::Invariant,
|
||||||
|
|
||||||
|
(ty::Covariant, ty::Covariant) => ty::Covariant,
|
||||||
|
|
||||||
|
(ty::Contravariant, ty::Contravariant) => ty::Contravariant,
|
||||||
|
|
||||||
|
(x, ty::Bivariant) | (ty::Bivariant, x) => x,
|
||||||
|
}
|
||||||
|
}
|
||||||
struct SolveContext<'a, 'tcx> {
|
struct SolveContext<'a, 'tcx> {
|
||||||
terms_cx: TermsContext<'a, 'tcx>,
|
terms_cx: TermsContext<'a, 'tcx>,
|
||||||
constraints: Vec<Constraint<'a>>,
|
constraints: Vec<Constraint<'a>>,
|
||||||
|
|
|
@ -1,22 +0,0 @@
|
||||||
use rustc_middle::ty;
|
|
||||||
|
|
||||||
pub(crate) fn glb(v1: ty::Variance, v2: ty::Variance) -> ty::Variance {
|
|
||||||
// Greatest lower bound of the variance lattice as
|
|
||||||
// defined in The Paper:
|
|
||||||
//
|
|
||||||
// *
|
|
||||||
// - +
|
|
||||||
// o
|
|
||||||
match (v1, v2) {
|
|
||||||
(ty::Invariant, _) | (_, ty::Invariant) => ty::Invariant,
|
|
||||||
|
|
||||||
(ty::Covariant, ty::Contravariant) => ty::Invariant,
|
|
||||||
(ty::Contravariant, ty::Covariant) => ty::Invariant,
|
|
||||||
|
|
||||||
(ty::Covariant, ty::Covariant) => ty::Covariant,
|
|
||||||
|
|
||||||
(ty::Contravariant, ty::Contravariant) => ty::Contravariant,
|
|
||||||
|
|
||||||
(x, ty::Bivariant) | (ty::Bivariant, x) => x,
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1261,7 +1261,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
|
|
||||||
fn provided_kind(
|
fn provided_kind(
|
||||||
&mut self,
|
&mut self,
|
||||||
_preceding_args: &[ty::GenericArg<'tcx>],
|
|
||||||
param: &ty::GenericParamDef,
|
param: &ty::GenericParamDef,
|
||||||
arg: &GenericArg<'tcx>,
|
arg: &GenericArg<'tcx>,
|
||||||
) -> ty::GenericArg<'tcx> {
|
) -> ty::GenericArg<'tcx> {
|
||||||
|
|
|
@ -31,12 +31,12 @@ use crate::{CoroutineTypes, Diverges, EnclosingBreakables, TypeckRootCtxt};
|
||||||
/// functions, closures, and `const`s, including performing type inference
|
/// functions, closures, and `const`s, including performing type inference
|
||||||
/// with [`InferCtxt`].
|
/// with [`InferCtxt`].
|
||||||
///
|
///
|
||||||
/// This is in contrast to [`ItemCtxt`], which is used to type-check item *signatures*
|
/// This is in contrast to `rustc_hir_analysis::collect::ItemCtxt`, which is
|
||||||
/// and thus does not perform type inference.
|
/// used to type-check item *signatures* and thus does not perform type
|
||||||
|
/// inference.
|
||||||
///
|
///
|
||||||
/// See [`ItemCtxt`]'s docs for more.
|
/// See `ItemCtxt`'s docs for more.
|
||||||
///
|
///
|
||||||
/// [`ItemCtxt`]: rustc_hir_analysis::collect::ItemCtxt
|
|
||||||
/// [`InferCtxt`]: infer::InferCtxt
|
/// [`InferCtxt`]: infer::InferCtxt
|
||||||
pub(crate) struct FnCtxt<'a, 'tcx> {
|
pub(crate) struct FnCtxt<'a, 'tcx> {
|
||||||
pub(super) body_id: LocalDefId,
|
pub(super) body_id: LocalDefId,
|
||||||
|
|
|
@ -12,8 +12,8 @@ use rustc_hir::{
|
||||||
GenericBound, HirId, Node, PatExpr, PatExprKind, Path, QPath, Stmt, StmtKind, TyKind,
|
GenericBound, HirId, Node, PatExpr, PatExprKind, Path, QPath, Stmt, StmtKind, TyKind,
|
||||||
WherePredicateKind, expr_needs_parens,
|
WherePredicateKind, expr_needs_parens,
|
||||||
};
|
};
|
||||||
use rustc_hir_analysis::collect::suggest_impl_trait;
|
|
||||||
use rustc_hir_analysis::hir_ty_lowering::HirTyLowerer;
|
use rustc_hir_analysis::hir_ty_lowering::HirTyLowerer;
|
||||||
|
use rustc_hir_analysis::suggest_impl_trait;
|
||||||
use rustc_middle::lint::in_external_macro;
|
use rustc_middle::lint::in_external_macro;
|
||||||
use rustc_middle::middle::stability::EvalResult;
|
use rustc_middle::middle::stability::EvalResult;
|
||||||
use rustc_middle::span_bug;
|
use rustc_middle::span_bug;
|
||||||
|
|
|
@ -413,7 +413,6 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
|
||||||
|
|
||||||
fn provided_kind(
|
fn provided_kind(
|
||||||
&mut self,
|
&mut self,
|
||||||
_preceding_args: &[ty::GenericArg<'tcx>],
|
|
||||||
param: &ty::GenericParamDef,
|
param: &ty::GenericParamDef,
|
||||||
arg: &GenericArg<'tcx>,
|
arg: &GenericArg<'tcx>,
|
||||||
) -> ty::GenericArg<'tcx> {
|
) -> ty::GenericArg<'tcx> {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue