Skip to content

Commit b7c687c

Browse files
committed
respite
1 parent 735e85c commit b7c687c

File tree

17 files changed

+279
-104
lines changed

17 files changed

+279
-104
lines changed

compiler/rustc_ast_lowering/src/lib.rs

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2335,11 +2335,16 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
23352335

23362336
let hir_id = this.lower_node_id(c.id);
23372337
// Calculate all the lifetimes that should be captured
2338-
// by the opaque type. This should include all in-scope
2339-
// lifetime parameters, including those defined in-band.
2338+
// by the anonymous constant. This is needed for binders,
2339+
// for example `for<'a> dyn Trait<{ inner_fn::<'a>() }> where
2340+
// we somehow have to deal with `'a` in the anonymous constant.
23402341
//
2341-
// Note: this must be done after lowering the output type,
2342-
// as the output type may introduce new in-band lifetimes.
2342+
// We therefore add these lifetimes as additional generic parameters.
2343+
2344+
// FIXME(const_generics): We currently add all lifetimes as generic params,
2345+
// but as we already mention the parent generics this is not actually needed.
2346+
//
2347+
// Consider only adding explicit higher ranked lifetimes here.
23432348
let lifetime_params: Vec<(Span, ParamName)> = this
23442349
.in_scope_lifetimes
23452350
.iter()
@@ -2353,15 +2358,14 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
23532358
this.lifetime_to_generic_param(span, hir_name, def_id)
23542359
}));
23552360

2356-
let mut generic_args = Vec::with_capacity(lifetime_params.len());
2357-
generic_args.extend(lifetime_params.iter().map(|&(span, hir_name)| {
2358-
GenericArg::Lifetime(hir::Lifetime {
2359-
hir_id: this.next_id(),
2360-
span,
2361-
name: hir::LifetimeName::Param(hir_name),
2362-
})
2363-
}));
2364-
let generic_args = this.arena.alloc_from_iter(generic_args);
2361+
let generic_args =
2362+
this.arena.alloc_from_iter(lifetime_params.iter().map(|&(span, hir_name)| {
2363+
GenericArg::Lifetime(hir::Lifetime {
2364+
hir_id: this.next_id(),
2365+
span,
2366+
name: hir::LifetimeName::Param(hir_name),
2367+
})
2368+
}));
23652369

23662370
hir::AnonConst {
23672371
hir_id,

compiler/rustc_hir/src/intravisit.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1091,6 +1091,8 @@ pub fn walk_stmt<'v, V: Visitor<'v>>(visitor: &mut V, statement: &'v Stmt<'v>) {
10911091

10921092
pub fn walk_anon_const<'v, V: Visitor<'v>>(visitor: &mut V, constant: &'v AnonConst<'v>) {
10931093
visitor.visit_id(constant.hir_id);
1094+
visitor.visit_generic_args(constant.generics.span, &constant.generic_args);
1095+
visitor.visit_generics(&constant.generics);
10941096
visitor.visit_nested_body(constant.body);
10951097
}
10961098

compiler/rustc_middle/src/hir/map/mod.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -629,6 +629,25 @@ impl<'hir> Map<'hir> {
629629
None
630630
}
631631

632+
/// Returns the containing scope which may also define generics.
633+
///
634+
/// Similar to `get_parent_item` except that it also
635+
/// returns anonymous constants.
636+
pub fn get_generic_context(&self, hir_id: HirId) -> HirId {
637+
for (hir_id, node) in self.parent_iter(hir_id) {
638+
match node {
639+
Node::Crate(_)
640+
| Node::Item(_)
641+
| Node::ForeignItem(_)
642+
| Node::TraitItem(_)
643+
| Node::ImplItem(_)
644+
| Node::AnonConst(_) => return hir_id,
645+
_ => {}
646+
}
647+
}
648+
hir_id
649+
}
650+
632651
/// Retrieves the `HirId` for `id`'s parent item, or `id` itself if no
633652
/// parent item is in this map. The "parent item" is the closest parent node
634653
/// in the HIR which is recorded by the map and is an item, either an item

compiler/rustc_middle/src/query/mod.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,10 @@ rustc_queries! {
8989
desc { |tcx| "HIR owner items in `{}`", tcx.def_path_str(key.to_def_id()) }
9090
}
9191

92+
query default_substs_for_anon_const(key: LocalDefId) -> SubstsRef<'tcx> {
93+
desc { |tcx| "computing the identity substs for `{}`", tcx.def_path_str(key.to_def_id()) }
94+
}
95+
9296
/// Computes the `DefId` of the corresponding const parameter in case the `key` is a
9397
/// const argument and returns `None` otherwise.
9498
///

compiler/rustc_middle/src/ty/consts.rs

Lines changed: 5 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
use crate::mir::interpret::ConstValue;
22
use crate::mir::interpret::{LitToConstInput, Scalar};
3-
use crate::ty::subst::InternalSubsts;
43
use crate::ty::{self, Ty, TyCtxt};
54
use crate::ty::{ParamEnv, ParamEnvAnd};
6-
use crate::middle::resolve_lifetime as rl;
75
use rustc_errors::ErrorReported;
86
use rustc_hir as hir;
97
use rustc_hir::def_id::LocalDefId;
@@ -100,77 +98,11 @@ impl<'tcx> Const<'tcx> {
10098
let name = tcx.hir().name(hir_id);
10199
ty::ConstKind::Param(ty::ParamConst::new(index, name))
102100
}
103-
_ => {
104-
let generics = tcx.generics_of(def.did);
105-
let substs = InternalSubsts::for_item(tcx, def.did.to_def_id(), |param, _| {
106-
if let Some(i) =
107-
(param.index as usize).checked_sub(generics.parent_count)
108-
{
109-
// Our own parameters are the resolved lifetimes.
110-
match param.kind {
111-
ty::GenericParamDefKind::Lifetime => {
112-
if let hir::GenericArg::Lifetime(lifetime) = &hir_ct.generic_args.args[i] {
113-
let lifetime_name = |def_id| {
114-
tcx.hir().name(tcx.hir().local_def_id_to_hir_id(def_id))
115-
};
116-
117-
match tcx.named_region(lifetime.hir_id) {
118-
Some(rl::Region::Static) => tcx.lifetimes.re_static,
119-
120-
Some(rl::Region::LateBound(debruijn, id, _)) => {
121-
let name = lifetime_name(id.expect_local());
122-
tcx.mk_region(ty::ReLateBound(
123-
debruijn,
124-
ty::BrNamed(id, name),
125-
))
126-
}
127-
128-
Some(rl::Region::LateBoundAnon(debruijn, index)) => tcx
129-
.mk_region(ty::ReLateBound(
130-
debruijn,
131-
ty::BrAnon(index),
132-
)),
133-
134-
Some(rl::Region::EarlyBound(index, id, _)) => {
135-
let name = lifetime_name(id.expect_local());
136-
tcx.mk_region(ty::ReEarlyBound(ty::EarlyBoundRegion {
137-
def_id: id,
138-
index,
139-
name,
140-
}))
141-
}
142-
143-
Some(rl::Region::Free(scope, id)) => {
144-
let name = lifetime_name(id.expect_local());
145-
tcx.mk_region(ty::ReFree(ty::FreeRegion {
146-
scope,
147-
bound_region: ty::BrNamed(id, name),
148-
}))
149-
150-
// (*) -- not late-bound, won't change
151-
}
152-
153-
None => {
154-
tcx.sess.delay_span_bug(
155-
lifetime.span,
156-
"unelided lifetime in signature",
157-
);
158-
tcx.lifetimes.re_static
159-
}
160-
}
161-
} else {
162-
bug!()
163-
}
164-
}.into(),
165-
_ => bug!(),
166-
}
167-
} else {
168-
tcx.mk_param_from_def(param)
169-
}
170-
});
171-
172-
ty::ConstKind::Unevaluated(def.to_global(), substs, None)
173-
}
101+
_ => ty::ConstKind::Unevaluated(
102+
def.to_global(),
103+
tcx.default_substs_for_anon_const(def.did),
104+
None,
105+
),
174106
};
175107

