pub trait AstConv<'tcx> {
    fn tcx<'a>(&'a self) -> TyCtxt<'tcx>;
    fn item_def_id(&self) -> DefId;
    fn get_type_parameter_bounds(
        &self,
        span: Span,
        def_id: DefId,
        assoc_name: Ident
    ) -> GenericPredicates<'tcx>; fn re_infer(
        &self,
        param: Option<&GenericParamDef>,
        span: Span
    ) -> Option<Region<'tcx>>; fn ty_infer(&self, param: Option<&GenericParamDef>, span: Span) -> Ty<'tcx>; fn allow_ty_infer(&self) -> bool; fn ct_infer(
        &self,
        ty: Ty<'tcx>,
        param: Option<&GenericParamDef>,
        span: Span
    ) -> Const<'tcx>; fn projected_ty_from_poly_trait_ref(
        &self,
        span: Span,
        item_def_id: DefId,
        item_segment: &PathSegment<'_>,
        poly_trait_ref: PolyTraitRef<'tcx>
    ) -> Ty<'tcx>; fn normalize_ty(&self, span: Span, ty: Ty<'tcx>) -> Ty<'tcx>; fn set_tainted_by_errors(&self, e: ErrorGuaranteed); fn record_ty(&self, hir_id: HirId, ty: Ty<'tcx>, span: Span); }

Required Methods§

Returns predicates in scope of the form X: Foo<T>, where X is a type parameter X with the given id def_id and T matches assoc_name. This is a subset of the full set of predicates.

This is used for one specific purpose: resolving “short-hand” associated type references like T::Item. In principle, we would do that by first getting the full set of predicates in scope and then filtering down to find those that apply to T, but this can lead to cycle errors. The problem is that we have to do this resolution in order to create the predicates in the first place. Hence, we have this “special pass”.

Returns the lifetime to use when a lifetime is omitted (and not elided).

Returns the type to use when a type is omitted.

Returns true if _ is allowed in type signatures in the current context.

Returns the const to use when a const is omitted.

Projecting an associated type from a (potentially) higher-ranked trait reference is more complicated, because of the possibility of late-bound regions appearing in the associated type binding. This is not legal in function signatures for that reason. In a function body, we can always handle it because we can use inference variables to remove the late-bound regions.

Normalize an associated type coming from the user.

This should only be used by astconv. Use FnCtxt::normalize or ObligationCtxt::normalize in downstream crates.

Invoked when we encounter an error from some prior pass (e.g., resolve) that is translated into a ty-error. This is used to help suppress derived errors typeck might otherwise report.

Implementations§

On missing type parameters, emit an E0393 error and provide a structured suggestion using the type parameter’s name as a placeholder.

When the code is using the Fn traits directly, instead of the Fn(A) -> B syntax, emit an error and attempt to build a reasonable structured suggestion.

When there are any missing associated types, emit an E0191 error and attempt to supply a reasonable suggestion on how to write it. For the case of multiple associated types in the same trait bound have the same name (as they come from different supertraits), we instead emit a generic note suggesting using a where clause to constraint instead.

Report an error that a generic argument did not match the generic parameter that was expected.

Creates the relevant generic argument substitutions corresponding to a set of generic parameters. This is a rather complex function. Let us 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 – 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 DefId P, supplies back the generic arguments that were given to that parent from within the path; so e.g., if you have <T as Foo>::Bar, the DefId 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 GenericArg.
  • inferred_kind: if no parameter was provided, and inference is enabled, then creates a suitable inference variable.

Checks that the correct number of generic arguments have been provided. Used specifically for function calls.

Checks that the correct number of generic arguments have been provided. This is used both for datatypes and function calls.

Emits an error regarding forbidden type binding associations

Prohibits explicit lifetime arguments if late-bound lifetime parameters are present. This is used both for datatypes and function calls.

Given a path path that refers to an item I with the declared generics decl_generics, returns an appropriate set of substitutions for this particular reference to I.

Given the type/lifetime/const arguments provided to some path (along with an implicit Self, if this is a trait reference), returns the complete set of substitutions. This may involve applying defaulted type parameters. Constraints on associated types are created from create_assoc_bindings_for_generic_args.

Example:

   T: std::ops::Index<usize, Output = u32>
// ^1 ^^^^^^^^^^^^^^2 ^^^^3  ^^^^^^^^^^^4
  1. The self_ty here would refer to the type T.
  2. The path in question is the path to the trait std::ops::Index, which will have been resolved to a def_id
  3. The generic_args contains info on the <...> contents. The usize type parameters are returned in the SubstsRef, the associated type bindings like Output = u32 are returned from create_assoc_bindings_for_generic_args.

Note that the type listing given here is exactly what the user provided.

For (generic) associated types

<Vec<u8> as Iterable<u8>>::Iter::<'a>

We have the parent substs are the substs for the parent trait: [Vec<u8>, u8] and generic_args are the arguments for the associated type itself: ['a]. The returned SubstsRef concatenates these two lists: [Vec<u8>, u8, 'a].

Instantiates the path for the given trait reference, assuming that it’s bound to a valid trait type. Returns the DefId of the defining trait. The type cannot be a type other than a trait type.

If the projections argument is None, then assoc type bindings like Foo<T = X> are disallowed. Otherwise, they are pushed onto the vector given.

Given a trait bound like Debug, applies that trait bound the given self-type to construct a full trait reference. The resulting trait reference is returned. This may also generate auxiliary bounds, which are added to bounds.

Example:

poly_trait_ref = Iterator<Item = u32>
self_ty = Foo

this would return Foo: Iterator and add <Foo as Iterator>::Item = u32 into bounds.

A note on binders: against our usual convention, there is an implied bounder around the self_ty and poly_trait_ref parameters here. So they may reference bound regions. If for example you had for<'a> Foo<'a>: Bar<'a>, then the self_ty would be Foo<'a> where 'a is a bound region at depth 0. Similarly, the poly_trait_ref would be Bar<'a>. The returned poly-trait-ref will have this binder instantiated explicitly, however.

Sets implicitly_sized to true on Bounds if necessary

This helper takes a converted parameter type (param_ty) and an unconverted list of bounds:

fn foo<T: Debug>
       ^  ^^^^^ `ast_bounds` parameter, in HIR form
       |
       `param_ty`, in ty form

It adds these ast_bounds into the bounds structure.

A note on binders: there is an implied binder around param_ty and ast_bounds. See instantiate_poly_trait_ref for more details.

Translates a list of bounds from the HIR into the Bounds data structure. The self-type for the bounds is given by param_ty.

Example:

fn foo<T: Bar + Baz>() { }
//     ^  ^^^^^^^^^ ast_bounds
//     param_ty

The sized_by_default parameter indicates if, in this context, the param_ty should be considered Sized unless there is an explicit ?Sized bound. This would be true in the example above, but is not true in supertrait listings like trait Foo: Bar + Baz.

span should be the declaration size of the parameter.

Convert the bounds in ast_bounds that refer to traits which define an associated type named assoc_name into ty::Bounds. Ignore the rest.

Given an HIR binding like Item = Foo or Item: Foo, pushes the corresponding predicates onto bounds.

A note on binders: given something like T: for<'a> Iterator<Item = &'a u32>, the trait_ref here will be for<'a> T: Iterator. The binding data however is from inside the binder (e.g., &'a u32) and hence may reference bound regions.

Check a type Path and convert it to a Ty.

Parses the programmer’s textual representation of a type into our internal notion of a type.

Parses the programmer’s textual representation of a type into our internal notion of a type. This is meant to be used within a path.

Turns a hir::Ty into a Ty. For diagnostics’ purposes we keep track of whether trait objects are borrowed like &dyn Trait to avoid emitting redundant errors.

Given a fn_hir_id for a impl function, suggest the type that is found on the corresponding function in the trait that the impl implements, if it exists. If arg_idx is Some, then it corresponds to an input type index, otherwise it corresponds to the return type.

Given the bounds on an object, determines what single region bound (if any) we can use to summarize this type. The basic idea is that we will use the bound the user provided, if they provided one, and otherwise search the supertypes of trait bounds for region bounds. It may be that we can derive no bound at all, in which case we return None.

Make sure that we are in the condition to suggest the blanket implementation.

Implementors§