Skip to content

Commit 03e3b67

Browse files
Rollup merge of rust-lang#156953 - aerooneqq:delegation-emit-err-when-incorrect-gen-args, r=petrochenkov
delegation: emit error when there is an infer lifetime in user-specified args This PR checks emit error if there as an infer lifetime anywhere in delegation's user-specified args. And `delegation_user_specified_args` is now query as we invoke it two times. Fixes rust-lang#156848. Part of rust-lang#118212. r? @petrochenkov
2 parents 33165e8 + a10c598 commit 03e3b67

14 files changed

Lines changed: 400 additions & 85 deletions

compiler/rustc_hir_analysis/src/collect.rs

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ use rustc_trait_selection::traits::{
4646
};
4747
use tracing::{debug, instrument};
4848

49-
use crate::errors;
49+
use crate::errors::{self, ElidedLifetimesAreNotAllowedInDelegations};
5050
use crate::hir_ty_lowering::{HirTyLowerer, InherentAssocCandidate, RegionInferReason};
5151

5252
pub(crate) mod dump;
@@ -131,6 +131,7 @@ pub(crate) struct ItemCtxt<'tcx> {
131131
tcx: TyCtxt<'tcx>,
132132
item_def_id: LocalDefId,
133133
tainted_by_errors: Cell<Option<ErrorGuaranteed>>,
134+
lowering_delegation_segment: bool,
134135
}
135136

136137
///////////////////////////////////////////////////////////////////////////
@@ -241,7 +242,24 @@ fn bad_placeholder<'cx, 'tcx>(
241242

242243
impl<'tcx> ItemCtxt<'tcx> {
243244
pub(crate) fn new(tcx: TyCtxt<'tcx>, item_def_id: LocalDefId) -> ItemCtxt<'tcx> {
244-
ItemCtxt { tcx, item_def_id, tainted_by_errors: Cell::new(None) }
245+
ItemCtxt::new_internal(tcx, item_def_id, false)
246+
}
247+
248+
fn new_internal(
249+
tcx: TyCtxt<'tcx>,
250+
item_def_id: LocalDefId,
251+
delegation: bool,
252+
) -> ItemCtxt<'tcx> {
253+
ItemCtxt {
254+
tcx,
255+
item_def_id,
256+
tainted_by_errors: Cell::new(None),
257+
lowering_delegation_segment: delegation,
258+
}
259+
}
260+
261+
pub(crate) fn new_for_delegation(tcx: TyCtxt<'tcx>, item_def_id: LocalDefId) -> ItemCtxt<'tcx> {
262+
ItemCtxt::new_internal(tcx, item_def_id, true)
245263
}
246264

247265
pub(crate) fn lower_ty(&self, hir_ty: &hir::Ty<'tcx>) -> Ty<'tcx> {
@@ -335,8 +353,15 @@ impl<'tcx> HirTyLowerer<'tcx> for ItemCtxt<'tcx> {
335353
.emit();
336354
ty::Region::new_error(self.tcx(), guar)
337355
} else {
356+
// If we found elided lifetime during lowering of delegation parent or child
357+
// segment then emit an error, as we need a named lifetime for proper signature
358+
// inheritance (#156848).
359+
if self.lowering_delegation_segment {
360+
self.tcx.dcx().emit_err(ElidedLifetimesAreNotAllowedInDelegations { span });
361+
}
362+
338363
// This indicates an illegal lifetime in a non-assoc-trait position
339-
ty::Region::new_error_with_message(self.tcx(), span, "unelided lifetime in signature")
364+
ty::Region::new_error_with_message(self.tcx(), span, "inferred lifetime in signature")
340365
}
341366
}
342367

compiler/rustc_hir_analysis/src/delegation.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use std::debug_assert_matches;
77
use rustc_data_structures::fx::FxHashMap;
88
use rustc_hir::def::DefKind;
99
use rustc_hir::def_id::{DefId, LocalDefId};
10-
use rustc_hir::{DelegationInfo, HirId, PathSegment};
10+
use rustc_hir::{DelegationInfo, PathSegment};
1111
use rustc_middle::ty::{
1212
self, EarlyBinder, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitableExt,
1313
};
@@ -551,7 +551,7 @@ pub(crate) fn inherit_predicates_for_delegation_item<'tcx>(
551551
}
552552
}
553553

554-
let (parent_args, child_args) = get_delegation_user_specified_args(tcx, def_id);
554+
let (parent_args, child_args) = tcx.delegation_user_specified_args(def_id);
555555
let (folder, args) = create_folder_and_args(tcx, def_id, sig_id, parent_args, child_args);
556556
let self_pos_kind = create_self_position_kind(tcx, def_id, sig_id);
557557
let filter_self_preds = matches!(self_pos_kind, SelfPositionKind::AfterLifetimes(true));
@@ -627,7 +627,7 @@ pub(crate) fn inherit_sig_for_delegation_item<'tcx>(
627627
return tcx.arena.alloc_from_iter((0..sig_len).map(|_| err_type));
628628
}
629629

630-
let (parent_args, child_args) = get_delegation_user_specified_args(tcx, def_id);
630+
let (parent_args, child_args) = tcx.delegation_user_specified_args(def_id);
631631
let (mut folder, args) = create_folder_and_args(tcx, def_id, sig_id, parent_args, child_args);
632632
let caller_sig = EarlyBinder::bind(caller_sig.skip_binder().fold_with(&mut folder));
633633

@@ -640,18 +640,18 @@ pub(crate) fn inherit_sig_for_delegation_item<'tcx>(
640640
// they will be used during delegation signature and predicates inheritance.
641641
// Example: reuse Trait::<'static, i32, 1>::foo::<A, B>
642642
// we want to extract [Self, 'static, i32, 1] for parent and [A, B] for child.
643-
fn get_delegation_user_specified_args<'tcx>(
643+
pub(crate) fn delegation_user_specified_args<'tcx>(
644644
tcx: TyCtxt<'tcx>,
645645
delegation_id: LocalDefId,
646646
) -> (&'tcx [ty::GenericArg<'tcx>], &'tcx [ty::GenericArg<'tcx>]) {
647647
let info = get_delegation_info(tcx, delegation_id);
648648

649-
let get_segment = |hir_id: HirId| -> Option<(&'tcx PathSegment<'tcx>, DefId)> {
649+
let get_segment = |hir_id| -> Option<(&'tcx PathSegment<'tcx>, DefId)> {
650650
let segment = tcx.hir_node(hir_id).expect_path_segment();
651651
segment.res.opt_def_id().map(|def_id| (segment, def_id))
652652
};
653653

654-
let ctx = ItemCtxt::new(tcx, delegation_id);
654+
let ctx = ItemCtxt::new_for_delegation(tcx, delegation_id);
655655
let lowerer = ctx.lowerer();
656656

657657
let parent_args = info.parent_args_segment_id.and_then(get_segment).map(|(segment, def_id)| {

compiler/rustc_hir_analysis/src/errors.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1680,6 +1680,13 @@ pub(crate) struct DelegationSelfTypeNotSpecified {
16801680
pub span: Span,
16811681
}
16821682

1683+
#[derive(Diagnostic)]
1684+
#[diag("inferred lifetimes are not allowed in delegations as we need to inherit signature")]
1685+
pub(crate) struct ElidedLifetimesAreNotAllowedInDelegations {
1686+
#[primary_span]
1687+
pub span: Span,
1688+
}
1689+
16831690
#[derive(Diagnostic)]
16841691
#[diag("method should be `async` or return a future, but it is synchronous")]
16851692
pub(crate) struct MethodShouldReturnFuture {

compiler/rustc_hir_analysis/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,7 @@ pub fn provide(providers: &mut Providers) {
137137
inferred_outlives_crate: outlives::inferred_outlives_crate,
138138
inferred_outlives_of: outlives::inferred_outlives_of,
139139
inherit_sig_for_delegation_item: delegation::inherit_sig_for_delegation_item,
140+
delegation_user_specified_args: delegation::delegation_user_specified_args,
140141
enforce_impl_non_lifetime_params_are_constrained:
141142
impl_wf_check::enforce_impl_non_lifetime_params_are_constrained,
142143
crate_variances: variance::crate_variances,

compiler/rustc_middle/src/queries.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2065,6 +2065,10 @@ rustc_queries! {
20652065
desc { "inheriting delegation signature" }
20662066
}
20672067

2068+
query delegation_user_specified_args(def_id: LocalDefId) -> (&'tcx [GenericArg<'tcx>], &'tcx [GenericArg<'tcx>]) {
2069+
desc { "getting delegation user-specified args" }
2070+
}
2071+
20682072
/// Does lifetime resolution on items. Importantly, we can't resolve
20692073
/// lifetimes directly on things like trait methods, because of trait params.
20702074
/// See `rustc_resolve::late::lifetimes` for details.

compiler/rustc_middle/src/query/erase.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,10 @@ impl<T0, T1> Erasable for (&'_ T0, &'_ T1) {
147147
type Storage = [u8; size_of::<(&'_ (), &'_ ())>()];
148148
}
149149

150+
impl<T0, T1> Erasable for (&'_ [T0], &'_ [T1]) {
151+
type Storage = [u8; size_of::<(&'_ [()], &'_ [()])>()];
152+
}
153+
150154
macro_rules! impl_erasable_for_types_with_no_type_params {
151155
($($ty:ty),+ $(,)?) => {
152156
$(

tests/ui/delegation/generics/generics-gen-args-errors.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ mod test_1 {
3636
//~| ERROR can't use generic parameters from outer item
3737
//~| ERROR: unresolved item provided when a constant was expected
3838
//~| ERROR: function takes 2 lifetime arguments but 0 lifetime arguments were supplied
39+
//~| ERROR: inferred lifetimes are not allowed in delegations as we need to inherit signature
3940
}
4041
}
4142

@@ -44,36 +45,45 @@ mod test_2 {
4445

4546
reuse foo::<> as bar1;
4647
//~^ ERROR: the placeholder `_` is not allowed within types on item signatures for functions
48+
//~| ERROR: inferred lifetimes are not allowed in delegations as we need to inherit signature
4749

4850
reuse foo::<String, String> as bar2;
4951
//~^ ERROR: function takes 3 generic arguments but 2 generic arguments were supplied
5052
//~| ERROR: function takes 2 lifetime arguments but 0 lifetime arguments were supplied
53+
//~| ERROR: inferred lifetimes are not allowed in delegations as we need to inherit signature
5154

5255
reuse foo::<'static, _, 'asdasd, 'static, 'static, 'static, _> as bar3;
5356
//~^ ERROR: use of undeclared lifetime name `'asdasd`
5457
//~| ERROR: function takes 2 lifetime arguments but 5 lifetime arguments were supplied
5558
//~| ERROR: function takes 3 generic arguments but 2 generic arguments were supplied
59+
//~| ERROR: inferred lifetimes are not allowed in delegations as we need to inherit signature
60+
5661
reuse foo::<String, 'static, 123, asdasd> as bar4;
5762
//~^ ERROR: cannot find type `asdasd` in this scope
5863
//~| ERROR: function takes 2 lifetime arguments but 1 lifetime argument was supplied
64+
//~| ERROR: inferred lifetimes are not allowed in delegations as we need to inherit signature
5965

6066
reuse foo::<1, 2, _, 4, 5, _> as bar5;
6167
//~^ ERROR: function takes 3 generic arguments but 6 generic arguments were supplied
6268
//~| ERROR: function takes 2 lifetime arguments but 0 lifetime arguments were supplied
69+
//~| ERROR: inferred lifetimes are not allowed in delegations as we need to inherit signature
6370

6471
reuse foo::<1, 2,asd,String, { let x = 0; }> as bar6;
6572
//~^ ERROR: cannot find type `asd` in this scope
6673
//~| ERROR: function takes 3 generic arguments but 5 generic arguments were supplied
6774
//~| ERROR: function takes 2 lifetime arguments but 0 lifetime arguments were supplied
75+
//~| ERROR: inferred lifetimes are not allowed in delegations as we need to inherit signature
6876

6977
reuse foo::<"asdasd", asd, "askdn", 'static, 'a> as bar7;
7078
//~^ ERROR: use of undeclared lifetime name `'a`
7179
//~| ERROR: cannot find type `asd` in this scope
7280
//~| ERROR: constant provided when a type was expected
81+
//~| ERROR: inferred lifetimes are not allowed in delegations as we need to inherit signature
7382

7483
reuse foo::<{}, {}, {}> as bar8;
7584
//~^ ERROR: constant provided when a type was expected
7685
//~| ERROR: function takes 2 lifetime arguments but 0 lifetime arguments were supplied
86+
//~| ERROR: inferred lifetimes are not allowed in delegations as we need to inherit signature
7787
}
7888

7989
mod test_3 {
@@ -90,34 +100,43 @@ mod test_3 {
90100
//~| ERROR: cannot find type `asdasa` in this scope
91101
//~| ERROR: trait takes 3 lifetime arguments but 0 lifetime arguments were supplied
92102
//~| ERROR: trait takes 2 generic arguments but 6 generic arguments were supplied
103+
//~| ERROR: inferred lifetimes are not allowed in delegations as we need to inherit signature
93104

94105
reuse Trait::<'static, 'static>::foo as bar2;
95106
//~^ ERROR: trait takes 3 lifetime arguments but 2 lifetime arguments were supplied
96107
//~| ERROR: the placeholder `_` is not allowed within types on item signatures for functions
108+
//~| ERROR: inferred lifetimes are not allowed in delegations as we need to inherit signature
97109
reuse Trait::<1, 2, 3, 4, 5>::foo as bar3;
98110
//~^ ERROR: trait takes 3 lifetime arguments but 0 lifetime arguments were supplied
99111
//~| ERROR: trait takes 2 generic arguments but 5 generic arguments were supplied
112+
//~| ERROR: inferred lifetimes are not allowed in delegations as we need to inherit signature
100113

101114
reuse Trait::<1, 2, true>::foo as bar4;
102115
//~^ ERROR: trait takes 3 lifetime arguments but 0 lifetime arguments were supplied
103116
//~| ERROR: trait takes 2 generic arguments but 3 generic arguments were supplied
117+
//~| ERROR: inferred lifetimes are not allowed in delegations as we need to inherit signature
104118

105119
reuse Trait::<'static>::foo as bar5;
106120
//~^ ERROR: trait takes 3 lifetime arguments but 1 lifetime argument was supplied
107121
//~| ERROR: the placeholder `_` is not allowed within types on item signatures for functions
122+
//~| ERROR: inferred lifetimes are not allowed in delegations as we need to inherit signature
108123

109124
reuse Trait::<1, 2, 'static, DDDD>::foo::<1, 2, 3, 4, 5, 6> as bar6;
110125
//~^ ERROR: cannot find type `DDDD` in this scope [E0425]
111126
//~| ERROR: trait takes 3 lifetime arguments but 1 lifetime argument was supplied
112127
//~| ERROR: trait takes 2 generic arguments but 3 generic arguments were supplied
113128
//~| ERROR: method takes 2 generic arguments but 6 generic arguments were supplied
114129
//~| ERROR: method takes 1 lifetime argument but 0 lifetime arguments were supplied
130+
//~| ERROR: inferred lifetimes are not allowed in delegations as we need to inherit signature
131+
//~| ERROR: inferred lifetimes are not allowed in delegations as we need to inherit signature
115132

116133
reuse Trait::<Trait, Clone, _, 'static, dyn Send, _>::foo::<1, 2, 3, _, 6> as bar7;
117134
//~^ ERROR: trait takes 3 lifetime arguments but 1 lifetime argument was supplied
118135
//~| ERROR: trait takes 2 generic arguments but 5 generic arguments were supplied
119136
//~| ERROR: method takes 2 generic arguments but 5 generic arguments were supplied
120137
//~| ERROR: method takes 1 lifetime argument but 0 lifetime arguments were supplied
138+
//~| ERROR: inferred lifetimes are not allowed in delegations as we need to inherit signature
139+
//~| ERROR: inferred lifetimes are not allowed in delegations as we need to inherit signature
121140
}
122141

123142
fn main() {}

0 commit comments

Comments
 (0)