Skip to content

Commit

Permalink
Auto merge of #97694 - Dylan-DPC:rollup-2yxo7ce, r=Dylan-DPC
Browse files Browse the repository at this point in the history
Rollup of 3 pull requests

Successful merges:

 - #97415 (Compute `is_late_bound_map` query separately from lifetime resolution)
 - #97471 (Provide more context when denying invalid type params )
 - #97681 (Add more eslint checks)

Failed merges:

 - #97446 (Make hir().get_generics and generics_of consistent.)

r? `@ghost`
`@rustbot` modify labels: rollup
  • Loading branch information
bors committed Jun 3, 2022
2 parents e40d5e8 + 5549d50 commit 9a74608
Show file tree
Hide file tree
Showing 48 changed files with 1,211 additions and 581 deletions.
41 changes: 17 additions & 24 deletions compiler/rustc_ast_lowering/src/lib.rs
Expand Up @@ -672,9 +672,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
LifetimeRes::Param { .. } => {
(hir::ParamName::Plain(ident), hir::LifetimeParamKind::Explicit)
}
LifetimeRes::Fresh { param, .. } => {
(hir::ParamName::Fresh(param), hir::LifetimeParamKind::Elided)
}
LifetimeRes::Fresh { .. } => (hir::ParamName::Fresh, hir::LifetimeParamKind::Elided),
LifetimeRes::Static | LifetimeRes::Error => return None,
res => panic!(
"Unexpected lifetime resolution {:?} for {:?} at {:?}",
Expand Down Expand Up @@ -1576,10 +1574,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
(hir::ParamName::Plain(ident), LifetimeRes::Param { param, binder: fn_node_id })
}
// Input lifetime like `'1`:
LifetimeRes::Fresh { param, .. } => (
hir::ParamName::Fresh(outer_def_id),
LifetimeRes::Fresh { param, binder: fn_node_id },
),
LifetimeRes::Fresh { param, .. } => {
(hir::ParamName::Fresh, LifetimeRes::Fresh { param, binder: fn_node_id })
}
LifetimeRes::Static | LifetimeRes::Error => continue,
res => {
panic!("Unexpected lifetime resolution {:?} for {:?} at {:?}", res, ident, span)
Expand Down Expand Up @@ -1749,18 +1746,18 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
) -> hir::Lifetime {
debug!(?self.captured_lifetimes);
let name = match res {
LifetimeRes::Param { param, binder } => {
LifetimeRes::Param { mut param, binder } => {
debug_assert_ne!(ident.name, kw::UnderscoreLifetime);
let p_name = ParamName::Plain(ident);
if let Some(LifetimeCaptureContext { parent_def_id, captures, binders_to_ignore }) =
&mut self.captured_lifetimes
&& !binders_to_ignore.contains(&binder)
{
match captures.entry(param) {
Entry::Occupied(_) => {}
Entry::Occupied(o) => param = self.resolver.local_def_id(o.get().1),
Entry::Vacant(v) => {
let p_id = self.resolver.next_node_id();
self.resolver.create_def(
let p_def_id = self.resolver.create_def(
*parent_def_id,
p_id,
DefPathData::LifetimeNs(p_name.ident().name),
Expand All @@ -1769,10 +1766,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
);

v.insert((span, p_id, p_name, res));
param = p_def_id;
}
}
}
hir::LifetimeName::Param(p_name)
hir::LifetimeName::Param(param, p_name)
}
LifetimeRes::Fresh { mut param, binder } => {
debug_assert_eq!(ident.name, kw::UnderscoreLifetime);
Expand All @@ -1792,21 +1790,14 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
span.with_parent(None),
);

let p_name = ParamName::Fresh(param);
v.insert((span, p_id, p_name, res));
v.insert((span, p_id, ParamName::Fresh, res));
param = p_def_id;
}
}
}
let p_name = ParamName::Fresh(param);
hir::LifetimeName::Param(p_name)
hir::LifetimeName::Param(param, ParamName::Fresh)
}
LifetimeRes::Anonymous { binder, elided } => {
let l_name = if elided {
hir::LifetimeName::Implicit
} else {
hir::LifetimeName::Underscore
};
if let Some(LifetimeCaptureContext { parent_def_id, captures, binders_to_ignore }) =
&mut self.captured_lifetimes
&& !binders_to_ignore.contains(&binder)
Expand All @@ -1819,18 +1810,20 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
ExpnId::root(),
span.with_parent(None),
);
let p_name = ParamName::Fresh(p_def_id);
captures.insert(p_def_id, (span, p_id, p_name, res));
hir::LifetimeName::Param(p_name)
captures.insert(p_def_id, (span, p_id, ParamName::Fresh, res));
hir::LifetimeName::Param(p_def_id, ParamName::Fresh)
} else if elided {
hir::LifetimeName::Implicit
} else {
l_name
hir::LifetimeName::Underscore
}
}
LifetimeRes::Static => hir::LifetimeName::Static,
LifetimeRes::Error => hir::LifetimeName::Error,
res => panic!("Unexpected lifetime resolution {:?} for {:?} at {:?}", res, ident, span),
};
debug!(?self.captured_lifetimes);
debug!(?name);
hir::Lifetime { hir_id: self.lower_node_id(id), span: self.lower_span(span), name }
}

Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_borrowck/src/diagnostics/region_name.rs
Expand Up @@ -567,14 +567,14 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
let lifetime =
self.try_match_adt_and_generic_args(substs, needle_fr, args, search_stack)?;
match lifetime.name {
hir::LifetimeName::Param(hir::ParamName::Plain(_) | hir::ParamName::Error)
hir::LifetimeName::Param(_, hir::ParamName::Plain(_) | hir::ParamName::Error)
| hir::LifetimeName::Error
| hir::LifetimeName::Static => {
let lifetime_span = lifetime.span;
Some(RegionNameHighlight::MatchedAdtAndSegment(lifetime_span))
}

hir::LifetimeName::Param(hir::ParamName::Fresh(_))
hir::LifetimeName::Param(_, hir::ParamName::Fresh)
| hir::LifetimeName::ImplicitObjectLifetimeDefault
| hir::LifetimeName::Implicit
| hir::LifetimeName::Underscore => {
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_borrowck/src/universal_regions.rs
Expand Up @@ -830,11 +830,11 @@ fn for_each_late_bound_region_defined_on<'tcx>(
fn_def_id: DefId,
mut f: impl FnMut(ty::Region<'tcx>),
) {
if let Some((owner, late_bounds)) = tcx.is_late_bound_map(fn_def_id.expect_local()) {
if let Some(late_bounds) = tcx.is_late_bound_map(fn_def_id.expect_local()) {
for &region_def_id in late_bounds.iter() {
let name = tcx.item_name(region_def_id.to_def_id());
let liberated_region = tcx.mk_region(ty::ReFree(ty::FreeRegion {
scope: owner.to_def_id(),
scope: fn_def_id,
bound_region: ty::BoundRegionKind::BrNamed(region_def_id.to_def_id(), name),
}));
f(liberated_region);
Expand Down
52 changes: 32 additions & 20 deletions compiler/rustc_hir/src/hir.rs
Expand Up @@ -26,7 +26,7 @@ use rustc_target::spec::abi::Abi;
use smallvec::SmallVec;
use std::fmt;

#[derive(Copy, Clone, Encodable, HashStable_Generic)]
#[derive(Debug, Copy, Clone, Encodable, HashStable_Generic)]
pub struct Lifetime {
pub hir_id: HirId,
pub span: Span,
Expand Down Expand Up @@ -60,7 +60,7 @@ pub enum ParamName {
/// ```
/// where `'f` is something like `Fresh(0)`. The indices are
/// unique per impl, but not necessarily continuous.
Fresh(LocalDefId),
Fresh,

/// Indicates an illegal name was given and an error has been
/// reported (so we should squelch other derived errors). Occurs
Expand All @@ -72,9 +72,7 @@ impl ParamName {
pub fn ident(&self) -> Ident {
match *self {
ParamName::Plain(ident) => ident,
ParamName::Fresh(_) | ParamName::Error => {
Ident::with_dummy_span(kw::UnderscoreLifetime)
}
ParamName::Fresh | ParamName::Error => Ident::with_dummy_span(kw::UnderscoreLifetime),
}
}

Expand All @@ -90,7 +88,7 @@ impl ParamName {
#[derive(HashStable_Generic)]
pub enum LifetimeName {
/// User-given names or fresh (synthetic) names.
Param(ParamName),
Param(LocalDefId, ParamName),

/// User wrote nothing (e.g., the lifetime in `&u32`).
Implicit,
Expand Down Expand Up @@ -127,7 +125,7 @@ impl LifetimeName {
| LifetimeName::Error => Ident::empty(),
LifetimeName::Underscore => Ident::with_dummy_span(kw::UnderscoreLifetime),
LifetimeName::Static => Ident::with_dummy_span(kw::StaticLifetime),
LifetimeName::Param(param_name) => param_name.ident(),
LifetimeName::Param(_, param_name) => param_name.ident(),
}
}

Expand All @@ -136,9 +134,9 @@ impl LifetimeName {
LifetimeName::ImplicitObjectLifetimeDefault
| LifetimeName::Implicit
| LifetimeName::Underscore
| LifetimeName::Param(ParamName::Fresh(_))
| LifetimeName::Param(_, ParamName::Fresh)
| LifetimeName::Error => true,
LifetimeName::Static | LifetimeName::Param(_) => false,
LifetimeName::Static | LifetimeName::Param(..) => false,
}
}

Expand All @@ -148,12 +146,12 @@ impl LifetimeName {
| LifetimeName::Implicit
| LifetimeName::Underscore => true,

// It might seem surprising that `Fresh(_)` counts as
// It might seem surprising that `Fresh` counts as
// *not* elided -- but this is because, as far as the code
// in the compiler is concerned -- `Fresh(_)` variants act
// in the compiler is concerned -- `Fresh` variants act
// equivalently to "some fresh name". They correspond to
// early-bound regions on an impl, in other words.
LifetimeName::Error | LifetimeName::Param(_) | LifetimeName::Static => false,
LifetimeName::Error | LifetimeName::Param(..) | LifetimeName::Static => false,
}
}

Expand All @@ -163,8 +161,8 @@ impl LifetimeName {

pub fn normalize_to_macros_2_0(&self) -> LifetimeName {
match *self {
LifetimeName::Param(param_name) => {
LifetimeName::Param(param_name.normalize_to_macros_2_0())
LifetimeName::Param(def_id, param_name) => {
LifetimeName::Param(def_id, param_name.normalize_to_macros_2_0())
}
lifetime_name => lifetime_name,
}
Expand All @@ -177,12 +175,6 @@ impl fmt::Display for Lifetime {
}
}

impl fmt::Debug for Lifetime {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "lifetime({}: {})", self.hir_id, self.name.ident())
}
}

impl Lifetime {
pub fn is_elided(&self) -> bool {
self.name.is_elided()
Expand Down Expand Up @@ -628,6 +620,16 @@ impl<'hir> Generics<'hir> {
})
}

pub fn outlives_for_param(
&self,
param_def_id: LocalDefId,
) -> impl Iterator<Item = &WhereRegionPredicate<'_>> {
self.predicates.iter().filter_map(move |pred| match pred {
WherePredicate::RegionPredicate(rp) if rp.is_param_bound(param_def_id) => Some(rp),
_ => None,
})
}

pub fn bounds_span_for_suggestions(&self, param_def_id: LocalDefId) -> Option<Span> {
self.bounds_for_param(param_def_id).flat_map(|bp| bp.bounds.iter().rev()).find_map(
|bound| {
Expand Down Expand Up @@ -769,6 +771,16 @@ pub struct WhereRegionPredicate<'hir> {
pub bounds: GenericBounds<'hir>,
}

impl<'hir> WhereRegionPredicate<'hir> {
/// Returns `true` if `param_def_id` matches the `lifetime` of this predicate.
pub fn is_param_bound(&self, param_def_id: LocalDefId) -> bool {
match self.lifetime.name {
LifetimeName::Param(id, _) => id == param_def_id,
_ => false,
}
}
}

/// An equality predicate (e.g., `T = int`); currently unsupported.
#[derive(Debug, HashStable_Generic)]
pub struct WhereEqPredicate<'hir> {
Expand Down
8 changes: 4 additions & 4 deletions compiler/rustc_hir/src/intravisit.rs
Expand Up @@ -510,11 +510,11 @@ pub fn walk_label<'v, V: Visitor<'v>>(visitor: &mut V, label: &'v Label) {
pub fn walk_lifetime<'v, V: Visitor<'v>>(visitor: &mut V, lifetime: &'v Lifetime) {
visitor.visit_id(lifetime.hir_id);
match lifetime.name {
LifetimeName::Param(ParamName::Plain(ident)) => {
LifetimeName::Param(_, ParamName::Plain(ident)) => {
visitor.visit_ident(ident);
}
LifetimeName::Param(ParamName::Fresh(_))
| LifetimeName::Param(ParamName::Error)
LifetimeName::Param(_, ParamName::Fresh)
| LifetimeName::Param(_, ParamName::Error)
| LifetimeName::Static
| LifetimeName::Error
| LifetimeName::Implicit
Expand Down Expand Up @@ -879,7 +879,7 @@ pub fn walk_generic_param<'v, V: Visitor<'v>>(visitor: &mut V, param: &'v Generi
visitor.visit_id(param.hir_id);
match param.name {
ParamName::Plain(ident) => visitor.visit_ident(ident),
ParamName::Error | ParamName::Fresh(_) => {}
ParamName::Error | ParamName::Fresh => {}
}
match param.kind {
GenericParamKind::Lifetime { .. } => {}
Expand Down
6 changes: 5 additions & 1 deletion compiler/rustc_middle/src/hir/map/mod.rs
Expand Up @@ -364,7 +364,11 @@ impl<'hir> Map<'hir> {
match node.node {
OwnerNode::ImplItem(impl_item) => Some(&impl_item.generics),
OwnerNode::TraitItem(trait_item) => Some(&trait_item.generics),
OwnerNode::Item(Item {
OwnerNode::ForeignItem(ForeignItem {
kind: ForeignItemKind::Fn(_, _, generics),
..
})
| OwnerNode::Item(Item {
kind:
ItemKind::Fn(_, generics, _)
| ItemKind::TyAlias(_, generics)
Expand Down
11 changes: 5 additions & 6 deletions compiler/rustc_middle/src/middle/resolve_lifetime.rs
Expand Up @@ -6,7 +6,6 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_hir::ItemLocalId;
use rustc_macros::HashStable;
use rustc_span::symbol::Symbol;

#[derive(Clone, Copy, PartialEq, Eq, Hash, TyEncodable, TyDecodable, Debug, HashStable)]
pub enum Region {
Expand All @@ -22,12 +21,12 @@ pub enum Region {
/// so that we can e.g. suggest elided-lifetimes-in-paths of the form <'_, '_> e.g.
#[derive(Clone, PartialEq, Eq, Hash, TyEncodable, TyDecodable, Debug, HashStable)]
pub enum LifetimeScopeForPath {
// Contains all lifetime names that are in scope and could possibly be used in generics
// arguments of path.
NonElided(Vec<Symbol>),
/// Contains all lifetime names that are in scope and could possibly be used in generics
/// arguments of path.
NonElided(Vec<LocalDefId>),

// Information that allows us to suggest args of the form `<'_>` in case
// no generic arguments were provided for a path.
/// Information that allows us to suggest args of the form `<'_>` in case
/// no generic arguments were provided for a path.
Elided,
}

Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_middle/src/query/mod.rs
Expand Up @@ -1584,7 +1584,7 @@ rustc_queries! {
Option<&'tcx FxHashMap<ItemLocalId, Region>> {
desc { "looking up a named region" }
}
query is_late_bound_map(_: LocalDefId) -> Option<(LocalDefId, &'tcx FxHashSet<LocalDefId>)> {
query is_late_bound_map(_: LocalDefId) -> Option<&'tcx FxHashSet<LocalDefId>> {
desc { "testing if a region is late bound" }
}
/// For a given item (like a struct), gets the default lifetimes to be used
Expand Down
7 changes: 7 additions & 0 deletions compiler/rustc_middle/src/ty/context.rs
Expand Up @@ -2803,6 +2803,13 @@ impl<'tcx> TyCtxt<'tcx> {
self.named_region_map(id.owner).and_then(|map| map.get(&id.local_id).cloned())
}

pub fn is_late_bound(self, id: HirId) -> bool {
self.is_late_bound_map(id.owner).map_or(false, |set| {
let def_id = self.hir().local_def_id(id);
set.contains(&def_id)
})
}

pub fn late_bound_vars(self, id: HirId) -> &'tcx List<ty::BoundVariableKind> {
self.mk_bound_variable_kinds(
self.late_bound_vars_map(id.owner)
Expand Down

0 comments on commit 9a74608

Please sign in to comment.