summaryrefslogtreecommitdiff
path: root/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs')
-rw-r--r--compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs74
1 files changed, 43 insertions, 31 deletions
diff --git a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
index 1c496f867a0..794812a5ce7 100644
--- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
+++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
@@ -17,6 +17,7 @@ use rustc_hir::{GenericArg, GenericParam, GenericParamKind, HirIdMap, LifetimeNa
use rustc_middle::bug;
use rustc_middle::hir::nested_filter;
use rustc_middle::middle::resolve_bound_vars::*;
+use rustc_middle::query::Providers;
use rustc_middle::ty::{self, TyCtxt, TypeSuperVisitable, TypeVisitor};
use rustc_session::lint;
use rustc_span::def_id::DefId;
@@ -232,8 +233,8 @@ impl<'a> fmt::Debug for TruncatedScopeDebug<'a> {
type ScopeRef<'a> = &'a Scope<'a>;
-pub(crate) fn provide(providers: &mut ty::query::Providers) {
- *providers = ty::query::Providers {
+pub(crate) fn provide(providers: &mut Providers) {
+ *providers = Providers {
resolve_bound_vars,
named_variable_map: |tcx, id| tcx.resolve_bound_vars(id).defs.get(&id),
@@ -526,7 +527,8 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
});
}
hir::ItemKind::OpaqueTy(hir::OpaqueTy {
- origin: hir::OpaqueTyOrigin::TyAlias, ..
+ origin: hir::OpaqueTyOrigin::TyAlias { .. },
+ ..
}) => {
// Opaque types are visited when we visit the
// `TyKind::OpaqueDef`, so that they have the lifetimes from
@@ -707,7 +709,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
let opaque_ty = self.tcx.hir().item(item_id);
match &opaque_ty.kind {
hir::ItemKind::OpaqueTy(hir::OpaqueTy {
- origin: hir::OpaqueTyOrigin::TyAlias,
+ origin: hir::OpaqueTyOrigin::TyAlias { .. },
..
}) => {
intravisit::walk_ty(self, ty);
@@ -987,7 +989,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
lifetime.ident
),
|lint| {
- let help = &format!(
+ let help = format!(
"you can use the `'static` lifetime directly, in place of `{}`",
lifetime.ident,
);
@@ -1365,7 +1367,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
self.tcx.sess.delay_span_bug(
lifetime_ref.ident.span,
- &format!("Could not resolve {:?} in scope {:#?}", lifetime_ref, self.scope,),
+ format!("Could not resolve {:?} in scope {:#?}", lifetime_ref, self.scope,),
);
}
@@ -1652,17 +1654,16 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
if binding.gen_args.parenthesized == hir::GenericArgsParentheses::ReturnTypeNotation {
let bound_vars = if let Some(type_def_id) = type_def_id
&& self.tcx.def_kind(type_def_id) == DefKind::Trait
- // FIXME(return_type_notation): We could bound supertrait methods.
- && let Some(assoc_fn) = self
- .tcx
- .associated_items(type_def_id)
- .find_by_name_and_kind(self.tcx, binding.ident, ty::AssocKind::Fn, type_def_id)
+ && let Some((mut bound_vars, assoc_fn)) =
+ BoundVarContext::supertrait_hrtb_vars(
+ self.tcx,
+ type_def_id,
+ binding.ident,
+ ty::AssocKind::Fn,
+ )
{
- self.tcx
- .generics_of(assoc_fn.def_id)
- .params
- .iter()
- .map(|param| match param.kind {
+ bound_vars.extend(self.tcx.generics_of(assoc_fn.def_id).params.iter().map(
+ |param| match param.kind {
ty::GenericParamDefKind::Lifetime => ty::BoundVariableKind::Region(
ty::BoundRegionKind::BrNamed(param.def_id, param.name),
),
@@ -1670,9 +1671,11 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
ty::BoundTyKind::Param(param.def_id, param.name),
),
ty::GenericParamDefKind::Const { .. } => ty::BoundVariableKind::Const,
- })
- .chain(self.tcx.fn_sig(assoc_fn.def_id).subst_identity().bound_vars())
- .collect()
+ },
+ ));
+ bound_vars
+ .extend(self.tcx.fn_sig(assoc_fn.def_id).subst_identity().bound_vars());
+ bound_vars
} else {
self.tcx.sess.delay_span_bug(
binding.ident.span,
@@ -1689,8 +1692,13 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
});
});
} else if let Some(type_def_id) = type_def_id {
- let bound_vars =
- BoundVarContext::supertrait_hrtb_vars(self.tcx, type_def_id, binding.ident);
+ let bound_vars = BoundVarContext::supertrait_hrtb_vars(
+ self.tcx,
+ type_def_id,
+ binding.ident,
+ ty::AssocKind::Type,
+ )
+ .map(|(bound_vars, _)| bound_vars);
self.with(scope, |this| {
let scope = Scope::Supertrait {
bound_vars: bound_vars.unwrap_or_default(),
@@ -1720,11 +1728,15 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
tcx: TyCtxt<'tcx>,
def_id: DefId,
assoc_name: Ident,
- ) -> Option<Vec<ty::BoundVariableKind>> {
- let trait_defines_associated_type_named = |trait_def_id: DefId| {
- tcx.associated_items(trait_def_id)
- .find_by_name_and_kind(tcx, assoc_name, ty::AssocKind::Type, trait_def_id)
- .is_some()
+ assoc_kind: ty::AssocKind,
+ ) -> Option<(Vec<ty::BoundVariableKind>, &'tcx ty::AssocItem)> {
+ let trait_defines_associated_item_named = |trait_def_id: DefId| {
+ tcx.associated_items(trait_def_id).find_by_name_and_kind(
+ tcx,
+ assoc_name,
+ assoc_kind,
+ trait_def_id,
+ )
};
use smallvec::{smallvec, SmallVec};
@@ -1742,10 +1754,10 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
_ => break None,
}
- if trait_defines_associated_type_named(def_id) {
- break Some(bound_vars.into_iter().collect());
+ if let Some(assoc_item) = trait_defines_associated_item_named(def_id) {
+ break Some((bound_vars.into_iter().collect(), assoc_item));
}
- let predicates = tcx.super_predicates_that_define_assoc_type((def_id, assoc_name));
+ let predicates = tcx.super_predicates_that_define_assoc_item((def_id, assoc_name));
let obligations = predicates.predicates.iter().filter_map(|&(pred, _)| {
let bound_predicate = pred.kind();
match bound_predicate.skip_binder() {
@@ -1913,7 +1925,7 @@ fn is_late_bound_map(
/// handles cycle detection as we go through the query system.
///
/// This is necessary in the first place for the following case:
- /// ```
+ /// ```rust,ignore (pseudo-Rust)
/// type Alias<'a, T> = <T as Trait<'a>>::Assoc;
/// fn foo<'a>(_: Alias<'a, ()>) -> Alias<'a, ()> { ... }
/// ```
@@ -1938,7 +1950,7 @@ fn is_late_bound_map(
ty::Param(param_ty) => {
self.arg_is_constrained[param_ty.index as usize] = true;
}
- ty::Alias(ty::Projection, _) => return ControlFlow::Continue(()),
+ ty::Alias(ty::Projection | ty::Inherent, _) => return ControlFlow::Continue(()),
_ => (),
}
t.super_visit_with(self)