1
Fork 0

introduce a UserTypeAnnotation enum

This commit is contained in:
Niko Matsakis 2018-10-10 17:07:10 -04:00
parent e339e84fff
commit aed6e4a083
13 changed files with 126 additions and 88 deletions

View file

@ -587,3 +587,16 @@ impl<'a, 'gcx> HashStable<StableHashingContext<'a>> for mir::ClosureOutlivesSubj
}
impl_stable_hash_for!(struct mir::interpret::GlobalId<'tcx> { instance, promoted });
impl<'a, 'gcx> HashStable<StableHashingContext<'a>> for mir::UserTypeAnnotation<'gcx> {
fn hash_stable<W: StableHasherResult>(&self,
hcx: &mut StableHashingContext<'a>,
hasher: &mut StableHasher<W>) {
mem::discriminant(self).hash_stable(hcx, hasher);
match *self {
mir::UserTypeAnnotation::Ty(ref ty) => {
ty.hash_stable(hcx, hasher);
}
}
}
}

View file

@ -710,7 +710,7 @@ pub struct LocalDecl<'tcx> {
/// e.g. via `let x: T`, then we carry that type here. The MIR
/// borrow checker needs this information since it can affect
/// region inference.
pub user_ty: Option<(CanonicalTy<'tcx>, Span)>,
pub user_ty: Option<(UserTypeAnnotation<'tcx>, Span)>,
/// Name of the local, used in debuginfo and pretty-printing.
///
@ -1737,7 +1737,7 @@ pub enum StatementKind<'tcx> {
/// - `Contravariant` -- requires that `T_y :> T`
/// - `Invariant` -- requires that `T_y == T`
/// - `Bivariant` -- no effect
AscribeUserType(Place<'tcx>, ty::Variance, CanonicalTy<'tcx>),
AscribeUserType(Place<'tcx>, ty::Variance, UserTypeAnnotation<'tcx>),
/// No-op. Useful for deleting instructions without affecting statement indices.
Nop,
@ -2188,7 +2188,7 @@ pub enum AggregateKind<'tcx> {
&'tcx AdtDef,
usize,
&'tcx Substs<'tcx>,
Option<CanonicalTy<'tcx>>,
Option<UserTypeAnnotation<'tcx>>,
Option<usize>,
),
@ -2392,7 +2392,7 @@ impl<'tcx> Debug for Rvalue<'tcx> {
/// this does not necessarily mean that they are "==" in Rust -- in
/// particular one must be wary of `NaN`!
#[derive(Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
#[derive(Copy, Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
pub struct Constant<'tcx> {
pub span: Span,
pub ty: Ty<'tcx>,
@ -2402,11 +2402,25 @@ pub struct Constant<'tcx> {
/// indicate that `Vec<_>` was explicitly specified.
///
/// Needed for NLL to impose user-given type constraints.
pub user_ty: Option<CanonicalTy<'tcx>>,
pub user_ty: Option<UserTypeAnnotation<'tcx>>,
pub literal: &'tcx ty::Const<'tcx>,
}
/// A user-given type annotation attached to a constant. These arise
/// from constants that are named via paths, like `Foo::<A>::new` and
/// so forth.
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
pub enum UserTypeAnnotation<'tcx> {
Ty(CanonicalTy<'tcx>),
}
EnumTypeFoldableImpl! {
impl<'tcx> TypeFoldable<'tcx> for UserTypeAnnotation<'tcx> {
(UserTypeAnnotation::Ty)(ty),
}
}
newtype_index! {
pub struct Promoted {
DEBUG_FORMAT = "promoted[{}]"

View file

@ -10,7 +10,7 @@
use hir::def_id::DefId;
use ty::subst::Substs;
use ty::{CanonicalTy, ClosureSubsts, GeneratorSubsts, Region, Ty};
use ty::{ClosureSubsts, GeneratorSubsts, Region, Ty};
use mir::*;
use syntax_pos::Span;
@ -147,9 +147,9 @@ macro_rules! make_mir_visitor {
fn visit_ascribe_user_ty(&mut self,
place: & $($mutability)* Place<'tcx>,
variance: & $($mutability)* ty::Variance,
c_ty: & $($mutability)* CanonicalTy<'tcx>,
user_ty: & $($mutability)* UserTypeAnnotation<'tcx>,
location: Location) {
self.super_ascribe_user_ty(place, variance, c_ty, location);
self.super_ascribe_user_ty(place, variance, user_ty, location);
}
fn visit_place(&mut self,
@ -214,8 +214,8 @@ macro_rules! make_mir_visitor {
self.super_ty(ty);
}
fn visit_user_ty(&mut self, ty: & $($mutability)* CanonicalTy<'tcx>) {
self.super_canonical_ty(ty);
fn visit_user_type_annotation(&mut self, ty: & $($mutability)* UserTypeAnnotation<'tcx>) {
self.super_user_type_annotation(ty);
}
fn visit_region(&mut self,
@ -390,9 +390,9 @@ macro_rules! make_mir_visitor {
StatementKind::AscribeUserType(
ref $($mutability)* place,
ref $($mutability)* variance,
ref $($mutability)* c_ty,
ref $($mutability)* user_ty,
) => {
self.visit_ascribe_user_ty(place, variance, c_ty, location);
self.visit_ascribe_user_ty(place, variance, user_ty, location);
}
StatementKind::Nop => {}
}
@ -637,10 +637,10 @@ macro_rules! make_mir_visitor {
fn super_ascribe_user_ty(&mut self,
place: & $($mutability)* Place<'tcx>,
_variance: & $($mutability)* ty::Variance,
c_ty: & $($mutability)* CanonicalTy<'tcx>,
user_ty: & $($mutability)* UserTypeAnnotation<'tcx>,
location: Location) {
self.visit_place(place, PlaceContext::Validate, location);
self.visit_user_ty(c_ty);
self.visit_user_type_annotation(user_ty);
}
fn super_place(&mut self,
@ -736,7 +736,7 @@ macro_rules! make_mir_visitor {
source_info: *source_info,
});
if let Some((user_ty, _)) = user_ty {
self.visit_user_ty(user_ty);
self.visit_user_type_annotation(user_ty);
}
self.visit_source_info(source_info);
self.visit_source_scope(visibility_scope);
@ -783,7 +783,7 @@ macro_rules! make_mir_visitor {
self.visit_source_scope(scope);
}
fn super_canonical_ty(&mut self, _ty: & $($mutability)* CanonicalTy<'tcx>) {
fn super_user_type_annotation(&mut self, _ty: & $($mutability)* UserTypeAnnotation<'tcx>) {
}
fn super_ty(&mut self, _ty: & $($mutability)* Ty<'tcx>) {

View file

@ -18,9 +18,10 @@ use rustc::mir::visit::TyContext;
use rustc::mir::visit::Visitor;
use rustc::mir::{BasicBlock, BasicBlockData, Location, Mir, Place, Rvalue};
use rustc::mir::{Statement, Terminator};
use rustc::mir::UserTypeAnnotation;
use rustc::ty::fold::TypeFoldable;
use rustc::ty::subst::Substs;
use rustc::ty::{self, CanonicalTy, ClosureSubsts, GeneratorSubsts, RegionVid};
use rustc::ty::{self, ClosureSubsts, GeneratorSubsts, RegionVid};
pub(super) fn generate_constraints<'cx, 'gcx, 'tcx>(
infcx: &InferCtxt<'cx, 'gcx, 'tcx>,
@ -179,7 +180,7 @@ impl<'cg, 'cx, 'gcx, 'tcx> Visitor<'tcx> for ConstraintGeneration<'cg, 'cx, 'gcx
&mut self,
_place: &Place<'tcx>,
_variance: &ty::Variance,
_c_ty: &CanonicalTy<'tcx>,
_user_ty: &UserTypeAnnotation<'tcx>,
_location: Location,
) {
}

View file

@ -9,8 +9,8 @@
// except according to those terms.
use rustc::ty::subst::Substs;
use rustc::ty::{self, CanonicalTy, ClosureSubsts, GeneratorSubsts, Ty, TypeFoldable};
use rustc::mir::{BasicBlock, Location, Mir, Statement, StatementKind};
use rustc::ty::{self, ClosureSubsts, GeneratorSubsts, Ty, TypeFoldable};
use rustc::mir::{BasicBlock, Location, Mir, Statement, StatementKind, UserTypeAnnotation};
use rustc::mir::visit::{MutVisitor, TyContext};
use rustc::infer::{InferCtxt, NLLRegionVariableOrigin};
@ -65,12 +65,12 @@ impl<'a, 'gcx, 'tcx> MutVisitor<'tcx> for NLLVisitor<'a, 'gcx, 'tcx> {
debug!("visit_ty: ty={:?}", ty);
}
fn visit_user_ty(&mut self, _ty: &mut CanonicalTy<'tcx>) {
// `user_ty` annotations represent the types that the user
fn visit_user_type_annotation(&mut self, _ty: &mut UserTypeAnnotation<'tcx>) {
// User type annotations represent the types that the user
// wrote in the progarm. We don't want to erase the regions
// from these types: rather, we want to add them as
// constraints at type-check time.
debug!("visit_user_ty: skipping renumber");
debug!("visit_user_type_annotation: skipping renumber");
}
fn visit_substs(&mut self, substs: &mut &'tcx Substs<'tcx>, location: Location) {

View file

@ -43,7 +43,7 @@ use rustc::traits::query::{Fallible, NoSolution};
use rustc::traits::{ObligationCause, PredicateObligations};
use rustc::ty::fold::TypeFoldable;
use rustc::ty::subst::{Subst, UnpackedKind};
use rustc::ty::{self, CanonicalTy, RegionVid, ToPolyTraitRef, Ty, TyCtxt, TyKind};
use rustc::ty::{self, RegionVid, ToPolyTraitRef, Ty, TyCtxt, TyKind};
use std::rc::Rc;
use std::{fmt, iter};
use syntax_pos::{Span, DUMMY_SP};
@ -966,7 +966,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
&mut self,
a: Ty<'tcx>,
v: ty::Variance,
b: CanonicalTy<'tcx>,
b: UserTypeAnnotation<'tcx>,
locations: Locations,
category: ConstraintCategory,
) -> Fallible<()> {
@ -1837,7 +1837,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
/// If this rvalue supports a user-given type annotation, then
/// extract and return it. This represents the final type of the
/// rvalue and will be unified with the inferred type.
fn rvalue_user_ty(&self, rvalue: &Rvalue<'tcx>) -> Option<CanonicalTy<'tcx>> {
fn rvalue_user_ty(&self, rvalue: &Rvalue<'tcx>) -> Option<UserTypeAnnotation<'tcx>> {
match rvalue {
Rvalue::Use(_)
| Rvalue::Repeat(..)

View file

@ -10,12 +10,12 @@
use borrow_check::nll::constraints::OutlivesConstraint;
use borrow_check::nll::type_check::{BorrowCheckContext, Locations};
use rustc::infer::{InferCtxt, NLLRegionVariableOrigin};
use rustc::infer::nll_relate::{TypeRelating, TypeRelatingDelegate};
use rustc::mir::ConstraintCategory;
use rustc::infer::{InferCtxt, NLLRegionVariableOrigin};
use rustc::mir::{ConstraintCategory, UserTypeAnnotation};
use rustc::traits::query::Fallible;
use rustc::ty::relate::TypeRelation;
use rustc::ty::{self, CanonicalTy, Ty};
use rustc::ty::{self, Ty};
use syntax_pos::DUMMY_SP;
/// Adds sufficient constraints to ensure that `a <: b`.
@ -61,20 +61,21 @@ pub(super) fn relate_type_and_user_type<'tcx>(
infcx: &InferCtxt<'_, '_, 'tcx>,
a: Ty<'tcx>,
v: ty::Variance,
canonical_b: CanonicalTy<'tcx>,
user_ty: UserTypeAnnotation<'tcx>,
locations: Locations,
category: ConstraintCategory,
borrowck_context: Option<&mut BorrowCheckContext<'_, 'tcx>>,
) -> Fallible<Ty<'tcx>> {
debug!(
"relate_type_and_user_type(a={:?}, v={:?}, b={:?}, locations={:?})",
a, v, canonical_b, locations
a, v, user_ty, locations
);
let (b, _values) = infcx.instantiate_canonical_with_fresh_inference_vars(
DUMMY_SP,
&canonical_b,
);
let (b, _values) = match user_ty {
UserTypeAnnotation::Ty(canonical_ty) => {
infcx.instantiate_canonical_with_fresh_inference_vars(DUMMY_SP, &canonical_ty)
}
};
// The `TypeRelating` code assumes that the "canonical variables"
// appear in the "a" side, so flip `Contravariant` ambient

View file

@ -20,7 +20,7 @@ use build::{GuardFrame, GuardFrameLocal, LocalsForNode};
use hair::*;
use rustc::hir;
use rustc::mir::*;
use rustc::ty::{self, CanonicalTy, Ty};
use rustc::ty::{self, Ty};
use rustc_data_structures::bit_set::BitSet;
use rustc_data_structures::fx::FxHashMap;
use syntax::ast::{Name, NodeId};
@ -491,7 +491,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
pub fn visit_bindings(
&mut self,
pattern: &Pattern<'tcx>,
mut pattern_user_ty: Option<(CanonicalTy<'tcx>, Span)>,
mut pattern_user_ty: Option<(UserTypeAnnotation<'tcx>, Span)>,
f: &mut impl FnMut(
&mut Self,
Mutability,
@ -500,7 +500,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
NodeId,
Span,
Ty<'tcx>,
Option<(CanonicalTy<'tcx>, Span)>,
Option<(UserTypeAnnotation<'tcx>, Span)>,
),
) {
match *pattern.kind {
@ -626,7 +626,7 @@ struct Binding<'tcx> {
struct Ascription<'tcx> {
span: Span,
source: Place<'tcx>,
user_ty: CanonicalTy<'tcx>,
user_ty: UserTypeAnnotation<'tcx>,
}
#[derive(Clone, Debug)]
@ -1470,7 +1470,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
num_patterns: usize,
var_id: NodeId,
var_ty: Ty<'tcx>,
user_var_ty: Option<(CanonicalTy<'tcx>, Span)>,
user_var_ty: Option<(UserTypeAnnotation<'tcx>, Span)>,
has_guard: ArmHasGuard,
opt_match_place: Option<(Option<Place<'tcx>>, Span)>,
pat_span: Span,

View file

@ -86,12 +86,12 @@ fn mirror_stmts<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
let mut pattern = cx.pattern_from_hir(&local.pat);
if let Some(ty) = &local.ty {
if let Some(user_ty) = cx.tables.user_provided_tys().get(ty.hir_id) {
if let Some(&user_ty) = cx.tables.user_provided_tys().get(ty.hir_id) {
pattern = Pattern {
ty: pattern.ty,
span: pattern.span,
kind: Box::new(PatternKind::AscribeUserType {
user_ty: *user_ty,
user_ty: UserTypeAnnotation::Ty(user_ty),
user_ty_span: ty.span,
subpattern: pattern
})

View file

@ -296,11 +296,11 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
let user_ty = cx.tables().user_substs(fun.hir_id)
.map(|user_substs| {
user_substs.unchecked_map(|user_substs| {
UserTypeAnnotation::Ty(user_substs.unchecked_map(|user_substs| {
// Here, we just pair an `AdtDef` with the
// `user_substs`, so no new types etc are introduced.
cx.tcx().mk_adt(adt_def, user_substs)
})
}))
});
let field_refs = args.iter()
@ -725,9 +725,11 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
}
hir::ExprKind::Type(ref source, ref ty) => {
let user_provided_tys = cx.tables.user_provided_tys();
let user_ty = *user_provided_tys
.get(ty.hir_id)
.expect(&format!("{:?} not found in user_provided_tys, source: {:?}", ty, source));
let user_ty = UserTypeAnnotation::Ty(
*user_provided_tys
.get(ty.hir_id)
.expect(&format!("{:?} not found in user_provided_tys, source: {:?}", ty, source))
);
if source.is_place_expr() {
ExprKind::PlaceTypeAscription {
source: source.to_ref(),
@ -763,7 +765,7 @@ fn user_substs_applied_to_def(
cx: &mut Cx<'a, 'gcx, 'tcx>,
hir_id: hir::HirId,
def: &Def,
) -> Option<CanonicalTy<'tcx>> {
) -> Option<UserTypeAnnotation<'tcx>> {
match def {
// A reference to something callable -- e.g., a fn, method, or
// a tuple-struct or tuple-variant. This has the type of a
@ -772,11 +774,14 @@ fn user_substs_applied_to_def(
Def::Method(_) |
Def::StructCtor(_, CtorKind::Fn) |
Def::VariantCtor(_, CtorKind::Fn) =>
Some(cx.tables().user_substs(hir_id)?.unchecked_map(|user_substs| {
// Here, we just pair a `DefId` with the
// `user_substs`, so no new types etc are introduced.
cx.tcx().mk_fn_def(def.def_id(), user_substs)
})),
Some(
UserTypeAnnotation::Ty(cx.tables().user_substs(hir_id)?.unchecked_map(|user_substs| {
// Here, we just pair a `DefId` with the
// `user_substs`, so no new types etc are introduced.
cx.tcx().mk_fn_def(def.def_id(), user_substs)
}),
)
),
Def::Const(_def_id) |
Def::AssociatedConst(_def_id) =>

View file

@ -14,11 +14,11 @@
//! unit-tested and separated from the Rust source and compiler data
//! structures.
use rustc::mir::{BinOp, BorrowKind, Field, UnOp};
use rustc::mir::{BinOp, BorrowKind, UserTypeAnnotation, Field, UnOp};
use rustc::hir::def_id::DefId;
use rustc::middle::region;
use rustc::ty::subst::Substs;
use rustc::ty::{AdtDef, CanonicalTy, UpvarSubsts, Region, Ty, Const};
use rustc::ty::{AdtDef, UpvarSubsts, Region, Ty, Const};
use rustc::hir;
use syntax::ast;
use syntax_pos::Span;
@ -268,7 +268,7 @@ pub enum ExprKind<'tcx> {
/// Optional user-given substs: for something like `let x =
/// Bar::<T> { ... }`.
user_ty: Option<CanonicalTy<'tcx>>,
user_ty: Option<UserTypeAnnotation<'tcx>>,
fields: Vec<FieldExprRef<'tcx>>,
base: Option<FruInfo<'tcx>>
@ -276,12 +276,12 @@ pub enum ExprKind<'tcx> {
PlaceTypeAscription {
source: ExprRef<'tcx>,
/// Type that the user gave to this expression
user_ty: CanonicalTy<'tcx>,
user_ty: UserTypeAnnotation<'tcx>,
},
ValueTypeAscription {
source: ExprRef<'tcx>,
/// Type that the user gave to this expression
user_ty: CanonicalTy<'tcx>,
user_ty: UserTypeAnnotation<'tcx>,
},
Closure {
closure_id: DefId,
@ -291,13 +291,7 @@ pub enum ExprKind<'tcx> {
},
Literal {
literal: &'tcx Const<'tcx>,
/// Optional user-given type: for something like
/// `collect::<Vec<_>>`, this would be present and would
/// indicate that `Vec<_>` was explicitly specified.
///
/// Needed for NLL to impose user-given type constraints.
user_ty: Option<CanonicalTy<'tcx>>,
user_ty: Option<UserTypeAnnotation<'tcx>>,
},
InlineAsm {
asm: &'tcx hir::InlineAsm,

View file

@ -20,9 +20,9 @@ use const_eval::{const_field, const_variant_index};
use hair::util::UserAnnotatedTyHelpers;
use rustc::mir::{fmt_const_val, Field, BorrowKind, Mutability};
use rustc::mir::{fmt_const_val, Field, BorrowKind, Mutability, UserTypeAnnotation};
use rustc::mir::interpret::{Scalar, GlobalId, ConstValue, sign_extend};
use rustc::ty::{self, CanonicalTy, TyCtxt, AdtDef, Ty, Region};
use rustc::ty::{self, Region, TyCtxt, AdtDef, Ty};
use rustc::ty::subst::{Substs, Kind};
use rustc::hir::{self, PatKind, RangeEnd};
use rustc::hir::def::{Def, CtorKind};
@ -69,7 +69,7 @@ pub enum PatternKind<'tcx> {
Wild,
AscribeUserType {
user_ty: CanonicalTy<'tcx>,
user_ty: UserTypeAnnotation<'tcx>,
subpattern: Pattern<'tcx>,
user_ty_span: Span,
},
@ -980,7 +980,7 @@ macro_rules! CloneImpls {
CloneImpls!{ <'tcx>
Span, Field, Mutability, ast::Name, ast::NodeId, usize, &'tcx ty::Const<'tcx>,
Region<'tcx>, Ty<'tcx>, BindingMode<'tcx>, &'tcx AdtDef,
&'tcx Substs<'tcx>, &'tcx Kind<'tcx>, CanonicalTy<'tcx>
&'tcx Substs<'tcx>, &'tcx Kind<'tcx>, UserTypeAnnotation<'tcx>
}
impl<'tcx> PatternFoldable<'tcx> for FieldPattern<'tcx> {

View file

@ -9,7 +9,8 @@
// except according to those terms.
use rustc::hir;
use rustc::ty::{self, AdtDef, CanonicalTy, TyCtxt};
use rustc::mir::UserTypeAnnotation;
use rustc::ty::{self, AdtDef, TyCtxt};
crate trait UserAnnotatedTyHelpers<'gcx: 'tcx, 'tcx> {
fn tcx(&self) -> TyCtxt<'_, 'gcx, 'tcx>;
@ -20,32 +21,41 @@ crate trait UserAnnotatedTyHelpers<'gcx: 'tcx, 'tcx> {
&self,
hir_id: hir::HirId,
adt_def: &'tcx AdtDef,
) -> Option<CanonicalTy<'tcx>> {
) -> Option<UserTypeAnnotation<'tcx>> {
let user_substs = self.tables().user_substs(hir_id)?;
Some(user_substs.unchecked_map(|user_substs| {
// Here, we just pair an `AdtDef` with the
// `user_substs`, so no new types etc are introduced.
self.tcx().mk_adt(adt_def, user_substs)
}))
Some(UserTypeAnnotation::Ty(user_substs.unchecked_map(
|user_substs| {
// Here, we just pair an `AdtDef` with the
// `user_substs`, so no new types etc are introduced.
self.tcx().mk_adt(adt_def, user_substs)
},
)))
}
/// Looks up the type associated with this hir-id and applies the
/// user-given substitutions; the hir-id must map to a suitable
/// type.
fn user_substs_applied_to_ty_of_hir_id(&self, hir_id: hir::HirId) -> Option<CanonicalTy<'tcx>> {
fn user_substs_applied_to_ty_of_hir_id(
&self,
hir_id: hir::HirId,
) -> Option<UserTypeAnnotation<'tcx>> {
let user_substs = self.tables().user_substs(hir_id)?;
match &self.tables().node_id_to_type(hir_id).sty {
ty::Adt(adt_def, _) => Some(user_substs.unchecked_map(|user_substs| {
// Ok to call `unchecked_map` because we just pair an
// `AdtDef` with the `user_substs`, so no new types
// etc are introduced.
self.tcx().mk_adt(adt_def, user_substs)
})),
ty::FnDef(def_id, _) => Some(user_substs.unchecked_map(|user_substs| {
// Here, we just pair a `DefId` with the
// `user_substs`, so no new types etc are introduced.
self.tcx().mk_fn_def(*def_id, user_substs)
})),
ty::Adt(adt_def, _) => Some(UserTypeAnnotation::Ty(user_substs.unchecked_map(
|user_substs| {
// Ok to call `unchecked_map` because we just pair an
// `AdtDef` with the `user_substs`, so no new types
// etc are introduced.
self.tcx().mk_adt(adt_def, user_substs)
},
))),
ty::FnDef(def_id, _) => Some(UserTypeAnnotation::Ty(user_substs.unchecked_map(
|user_substs| {
// Here, we just pair a `DefId` with the
// `user_substs`, so no new types etc are introduced.
self.tcx().mk_fn_def(*def_id, user_substs)
},
))),
sty => bug!(
"sty: {:?} should not have user-substs {:?} recorded ",
sty,