1
Fork 0

Refactor where predicates, and reserve for attributes support

This commit is contained in:
Frank King 2024-11-25 16:38:35 +08:00
parent 67a8c64259
commit 161221da9e
44 changed files with 394 additions and 408 deletions

View file

@ -1268,15 +1268,14 @@ impl<'ra: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'_, 'ast, 'r
debug!("visit_where_predicate {:?}", p);
let previous_value = replace(&mut self.diag_metadata.current_where_predicate, Some(p));
self.with_lifetime_rib(LifetimeRibKind::AnonymousReportError, |this| {
if let WherePredicate::BoundPredicate(WhereBoundPredicate {
ref bounded_ty,
ref bounds,
ref bound_generic_params,
span: predicate_span,
if let WherePredicateKind::BoundPredicate(WhereBoundPredicate {
bounded_ty,
bounds,
bound_generic_params,
..
}) = p
}) = &p.kind
{
let span = predicate_span.shrink_to_lo().to(bounded_ty.span.shrink_to_lo());
let span = p.span.shrink_to_lo().to(bounded_ty.span.shrink_to_lo());
this.with_generic_param_rib(
bound_generic_params,
RibKind::Normal,

View file

@ -1317,21 +1317,24 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
/// Given `where <T as Bar>::Baz: String`, suggest `where T: Bar<Baz = String>`.
fn restrict_assoc_type_in_where_clause(&mut self, span: Span, err: &mut Diag<'_>) -> bool {
// Detect that we are actually in a `where` predicate.
let (bounded_ty, bounds, where_span) =
if let Some(ast::WherePredicate::BoundPredicate(ast::WhereBoundPredicate {
bounded_ty,
bound_generic_params,
bounds,
span,
})) = self.diag_metadata.current_where_predicate
{
if !bound_generic_params.is_empty() {
return false;
}
(bounded_ty, bounds, span)
} else {
let (bounded_ty, bounds, where_span) = if let Some(ast::WherePredicate {
kind:
ast::WherePredicateKind::BoundPredicate(ast::WhereBoundPredicate {
bounded_ty,
bound_generic_params,
bounds,
}),
span,
..
}) = self.diag_metadata.current_where_predicate
{
if !bound_generic_params.is_empty() {
return false;
};
}
(bounded_ty, bounds, span)
} else {
return false;
};
// Confirm that the target is an associated type.
let (ty, _, path) = if let ast::TyKind::Path(Some(qself), path) = &bounded_ty.kind {
@ -2840,9 +2843,10 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
// for<'a, 'b> T: Trait<T> + 'b
// ^^^^^^^^^^^ suggest outer binder `for<'a, 'b>`
if let LifetimeBinderKind::WhereBound = kind
&& let Some(ast::WherePredicate::BoundPredicate(
&& let Some(predicate) = self.diag_metadata.current_where_predicate
&& let ast::WherePredicateKind::BoundPredicate(
ast::WhereBoundPredicate { bounded_ty, bounds, .. },
)) = self.diag_metadata.current_where_predicate
) = &predicate.kind
&& bounded_ty.id == binder
{
for bound in bounds {
@ -3473,7 +3477,6 @@ fn mk_where_bound_predicate(
};
let new_where_bound_predicate = ast::WhereBoundPredicate {
span: DUMMY_SP,
bound_generic_params: ThinVec::new(),
bounded_ty: ast::ptr::P(ty.clone()),
bounds: vec![ast::GenericBound::Trait(ast::PolyTraitRef {