(Re-)Implement impl_trait_in_bindings
This commit is contained in:
parent
1da411e750
commit
d714a22e7b
45 changed files with 391 additions and 25 deletions
|
@ -29,7 +29,7 @@ use rustc_errors::{
|
|||
use rustc_hir::def::DefKind;
|
||||
use rustc_hir::def_id::{DefId, LocalDefId};
|
||||
use rustc_hir::intravisit::{self, Visitor, walk_generics};
|
||||
use rustc_hir::{self as hir, GenericParamKind, Node};
|
||||
use rustc_hir::{self as hir, GenericParamKind, HirId, Node};
|
||||
use rustc_infer::infer::{InferCtxt, TyCtxtInferExt};
|
||||
use rustc_infer::traits::ObligationCause;
|
||||
use rustc_middle::hir::nested_filter;
|
||||
|
@ -436,6 +436,15 @@ impl<'tcx> HirTyLowerer<'tcx> for ItemCtxt<'tcx> {
|
|||
ty::Const::new_error_with_message(self.tcx(), span, "bad placeholder constant")
|
||||
}
|
||||
|
||||
fn register_trait_ascription_bounds(
|
||||
&self,
|
||||
_: Vec<(ty::Clause<'tcx>, Span)>,
|
||||
_: HirId,
|
||||
span: Span,
|
||||
) {
|
||||
self.dcx().span_delayed_bug(span, "trait ascription type not allowed here");
|
||||
}
|
||||
|
||||
fn probe_ty_param_bounds(
|
||||
&self,
|
||||
span: Span,
|
||||
|
|
|
@ -852,6 +852,21 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
|
|||
};
|
||||
self.with(scope, |this| this.visit_ty(mt.ty));
|
||||
}
|
||||
hir::TyKind::TraitAscription(bounds) => {
|
||||
let scope = Scope::TraitRefBoundary { s: self.scope };
|
||||
self.with(scope, |this| {
|
||||
let scope = Scope::LateBoundary {
|
||||
s: this.scope,
|
||||
what: "`impl Trait` in binding",
|
||||
deny_late_regions: true,
|
||||
};
|
||||
this.with(scope, |this| {
|
||||
for bound in bounds {
|
||||
this.visit_param_bound(bound);
|
||||
}
|
||||
})
|
||||
});
|
||||
}
|
||||
_ => intravisit::walk_ty(self, ty),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -123,6 +123,13 @@ pub trait HirTyLowerer<'tcx> {
|
|||
/// Returns the const to use when a const is omitted.
|
||||
fn ct_infer(&self, param: Option<&ty::GenericParamDef>, span: Span) -> Const<'tcx>;
|
||||
|
||||
fn register_trait_ascription_bounds(
|
||||
&self,
|
||||
bounds: Vec<(ty::Clause<'tcx>, Span)>,
|
||||
hir_id: HirId,
|
||||
span: Span,
|
||||
);
|
||||
|
||||
/// Probe bounds in scope where the bounded type coincides with the given type parameter.
|
||||
///
|
||||
/// Rephrased, this returns bounds of the form `T: Trait`, where `T` is a type parameter
|
||||
|
@ -2375,6 +2382,25 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
|
||||
self.lower_opaque_ty(opaque_ty.def_id, in_trait)
|
||||
}
|
||||
hir::TyKind::TraitAscription(hir_bounds) => {
|
||||
// Impl trait in bindings lower as an infer var with additional
|
||||
// set of type bounds.
|
||||
let self_ty = self.ty_infer(None, hir_ty.span);
|
||||
let mut bounds = Bounds::default();
|
||||
self.lower_bounds(
|
||||
self_ty,
|
||||
hir_bounds.iter(),
|
||||
&mut bounds,
|
||||
ty::List::empty(),
|
||||
PredicateFilter::All,
|
||||
);
|
||||
self.register_trait_ascription_bounds(
|
||||
bounds.clauses().collect(),
|
||||
hir_ty.hir_id,
|
||||
hir_ty.span,
|
||||
);
|
||||
self_ty
|
||||
}
|
||||
// If we encounter a type relative path with RTN generics, then it must have
|
||||
// *not* gone through `lower_ty_maybe_return_type_notation`, and therefore
|
||||
// it's certainly in an illegal position.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue