Skip to content

Commit 1db0925

Browse files
committed
Make fn late-bound lifetimes part of the generics.
1 parent d7cc37c commit 1db0925

File tree

31 files changed

+335
-362
lines changed

31 files changed

+335
-362
lines changed

compiler/rustc_const_eval/src/const_eval/machine.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ impl<'mir, 'tcx> InterpCx<'mir, 'tcx, CompileTimeInterpreter<'mir, 'tcx>> {
5858
*self.tcx,
5959
ty::ParamEnv::reveal_all(),
6060
const_panic_fmt,
61-
self.tcx.intern_substs(&[]),
61+
self.tcx.intern_substs(&[self.tcx.lifetimes.re_erased.into()]),
6262
)
6363
.unwrap()
6464
.unwrap(),

compiler/rustc_hir_analysis/src/check/check.rs

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -290,7 +290,7 @@ pub(super) fn check_opaque_for_inheriting_lifetimes<'tcx>(
290290
type BreakTy = Ty<'tcx>;
291291

292292
fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
293-
debug!("check_opaque_for_inheriting_lifetimes: (visit_ty) t={:?}", t);
293+
debug!("(visit_ty) t={:?}", t);
294294
if t == self.opaque_identity_ty {
295295
ControlFlow::CONTINUE
296296
} else {
@@ -328,14 +328,18 @@ pub(super) fn check_opaque_for_inheriting_lifetimes<'tcx>(
328328

329329
if let ItemKind::OpaqueTy(hir::OpaqueTy {
330330
origin: hir::OpaqueTyOrigin::AsyncFn(..) | hir::OpaqueTyOrigin::FnReturn(..),
331+
in_trait,
331332
..
332333
}) = item.kind
333334
{
335+
let substs = InternalSubsts::identity_for_item(tcx, def_id.to_def_id());
336+
let opaque_identity_ty = if in_trait {
337+
tcx.mk_projection(def_id.to_def_id(), substs)
338+
} else {
339+
tcx.mk_opaque(def_id.to_def_id(), substs)
340+
};
334341
let mut visitor = ProhibitOpaqueVisitor {
335-
opaque_identity_ty: tcx.mk_opaque(
336-
def_id.to_def_id(),
337-
InternalSubsts::identity_for_item(tcx, def_id.to_def_id()),
338-
),
342+
opaque_identity_ty,
339343
generics: tcx.generics_of(def_id),
340344
tcx,
341345
selftys: vec![],
@@ -344,10 +348,7 @@ pub(super) fn check_opaque_for_inheriting_lifetimes<'tcx>(
344348
.explicit_item_bounds(def_id)
345349
.iter()
346350
.try_for_each(|(predicate, _)| predicate.visit_with(&mut visitor));
347-
debug!(
348-
"check_opaque_for_inheriting_lifetimes: prohibit_opaque={:?}, visitor.opaque_identity_ty={:?}, visitor.generics={:?}",
349-
prohibit_opaque, visitor.opaque_identity_ty, visitor.generics
350-
);
351+
debug!(?prohibit_opaque);
351352

352353
if let Some(ty) = prohibit_opaque.break_value() {
353354
visitor.visit_item(&item);

compiler/rustc_hir_analysis/src/check/compare_method.rs

Lines changed: 30 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,7 @@ fn compare_predicate_entailment<'tcx>(
149149
impl_trait_ref: ty::TraitRef<'tcx>,
150150
) -> Result<(), ErrorGuaranteed> {
151151
let trait_to_impl_substs = impl_trait_ref.substs;
152+
debug!(?trait_to_impl_substs);
152153

153154
// This node-id should be used for the `body_id` field on each
154155
// `ObligationCause` (and the `FnCtxt`).
@@ -173,7 +174,7 @@ fn compare_predicate_entailment<'tcx>(
173174
// Create mapping from trait to placeholder.
174175
let trait_to_placeholder_substs =
175176
impl_to_placeholder_substs.rebase_onto(tcx, impl_m.container_id(tcx), trait_to_impl_substs);
176-
debug!("compare_impl_method: trait_to_placeholder_substs={:?}", trait_to_placeholder_substs);
177+
debug!(?trait_to_placeholder_substs);
177178

178179
let impl_m_generics = tcx.generics_of(impl_m.def_id);
179180
let trait_m_generics = tcx.generics_of(trait_m.def_id);
@@ -191,7 +192,7 @@ fn compare_predicate_entailment<'tcx>(
191192
let impl_predicates = tcx.predicates_of(impl_m_predicates.parent.unwrap());
192193
let mut hybrid_preds = impl_predicates.instantiate_identity(tcx);
193194

194-
debug!("compare_impl_method: impl_bounds={:?}", hybrid_preds);
195+
debug!("impl_bounds={:?}", hybrid_preds);
195196

196197
// This is the only tricky bit of the new way we check implementation methods
197198
// We need to build a set of predicates where only the method-level bounds
@@ -218,7 +219,7 @@ fn compare_predicate_entailment<'tcx>(
218219
let infcx = &tcx.infer_ctxt().build();
219220
let ocx = ObligationCtxt::new(infcx);
220221

221-
debug!("compare_impl_method: caller_bounds={:?}", param_env.caller_bounds());
222+
debug!("caller_bounds={:?}", param_env.caller_bounds());
222223

223224
let mut selcx = traits::SelectionContext::new(&infcx);
224225
let impl_m_own_bounds = impl_m_predicates.instantiate_own(tcx, impl_to_placeholder_substs);
@@ -258,18 +259,17 @@ fn compare_predicate_entailment<'tcx>(
258259

259260
let mut wf_tys = FxHashSet::default();
260261

261-
let impl_sig = infcx.replace_bound_vars_with_fresh_vars(
262-
impl_m_span,
263-
infer::HigherRankedType,
264-
tcx.fn_sig(impl_m.def_id),
265-
);
262+
let impl_sig = tcx.mk_fn_def(impl_m.def_id, impl_to_placeholder_substs).fn_sig(tcx);
263+
let impl_sig =
264+
infcx.replace_bound_vars_with_fresh_vars(impl_m_span, infer::HigherRankedType, impl_sig);
266265

267266
let norm_cause = ObligationCause::misc(impl_m_span, impl_m_hir_id);
268267
let impl_sig = ocx.normalize(norm_cause.clone(), param_env, impl_sig);
269268
let impl_fty = tcx.mk_fn_ptr(ty::Binder::dummy(impl_sig));
270-
debug!("compare_impl_method: impl_fty={:?}", impl_fty);
269+
debug!(?impl_fty);
271270

272-
let trait_sig = tcx.bound_fn_sig(trait_m.def_id).subst(tcx, trait_to_placeholder_substs);
271+
let trait_sig = tcx.type_of(trait_m.def_id).fn_sig(tcx);
272+
let trait_sig = ty::EarlyBinder(trait_sig).subst(tcx, trait_to_placeholder_substs);
273273
let trait_sig = tcx.liberate_late_bound_regions(impl_m.def_id, trait_sig);
274274

275275
// Next, add all inputs and output as well-formed tys. Importantly,
@@ -281,8 +281,7 @@ fn compare_predicate_entailment<'tcx>(
281281
// as we don't normalize during implied bounds computation.
282282
wf_tys.extend(trait_sig.inputs_and_output.iter());
283283
let trait_fty = tcx.mk_fn_ptr(ty::Binder::dummy(trait_sig));
284-
285-
debug!("compare_impl_method: trait_fty={:?}", trait_fty);
284+
debug!(?trait_fty);
286285

287286
// FIXME: We'd want to keep more accurate spans than "the method signature" when
288287
// processing the comparison between the trait and impl fn, but we sadly lose them
@@ -431,6 +430,7 @@ fn compare_predicate_entailment<'tcx>(
431430
Ok(())
432431
}
433432

433+
#[instrument(level = "debug", skip(tcx), ret)]
434434
pub fn collect_trait_impl_trait_tys<'tcx>(
435435
tcx: TyCtxt<'tcx>,
436436
def_id: DefId,
@@ -464,25 +464,23 @@ pub fn collect_trait_impl_trait_tys<'tcx>(
464464
let infcx = &tcx.infer_ctxt().build();
465465
let ocx = ObligationCtxt::new(infcx);
466466

467+
let impl_sig = tcx.mk_fn_def(impl_m.def_id, impl_to_placeholder_substs).fn_sig(tcx);
468+
let impl_sig =
469+
infcx.replace_bound_vars_with_fresh_vars(return_span, infer::HigherRankedType, impl_sig);
470+
467471
let norm_cause = ObligationCause::misc(return_span, impl_m_hir_id);
468-
let impl_sig = ocx.normalize(
469-
norm_cause.clone(),
470-
param_env,
471-
infcx.replace_bound_vars_with_fresh_vars(
472-
return_span,
473-
infer::HigherRankedType,
474-
tcx.fn_sig(impl_m.def_id),
475-
),
476-
);
472+
let impl_sig = ocx.normalize(norm_cause.clone(), param_env, impl_sig);
477473
let impl_return_ty = impl_sig.output();
478474

475+
let unnormalized_trait_sig = tcx.type_of(trait_m.def_id).fn_sig(tcx);
476+
let unnormalized_trait_sig =
477+
ty::EarlyBinder(unnormalized_trait_sig).subst(tcx, trait_to_placeholder_substs);
478+
let unnormalized_trait_sig =
479+
tcx.liberate_late_bound_regions(impl_m.def_id, unnormalized_trait_sig);
480+
479481
let mut collector = ImplTraitInTraitCollector::new(&ocx, return_span, param_env, impl_m_hir_id);
480-
let unnormalized_trait_sig = tcx
481-
.liberate_late_bound_regions(
482-
impl_m.def_id,
483-
tcx.bound_fn_sig(trait_m.def_id).subst(tcx, trait_to_placeholder_substs),
484-
)
485-
.fold_with(&mut collector);
482+
let unnormalized_trait_sig = unnormalized_trait_sig.fold_with(&mut collector);
483+
486484
let trait_sig = ocx.normalize(norm_cause.clone(), param_env, unnormalized_trait_sig);
487485
let trait_return_ty = trait_sig.output();
488486

@@ -704,15 +702,11 @@ fn check_region_bounds_on_impl_item<'tcx>(
704702
trait_generics: &ty::Generics,
705703
impl_generics: &ty::Generics,
706704
) -> Result<(), ErrorGuaranteed> {
707-
let trait_params = trait_generics.own_counts().lifetimes;
708-
let impl_params = impl_generics.own_counts().lifetimes;
709-
710-
debug!(
711-
"check_region_bounds_on_impl_item: \
712-
trait_generics={:?} \
713-
impl_generics={:?}",
714-
trait_generics, impl_generics
715-
);
705+
// For backwards compatibility reasons, we can only check that we have the correct amount
706+
// of early-bound lifetimes. The user is allowed to introduce as many late-bound lifetime
707+
// as they want.
708+
let trait_params = trait_generics.own_counts().early_lifetimes;
709+
let impl_params = impl_generics.own_counts().early_lifetimes;
716710

717711
// Must have same number of early-bound lifetime parameters.
718712
// Unfortunately, if the user screws up the bounds, then this

compiler/rustc_hir_analysis/src/check/intrinsic.rs

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -17,25 +17,23 @@ use rustc_target::spec::abi::Abi;
1717

1818
use std::iter;
1919

20+
#[instrument(level = "trace", skip(tcx))]
2021
fn equate_intrinsic_type<'tcx>(
2122
tcx: TyCtxt<'tcx>,
2223
it: &hir::ForeignItem<'_>,
2324
n_tps: usize,
2425
n_lts: usize,
2526
sig: ty::PolyFnSig<'tcx>,
2627
) {
27-
let (own_counts, span) = match &it.kind {
28-
hir::ForeignItemKind::Fn(.., generics) => {
29-
let own_counts = tcx.generics_of(it.def_id.to_def_id()).own_counts();
30-
(own_counts, generics.span)
31-
}
32-
_ => {
33-
struct_span_err!(tcx.sess, it.span, E0622, "intrinsic must be a function")
34-
.span_label(it.span, "expected a function")
35-
.emit();
36-
return;
37-
}
28+
let hir::ForeignItemKind::Fn(.., generics) = &it.kind else {
29+
struct_span_err!(tcx.sess, it.span, E0622, "intrinsic must be a function")
30+
.span_label(it.span, "expected a function")
31+
.emit();
32+
return;
3833
};
34+
let span = generics.span;
35+
let generics = tcx.generics_of(it.def_id.to_def_id());
36+
let own_counts = generics.own_counts();
3937

4038
let gen_count_ok = |found: usize, expected: usize, descr: &str| -> bool {
4139
if found != expected {
@@ -51,13 +49,15 @@ fn equate_intrinsic_type<'tcx>(
5149
}
5250
};
5351

54-
if gen_count_ok(own_counts.lifetimes, n_lts, "lifetime")
52+
if gen_count_ok(own_counts.early_lifetimes, n_lts, "lifetime")
5553
&& gen_count_ok(own_counts.types, n_tps, "type")
5654
&& gen_count_ok(own_counts.consts, 0, "const")
5755
{
5856
let fty = tcx.mk_fn_ptr(sig);
5957
let cause = ObligationCause::new(it.span, it.hir_id(), ObligationCauseCode::IntrinsicType);
60-
require_same_types(tcx, &cause, tcx.mk_fn_ptr(tcx.fn_sig(it.def_id)), fty);
58+
let fn_def = tcx.type_of(it.def_id).fn_sig(tcx);
59+
debug!(?fn_def);
60+
require_same_types(tcx, &cause, tcx.mk_fn_ptr(fn_def), fty);
6161
}
6262
}
6363

compiler/rustc_hir_analysis/src/collect.rs

Lines changed: 7 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -20,15 +20,14 @@ use crate::errors;
2020
use rustc_ast as ast;
2121
use rustc_ast::{MetaItemKind, NestedMetaItem};
2222
use rustc_attr::{list_contains_name, InlineAttr, InstructionSetAttr, OptimizeAttr};
23-
use rustc_data_structures::captures::Captures;
2423
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
2524
use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder, ErrorGuaranteed, StashKey};
2625
use rustc_hir as hir;
2726
use rustc_hir::def::CtorKind;
2827
use rustc_hir::def_id::{DefId, LocalDefId, LOCAL_CRATE};
2928
use rustc_hir::intravisit::{self, Visitor};
3029
use rustc_hir::weak_lang_items;
31-
use rustc_hir::{GenericParamKind, Node};
30+
use rustc_hir::Node;
3231
use rustc_middle::hir::nested_filter;
3332
use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs};
3433
use rustc_middle::mir::mono::Linkage;
@@ -1132,7 +1131,7 @@ fn fn_sig(tcx: TyCtxt<'_>, def_id: DefId) -> ty::PolyFnSig<'_> {
11321131

11331132
let icx = ItemCtxt::new(tcx, def_id.to_def_id());
11341133

1135-
match tcx.hir().get(hir_id) {
1134+
let sig = match tcx.hir().get(hir_id) {
11361135
TraitItem(hir::TraitItem {
11371136
kind: TraitItemKind::Fn(sig, TraitFn::Provided(_)),
11381137
generics,
@@ -1213,7 +1212,11 @@ fn fn_sig(tcx: TyCtxt<'_>, def_id: DefId) -> ty::PolyFnSig<'_> {
12131212
x => {
12141213
bug!("unexpected sort of node in fn_sig(): {:?}", x);
12151214
}
1216-
}
1215+
};
1216+
1217+
assert!(sig.no_bound_vars().is_some());
1218+
1219+
sig
12171220
}
12181221

12191222
fn infer_return_ty_for_fn_sig<'tcx>(
@@ -1335,21 +1338,6 @@ fn impl_polarity(tcx: TyCtxt<'_>, def_id: DefId) -> ty::ImplPolarity {
13351338
}
13361339
}
13371340

1338-
/// Returns the early-bound lifetimes declared in this generics
1339-
/// listing. For anything other than fns/methods, this is just all
1340-
/// the lifetimes that are declared. For fns or methods, we have to
1341-
/// screen out those that do not appear in any where-clauses etc using
1342-
/// `resolve_lifetime::early_bound_lifetimes`.
1343-
fn early_bound_lifetimes_from_generics<'a, 'tcx: 'a>(
1344-
tcx: TyCtxt<'tcx>,
1345-
generics: &'a hir::Generics<'a>,
1346-
) -> impl Iterator<Item = &'a hir::GenericParam<'a>> + Captures<'tcx> {
1347-
generics.params.iter().filter(move |param| match param.kind {
1348-
GenericParamKind::Lifetime { .. } => !tcx.is_late_bound(param.hir_id),
1349-
_ => false,
1350-
})
1351-
}
1352-
13531341
/// Returns a list of type predicates for the definition with ID `def_id`, including inferred
13541342
/// lifetime constraints. This includes all predicates returned by `explicit_predicates_of`, plus
13551343
/// inferred constraints concerning which regions outlive other regions.

0 commit comments

Comments
 (0)