1
Fork 0

Store all generic bounds as where predicates.

This commit is contained in:
Camille GILLOT 2022-02-07 22:58:30 +01:00
parent 05b29f9a92
commit 94449e6101
30 changed files with 770 additions and 953 deletions

View file

@ -1328,13 +1328,11 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
match param.kind {
GenericParamKind::Lifetime { .. } => {}
GenericParamKind::Type { ref default, .. } => {
walk_list!(this, visit_param_bound, param.bounds);
if let Some(ref ty) = default {
this.visit_ty(&ty);
}
}
GenericParamKind::Const { ref ty, default } => {
walk_list!(this, visit_param_bound, param.bounds);
this.visit_ty(&ty);
if let Some(default) = default {
this.visit_body(this.tcx.hir().body(default.body));
@ -1393,6 +1391,32 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
}) => {
this.visit_lifetime(lifetime);
walk_list!(this, visit_param_bound, bounds);
if lifetime.name != hir::LifetimeName::Static {
for bound in bounds {
let hir::GenericBound::Outlives(ref lt) = bound else {
continue;
};
if lt.name != hir::LifetimeName::Static {
continue;
}
this.insert_lifetime(lt, Region::Static);
this.tcx
.sess
.struct_span_warn(
lifetime.span,
&format!(
"unnecessary lifetime parameter `{}`",
lifetime.name.ident(),
),
)
.help(&format!(
"you can use the `'static` lifetime directly, in place of `{}`",
lifetime.name.ident(),
))
.emit();
}
}
}
&hir::WherePredicate::EqPredicate(hir::WhereEqPredicate {
ref lhs_ty,
@ -1714,8 +1738,6 @@ fn object_lifetime_defaults_for_item<'tcx>(
GenericParamKind::Type { .. } => {
let mut set = Set1::Empty;
add_bounds(&mut set, &param.bounds);
let param_def_id = tcx.hir().local_def_id(param.hir_id);
for predicate in generics.predicates {
// Look for `type: ...` where clauses.
@ -3124,50 +3146,6 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
// It is a soft error to shadow a lifetime within a parent scope.
self.check_lifetime_param_for_shadowing(old_scope, &lifetime_i);
for bound in lifetime_i.bounds {
match bound {
hir::GenericBound::Outlives(ref lt) => match lt.name {
hir::LifetimeName::Underscore => {
self.tcx.sess.delay_span_bug(
lt.span,
"use of `'_` in illegal place, but not caught by lowering",
);
}
hir::LifetimeName::Static => {
self.insert_lifetime(lt, Region::Static);
self.tcx
.sess
.struct_span_warn(
lifetime_i.span.to(lt.span),
&format!(
"unnecessary lifetime parameter `{}`",
lifetime_i.name.ident(),
),
)
.help(&format!(
"you can use the `'static` lifetime directly, in place of `{}`",
lifetime_i.name.ident(),
))
.emit();
}
hir::LifetimeName::Param(_) | hir::LifetimeName::Implicit => {
self.resolve_lifetime_ref(lt);
}
hir::LifetimeName::ImplicitObjectLifetimeDefault => {
self.tcx.sess.delay_span_bug(
lt.span,
"lowering generated `ImplicitObjectLifetimeDefault` \
outside of an object type",
);
}
hir::LifetimeName::Error => {
// No need to do anything, error already reported.
}
},
_ => bug!(),
}
}
}
}
@ -3326,18 +3304,6 @@ fn insert_late_bound_lifetimes(
// ignore binders here and scrape up all names we see.
let mut appears_in_where_clause = AllCollector::default();
appears_in_where_clause.visit_generics(generics);
for param in generics.params {
if let hir::GenericParamKind::Lifetime { .. } = param.kind {
if !param.bounds.is_empty() {
// `'a: 'b` means both `'a` and `'b` are referenced
appears_in_where_clause
.regions
.insert(hir::LifetimeName::Param(param.name.normalize_to_macros_2_0()));
}
}
}
debug!(?appears_in_where_clause.regions);
// Late bound regions are those that: