map: &'a mut NamedRegionMap,
scope: ScopeRef<'a>,
- /// Used to disallow the use of in-band lifetimes in `fn` or `Fn` syntax.
- is_in_fn_syntax: bool,
-
- is_in_const_generic: bool,
-
/// Indicates that we only care about the definition of a trait. This should
/// be false if the `Item` we are resolving lifetimes for is not a trait or
/// we eventually need lifetimes resolve for trait items.
/// The reason for this separate call is to resolve what would otherwise
/// be a cycle. Consider this example:
///
-/// ```rust
+/// ```ignore UNSOLVED (maybe @jackh726 knows what lifetime parameter to give Sub)
/// trait Base<'a> {
/// type BaseItem;
/// }
tcx,
map: &mut named_region_map,
scope: ROOT_SCOPE,
- is_in_fn_syntax: false,
- is_in_const_generic: false,
trait_definition_only,
labels_in_fn: vec![],
xcrate_object_lifetime_defaults: Default::default(),
hir_id: hir::HirId,
) {
let name = match fk {
- intravisit::FnKind::ItemFn(id, _, _, _) => id.name,
- intravisit::FnKind::Method(id, _, _) => id.name,
+ intravisit::FnKind::ItemFn(id, _, _) => id.name,
+ intravisit::FnKind::Method(id, _) => id.name,
intravisit::FnKind::Closure => sym::closure,
};
let name = name.as_str();
match ty.kind {
hir::TyKind::BareFn(ref c) => {
let next_early_index = self.next_early_index();
- let was_in_fn_syntax = self.is_in_fn_syntax;
- self.is_in_fn_syntax = true;
let lifetime_span: Option<Span> =
c.generic_params.iter().rev().find_map(|param| match param.kind {
GenericParamKind::Lifetime { .. } => Some(param.span),
intravisit::walk_ty(this, ty);
});
self.missing_named_lifetime_spots.pop();
- self.is_in_fn_syntax = was_in_fn_syntax;
}
hir::TyKind::TraitObject(bounds, ref lifetime, _) => {
debug!(?bounds, ?lifetime, "TraitObject");
}
});
match lifetime.name {
- LifetimeName::Implicit(_) => {
+ LifetimeName::Implicit => {
// For types like `dyn Foo`, we should
// generate a special form of elided.
span_bug!(ty.span, "object-lifetime-default expected, not implicit",);
self.insert_lifetime(lifetime_ref, Region::Static);
return;
}
- if self.is_in_const_generic && lifetime_ref.name != LifetimeName::Error {
- self.emit_non_static_lt_in_const_generic_error(lifetime_ref);
- return;
- }
self.resolve_lifetime_ref(lifetime_ref);
}
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 } => {
- let was_in_const_generic = this.is_in_const_generic;
- this.is_in_const_generic = true;
- 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));
}
- this.is_in_const_generic = was_in_const_generic;
}
}
}
- for predicate in generics.where_clause.predicates {
+ for predicate in generics.predicates {
match predicate {
&hir::WherePredicate::BoundPredicate(hir::WhereBoundPredicate {
ref bounded_ty,
}) => {
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,
GenericParamKind::Type { .. } => {
let mut set = Set1::Empty;
- add_bounds(&mut set, ¶m.bounds);
-
let param_def_id = tcx.hir().local_def_id(param.hir_id);
- for predicate in generics.where_clause.predicates {
+ for predicate in generics.predicates {
// Look for `type: ...` where clauses.
let hir::WherePredicate::BoundPredicate(ref data) = *predicate else { continue };
tcx: *tcx,
map,
scope: &wrap_scope,
- is_in_fn_syntax: self.is_in_fn_syntax,
- is_in_const_generic: self.is_in_const_generic,
trait_definition_only: self.trait_definition_only,
labels_in_fn,
xcrate_object_lifetime_defaults,
let result = loop {
match *scope {
Scope::Body { id, s } => {
- // Non-static lifetimes are prohibited in anonymous constants without
- // `generic_const_exprs`.
- self.maybe_emit_forbidden_non_static_lifetime_error(id, lifetime_ref);
-
outermost_body = Some(id);
scope = s;
}
self.insert_lifetime(lifetime_ref, def);
} else {
- self.emit_undeclared_lifetime_error(lifetime_ref);
+ self.tcx.sess.delay_span_bug(
+ lifetime_ref.span,
+ &format!("Could not resolve {:?} in scope {:#?}", lifetime_ref, self.scope,),
+ );
}
}
);
if generic_args.parenthesized {
- let was_in_fn_syntax = self.is_in_fn_syntax;
- self.is_in_fn_syntax = true;
self.visit_fn_like_elision(generic_args.inputs(), Some(generic_args.bindings[0].ty()));
- self.is_in_fn_syntax = was_in_fn_syntax;
return;
}
/// Returns all the late-bound vars that come into scope from supertrait HRTBs, based on the
/// associated type name and starting trait.
/// For example, imagine we have
- /// ```rust
+ /// ```ignore (illustrative)
/// trait Foo<'a, 'b> {
/// type As;
/// }
let error = loop {
match *scope {
// Do not assign any resolution, it will be inferred.
- Scope::Body { .. } => break Ok(()),
+ Scope::Body { .. } => return,
- Scope::Root => break Err(None),
+ Scope::Root => break None,
Scope::Binder { s, ref lifetimes, scope_type, .. } => {
// collect named lifetimes for suggestions
self.insert_lifetime(lifetime_ref, lifetime);
}
- break Ok(());
+ return;
}
Scope::Elision { elide: Elide::Exact(l), .. } => {
for lifetime_ref in lifetime_refs {
self.insert_lifetime(lifetime_ref, lifetime);
}
- break Ok(());
+ return;
}
Scope::Elision { elide: Elide::Error(ref e), ref s, .. } => {
_ => break,
}
}
- break Err(Some(&e[..]));
+ break Some(&e[..]);
}
- Scope::Elision { elide: Elide::Forbid, .. } => break Err(None),
+ Scope::Elision { elide: Elide::Forbid, .. } => break None,
Scope::ObjectLifetimeDefault { s, .. }
| Scope::Supertrait { s, .. }
}
};
- let error = match error {
- Ok(()) => {
- self.report_elided_lifetime_in_ty(lifetime_refs);
- return;
- }
- Err(error) => error,
- };
-
// If we specifically need the `scope_for_path` map, then we're in the
// diagnostic pass and we don't want to emit more errors.
if self.map.scope_for_path.is_some() {
if let hir::ParamName::Plain(_) = lifetime_i_name {
let name = lifetime_i_name.ident().name;
if name == kw::UnderscoreLifetime || name == kw::StaticLifetime {
- let mut err = struct_span_err!(
- self.tcx.sess,
- lifetime_i.span,
- E0262,
- "invalid lifetime parameter name: `{}`",
- lifetime_i.name.ident(),
- );
- err.span_label(
+ self.tcx.sess.delay_span_bug(
lifetime_i.span,
- format!("{} is a reserved lifetime name", name),
+ &format!("invalid lifetime parameter name: `{}`", lifetime_i.name.ident()),
);
- err.emit();
}
}
// 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!(),
- }
- }
}
}
// 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: