Skip to content

Commit 66ccf36

Browse files
committed
Auto merge of rust-lang#104711 - Dylan-DPC:rollup-gkw1qr8, r=Dylan-DPC
Rollup of 6 pull requests Successful merges: - rust-lang#104295 (Check generics parity before collecting return-position `impl Trait`s in trait) - rust-lang#104464 (Reduce exceptions overallocation on non Windows x86_64) - rust-lang#104615 (Create def_id for async fns during lowering) - rust-lang#104669 (Only declare bindings for if-let guards once per arm) - rust-lang#104701 (Remove a lifetime resolution hack from `compare_predicate_entailment`) - rust-lang#104710 (disable strict-provenance-violating doctests in Miri) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
2 parents b7463e8 + a40659d commit 66ccf36

File tree

15 files changed

+114
-69
lines changed

15 files changed

+114
-69
lines changed

compiler/rustc_ast_lowering/src/lib.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -1817,9 +1817,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
18171817

18181818
let opaque_ty_span = self.mark_span_with_reason(DesugaringKind::Async, span, None);
18191819

1820-
let opaque_ty_def_id = self.local_def_id(opaque_ty_node_id);
18211820
let fn_def_id = self.local_def_id(fn_node_id);
18221821

1822+
let opaque_ty_def_id =
1823+
self.create_def(fn_def_id, opaque_ty_node_id, DefPathData::ImplTrait);
1824+
18231825
// When we create the opaque type for this async fn, it is going to have
18241826
// to capture all the lifetimes involved in the signature (including in the
18251827
// return type). This is done by introducing lifetime parameters for:

compiler/rustc_hir_analysis/src/check/compare_method.rs

+37-43
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,8 @@ use rustc_infer::traits::util;
1414
use rustc_middle::ty::error::{ExpectedFound, TypeError};
1515
use rustc_middle::ty::util::ExplicitSelf;
1616
use rustc_middle::ty::{
17-
self, AssocItem, DefIdTree, TraitRef, Ty, TypeFoldable, TypeFolder, TypeSuperFoldable,
18-
TypeVisitable,
17+
self, DefIdTree, InternalSubsts, Ty, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitable,
1918
};
20-
use rustc_middle::ty::{FnSig, InternalSubsts};
2119
use rustc_middle::ty::{GenericParamDefKind, ToPredicate, TyCtxt};
2220
use rustc_span::Span;
2321
use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt;
@@ -51,11 +49,11 @@ pub(crate) fn compare_impl_method<'tcx>(
5149
return;
5250
}
5351

54-
if let Err(_) = compare_number_of_generics(tcx, impl_m, impl_m_span, trait_m, trait_item_span) {
52+
if let Err(_) = compare_number_of_generics(tcx, impl_m, trait_m, trait_item_span, false) {
5553
return;
5654
}
5755

58-
if let Err(_) = compare_generic_param_kinds(tcx, impl_m, trait_m) {
56+
if let Err(_) = compare_generic_param_kinds(tcx, impl_m, trait_m, false) {
5957
return;
6058
}
6159

@@ -144,9 +142,9 @@ pub(crate) fn compare_impl_method<'tcx>(
144142
#[instrument(level = "debug", skip(tcx, impl_m_span, impl_trait_ref))]
145143
fn compare_predicate_entailment<'tcx>(
146144
tcx: TyCtxt<'tcx>,
147-
impl_m: &AssocItem,
145+
impl_m: &ty::AssocItem,
148146
impl_m_span: Span,
149-
trait_m: &AssocItem,
147+
trait_m: &ty::AssocItem,
150148
impl_trait_ref: ty::TraitRef<'tcx>,
151149
) -> Result<(), ErrorGuaranteed> {
152150
let trait_to_impl_substs = impl_trait_ref.substs;
@@ -157,8 +155,7 @@ fn compare_predicate_entailment<'tcx>(
157155
// FIXME(@lcnr): remove that after removing `cause.body_id` from
158156
// obligations.
159157
let impl_m_hir_id = tcx.hir().local_def_id_to_hir_id(impl_m.def_id.expect_local());
160-
// We sometimes modify the span further down.
161-
let mut cause = ObligationCause::new(
158+
let cause = ObligationCause::new(
162159
impl_m_span,
163160
impl_m_hir_id,
164161
ObligationCauseCode::CompareImplItemObligation {
@@ -291,30 +288,19 @@ fn compare_predicate_entailment<'tcx>(
291288
// type would be more appropriate. In other places we have a `Vec<Span>`
292289
// corresponding to their `Vec<Predicate>`, but we don't have that here.
293290
// Fixing this would improve the output of test `issue-83765.rs`.
294-
let mut result = ocx.sup(&cause, param_env, trait_fty, impl_fty);
295-
296-
// HACK(RPITIT): #101614. When we are trying to infer the hidden types for
297-
// RPITITs, we need to equate the output tys instead of just subtyping. If
298-
// we just use `sup` above, we'll end up `&'static str <: _#1t`, which causes
299-
// us to infer `_#1t = #'_#2r str`, where `'_#2r` is unconstrained, which gets
300-
// fixed up to `ReEmpty`, and which is certainly not what we want.
301-
if trait_fty.has_infer_types() {
302-
result =
303-
result.and_then(|()| ocx.eq(&cause, param_env, trait_sig.output(), impl_sig.output()));
304-
}
291+
let result = ocx.sup(&cause, param_env, trait_fty, impl_fty);
305292

306293
if let Err(terr) = result {
307294
debug!(?terr, "sub_types failed: impl ty {:?}, trait ty {:?}", impl_fty, trait_fty);
308295

309296
let emitted = report_trait_method_mismatch(
310-
tcx,
311-
&mut cause,
312297
&infcx,
298+
cause,
313299
terr,
314300
(trait_m, trait_fty),
315301
(impl_m, impl_fty),
316-
&trait_sig,
317-
&impl_trait_ref,
302+
trait_sig,
303+
impl_trait_ref,
318304
);
319305
return Err(emitted);
320306
}
@@ -352,11 +338,15 @@ pub fn collect_trait_impl_trait_tys<'tcx>(
352338
let impl_trait_ref = tcx.impl_trait_ref(impl_m.impl_container(tcx).unwrap()).unwrap();
353339
let param_env = tcx.param_env(def_id);
354340

341+
// First, check a few of the same thing as `compare_impl_method`, just so we don't ICE during substitutions later.
342+
compare_number_of_generics(tcx, impl_m, trait_m, tcx.hir().span_if_local(impl_m.def_id), true)?;
343+
compare_generic_param_kinds(tcx, impl_m, trait_m, true)?;
344+
355345
let trait_to_impl_substs = impl_trait_ref.substs;
356346

357347
let impl_m_hir_id = tcx.hir().local_def_id_to_hir_id(impl_m.def_id.expect_local());
358348
let return_span = tcx.hir().fn_decl_by_hir_id(impl_m_hir_id).unwrap().output.span();
359-
let mut cause = ObligationCause::new(
349+
let cause = ObligationCause::new(
360350
return_span,
361351
impl_m_hir_id,
362352
ObligationCauseCode::CompareImplItemObligation {
@@ -376,6 +366,7 @@ pub fn collect_trait_impl_trait_tys<'tcx>(
376366
let infcx = &tcx.infer_ctxt().build();
377367
let ocx = ObligationCtxt::new(infcx);
378368

369+
// Normalize the impl signature with fresh variables for lifetime inference.
379370
let norm_cause = ObligationCause::misc(return_span, impl_m_hir_id);
380371
let impl_sig = ocx.normalize(
381372
norm_cause.clone(),
@@ -388,6 +379,10 @@ pub fn collect_trait_impl_trait_tys<'tcx>(
388379
);
389380
let impl_return_ty = impl_sig.output();
390381

382+
// Normalize the trait signature with liberated bound vars, passing it through
383+
// the ImplTraitInTraitCollector, which gathers all of the RPITITs and replaces
384+
// them with inference variables.
385+
// We will use these inference variables to collect the hidden types of RPITITs.
391386
let mut collector = ImplTraitInTraitCollector::new(&ocx, return_span, param_env, impl_m_hir_id);
392387
let unnormalized_trait_sig = tcx
393388
.liberate_late_bound_regions(
@@ -448,14 +443,13 @@ pub fn collect_trait_impl_trait_tys<'tcx>(
448443
// emit an error now because `compare_predicate_entailment` will not report the error
449444
// when normalization fails.
450445
let emitted = report_trait_method_mismatch(
451-
tcx,
452-
&mut cause,
453446
infcx,
447+
cause,
454448
terr,
455449
(trait_m, trait_fty),
456450
(impl_m, impl_fty),
457-
&trait_sig,
458-
&impl_trait_ref,
451+
trait_sig,
452+
impl_trait_ref,
459453
);
460454
return Err(emitted);
461455
}
@@ -625,23 +619,21 @@ impl<'tcx> TypeFolder<'tcx> for ImplTraitInTraitCollector<'_, 'tcx> {
625619
}
626620

627621
fn report_trait_method_mismatch<'tcx>(
628-
tcx: TyCtxt<'tcx>,
629-
cause: &mut ObligationCause<'tcx>,
630622
infcx: &InferCtxt<'tcx>,
623+
mut cause: ObligationCause<'tcx>,
631624
terr: TypeError<'tcx>,
632-
(trait_m, trait_fty): (&AssocItem, Ty<'tcx>),
633-
(impl_m, impl_fty): (&AssocItem, Ty<'tcx>),
634-
trait_sig: &FnSig<'tcx>,
635-
impl_trait_ref: &TraitRef<'tcx>,
625+
(trait_m, trait_fty): (&ty::AssocItem, Ty<'tcx>),
626+
(impl_m, impl_fty): (&ty::AssocItem, Ty<'tcx>),
627+
trait_sig: ty::FnSig<'tcx>,
628+
impl_trait_ref: ty::TraitRef<'tcx>,
636629
) -> ErrorGuaranteed {
630+
let tcx = infcx.tcx;
637631
let (impl_err_span, trait_err_span) =
638632
extract_spans_for_error_reporting(&infcx, terr, &cause, impl_m, trait_m);
639633

640-
cause.span = impl_err_span;
641-
642634
let mut diag = struct_span_err!(
643635
tcx.sess,
644-
cause.span(),
636+
impl_err_span,
645637
E0053,
646638
"method `{}` has an incompatible type for trait",
647639
trait_m.name
@@ -712,6 +704,7 @@ fn report_trait_method_mismatch<'tcx>(
712704
_ => {}
713705
}
714706

707+
cause.span = impl_err_span;
715708
infcx.err_ctxt().note_type_err(
716709
&mut diag,
717710
&cause,
@@ -922,9 +915,9 @@ fn compare_self_type<'tcx>(
922915
fn compare_number_of_generics<'tcx>(
923916
tcx: TyCtxt<'tcx>,
924917
impl_: &ty::AssocItem,
925-
_impl_span: Span,
926918
trait_: &ty::AssocItem,
927919
trait_span: Option<Span>,
920+
delay: bool,
928921
) -> Result<(), ErrorGuaranteed> {
929922
let trait_own_counts = tcx.generics_of(trait_.def_id).own_counts();
930923
let impl_own_counts = tcx.generics_of(impl_.def_id).own_counts();
@@ -1054,7 +1047,7 @@ fn compare_number_of_generics<'tcx>(
10541047
err.span_label(*span, "`impl Trait` introduces an implicit type parameter");
10551048
}
10561049

1057-
let reported = err.emit();
1050+
let reported = err.emit_unless(delay);
10581051
err_occurred = Some(reported);
10591052
}
10601053
}
@@ -1306,6 +1299,7 @@ fn compare_generic_param_kinds<'tcx>(
13061299
tcx: TyCtxt<'tcx>,
13071300
impl_item: &ty::AssocItem,
13081301
trait_item: &ty::AssocItem,
1302+
delay: bool,
13091303
) -> Result<(), ErrorGuaranteed> {
13101304
assert_eq!(impl_item.kind, trait_item.kind);
13111305

@@ -1363,7 +1357,7 @@ fn compare_generic_param_kinds<'tcx>(
13631357
err.span_label(impl_header_span, "");
13641358
err.span_label(param_impl_span, make_param_message("found", param_impl));
13651359

1366-
let reported = err.emit();
1360+
let reported = err.emit_unless(delay);
13671361
return Err(reported);
13681362
}
13691363
}
@@ -1489,9 +1483,9 @@ pub(crate) fn compare_ty_impl<'tcx>(
14891483
debug!("compare_impl_type(impl_trait_ref={:?})", impl_trait_ref);
14901484

14911485
let _: Result<(), ErrorGuaranteed> = (|| {
1492-
compare_number_of_generics(tcx, impl_ty, impl_ty_span, trait_ty, trait_item_span)?;
1486+
compare_number_of_generics(tcx, impl_ty, trait_ty, trait_item_span, false)?;
14931487

1494-
compare_generic_param_kinds(tcx, impl_ty, trait_ty)?;
1488+
compare_generic_param_kinds(tcx, impl_ty, trait_ty, false)?;
14951489

14961490
let sp = tcx.def_span(impl_ty.def_id);
14971491
compare_type_predicate_entailment(tcx, impl_ty, sp, trait_ty, impl_trait_ref)?;

compiler/rustc_mir_build/src/build/block.rs

+3-4
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
use crate::build::matches::ArmHasGuard;
21
use crate::build::ForGuard::OutsideGuard;
32
use crate::build::{BlockAnd, BlockAndExtension, BlockFrame, Builder};
43
use rustc_middle::middle::region::Scope;
@@ -231,7 +230,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
231230
visibility_scope,
232231
remainder_span,
233232
pattern,
234-
ArmHasGuard(false),
233+
None,
235234
Some((None, initializer_span)),
236235
);
237236
this.visit_primary_bindings(
@@ -308,7 +307,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
308307
visibility_scope,
309308
remainder_span,
310309
pattern,
311-
ArmHasGuard(false),
310+
None,
312311
Some((None, initializer_span)),
313312
);
314313
this.expr_into_pattern(block, &pattern, init)
@@ -324,7 +323,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
324323
visibility_scope,
325324
remainder_span,
326325
pattern,
327-
ArmHasGuard(false),
326+
None,
328327
None,
329328
);
330329
block.unit()

compiler/rustc_mir_build/src/build/expr/into.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
108108
ExprKind::Let { expr, ref pat } => {
109109
let scope = this.local_scope();
110110
let (true_block, false_block) = this.in_if_then_scope(scope, expr_span, |this| {
111-
this.lower_let_expr(block, &this.thir[expr], pat, scope, None, expr_span)
111+
this.lower_let_expr(block, &this.thir[expr], pat, scope, None, expr_span, true)
112112
});
113113

114114
this.cfg.push_assign_constant(

compiler/rustc_mir_build/src/build/matches/mod.rs

+15-11
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
8484
break_scope,
8585
Some(variable_source_info.scope),
8686
variable_source_info.span,
87+
true,
8788
),
8889
_ => {
8990
let temp_scope = temp_scope_override.unwrap_or_else(|| this.local_scope());
@@ -357,7 +358,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
357358
None,
358359
arm.span,
359360
&arm.pattern,
360-
ArmHasGuard(arm.guard.is_some()),
361+
arm.guard.as_ref(),
361362
opt_scrutinee_place,
362363
);
363364

@@ -645,7 +646,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
645646
mut visibility_scope: Option<SourceScope>,
646647
scope_span: Span,
647648
pattern: &Pat<'tcx>,
648-
has_guard: ArmHasGuard,
649+
guard: Option<&Guard<'tcx>>,
649650
opt_match_place: Option<(Option<&Place<'tcx>>, Span)>,
650651
) -> Option<SourceScope> {
651652
self.visit_primary_bindings(
@@ -667,12 +668,16 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
667668
var,
668669
ty,
669670
user_ty,
670-
has_guard,
671+
ArmHasGuard(guard.is_some()),
671672
opt_match_place.map(|(x, y)| (x.cloned(), y)),
672673
pattern.span,
673674
);
674675
},
675676
);
677+
if let Some(Guard::IfLet(guard_pat, _)) = guard {
678+
// FIXME: pass a proper `opt_match_place`
679+
self.declare_bindings(visibility_scope, scope_span, guard_pat, None, None);
680+
}
676681
visibility_scope
677682
}
678683

@@ -1766,6 +1771,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
17661771
// Pat binding - used for `let` and function parameters as well.
17671772

17681773
impl<'a, 'tcx> Builder<'a, 'tcx> {
1774+
/// If the bindings have already been declared, set `declare_bindings` to
1775+
/// `false` to avoid duplicated bindings declaration. Used for if-let guards.
17691776
pub(crate) fn lower_let_expr(
17701777
&mut self,
17711778
mut block: BasicBlock,
@@ -1774,6 +1781,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
17741781
else_target: region::Scope,
17751782
source_scope: Option<SourceScope>,
17761783
span: Span,
1784+
declare_bindings: bool,
17771785
) -> BlockAnd<()> {
17781786
let expr_span = expr.span;
17791787
let expr_place_builder = unpack!(block = self.lower_scrutinee(block, expr, expr_span));
@@ -1797,13 +1805,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
17971805
let otherwise_post_guard_block = otherwise_candidate.pre_binding_block.unwrap();
17981806
self.break_for_else(otherwise_post_guard_block, else_target, self.source_info(expr_span));
17991807

1800-
self.declare_bindings(
1801-
source_scope,
1802-
pat.span.to(span),
1803-
pat,
1804-
ArmHasGuard(false),
1805-
opt_expr_place,
1806-
);
1808+
if declare_bindings {
1809+
self.declare_bindings(source_scope, pat.span.to(span), pat, None, opt_expr_place);
1810+
}
18071811

18081812
let post_guard_block = self.bind_pattern(
18091813
self.source_info(pat.span),
@@ -1984,7 +1988,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
19841988
Guard::IfLet(ref pat, scrutinee) => {
19851989
let s = &this.thir[scrutinee];
19861990
guard_span = s.span;
1987-
this.lower_let_expr(block, s, pat, match_scope, None, arm.span)
1991+
this.lower_let_expr(block, s, pat, match_scope, None, arm.span, false)
19881992
}
19891993
});
19901994

compiler/rustc_mir_build/src/build/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -924,7 +924,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
924924
scope,
925925
expr.span,
926926
&pat,
927-
matches::ArmHasGuard(false),
927+
None,
928928
Some((Some(&place), span)),
929929
);
930930
let place_builder = PlaceBuilder::from(local);

compiler/rustc_resolve/src/def_collector.rs

+2-7
Original file line numberDiff line numberDiff line change
@@ -131,22 +131,17 @@ impl<'a, 'b> visit::Visitor<'a> for DefCollector<'a, 'b> {
131131

132132
fn visit_fn(&mut self, fn_kind: FnKind<'a>, span: Span, _: NodeId) {
133133
if let FnKind::Fn(_, _, sig, _, generics, body) = fn_kind {
134-
if let Async::Yes { closure_id, return_impl_trait_id, .. } = sig.header.asyncness {
134+
if let Async::Yes { closure_id, .. } = sig.header.asyncness {
135135
self.visit_generics(generics);
136136

137-
let return_impl_trait_id =
138-
self.create_def(return_impl_trait_id, DefPathData::ImplTrait, span);
139-
140137
// For async functions, we need to create their inner defs inside of a
141138
// closure to match their desugared representation. Besides that,
142139
// we must mirror everything that `visit::walk_fn` below does.
143140
self.visit_fn_header(&sig.header);
144141
for param in &sig.decl.inputs {
145142
self.visit_param(param);
146143
}
147-
self.with_parent(return_impl_trait_id, |this| {
148-
this.visit_fn_ret_ty(&sig.decl.output)
149-
});
144+
self.visit_fn_ret_ty(&sig.decl.output);
150145
// If this async fn has no body (i.e. it's an async fn signature in a trait)
151146
// then the closure_def will never be used, and we should avoid generating a
152147
// def-id for it.

0 commit comments

Comments
 (0)