Skip to content

Commit 66203ad

Browse files
committed
Lower extra lifetimes before normal generic params.
1 parent c96a690 commit 66203ad

File tree

3 files changed

+71
-11
lines changed

3 files changed

+71
-11
lines changed

compiler/rustc_ast_lowering/src/lib.rs

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -851,25 +851,32 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
851851
/// name resolver owing to lifetime elision; this also populates the resolver's node-id->def-id
852852
/// map, so that later calls to `opt_node_id_to_def_id` that refer to these extra lifetime
853853
/// parameters will be successful.
854-
#[instrument(level = "debug", skip(self))]
854+
#[instrument(level = "debug", skip(self), ret)]
855855
#[inline]
856856
fn lower_lifetime_binder(
857857
&mut self,
858858
binder: NodeId,
859859
generic_params: &[GenericParam],
860860
) -> &'hir [hir::GenericParam<'hir>] {
861-
let mut generic_params: Vec<_> = self
862-
.lower_generic_params_mut(generic_params, hir::GenericParamSource::Binder)
863-
.collect();
861+
// Start by creating params for extra lifetimes params, as this creates the definitions
862+
// that may be referred to by the AST inside `generic_params`.
864863
let extra_lifetimes = self.resolver.extra_lifetime_params(binder);
865864
debug!(?extra_lifetimes);
866-
generic_params.extend(extra_lifetimes.into_iter().filter_map(|(ident, node_id, res)| {
867-
self.lifetime_res_to_generic_param(ident, node_id, res, hir::GenericParamSource::Binder)
868-
}));
869-
let generic_params = self.arena.alloc_from_iter(generic_params);
870-
debug!(?generic_params);
871-
872-
generic_params
865+
let extra_lifetimes: Vec<_> = extra_lifetimes
866+
.into_iter()
867+
.filter_map(|(ident, node_id, res)| {
868+
self.lifetime_res_to_generic_param(
869+
ident,
870+
node_id,
871+
res,
872+
hir::GenericParamSource::Binder,
873+
)
874+
})
875+
.collect();
876+
let arena = self.arena;
877+
let explicit_generic_params =
878+
self.lower_generic_params_mut(generic_params, hir::GenericParamSource::Binder);
879+
arena.alloc_from_iter(explicit_generic_params.chain(extra_lifetimes.into_iter()))
873880
}
874881

875882
fn with_dyn_type_scope<T>(&mut self, in_scope: bool, f: impl FnOnce(&mut Self) -> T) -> T {
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
//! Regression test for <https://github.com/rust-lang/rust/issues/143413>
2+
//! The anonymous lifetime in `c(&())` is desugared by the resolver as an extra lifetime parameter
3+
//! at the end of the `for` binder. Verify that lowering creates the definition for that extra
4+
//! lifetime parameter before lowering `c(&())`.
5+
6+
type A = for<const B: c(&())> D;
7+
//~^ ERROR cannot find type `c` in this scope
8+
//~| ERROR cannot find trait `D` in this scope
9+
//~| ERROR only lifetime parameters can be used in this context
10+
//~| WARN trait objects without an explicit `dyn` are deprecated
11+
//~| WARN this is accepted in the current edition
12+
13+
fn main() {}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
error[E0412]: cannot find type `c` in this scope
2+
--> $DIR/elided-lifetime-in-const-param-type.rs:6:23
3+
|
4+
LL | type A = for<const B: c(&())> D;
5+
| ^ not found in this scope
6+
7+
error[E0405]: cannot find trait `D` in this scope
8+
--> $DIR/elided-lifetime-in-const-param-type.rs:6:31
9+
|
10+
LL | type A = for<const B: c(&())> D;
11+
| ^ not found in this scope
12+
13+
error[E0658]: only lifetime parameters can be used in this context
14+
--> $DIR/elided-lifetime-in-const-param-type.rs:6:20
15+
|
16+
LL | type A = for<const B: c(&())> D;
17+
| ^
18+
|
19+
= note: see issue #108185 <https://github.com/rust-lang/rust/issues/108185> for more information
20+
= help: add `#![feature(non_lifetime_binders)]` to the crate attributes to enable
21+
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
22+
23+
warning: trait objects without an explicit `dyn` are deprecated
24+
--> $DIR/elided-lifetime-in-const-param-type.rs:6:10
25+
|
26+
LL | type A = for<const B: c(&())> D;
27+
| ^^^^^^^^^^^^^^^^^^^^^^
28+
|
29+
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
30+
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
31+
= note: `#[warn(bare_trait_objects)]` on by default
32+
help: if this is a dyn-compatible trait, use `dyn`
33+
|
34+
LL | type A = dyn for<const B: c(&())> D;
35+
| +++
36+
37+
error: aborting due to 3 previous errors; 1 warning emitted
38+
39+
Some errors have detailed explanations: E0405, E0412, E0658.
40+
For more information about an error, try `rustc --explain E0405`.

0 commit comments

Comments
 (0)