Add var to BoundRegion. Add query to get bound vars for applicable items.
This commit is contained in:
parent
666859a6f8
commit
6d5efa9f04
53 changed files with 1274 additions and 385 deletions
|
@ -166,7 +166,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
parent_substs: &[subst::GenericArg<'tcx>],
|
||||
has_self: bool,
|
||||
self_ty: Option<Ty<'tcx>>,
|
||||
arg_count: GenericArgCountResult,
|
||||
arg_count: &GenericArgCountResult,
|
||||
ctx: &mut impl CreateSubstsForGenericArgsCtxt<'a, 'tcx>,
|
||||
) -> SubstsRef<'tcx> {
|
||||
// Collect the segments of the path; we need to substitute arguments
|
||||
|
|
|
@ -210,14 +210,20 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
let r = match tcx.named_region(lifetime.hir_id) {
|
||||
Some(rl::Region::Static) => tcx.lifetimes.re_static,
|
||||
|
||||
Some(rl::Region::LateBound(debruijn, _, id, _)) => {
|
||||
let name = lifetime_name(id.expect_local());
|
||||
let br = ty::BoundRegion { kind: ty::BrNamed(id, name) };
|
||||
Some(rl::Region::LateBound(debruijn, index, def_id, _)) => {
|
||||
let name = lifetime_name(def_id.expect_local());
|
||||
let br = ty::BoundRegion {
|
||||
var: ty::BoundVar::from_u32(index),
|
||||
kind: ty::BrNamed(def_id, name),
|
||||
};
|
||||
tcx.mk_region(ty::ReLateBound(debruijn, br))
|
||||
}
|
||||
|
||||
Some(rl::Region::LateBoundAnon(debruijn, _index, anon_index)) => {
|
||||
let br = ty::BoundRegion { kind: ty::BrAnon(anon_index) };
|
||||
Some(rl::Region::LateBoundAnon(debruijn, index, anon_index)) => {
|
||||
let br = ty::BoundRegion {
|
||||
var: ty::BoundVar::from_u32(index),
|
||||
kind: ty::BrAnon(anon_index),
|
||||
};
|
||||
tcx.mk_region(ty::ReLateBound(debruijn, br))
|
||||
}
|
||||
|
||||
|
@ -266,7 +272,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
def_id: DefId,
|
||||
item_segment: &hir::PathSegment<'_>,
|
||||
) -> SubstsRef<'tcx> {
|
||||
let (substs, assoc_bindings, _) = self.create_substs_for_ast_path(
|
||||
let (substs, _) = self.create_substs_for_ast_path(
|
||||
span,
|
||||
def_id,
|
||||
&[],
|
||||
|
@ -275,6 +281,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
item_segment.infer_args,
|
||||
None,
|
||||
);
|
||||
let assoc_bindings = self.create_assoc_bindings_for_generic_args(item_segment.args());
|
||||
|
||||
if let Some(b) = assoc_bindings.first() {
|
||||
Self::prohibit_assoc_ty_binding(self.tcx(), b.span);
|
||||
|
@ -314,6 +321,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
/// `[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]`.
|
||||
#[tracing::instrument(level = "debug", skip(self, span))]
|
||||
fn create_substs_for_ast_path<'a>(
|
||||
&self,
|
||||
span: Span,
|
||||
|
@ -323,15 +331,10 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
generic_args: &'a hir::GenericArgs<'_>,
|
||||
infer_args: bool,
|
||||
self_ty: Option<Ty<'tcx>>,
|
||||
) -> (SubstsRef<'tcx>, Vec<ConvertedBinding<'a, 'tcx>>, GenericArgCountResult) {
|
||||
) -> (SubstsRef<'tcx>, GenericArgCountResult) {
|
||||
// If the type is parameterized by this region, then replace this
|
||||
// region with the current anon region binding (in other words,
|
||||
// whatever & would get replaced with).
|
||||
debug!(
|
||||
"create_substs_for_ast_path(def_id={:?}, self_ty={:?}, \
|
||||
generic_args={:?})",
|
||||
def_id, self_ty, generic_args
|
||||
);
|
||||
|
||||
let tcx = self.tcx();
|
||||
let generics = tcx.generics_of(def_id);
|
||||
|
@ -367,7 +370,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
// here and so associated type bindings will be handled regardless of whether there are any
|
||||
// non-`Self` generic parameters.
|
||||
if generics.params.len() == 0 {
|
||||
return (tcx.intern_substs(&[]), vec![], arg_count);
|
||||
return (tcx.intern_substs(&[]), arg_count);
|
||||
}
|
||||
|
||||
let is_object = self_ty.map_or(false, |ty| ty == self.tcx().types.trait_object_dummy_self);
|
||||
|
@ -540,7 +543,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
parent_substs,
|
||||
self_ty.is_some(),
|
||||
self_ty,
|
||||
arg_count.clone(),
|
||||
&arg_count,
|
||||
&mut substs_ctx,
|
||||
);
|
||||
|
||||
|
@ -551,6 +554,18 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
generic_args.args.is_empty(),
|
||||
);
|
||||
|
||||
debug!(
|
||||
"create_substs_for_ast_path(generic_params={:?}, self_ty={:?}) -> {:?}",
|
||||
generics, self_ty, substs
|
||||
);
|
||||
|
||||
(substs, arg_count)
|
||||
}
|
||||
|
||||
fn create_assoc_bindings_for_generic_args<'a>(
|
||||
&self,
|
||||
generic_args: &'a hir::GenericArgs<'_>,
|
||||
) -> Vec<ConvertedBinding<'a, 'tcx>> {
|
||||
// Convert associated-type bindings or constraints into a separate vector.
|
||||
// Example: Given this:
|
||||
//
|
||||
|
@ -581,12 +596,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
})
|
||||
.collect();
|
||||
|
||||
debug!(
|
||||
"create_substs_for_ast_path(generic_params={:?}, self_ty={:?}) -> {:?}",
|
||||
generics, self_ty, substs
|
||||
);
|
||||
|
||||
(substs, assoc_bindings, arg_count)
|
||||
assoc_bindings
|
||||
}
|
||||
|
||||
crate fn create_substs_for_associated_item(
|
||||
|
@ -636,55 +646,6 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
)
|
||||
}
|
||||
|
||||
/// The given trait-ref must actually be a trait.
|
||||
pub(super) fn instantiate_poly_trait_ref_inner(
|
||||
&self,
|
||||
trait_ref: &hir::TraitRef<'_>,
|
||||
span: Span,
|
||||
constness: Constness,
|
||||
self_ty: Ty<'tcx>,
|
||||
bounds: &mut Bounds<'tcx>,
|
||||
speculative: bool,
|
||||
) -> GenericArgCountResult {
|
||||
let trait_def_id = trait_ref.trait_def_id().unwrap_or_else(|| FatalError.raise());
|
||||
|
||||
debug!("instantiate_poly_trait_ref({:?}, def_id={:?})", trait_ref, trait_def_id);
|
||||
|
||||
self.prohibit_generics(trait_ref.path.segments.split_last().unwrap().1);
|
||||
|
||||
let (substs, assoc_bindings, arg_count) = self.create_substs_for_ast_trait_ref(
|
||||
trait_ref.path.span,
|
||||
trait_def_id,
|
||||
self_ty,
|
||||
trait_ref.path.segments.last().unwrap(),
|
||||
);
|
||||
let poly_trait_ref = ty::Binder::bind(ty::TraitRef::new(trait_def_id, substs), self.tcx());
|
||||
|
||||
bounds.trait_bounds.push((poly_trait_ref, span, constness));
|
||||
|
||||
let mut dup_bindings = FxHashMap::default();
|
||||
for binding in &assoc_bindings {
|
||||
// Specify type to assert that error was already reported in `Err` case.
|
||||
let _: Result<_, ErrorReported> = self.add_predicates_for_ast_type_binding(
|
||||
trait_ref.hir_ref_id,
|
||||
poly_trait_ref,
|
||||
binding,
|
||||
bounds,
|
||||
speculative,
|
||||
&mut dup_bindings,
|
||||
binding.span,
|
||||
);
|
||||
// Okay to ignore `Err` because of `ErrorReported` (see above).
|
||||
}
|
||||
|
||||
debug!(
|
||||
"instantiate_poly_trait_ref({:?}, bounds={:?}) -> {:?}",
|
||||
trait_ref, bounds, poly_trait_ref
|
||||
);
|
||||
|
||||
arg_count
|
||||
}
|
||||
|
||||
/// 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`.
|
||||
|
@ -704,21 +665,55 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
/// 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.
|
||||
#[tracing::instrument(level = "debug", skip(self, span, constness, bounds, speculative))]
|
||||
pub fn instantiate_poly_trait_ref(
|
||||
&self,
|
||||
poly_trait_ref: &hir::PolyTraitRef<'_>,
|
||||
trait_ref: &hir::TraitRef<'_>,
|
||||
span: Span,
|
||||
constness: Constness,
|
||||
self_ty: Ty<'tcx>,
|
||||
bounds: &mut Bounds<'tcx>,
|
||||
speculative: bool,
|
||||
) -> GenericArgCountResult {
|
||||
self.instantiate_poly_trait_ref_inner(
|
||||
&poly_trait_ref.trait_ref,
|
||||
poly_trait_ref.span,
|
||||
constness,
|
||||
let trait_def_id = trait_ref.trait_def_id().unwrap_or_else(|| FatalError.raise());
|
||||
|
||||
self.prohibit_generics(trait_ref.path.segments.split_last().unwrap().1);
|
||||
|
||||
let tcx = self.tcx();
|
||||
let bound_vars = tcx.late_bound_vars(trait_ref.hir_ref_id);
|
||||
debug!(?bound_vars);
|
||||
|
||||
let (substs, arg_count) = self.create_substs_for_ast_trait_ref(
|
||||
trait_ref.path.span,
|
||||
trait_def_id,
|
||||
self_ty,
|
||||
bounds,
|
||||
false,
|
||||
)
|
||||
trait_ref.path.segments.last().unwrap(),
|
||||
);
|
||||
let assoc_bindings = self
|
||||
.create_assoc_bindings_for_generic_args(trait_ref.path.segments.last().unwrap().args());
|
||||
|
||||
let poly_trait_ref =
|
||||
ty::Binder::bind_with_vars(ty::TraitRef::new(trait_def_id, substs), bound_vars);
|
||||
|
||||
debug!(?poly_trait_ref, ?assoc_bindings);
|
||||
bounds.trait_bounds.push((poly_trait_ref, span, constness));
|
||||
|
||||
let mut dup_bindings = FxHashMap::default();
|
||||
for binding in &assoc_bindings {
|
||||
// Specify type to assert that error was already reported in `Err` case.
|
||||
let _: Result<_, ErrorReported> = self.add_predicates_for_ast_type_binding(
|
||||
trait_ref.hir_ref_id,
|
||||
poly_trait_ref,
|
||||
binding,
|
||||
bounds,
|
||||
speculative,
|
||||
&mut dup_bindings,
|
||||
binding.span,
|
||||
);
|
||||
// Okay to ignore `Err` because of `ErrorReported` (see above).
|
||||
}
|
||||
|
||||
arg_count
|
||||
}
|
||||
|
||||
pub fn instantiate_lang_item_trait_ref(
|
||||
|
@ -732,7 +727,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
) {
|
||||
let trait_def_id = self.tcx().require_lang_item(lang_item, Some(span));
|
||||
|
||||
let (substs, assoc_bindings, _) = self.create_substs_for_ast_path(
|
||||
let (substs, _) = self.create_substs_for_ast_path(
|
||||
span,
|
||||
trait_def_id,
|
||||
&[],
|
||||
|
@ -741,7 +736,11 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
false,
|
||||
Some(self_ty),
|
||||
);
|
||||
let poly_trait_ref = ty::Binder::bind(ty::TraitRef::new(trait_def_id, substs), self.tcx());
|
||||
let assoc_bindings = self.create_assoc_bindings_for_generic_args(args);
|
||||
let tcx = self.tcx();
|
||||
let bound_vars = tcx.late_bound_vars(hir_id);
|
||||
let poly_trait_ref =
|
||||
ty::Binder::bind_with_vars(ty::TraitRef::new(trait_def_id, substs), bound_vars);
|
||||
bounds.trait_bounds.push((poly_trait_ref, span, Constness::NotConst));
|
||||
|
||||
let mut dup_bindings = FxHashMap::default();
|
||||
|
@ -765,23 +764,23 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
self_ty: Ty<'tcx>,
|
||||
trait_segment: &hir::PathSegment<'_>,
|
||||
) -> ty::TraitRef<'tcx> {
|
||||
let (substs, assoc_bindings, _) =
|
||||
let (substs, _) =
|
||||
self.create_substs_for_ast_trait_ref(span, trait_def_id, self_ty, trait_segment);
|
||||
let assoc_bindings = self.create_assoc_bindings_for_generic_args(trait_segment.args());
|
||||
if let Some(b) = assoc_bindings.first() {
|
||||
Self::prohibit_assoc_ty_binding(self.tcx(), b.span);
|
||||
}
|
||||
ty::TraitRef::new(trait_def_id, substs)
|
||||
}
|
||||
|
||||
#[tracing::instrument(level = "debug", skip(self, span))]
|
||||
fn create_substs_for_ast_trait_ref<'a>(
|
||||
&self,
|
||||
span: Span,
|
||||
trait_def_id: DefId,
|
||||
self_ty: Ty<'tcx>,
|
||||
trait_segment: &'a hir::PathSegment<'a>,
|
||||
) -> (SubstsRef<'tcx>, Vec<ConvertedBinding<'a, 'tcx>>, GenericArgCountResult) {
|
||||
debug!("create_substs_for_ast_trait_ref(trait_segment={:?})", trait_segment);
|
||||
|
||||
) -> (SubstsRef<'tcx>, GenericArgCountResult) {
|
||||
self.complain_about_internal_fn_trait(span, trait_def_id, trait_segment);
|
||||
|
||||
self.create_substs_for_ast_path(
|
||||
|
@ -803,7 +802,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
}
|
||||
|
||||
// Returns `true` if a bounds list includes `?Sized`.
|
||||
pub fn is_unsized(&self, ast_bounds: &[&hir::GenericBound<'_>], span: Span) -> bool {
|
||||
pub fn is_unsized(&self, ast_bounds: &[hir::GenericBound<'_>], span: Span) -> bool {
|
||||
let tcx = self.tcx();
|
||||
|
||||
// Try to find an unbound in bounds.
|
||||
|
@ -858,28 +857,44 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
/// **A note on binders:** there is an implied binder around
|
||||
/// `param_ty` and `ast_bounds`. See `instantiate_poly_trait_ref`
|
||||
/// for more details.
|
||||
#[tracing::instrument(level = "debug", skip(self, bounds))]
|
||||
fn add_bounds(
|
||||
&self,
|
||||
param_ty: Ty<'tcx>,
|
||||
ast_bounds: &[&hir::GenericBound<'_>],
|
||||
ast_bounds: &[hir::GenericBound<'_>],
|
||||
bounds: &mut Bounds<'tcx>,
|
||||
bound_vars: &'tcx ty::List<ty::BoundVariableKind>,
|
||||
) {
|
||||
let constness = self.default_constness_for_trait_bounds();
|
||||
for ast_bound in ast_bounds {
|
||||
match *ast_bound {
|
||||
hir::GenericBound::Trait(ref b, hir::TraitBoundModifier::None) => {
|
||||
self.instantiate_poly_trait_ref(b, constness, param_ty, bounds);
|
||||
self.instantiate_poly_trait_ref(
|
||||
&b.trait_ref,
|
||||
b.span,
|
||||
constness,
|
||||
param_ty,
|
||||
bounds,
|
||||
false,
|
||||
);
|
||||
}
|
||||
hir::GenericBound::Trait(ref b, hir::TraitBoundModifier::MaybeConst) => {
|
||||
self.instantiate_poly_trait_ref(b, Constness::NotConst, param_ty, bounds);
|
||||
self.instantiate_poly_trait_ref(
|
||||
&b.trait_ref,
|
||||
b.span,
|
||||
Constness::NotConst,
|
||||
param_ty,
|
||||
bounds,
|
||||
false,
|
||||
);
|
||||
}
|
||||
hir::GenericBound::Trait(_, hir::TraitBoundModifier::Maybe) => {}
|
||||
hir::GenericBound::LangItemTrait(lang_item, span, hir_id, args) => self
|
||||
.instantiate_lang_item_trait_ref(
|
||||
*lang_item, *span, *hir_id, args, param_ty, bounds,
|
||||
lang_item, span, hir_id, args, param_ty, bounds,
|
||||
),
|
||||
hir::GenericBound::Outlives(ref l) => bounds.region_bounds.push((
|
||||
ty::Binder::bind(self.ast_region_to_region(l, None), self.tcx()),
|
||||
ty::Binder::bind_with_vars(self.ast_region_to_region(l, None), bound_vars),
|
||||
l.span,
|
||||
)),
|
||||
}
|
||||
|
@ -909,7 +924,6 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
sized_by_default: SizedByDefault,
|
||||
span: Span,
|
||||
) -> Bounds<'tcx> {
|
||||
let ast_bounds: Vec<_> = ast_bounds.iter().collect();
|
||||
self.compute_bounds_inner(param_ty, &ast_bounds, sized_by_default, span)
|
||||
}
|
||||
|
||||
|
@ -929,7 +943,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
if let Some(trait_ref) = ast_bound.trait_ref() {
|
||||
if let Some(trait_did) = trait_ref.trait_def_id() {
|
||||
if self.tcx().trait_may_define_assoc_type(trait_did, assoc_name) {
|
||||
result.push(ast_bound);
|
||||
result.push(ast_bound.clone());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -941,13 +955,13 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
fn compute_bounds_inner(
|
||||
&self,
|
||||
param_ty: Ty<'tcx>,
|
||||
ast_bounds: &[&hir::GenericBound<'_>],
|
||||
ast_bounds: &[hir::GenericBound<'_>],
|
||||
sized_by_default: SizedByDefault,
|
||||
span: Span,
|
||||
) -> Bounds<'tcx> {
|
||||
let mut bounds = Bounds::default();
|
||||
|
||||
self.add_bounds(param_ty, ast_bounds, &mut bounds);
|
||||
self.add_bounds(param_ty, ast_bounds, &mut bounds, ty::List::empty());
|
||||
|
||||
bounds.implicitly_sized = if let SizedByDefault::Yes = sized_by_default {
|
||||
if !self.is_unsized(ast_bounds, span) { Some(span) } else { None }
|
||||
|
@ -964,6 +978,10 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
/// **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.
|
||||
#[tracing::instrument(
|
||||
level = "debug",
|
||||
skip(self, bounds, speculative, dup_bindings, path_span)
|
||||
)]
|
||||
fn add_predicates_for_ast_type_binding(
|
||||
&self,
|
||||
hir_ref_id: hir::HirId,
|
||||
|
@ -990,7 +1008,6 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
//
|
||||
// We want to produce `<B as SuperTrait<i32>>::T == foo`.
|
||||
|
||||
debug!(?hir_ref_id, ?trait_ref, ?binding, ?bounds, "add_predicates_for_ast_type_binding",);
|
||||
let tcx = self.tcx();
|
||||
|
||||
let candidate =
|
||||
|
@ -1140,10 +1157,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
//
|
||||
// Calling `skip_binder` is okay, because `add_bounds` expects the `param_ty`
|
||||
// parameter to have a skipped binder.
|
||||
let param_ty =
|
||||
tcx.mk_projection(assoc_ty.def_id, projection_ty.skip_binder().substs);
|
||||
let ast_bounds: Vec<_> = ast_bounds.iter().collect();
|
||||
self.add_bounds(param_ty, &ast_bounds, bounds);
|
||||
let param_ty = tcx.mk_ty(ty::Projection(projection_ty.skip_binder()));
|
||||
self.add_bounds(param_ty, ast_bounds, bounds, candidate.bound_vars());
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
|
@ -1177,10 +1192,12 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
Err(GenericArgCountMismatch { invalid_args: cur_potential_assoc_types, .. }),
|
||||
..
|
||||
} = self.instantiate_poly_trait_ref(
|
||||
trait_bound,
|
||||
&trait_bound.trait_ref,
|
||||
trait_bound.span,
|
||||
Constness::NotConst,
|
||||
dummy_self,
|
||||
&mut bounds,
|
||||
false,
|
||||
) {
|
||||
potential_assoc_types.extend(cur_potential_assoc_types);
|
||||
}
|
||||
|
@ -2169,12 +2186,13 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
}
|
||||
}
|
||||
|
||||
/// Parses the programmer's textual representation of a type into our
|
||||
/// internal notion of a type.
|
||||
pub fn ast_ty_to_ty(&self, ast_ty: &hir::Ty<'_>) -> Ty<'tcx> {
|
||||
self.ast_ty_to_ty_inner(ast_ty, false)
|
||||
}
|
||||
|
||||
/// Parses the programmer's textual representation of a type into our
|
||||
/// internal notion of a type.
|
||||
///
|
||||
/// 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.
|
||||
#[tracing::instrument(level = "debug", skip(self))]
|
||||
|
@ -2200,6 +2218,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
require_c_abi_if_c_variadic(tcx, &bf.decl, bf.abi, ast_ty.span);
|
||||
|
||||
tcx.mk_fn_ptr(self.ty_of_fn(
|
||||
ast_ty.hir_id,
|
||||
bf.unsafety,
|
||||
bf.abi,
|
||||
&bf.decl,
|
||||
|
@ -2242,7 +2261,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
}
|
||||
hir::TyKind::Path(hir::QPath::LangItem(lang_item, span)) => {
|
||||
let def_id = tcx.require_lang_item(lang_item, Some(span));
|
||||
let (substs, _, _) = self.create_substs_for_ast_path(
|
||||
let (substs, _) = self.create_substs_for_ast_path(
|
||||
span,
|
||||
def_id,
|
||||
&[],
|
||||
|
@ -2279,7 +2298,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
result_ty
|
||||
}
|
||||
|
||||
pub fn impl_trait_ty_to_ty(
|
||||
fn impl_trait_ty_to_ty(
|
||||
&self,
|
||||
def_id: DefId,
|
||||
lifetimes: &[hir::GenericArg<'_>],
|
||||
|
@ -2340,6 +2359,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
|
||||
pub fn ty_of_fn(
|
||||
&self,
|
||||
hir_id: hir::HirId,
|
||||
unsafety: hir::Unsafety,
|
||||
abi: abi::Abi,
|
||||
decl: &hir::FnDecl<'_>,
|
||||
|
@ -2350,6 +2370,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
debug!("ty_of_fn");
|
||||
|
||||
let tcx = self.tcx();
|
||||
let bound_vars = tcx.late_bound_vars(hir_id);
|
||||
debug!(?bound_vars);
|
||||
|
||||
// We proactively collect all the inferred type params to emit a single error per fn def.
|
||||
let mut visitor = PlaceholderHirTyCollector::default();
|
||||
|
@ -2369,10 +2391,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
|
||||
debug!("ty_of_fn: output_ty={:?}", output_ty);
|
||||
|
||||
let bare_fn_ty = ty::Binder::bind(
|
||||
tcx.mk_fn_sig(input_tys, output_ty, decl.c_variadic, unsafety, abi),
|
||||
tcx,
|
||||
);
|
||||
let fn_ty = tcx.mk_fn_sig(input_tys, output_ty, decl.c_variadic, unsafety, abi);
|
||||
let bare_fn_ty = ty::Binder::bind_with_vars(fn_ty, bound_vars);
|
||||
|
||||
if !self.allow_ty_infer() {
|
||||
// We always collect the spans for placeholder types when evaluating `fn`s, but we
|
||||
|
|
|
@ -69,7 +69,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
let expr_def_id = self.tcx.hir().local_def_id(expr.hir_id);
|
||||
|
||||
let ClosureSignatures { bound_sig, liberated_sig } =
|
||||
self.sig_of_closure(expr_def_id.to_def_id(), decl, body, expected_sig);
|
||||
self.sig_of_closure(expr.hir_id, expr_def_id.to_def_id(), decl, body, expected_sig);
|
||||
|
||||
debug!("check_closure: ty_of_closure returns {:?}", liberated_sig);
|
||||
|
||||
|
@ -288,15 +288,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
|
||||
fn sig_of_closure(
|
||||
&self,
|
||||
hir_id: hir::HirId,
|
||||
expr_def_id: DefId,
|
||||
decl: &hir::FnDecl<'_>,
|
||||
body: &hir::Body<'_>,
|
||||
expected_sig: Option<ExpectedSig<'tcx>>,
|
||||
) -> ClosureSignatures<'tcx> {
|
||||
if let Some(e) = expected_sig {
|
||||
self.sig_of_closure_with_expectation(expr_def_id, decl, body, e)
|
||||
self.sig_of_closure_with_expectation(hir_id, expr_def_id, decl, body, e)
|
||||
} else {
|
||||
self.sig_of_closure_no_expectation(expr_def_id, decl, body)
|
||||
self.sig_of_closure_no_expectation(hir_id, expr_def_id, decl, body)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -304,13 +305,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
/// types that the user gave into a signature.
|
||||
fn sig_of_closure_no_expectation(
|
||||
&self,
|
||||
hir_id: hir::HirId,
|
||||
expr_def_id: DefId,
|
||||
decl: &hir::FnDecl<'_>,
|
||||
body: &hir::Body<'_>,
|
||||
) -> ClosureSignatures<'tcx> {
|
||||
debug!("sig_of_closure_no_expectation()");
|
||||
|
||||
let bound_sig = self.supplied_sig_of_closure(expr_def_id, decl, body);
|
||||
let bound_sig = self.supplied_sig_of_closure(hir_id, expr_def_id, decl, body);
|
||||
|
||||
self.closure_sigs(expr_def_id, body, bound_sig)
|
||||
}
|
||||
|
@ -364,6 +366,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
/// regions with depth 1, which are bound then by the closure.
|
||||
fn sig_of_closure_with_expectation(
|
||||
&self,
|
||||
hir_id: hir::HirId,
|
||||
expr_def_id: DefId,
|
||||
decl: &hir::FnDecl<'_>,
|
||||
body: &hir::Body<'_>,
|
||||
|
@ -375,7 +378,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
// expectation if things don't see to match up with what we
|
||||
// expect.
|
||||
if expected_sig.sig.c_variadic() != decl.c_variadic {
|
||||
return self.sig_of_closure_no_expectation(expr_def_id, decl, body);
|
||||
return self.sig_of_closure_no_expectation(hir_id, expr_def_id, decl, body);
|
||||
} else if expected_sig.sig.skip_binder().inputs_and_output.len() != decl.inputs.len() + 1 {
|
||||
return self.sig_of_closure_with_mismatched_number_of_arguments(
|
||||
expr_def_id,
|
||||
|
@ -411,9 +414,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
// Along the way, it also writes out entries for types that the user
|
||||
// wrote into our typeck results, which are then later used by the privacy
|
||||
// check.
|
||||
match self.check_supplied_sig_against_expectation(expr_def_id, decl, body, &closure_sigs) {
|
||||
match self.check_supplied_sig_against_expectation(
|
||||
hir_id,
|
||||
expr_def_id,
|
||||
decl,
|
||||
body,
|
||||
&closure_sigs,
|
||||
) {
|
||||
Ok(infer_ok) => self.register_infer_ok_obligations(infer_ok),
|
||||
Err(_) => return self.sig_of_closure_no_expectation(expr_def_id, decl, body),
|
||||
Err(_) => return self.sig_of_closure_no_expectation(hir_id, expr_def_id, decl, body),
|
||||
}
|
||||
|
||||
closure_sigs
|
||||
|
@ -460,6 +469,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
/// strategy.
|
||||
fn check_supplied_sig_against_expectation(
|
||||
&self,
|
||||
hir_id: hir::HirId,
|
||||
expr_def_id: DefId,
|
||||
decl: &hir::FnDecl<'_>,
|
||||
body: &hir::Body<'_>,
|
||||
|
@ -469,7 +479,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
//
|
||||
// (See comment on `sig_of_closure_with_expectation` for the
|
||||
// meaning of these letters.)
|
||||
let supplied_sig = self.supplied_sig_of_closure(expr_def_id, decl, body);
|
||||
let supplied_sig = self.supplied_sig_of_closure(hir_id, expr_def_id, decl, body);
|
||||
|
||||
debug!("check_supplied_sig_against_expectation: supplied_sig={:?}", supplied_sig);
|
||||
|
||||
|
@ -534,6 +544,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
/// Also, record this closure signature for later.
|
||||
fn supplied_sig_of_closure(
|
||||
&self,
|
||||
hir_id: hir::HirId,
|
||||
expr_def_id: DefId,
|
||||
decl: &hir::FnDecl<'_>,
|
||||
body: &hir::Body<'_>,
|
||||
|
@ -545,6 +556,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
decl, body.generator_kind,
|
||||
);
|
||||
|
||||
let bound_vars = self.tcx.late_bound_vars(hir_id);
|
||||
|
||||
// First, convert the types that the user supplied (if any).
|
||||
let supplied_arguments = decl.inputs.iter().map(|a| astconv.ast_ty_to_ty(a));
|
||||
let supplied_return = match decl.output {
|
||||
|
@ -571,7 +584,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
},
|
||||
};
|
||||
|
||||
let result = ty::Binder::bind(
|
||||
let result = ty::Binder::bind_with_vars(
|
||||
self.tcx.mk_fn_sig(
|
||||
supplied_arguments,
|
||||
supplied_return,
|
||||
|
@ -579,7 +592,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
hir::Unsafety::Normal,
|
||||
Abi::RustCall,
|
||||
),
|
||||
self.tcx,
|
||||
bound_vars,
|
||||
);
|
||||
|
||||
debug!("supplied_sig_of_closure: result={:?}", result);
|
||||
|
|
|
@ -1462,7 +1462,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
&[][..],
|
||||
has_self,
|
||||
self_ty,
|
||||
arg_count,
|
||||
&arg_count,
|
||||
&mut CreateCtorSubstsContext {
|
||||
fcx: self,
|
||||
span,
|
||||
|
|
|
@ -186,7 +186,10 @@ pub fn resolve_interior<'a, 'tcx>(
|
|||
// which means that none of the regions inside relate to any other, even if
|
||||
// typeck had previously found constraints that would cause them to be related.
|
||||
let folded = fcx.tcx.fold_regions(erased, &mut false, |_, current_depth| {
|
||||
let br = ty::BoundRegion { kind: ty::BrAnon(counter) };
|
||||
let br = ty::BoundRegion {
|
||||
var: ty::BoundVar::from_u32(counter),
|
||||
kind: ty::BrAnon(counter),
|
||||
};
|
||||
let r = fcx.tcx.mk_region(ty::ReLateBound(current_depth, br));
|
||||
counter += 1;
|
||||
r
|
||||
|
@ -202,11 +205,15 @@ pub fn resolve_interior<'a, 'tcx>(
|
|||
|
||||
// Extract type components to build the witness type.
|
||||
let type_list = fcx.tcx.mk_type_list(type_causes.iter().map(|cause| cause.ty));
|
||||
let witness = fcx.tcx.mk_generator_witness(ty::Binder::bind(type_list, fcx.tcx));
|
||||
let bound_vars = fcx.tcx.mk_bound_variable_kinds(
|
||||
(0..counter).map(|i| ty::BoundVariableKind::Region(ty::BrAnon(i))),
|
||||
);
|
||||
let witness =
|
||||
fcx.tcx.mk_generator_witness(ty::Binder::bind_with_vars(type_list, bound_vars.clone()));
|
||||
|
||||
// Store the generator types and spans into the typeck results for this generator.
|
||||
visitor.fcx.inh.typeck_results.borrow_mut().generator_interior_types =
|
||||
ty::Binder::bind(type_causes, fcx.tcx);
|
||||
ty::Binder::bind_with_vars(type_causes, bound_vars);
|
||||
|
||||
debug!(
|
||||
"types in generator after region replacement {:?}, span = {:?}",
|
||||
|
|
|
@ -101,12 +101,21 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
|
|||
let intrinsic_name = tcx.item_name(it.def_id.to_def_id());
|
||||
let name_str = intrinsic_name.as_str();
|
||||
|
||||
let bound_vars = tcx.mk_bound_variable_kinds(
|
||||
[ty::BoundVariableKind::Region(ty::BrAnon(0)), ty::BoundVariableKind::Region(ty::BrEnv)]
|
||||
.iter()
|
||||
.copied(),
|
||||
);
|
||||
let mk_va_list_ty = |mutbl| {
|
||||
tcx.lang_items().va_list().map(|did| {
|
||||
let region = tcx
|
||||
.mk_region(ty::ReLateBound(ty::INNERMOST, ty::BoundRegion { kind: ty::BrAnon(0) }));
|
||||
let env_region =
|
||||
tcx.mk_region(ty::ReLateBound(ty::INNERMOST, ty::BoundRegion { kind: ty::BrEnv }));
|
||||
let region = tcx.mk_region(ty::ReLateBound(
|
||||
ty::INNERMOST,
|
||||
ty::BoundRegion { var: ty::BoundVar::from_u32(0), kind: ty::BrAnon(0) },
|
||||
));
|
||||
let env_region = tcx.mk_region(ty::ReLateBound(
|
||||
ty::INNERMOST,
|
||||
ty::BoundRegion { var: ty::BoundVar::from_u32(1), kind: ty::BrEnv },
|
||||
));
|
||||
let va_list_ty = tcx.type_of(did).subst(tcx, &[region.into()]);
|
||||
(tcx.mk_ref(env_region, ty::TypeAndMut { ty: va_list_ty, mutbl }), va_list_ty)
|
||||
})
|
||||
|
@ -305,7 +314,7 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
|
|||
tcx.associated_items(tcx.lang_items().discriminant_kind_trait().unwrap());
|
||||
let discriminant_def_id = assoc_items.in_definition_order().next().unwrap().def_id;
|
||||
|
||||
let br = ty::BoundRegion { kind: ty::BrAnon(0) };
|
||||
let br = ty::BoundRegion { var: ty::BoundVar::from_u32(0), kind: ty::BrAnon(0) };
|
||||
(
|
||||
1,
|
||||
vec![
|
||||
|
@ -366,7 +375,7 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
|
|||
(n_tps, inputs, output, unsafety)
|
||||
};
|
||||
let sig = tcx.mk_fn_sig(inputs.into_iter(), output, false, unsafety, Abi::RustIntrinsic);
|
||||
let sig = ty::Binder::bind(sig, tcx);
|
||||
let sig = ty::Binder::bind_with_vars(sig, bound_vars);
|
||||
equate_intrinsic_type(tcx, it, n_tps, sig)
|
||||
}
|
||||
|
||||
|
|
|
@ -381,7 +381,7 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
|
|||
parent_substs,
|
||||
false,
|
||||
None,
|
||||
arg_count_correct,
|
||||
&arg_count_correct,
|
||||
&mut MethodSubstsCtxt { cfcx: self, pick, seg },
|
||||
)
|
||||
}
|
||||
|
|
|
@ -497,6 +497,7 @@ fn typeck_with_fallback<'tcx>(
|
|||
let fcx = FnCtxt::new(&inh, param_env, body.value.hir_id);
|
||||
<dyn AstConv<'_>>::ty_of_fn(
|
||||
&fcx,
|
||||
id,
|
||||
header.unsafety,
|
||||
header.abi,
|
||||
decl,
|
||||
|
|
|
@ -1712,6 +1712,7 @@ fn fn_sig(tcx: TyCtxt<'_>, def_id: DefId) -> ty::PolyFnSig<'_> {
|
|||
}
|
||||
None => <dyn AstConv<'_>>::ty_of_fn(
|
||||
&icx,
|
||||
hir_id,
|
||||
sig.header.unsafety,
|
||||
sig.header.abi,
|
||||
&sig.decl,
|
||||
|
@ -1729,6 +1730,7 @@ fn fn_sig(tcx: TyCtxt<'_>, def_id: DefId) -> ty::PolyFnSig<'_> {
|
|||
..
|
||||
}) => <dyn AstConv<'_>>::ty_of_fn(
|
||||
&icx,
|
||||
hir_id,
|
||||
header.unsafety,
|
||||
header.abi,
|
||||
decl,
|
||||
|
@ -2082,6 +2084,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericP
|
|||
match predicate {
|
||||
hir::WherePredicate::BoundPredicate(bound_pred) => {
|
||||
let ty = icx.to_ty(&bound_pred.bounded_ty);
|
||||
let bound_vars = icx.tcx.late_bound_vars(bound_pred.bounded_ty.hir_id);
|
||||
|
||||
// Keep the type around in a dummy predicate, in case of no bounds.
|
||||
// That way, `where Ty:` is not a complete noop (see #53696) and `Ty`
|
||||
|
@ -2097,12 +2100,12 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericP
|
|||
} else {
|
||||
let span = bound_pred.bounded_ty.span;
|
||||
let re_root_empty = tcx.lifetimes.re_root_empty;
|
||||
let predicate = ty::Binder::bind(
|
||||
let predicate = ty::Binder::bind_with_vars(
|
||||
ty::PredicateKind::TypeOutlives(ty::OutlivesPredicate(
|
||||
ty,
|
||||
re_root_empty,
|
||||
)),
|
||||
tcx,
|
||||
bound_vars,
|
||||
);
|
||||
predicates.insert((predicate.to_predicate(tcx), span));
|
||||
}
|
||||
|
@ -2120,10 +2123,12 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericP
|
|||
let mut bounds = Bounds::default();
|
||||
let _ = <dyn AstConv<'_>>::instantiate_poly_trait_ref(
|
||||
&icx,
|
||||
&poly_trait_ref,
|
||||
&poly_trait_ref.trait_ref,
|
||||
poly_trait_ref.span,
|
||||
constness,
|
||||
ty,
|
||||
&mut bounds,
|
||||
false,
|
||||
);
|
||||
predicates.extend(bounds.predicates(tcx, ty));
|
||||
}
|
||||
|
@ -2146,11 +2151,11 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericP
|
|||
let region =
|
||||
<dyn AstConv<'_>>::ast_region_to_region(&icx, lifetime, None);
|
||||
predicates.insert((
|
||||
ty::Binder::bind(
|
||||
ty::Binder::bind_with_vars(
|
||||
ty::PredicateKind::TypeOutlives(ty::OutlivesPredicate(
|
||||
ty, region,
|
||||
)),
|
||||
tcx,
|
||||
bound_vars,
|
||||
)
|
||||
.to_predicate(tcx),
|
||||
lifetime.span,
|
||||
|
@ -2373,7 +2378,14 @@ fn predicates_from_bound<'tcx>(
|
|||
};
|
||||
|
||||
let mut bounds = Bounds::default();
|
||||
let _ = astconv.instantiate_poly_trait_ref(tr, constness, param_ty, &mut bounds);
|
||||
let _ = astconv.instantiate_poly_trait_ref(
|
||||
&tr.trait_ref,
|
||||
tr.span,
|
||||
constness,
|
||||
param_ty,
|
||||
&mut bounds,
|
||||
false,
|
||||
);
|
||||
bounds.predicates(astconv.tcx(), param_ty)
|
||||
}
|
||||
hir::GenericBound::LangItemTrait(lang_item, span, hir_id, args) => {
|
||||
|
@ -2409,8 +2421,10 @@ fn compute_sig_of_foreign_fn_decl<'tcx>(
|
|||
} else {
|
||||
hir::Unsafety::Unsafe
|
||||
};
|
||||
let hir_id = tcx.hir().local_def_id_to_hir_id(def_id.expect_local());
|
||||
let fty = <dyn AstConv<'_>>::ty_of_fn(
|
||||
&ItemCtxt::new(tcx, def_id),
|
||||
hir_id,
|
||||
unsafety,
|
||||
abi,
|
||||
decl,
|
||||
|
|
|
@ -430,7 +430,7 @@ pub fn hir_ty_to_ty<'tcx>(tcx: TyCtxt<'tcx>, hir_ty: &hir::Ty<'_>) -> Ty<'tcx> {
|
|||
let env_node_id = tcx.hir().get_parent_item(hir_ty.hir_id);
|
||||
let env_def_id = tcx.hir().local_def_id(env_node_id);
|
||||
let item_cx = self::collect::ItemCtxt::new(tcx, env_def_id.to_def_id());
|
||||
item_cx.to_ty(hir_ty)
|
||||
AstConv::ast_ty_to_ty(&item_cx, hir_ty)
|
||||
}
|
||||
|
||||
pub fn hir_trait_to_predicates<'tcx>(
|
||||
|
@ -445,7 +445,7 @@ pub fn hir_trait_to_predicates<'tcx>(
|
|||
let env_def_id = tcx.hir().local_def_id(env_hir_id);
|
||||
let item_cx = self::collect::ItemCtxt::new(tcx, env_def_id.to_def_id());
|
||||
let mut bounds = Bounds::default();
|
||||
let _ = <dyn AstConv<'_>>::instantiate_poly_trait_ref_inner(
|
||||
let _ = <dyn AstConv<'_>>::instantiate_poly_trait_ref(
|
||||
&item_cx,
|
||||
hir_trait,
|
||||
DUMMY_SP,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue