diff options
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.rs | 74 |
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) |