176108
tcx.mk_const(ty::Const { val, ty })

compiler/rustc_resolve/src/late/lifetimes.rs

Lines changed: 59 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ use std::borrow::Cow;
2828
use std::cell::Cell;
2929
use std::mem::take;
3030

31-
use tracing::debug;
31+
use tracing::*;
3232

3333
// This counts the no of times a lifetime is used
3434
#[derive(Clone, Copy, Debug)]
@@ -192,7 +192,7 @@ crate struct LifetimeContext<'a, 'tcx> {
192192
#[derive(Debug)]
193193
enum Scope<'a> {
194194
/// Declares lifetimes, and each can be early-bound or late-bound.
195-
/// The `DebruijnIndex` of late-bound lifetimes starts at `1` and
195+
/// The `DebruijnIndex` of late-bound lifetimes starts at `0` and
196196
/// it should be shifted by the number of `Binder`s in between the
197197
/// declaration `Binder` and the location it's referenced from.
198198
Binder {
@@ -207,6 +207,12 @@ enum Scope<'a> {
207207
/// impls, but not other kinds of items.
208208
track_lifetime_uses: bool,
209209

210+
/// Whether these lifetimes are synthetic and only added
211+
/// for anon consts.
212+
///
213+
/// We do not emit lints in `check_uses_for_lifetimes_defined_by_scope`.
214+
from_anon_const: bool,
215+
210216
/// Whether or not this binder would serve as the parent
211217
/// binder for opaque types introduced within. For example:
212218
///
@@ -467,6 +473,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
467473
lifetimes,
468474
next_early_index: index + non_lifetime_count,
469475
opaque_type_parent: true,
476+
from_anon_const: false,
470477
track_lifetime_uses,
471478
s: ROOT_SCOPE,
472479
};
@@ -480,9 +487,36 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
480487
}
481488

482489
fn visit_anon_const(&mut self, ct: &'tcx hir::AnonConst<'tcx>) {
483-
self.visit_generics(&ct.generics);
484490
self.visit_generic_args(crate::DUMMY_SP, &ct.generic_args);
485-
intravisit::walk_anon_const(self, ct);
491+
492+
let generics = &ct.generics;
493+
let mut index = self.next_early_index();
494+
debug!("visit_anon_const: index = {}", index);
495+
let lifetimes = generics
496+
.params
497+
.iter()
498+
.map(|param| match param.kind {
499+
GenericParamKind::Lifetime { .. } => {
500+
Region::early(&self.tcx.hir(), &mut index, param)
501+
}
502+
GenericParamKind::Type { .. } | GenericParamKind::Const { .. } => {
503+
bug!("unexpected param: {:?}", param)
504+
}
505+
})
506+
.collect();
507+
let scope = Scope::Binder {
508+
lifetimes,
509+
next_early_index: index,
510+
s: self.scope,
511+
track_lifetime_uses: true,
512+
from_anon_const: true,
513+
opaque_type_parent: true,
514+
};
515+
self.with(scope, |_, this| {
516+
this.visit_id(ct.hir_id);
517+
this.visit_generics(generics);
518+
this.visit_nested_body(ct.body);
519+
});
486520
}
487521

