From 16e1aaf09da5d516487118e048bf37e8c44f1b77 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Tue, 2 Oct 2018 14:05:23 -0400 Subject: [PATCH] document `create_substs_for_generic_args` --- src/librustc_typeck/astconv.rs | 43 ++++++++++++++++++++++++++-------- 1 file changed, 33 insertions(+), 10 deletions(-) diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 28d2ae413de..e4ad02595d1 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -402,21 +402,44 @@ fn check_generic_arg_count( } /// Creates the relevant generic argument substitutions - /// corresponding to a set of generic parameters. - pub fn create_substs_for_generic_args<'a, 'b, A, P, I>( + /// corresponding to a set of generic parameters. This is a + /// rather complex little function. Let me try to explain the + /// role of each of its parameters: + /// + /// To start, we are given the `def_id` of the thing we are + /// creating the substitutions for, and a partial set of + /// substitutions `parent_substs`. In general, the substitutions + /// for an item begin with substitutions for all the "parents" of + /// that item -- so e.g. for a method it might include the + /// parameters from the impl. + /// + /// Therefore, the method begins by walking down these parents, + /// starting with the outermost parent and proceed inwards until + /// it reaches `def_id`. For each parent P, it will check `parent_substs` + /// first to see if the parent's substitutions are listed in there. If so, + /// we can append those and move on. Otherwise, it invokes the + /// three callback functions: + /// + /// - `args_for_def_id`: given the def-id P, supplies back the + /// generic arguments that were given to that parent from within + /// the path; so e.g. if you have `::Bar`, the def-id + /// might refer to the trait `Foo`, and the arguments might be + /// `[T]`. The boolean value indicates whether to infer values + /// for arguments whose values were not explicitly provided. + /// - `provided_kind`: given the generic parameter and the value from `args_for_def_id`, + /// instantiate a `Kind` + /// - `inferred_kind`: if no parameter was provided, and inference is enabled, then + /// creates a suitable inference variable. + pub fn create_substs_for_generic_args<'a, 'b>( tcx: TyCtxt<'a, 'gcx, 'tcx>, def_id: DefId, parent_substs: &[Kind<'tcx>], has_self: bool, self_ty: Option>, - args_for_def_id: A, - provided_kind: P, - inferred_kind: I, - ) -> &'tcx Substs<'tcx> where - A: Fn(DefId) -> (Option<&'b GenericArgs>, bool), - P: Fn(&GenericParamDef, &GenericArg) -> Kind<'tcx>, - I: Fn(Option<&[Kind<'tcx>]>, &GenericParamDef, bool) -> Kind<'tcx> - { + args_for_def_id: impl Fn(DefId) -> (Option<&'b GenericArgs>, bool), + provided_kind: impl Fn(&GenericParamDef, &GenericArg) -> Kind<'tcx>, + inferred_kind: impl Fn(Option<&[Kind<'tcx>]>, &GenericParamDef, bool) -> Kind<'tcx>, + ) -> &'tcx Substs<'tcx> { // Collect the segments of the path: we need to substitute arguments // for parameters throughout the entire path (wherever there are // generic parameters). -- 2.44.0