488522
fn visit_foreign_item(&mut self, item: &'tcx hir::ForeignItem<'tcx>) {
@@ -535,6 +569,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
535569
s: self.scope,
536570
next_early_index,
537571
track_lifetime_uses: true,
572+
from_anon_const: false,
538573
opaque_type_parent: false,
539574
};
540575
self.with(scope, |old_scope, this| {
@@ -708,6 +743,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
708743
next_early_index,
709744
s: this.scope,
710745
track_lifetime_uses: true,
746+
from_anon_const: false,
711747
opaque_type_parent: false,
712748
};
713749
this.with(scope, |_old_scope, this| {
@@ -723,6 +759,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
723759
next_early_index,
724760
s: self.scope,
725761
track_lifetime_uses: true,
762+
from_anon_const: false,
726763
opaque_type_parent: false,
727764
};
728765
self.with(scope, |_old_scope, this| {
@@ -775,6 +812,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
775812
next_early_index: index + non_lifetime_count,
776813
s: self.scope,
777814
track_lifetime_uses: true,
815+
from_anon_const: false,
778816
opaque_type_parent: true,
779817
};
780818
self.with(scope, |old_scope, this| {
@@ -837,6 +875,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
837875
next_early_index: index + non_lifetime_count,
838876
s: self.scope,
839877
track_lifetime_uses: true,
878+
from_anon_const: false,
840879
opaque_type_parent: true,
841880
};
842881
self.with(scope, |old_scope, this| {
@@ -934,6 +973,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
934973
s: self.scope,
935974
next_early_index,
936975
track_lifetime_uses: true,
976+
from_anon_const: false,
937977
opaque_type_parent: false,
938978
};
939979
let result = self.with(scope, |old_scope, this| {
@@ -977,6 +1017,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
9771017
s: self.scope,
9781018
next_early_index: self.next_early_index(),
9791019
track_lifetime_uses: true,
1020+
from_anon_const: false,
9801021
opaque_type_parent: false,
9811022
};
9821023
self.with(scope, |_, this| {
@@ -1027,6 +1068,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
10271068
s: self.scope,
10281069
next_early_index,
10291070
track_lifetime_uses: true,
1071+
from_anon_const: false,
10301072
opaque_type_parent: false,
10311073
};
10321074
self.with(scope, |old_scope, this| {
@@ -1370,6 +1412,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
13701412
f(self)
13711413
}
13721414

1415+
#[instrument(skip(self, f))]
13731416
fn with<F>(&mut self, wrap_scope: Scope<'_>, f: F)
13741417
where
13751418
F: for<'b> FnOnce(ScopeRef<'_>, &mut LifetimeContext<'b, 'tcx>),
@@ -1390,10 +1433,8 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
13901433
lifetime_uses,
13911434
missing_named_lifetime_spots,
13921435
};
1393-
debug!("entering scope {:?}", this.scope);
13941436
f(self.scope, &mut this);
13951437
this.check_uses_for_lifetimes_defined_by_scope();
1396-
debug!("exiting scope {:?}", this.scope);
13971438
self.labels_in_fn = this.labels_in_fn;
13981439
self.xcrate_object_lifetime_defaults = this.xcrate_object_lifetime_defaults;
13991440
self.missing_named_lifetime_spots = this.missing_named_lifetime_spots;
@@ -1537,6 +1578,10 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
15371578

15381579
fn check_uses_for_lifetimes_defined_by_scope(&mut self) {
15391580
let defined_by = match self.scope {
1581+
Scope::Binder { from_anon_const: true, .. } => {
1582+
debug!("check_uses_for_lifetimes_defined_by_scope: synthetic anon const binder");
1583+
return;
1584+
}
15401585
Scope::Binder { lifetimes, .. } => lifetimes,
15411586
_ => {
15421587
debug!("check_uses_for_lifetimes_defined_by_scope: not in a binder scope");
@@ -1743,6 +1788,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
17431788
next_early_index,
17441789
s: self.scope,
17451790
opaque_type_parent: true,
1791+
from_anon_const: false,
17461792
track_lifetime_uses: false,
17471793
};
17481794
self.with(scope, move |old_scope, this| {
@@ -2342,6 +2388,13 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
23422388
self.outer_index.shift_out(1);
23432389
}
23442390

2391+
fn visit_anon_const(&mut self, _ct: &hir::AnonConst<'_>) {
2392+
// Do not look inside of anonymous constants, they should
2393+
// not participate in lifetime elision.
2394+
2395+
// FIXME(const_generics): is this true?
2396+
}
2397+
23452398
fn visit_param_bound(&mut self, bound: &hir::GenericBound<'_>) {
23462399
if let hir::GenericBound::LangItemTrait { .. } = bound {
23472400
self.outer_index.shift_in(1);

0 commit comments

Comments
 (0)