Auto merge of #104711 - Dylan-DPC:rollup-gkw1qr8, r=Dylan-DPC
Rollup of 6 pull requests Successful merges: - #104295 (Check generics parity before collecting return-position `impl Trait`s in trait) - #104464 (Reduce exceptions overallocation on non Windows x86_64) - #104615 (Create def_id for async fns during lowering) - #104669 (Only declare bindings for if-let guards once per arm) - #104701 (Remove a lifetime resolution hack from `compare_predicate_entailment`) - #104710 (disable strict-provenance-violating doctests in Miri) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
66ccf36f16
15 changed files with 114 additions and 69 deletions
|
@ -1817,9 +1817,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
|
|
||||||
let opaque_ty_span = self.mark_span_with_reason(DesugaringKind::Async, span, None);
|
let opaque_ty_span = self.mark_span_with_reason(DesugaringKind::Async, span, None);
|
||||||
|
|
||||||
let opaque_ty_def_id = self.local_def_id(opaque_ty_node_id);
|
|
||||||
let fn_def_id = self.local_def_id(fn_node_id);
|
let fn_def_id = self.local_def_id(fn_node_id);
|
||||||
|
|
||||||
|
let opaque_ty_def_id =
|
||||||
|
self.create_def(fn_def_id, opaque_ty_node_id, DefPathData::ImplTrait);
|
||||||
|
|
||||||
// When we create the opaque type for this async fn, it is going to have
|
// When we create the opaque type for this async fn, it is going to have
|
||||||
// to capture all the lifetimes involved in the signature (including in the
|
// to capture all the lifetimes involved in the signature (including in the
|
||||||
// return type). This is done by introducing lifetime parameters for:
|
// return type). This is done by introducing lifetime parameters for:
|
||||||
|
|
|
@ -14,10 +14,8 @@ use rustc_infer::traits::util;
|
||||||
use rustc_middle::ty::error::{ExpectedFound, TypeError};
|
use rustc_middle::ty::error::{ExpectedFound, TypeError};
|
||||||
use rustc_middle::ty::util::ExplicitSelf;
|
use rustc_middle::ty::util::ExplicitSelf;
|
||||||
use rustc_middle::ty::{
|
use rustc_middle::ty::{
|
||||||
self, AssocItem, DefIdTree, TraitRef, Ty, TypeFoldable, TypeFolder, TypeSuperFoldable,
|
self, DefIdTree, InternalSubsts, Ty, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitable,
|
||||||
TypeVisitable,
|
|
||||||
};
|
};
|
||||||
use rustc_middle::ty::{FnSig, InternalSubsts};
|
|
||||||
use rustc_middle::ty::{GenericParamDefKind, ToPredicate, TyCtxt};
|
use rustc_middle::ty::{GenericParamDefKind, ToPredicate, TyCtxt};
|
||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt;
|
use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt;
|
||||||
|
@ -51,11 +49,11 @@ pub(crate) fn compare_impl_method<'tcx>(
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Err(_) = compare_number_of_generics(tcx, impl_m, impl_m_span, trait_m, trait_item_span) {
|
if let Err(_) = compare_number_of_generics(tcx, impl_m, trait_m, trait_item_span, false) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Err(_) = compare_generic_param_kinds(tcx, impl_m, trait_m) {
|
if let Err(_) = compare_generic_param_kinds(tcx, impl_m, trait_m, false) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -144,9 +142,9 @@ pub(crate) fn compare_impl_method<'tcx>(
|
||||||
#[instrument(level = "debug", skip(tcx, impl_m_span, impl_trait_ref))]
|
#[instrument(level = "debug", skip(tcx, impl_m_span, impl_trait_ref))]
|
||||||
fn compare_predicate_entailment<'tcx>(
|
fn compare_predicate_entailment<'tcx>(
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
impl_m: &AssocItem,
|
impl_m: &ty::AssocItem,
|
||||||
impl_m_span: Span,
|
impl_m_span: Span,
|
||||||
trait_m: &AssocItem,
|
trait_m: &ty::AssocItem,
|
||||||
impl_trait_ref: ty::TraitRef<'tcx>,
|
impl_trait_ref: ty::TraitRef<'tcx>,
|
||||||
) -> Result<(), ErrorGuaranteed> {
|
) -> Result<(), ErrorGuaranteed> {
|
||||||
let trait_to_impl_substs = impl_trait_ref.substs;
|
let trait_to_impl_substs = impl_trait_ref.substs;
|
||||||
|
@ -157,8 +155,7 @@ fn compare_predicate_entailment<'tcx>(
|
||||||
// FIXME(@lcnr): remove that after removing `cause.body_id` from
|
// FIXME(@lcnr): remove that after removing `cause.body_id` from
|
||||||
// obligations.
|
// obligations.
|
||||||
let impl_m_hir_id = tcx.hir().local_def_id_to_hir_id(impl_m.def_id.expect_local());
|
let impl_m_hir_id = tcx.hir().local_def_id_to_hir_id(impl_m.def_id.expect_local());
|
||||||
// We sometimes modify the span further down.
|
let cause = ObligationCause::new(
|
||||||
let mut cause = ObligationCause::new(
|
|
||||||
impl_m_span,
|
impl_m_span,
|
||||||
impl_m_hir_id,
|
impl_m_hir_id,
|
||||||
ObligationCauseCode::CompareImplItemObligation {
|
ObligationCauseCode::CompareImplItemObligation {
|
||||||
|
@ -291,30 +288,19 @@ fn compare_predicate_entailment<'tcx>(
|
||||||
// type would be more appropriate. In other places we have a `Vec<Span>`
|
// type would be more appropriate. In other places we have a `Vec<Span>`
|
||||||
// corresponding to their `Vec<Predicate>`, but we don't have that here.
|
// corresponding to their `Vec<Predicate>`, but we don't have that here.
|
||||||
// Fixing this would improve the output of test `issue-83765.rs`.
|
// Fixing this would improve the output of test `issue-83765.rs`.
|
||||||
let mut result = ocx.sup(&cause, param_env, trait_fty, impl_fty);
|
let result = ocx.sup(&cause, param_env, trait_fty, impl_fty);
|
||||||
|
|
||||||
// HACK(RPITIT): #101614. When we are trying to infer the hidden types for
|
|
||||||
// RPITITs, we need to equate the output tys instead of just subtyping. If
|
|
||||||
// we just use `sup` above, we'll end up `&'static str <: _#1t`, which causes
|
|
||||||
// us to infer `_#1t = #'_#2r str`, where `'_#2r` is unconstrained, which gets
|
|
||||||
// fixed up to `ReEmpty`, and which is certainly not what we want.
|
|
||||||
if trait_fty.has_infer_types() {
|
|
||||||
result =
|
|
||||||
result.and_then(|()| ocx.eq(&cause, param_env, trait_sig.output(), impl_sig.output()));
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Err(terr) = result {
|
if let Err(terr) = result {
|
||||||
debug!(?terr, "sub_types failed: impl ty {:?}, trait ty {:?}", impl_fty, trait_fty);
|
debug!(?terr, "sub_types failed: impl ty {:?}, trait ty {:?}", impl_fty, trait_fty);
|
||||||
|
|
||||||
let emitted = report_trait_method_mismatch(
|
let emitted = report_trait_method_mismatch(
|
||||||
tcx,
|
|
||||||
&mut cause,
|
|
||||||
&infcx,
|
&infcx,
|
||||||
|
cause,
|
||||||
terr,
|
terr,
|
||||||
(trait_m, trait_fty),
|
(trait_m, trait_fty),
|
||||||
(impl_m, impl_fty),
|
(impl_m, impl_fty),
|
||||||
&trait_sig,
|
trait_sig,
|
||||||
&impl_trait_ref,
|
impl_trait_ref,
|
||||||
);
|
);
|
||||||
return Err(emitted);
|
return Err(emitted);
|
||||||
}
|
}
|
||||||
|
@ -352,11 +338,15 @@ pub fn collect_trait_impl_trait_tys<'tcx>(
|
||||||
let impl_trait_ref = tcx.impl_trait_ref(impl_m.impl_container(tcx).unwrap()).unwrap();
|
let impl_trait_ref = tcx.impl_trait_ref(impl_m.impl_container(tcx).unwrap()).unwrap();
|
||||||
let param_env = tcx.param_env(def_id);
|
let param_env = tcx.param_env(def_id);
|
||||||
|
|
||||||
|
// First, check a few of the same thing as `compare_impl_method`, just so we don't ICE during substitutions later.
|
||||||
|
compare_number_of_generics(tcx, impl_m, trait_m, tcx.hir().span_if_local(impl_m.def_id), true)?;
|
||||||
|
compare_generic_param_kinds(tcx, impl_m, trait_m, true)?;
|
||||||
|
|
||||||
let trait_to_impl_substs = impl_trait_ref.substs;
|
let trait_to_impl_substs = impl_trait_ref.substs;
|
||||||
|
|
||||||
let impl_m_hir_id = tcx.hir().local_def_id_to_hir_id(impl_m.def_id.expect_local());
|
let impl_m_hir_id = tcx.hir().local_def_id_to_hir_id(impl_m.def_id.expect_local());
|
||||||
let return_span = tcx.hir().fn_decl_by_hir_id(impl_m_hir_id).unwrap().output.span();
|
let return_span = tcx.hir().fn_decl_by_hir_id(impl_m_hir_id).unwrap().output.span();
|
||||||
let mut cause = ObligationCause::new(
|
let cause = ObligationCause::new(
|
||||||
return_span,
|
return_span,
|
||||||
impl_m_hir_id,
|
impl_m_hir_id,
|
||||||
ObligationCauseCode::CompareImplItemObligation {
|
ObligationCauseCode::CompareImplItemObligation {
|
||||||
|
@ -376,6 +366,7 @@ pub fn collect_trait_impl_trait_tys<'tcx>(
|
||||||
let infcx = &tcx.infer_ctxt().build();
|
let infcx = &tcx.infer_ctxt().build();
|
||||||
let ocx = ObligationCtxt::new(infcx);
|
let ocx = ObligationCtxt::new(infcx);
|
||||||
|
|
||||||
|
// Normalize the impl signature with fresh variables for lifetime inference.
|
||||||
let norm_cause = ObligationCause::misc(return_span, impl_m_hir_id);
|
let norm_cause = ObligationCause::misc(return_span, impl_m_hir_id);
|
||||||
let impl_sig = ocx.normalize(
|
let impl_sig = ocx.normalize(
|
||||||
norm_cause.clone(),
|
norm_cause.clone(),
|
||||||
|
@ -388,6 +379,10 @@ pub fn collect_trait_impl_trait_tys<'tcx>(
|
||||||
);
|
);
|
||||||
let impl_return_ty = impl_sig.output();
|
let impl_return_ty = impl_sig.output();
|
||||||
|
|
||||||
|
// Normalize the trait signature with liberated bound vars, passing it through
|
||||||
|
// the ImplTraitInTraitCollector, which gathers all of the RPITITs and replaces
|
||||||
|
// them with inference variables.
|
||||||
|
// We will use these inference variables to collect the hidden types of RPITITs.
|
||||||
let mut collector = ImplTraitInTraitCollector::new(&ocx, return_span, param_env, impl_m_hir_id);
|
let mut collector = ImplTraitInTraitCollector::new(&ocx, return_span, param_env, impl_m_hir_id);
|
||||||
let unnormalized_trait_sig = tcx
|
let unnormalized_trait_sig = tcx
|
||||||
.liberate_late_bound_regions(
|
.liberate_late_bound_regions(
|
||||||
|
@ -448,14 +443,13 @@ pub fn collect_trait_impl_trait_tys<'tcx>(
|
||||||
// emit an error now because `compare_predicate_entailment` will not report the error
|
// emit an error now because `compare_predicate_entailment` will not report the error
|
||||||
// when normalization fails.
|
// when normalization fails.
|
||||||
let emitted = report_trait_method_mismatch(
|
let emitted = report_trait_method_mismatch(
|
||||||
tcx,
|
|
||||||
&mut cause,
|
|
||||||
infcx,
|
infcx,
|
||||||
|
cause,
|
||||||
terr,
|
terr,
|
||||||
(trait_m, trait_fty),
|
(trait_m, trait_fty),
|
||||||
(impl_m, impl_fty),
|
(impl_m, impl_fty),
|
||||||
&trait_sig,
|
trait_sig,
|
||||||
&impl_trait_ref,
|
impl_trait_ref,
|
||||||
);
|
);
|
||||||
return Err(emitted);
|
return Err(emitted);
|
||||||
}
|
}
|
||||||
|
@ -625,23 +619,21 @@ impl<'tcx> TypeFolder<'tcx> for ImplTraitInTraitCollector<'_, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn report_trait_method_mismatch<'tcx>(
|
fn report_trait_method_mismatch<'tcx>(
|
||||||
tcx: TyCtxt<'tcx>,
|
|
||||||
cause: &mut ObligationCause<'tcx>,
|
|
||||||
infcx: &InferCtxt<'tcx>,
|
infcx: &InferCtxt<'tcx>,
|
||||||
|
mut cause: ObligationCause<'tcx>,
|
||||||
terr: TypeError<'tcx>,
|
terr: TypeError<'tcx>,
|
||||||
(trait_m, trait_fty): (&AssocItem, Ty<'tcx>),
|
(trait_m, trait_fty): (&ty::AssocItem, Ty<'tcx>),
|
||||||
(impl_m, impl_fty): (&AssocItem, Ty<'tcx>),
|
(impl_m, impl_fty): (&ty::AssocItem, Ty<'tcx>),
|
||||||
trait_sig: &FnSig<'tcx>,
|
trait_sig: ty::FnSig<'tcx>,
|
||||||
impl_trait_ref: &TraitRef<'tcx>,
|
impl_trait_ref: ty::TraitRef<'tcx>,
|
||||||
) -> ErrorGuaranteed {
|
) -> ErrorGuaranteed {
|
||||||
|
let tcx = infcx.tcx;
|
||||||
let (impl_err_span, trait_err_span) =
|
let (impl_err_span, trait_err_span) =
|
||||||
extract_spans_for_error_reporting(&infcx, terr, &cause, impl_m, trait_m);
|
extract_spans_for_error_reporting(&infcx, terr, &cause, impl_m, trait_m);
|
||||||
|
|
||||||
cause.span = impl_err_span;
|
|
||||||
|
|
||||||
let mut diag = struct_span_err!(
|
let mut diag = struct_span_err!(
|
||||||
tcx.sess,
|
tcx.sess,
|
||||||
cause.span(),
|
impl_err_span,
|
||||||
E0053,
|
E0053,
|
||||||
"method `{}` has an incompatible type for trait",
|
"method `{}` has an incompatible type for trait",
|
||||||
trait_m.name
|
trait_m.name
|
||||||
|
@ -712,6 +704,7 @@ fn report_trait_method_mismatch<'tcx>(
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cause.span = impl_err_span;
|
||||||
infcx.err_ctxt().note_type_err(
|
infcx.err_ctxt().note_type_err(
|
||||||
&mut diag,
|
&mut diag,
|
||||||
&cause,
|
&cause,
|
||||||
|
@ -922,9 +915,9 @@ fn compare_self_type<'tcx>(
|
||||||
fn compare_number_of_generics<'tcx>(
|
fn compare_number_of_generics<'tcx>(
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
impl_: &ty::AssocItem,
|
impl_: &ty::AssocItem,
|
||||||
_impl_span: Span,
|
|
||||||
trait_: &ty::AssocItem,
|
trait_: &ty::AssocItem,
|
||||||
trait_span: Option<Span>,
|
trait_span: Option<Span>,
|
||||||
|
delay: bool,
|
||||||
) -> Result<(), ErrorGuaranteed> {
|
) -> Result<(), ErrorGuaranteed> {
|
||||||
let trait_own_counts = tcx.generics_of(trait_.def_id).own_counts();
|
let trait_own_counts = tcx.generics_of(trait_.def_id).own_counts();
|
||||||
let impl_own_counts = tcx.generics_of(impl_.def_id).own_counts();
|
let impl_own_counts = tcx.generics_of(impl_.def_id).own_counts();
|
||||||
|
@ -1054,7 +1047,7 @@ fn compare_number_of_generics<'tcx>(
|
||||||
err.span_label(*span, "`impl Trait` introduces an implicit type parameter");
|
err.span_label(*span, "`impl Trait` introduces an implicit type parameter");
|
||||||
}
|
}
|
||||||
|
|
||||||
let reported = err.emit();
|
let reported = err.emit_unless(delay);
|
||||||
err_occurred = Some(reported);
|
err_occurred = Some(reported);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1306,6 +1299,7 @@ fn compare_generic_param_kinds<'tcx>(
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
impl_item: &ty::AssocItem,
|
impl_item: &ty::AssocItem,
|
||||||
trait_item: &ty::AssocItem,
|
trait_item: &ty::AssocItem,
|
||||||
|
delay: bool,
|
||||||
) -> Result<(), ErrorGuaranteed> {
|
) -> Result<(), ErrorGuaranteed> {
|
||||||
assert_eq!(impl_item.kind, trait_item.kind);
|
assert_eq!(impl_item.kind, trait_item.kind);
|
||||||
|
|
||||||
|
@ -1363,7 +1357,7 @@ fn compare_generic_param_kinds<'tcx>(
|
||||||
err.span_label(impl_header_span, "");
|
err.span_label(impl_header_span, "");
|
||||||
err.span_label(param_impl_span, make_param_message("found", param_impl));
|
err.span_label(param_impl_span, make_param_message("found", param_impl));
|
||||||
|
|
||||||
let reported = err.emit();
|
let reported = err.emit_unless(delay);
|
||||||
return Err(reported);
|
return Err(reported);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1489,9 +1483,9 @@ pub(crate) fn compare_ty_impl<'tcx>(
|
||||||
debug!("compare_impl_type(impl_trait_ref={:?})", impl_trait_ref);
|
debug!("compare_impl_type(impl_trait_ref={:?})", impl_trait_ref);
|
||||||
|
|
||||||
let _: Result<(), ErrorGuaranteed> = (|| {
|
let _: Result<(), ErrorGuaranteed> = (|| {
|
||||||
compare_number_of_generics(tcx, impl_ty, impl_ty_span, trait_ty, trait_item_span)?;
|
compare_number_of_generics(tcx, impl_ty, trait_ty, trait_item_span, false)?;
|
||||||
|
|
||||||
compare_generic_param_kinds(tcx, impl_ty, trait_ty)?;
|
compare_generic_param_kinds(tcx, impl_ty, trait_ty, false)?;
|
||||||
|
|
||||||
let sp = tcx.def_span(impl_ty.def_id);
|
let sp = tcx.def_span(impl_ty.def_id);
|
||||||
compare_type_predicate_entailment(tcx, impl_ty, sp, trait_ty, impl_trait_ref)?;
|
compare_type_predicate_entailment(tcx, impl_ty, sp, trait_ty, impl_trait_ref)?;
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
use crate::build::matches::ArmHasGuard;
|
|
||||||
use crate::build::ForGuard::OutsideGuard;
|
use crate::build::ForGuard::OutsideGuard;
|
||||||
use crate::build::{BlockAnd, BlockAndExtension, BlockFrame, Builder};
|
use crate::build::{BlockAnd, BlockAndExtension, BlockFrame, Builder};
|
||||||
use rustc_middle::middle::region::Scope;
|
use rustc_middle::middle::region::Scope;
|
||||||
|
@ -231,7 +230,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||||
visibility_scope,
|
visibility_scope,
|
||||||
remainder_span,
|
remainder_span,
|
||||||
pattern,
|
pattern,
|
||||||
ArmHasGuard(false),
|
None,
|
||||||
Some((None, initializer_span)),
|
Some((None, initializer_span)),
|
||||||
);
|
);
|
||||||
this.visit_primary_bindings(
|
this.visit_primary_bindings(
|
||||||
|
@ -308,7 +307,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||||
visibility_scope,
|
visibility_scope,
|
||||||
remainder_span,
|
remainder_span,
|
||||||
pattern,
|
pattern,
|
||||||
ArmHasGuard(false),
|
None,
|
||||||
Some((None, initializer_span)),
|
Some((None, initializer_span)),
|
||||||
);
|
);
|
||||||
this.expr_into_pattern(block, &pattern, init)
|
this.expr_into_pattern(block, &pattern, init)
|
||||||
|
@ -324,7 +323,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||||
visibility_scope,
|
visibility_scope,
|
||||||
remainder_span,
|
remainder_span,
|
||||||
pattern,
|
pattern,
|
||||||
ArmHasGuard(false),
|
None,
|
||||||
None,
|
None,
|
||||||
);
|
);
|
||||||
block.unit()
|
block.unit()
|
||||||
|
|
|
@ -108,7 +108,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||||
ExprKind::Let { expr, ref pat } => {
|
ExprKind::Let { expr, ref pat } => {
|
||||||
let scope = this.local_scope();
|
let scope = this.local_scope();
|
||||||
let (true_block, false_block) = this.in_if_then_scope(scope, expr_span, |this| {
|
let (true_block, false_block) = this.in_if_then_scope(scope, expr_span, |this| {
|
||||||
this.lower_let_expr(block, &this.thir[expr], pat, scope, None, expr_span)
|
this.lower_let_expr(block, &this.thir[expr], pat, scope, None, expr_span, true)
|
||||||
});
|
});
|
||||||
|
|
||||||
this.cfg.push_assign_constant(
|
this.cfg.push_assign_constant(
|
||||||
|
|
|
@ -84,6 +84,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||||
break_scope,
|
break_scope,
|
||||||
Some(variable_source_info.scope),
|
Some(variable_source_info.scope),
|
||||||
variable_source_info.span,
|
variable_source_info.span,
|
||||||
|
true,
|
||||||
),
|
),
|
||||||
_ => {
|
_ => {
|
||||||
let temp_scope = temp_scope_override.unwrap_or_else(|| this.local_scope());
|
let temp_scope = temp_scope_override.unwrap_or_else(|| this.local_scope());
|
||||||
|
@ -357,7 +358,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||||
None,
|
None,
|
||||||
arm.span,
|
arm.span,
|
||||||
&arm.pattern,
|
&arm.pattern,
|
||||||
ArmHasGuard(arm.guard.is_some()),
|
arm.guard.as_ref(),
|
||||||
opt_scrutinee_place,
|
opt_scrutinee_place,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -645,7 +646,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||||
mut visibility_scope: Option<SourceScope>,
|
mut visibility_scope: Option<SourceScope>,
|
||||||
scope_span: Span,
|
scope_span: Span,
|
||||||
pattern: &Pat<'tcx>,
|
pattern: &Pat<'tcx>,
|
||||||
has_guard: ArmHasGuard,
|
guard: Option<&Guard<'tcx>>,
|
||||||
opt_match_place: Option<(Option<&Place<'tcx>>, Span)>,
|
opt_match_place: Option<(Option<&Place<'tcx>>, Span)>,
|
||||||
) -> Option<SourceScope> {
|
) -> Option<SourceScope> {
|
||||||
self.visit_primary_bindings(
|
self.visit_primary_bindings(
|
||||||
|
@ -667,12 +668,16 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||||
var,
|
var,
|
||||||
ty,
|
ty,
|
||||||
user_ty,
|
user_ty,
|
||||||
has_guard,
|
ArmHasGuard(guard.is_some()),
|
||||||
opt_match_place.map(|(x, y)| (x.cloned(), y)),
|
opt_match_place.map(|(x, y)| (x.cloned(), y)),
|
||||||
pattern.span,
|
pattern.span,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
if let Some(Guard::IfLet(guard_pat, _)) = guard {
|
||||||
|
// FIXME: pass a proper `opt_match_place`
|
||||||
|
self.declare_bindings(visibility_scope, scope_span, guard_pat, None, None);
|
||||||
|
}
|
||||||
visibility_scope
|
visibility_scope
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1766,6 +1771,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||||
// Pat binding - used for `let` and function parameters as well.
|
// Pat binding - used for `let` and function parameters as well.
|
||||||
|
|
||||||
impl<'a, 'tcx> Builder<'a, 'tcx> {
|
impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||||
|
/// If the bindings have already been declared, set `declare_bindings` to
|
||||||
|
/// `false` to avoid duplicated bindings declaration. Used for if-let guards.
|
||||||
pub(crate) fn lower_let_expr(
|
pub(crate) fn lower_let_expr(
|
||||||
&mut self,
|
&mut self,
|
||||||
mut block: BasicBlock,
|
mut block: BasicBlock,
|
||||||
|
@ -1774,6 +1781,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||||
else_target: region::Scope,
|
else_target: region::Scope,
|
||||||
source_scope: Option<SourceScope>,
|
source_scope: Option<SourceScope>,
|
||||||
span: Span,
|
span: Span,
|
||||||
|
declare_bindings: bool,
|
||||||
) -> BlockAnd<()> {
|
) -> BlockAnd<()> {
|
||||||
let expr_span = expr.span;
|
let expr_span = expr.span;
|
||||||
let expr_place_builder = unpack!(block = self.lower_scrutinee(block, expr, expr_span));
|
let expr_place_builder = unpack!(block = self.lower_scrutinee(block, expr, expr_span));
|
||||||
|
@ -1797,13 +1805,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||||
let otherwise_post_guard_block = otherwise_candidate.pre_binding_block.unwrap();
|
let otherwise_post_guard_block = otherwise_candidate.pre_binding_block.unwrap();
|
||||||
self.break_for_else(otherwise_post_guard_block, else_target, self.source_info(expr_span));
|
self.break_for_else(otherwise_post_guard_block, else_target, self.source_info(expr_span));
|
||||||
|
|
||||||
self.declare_bindings(
|
if declare_bindings {
|
||||||
source_scope,
|
self.declare_bindings(source_scope, pat.span.to(span), pat, None, opt_expr_place);
|
||||||
pat.span.to(span),
|
}
|
||||||
pat,
|
|
||||||
ArmHasGuard(false),
|
|
||||||
opt_expr_place,
|
|
||||||
);
|
|
||||||
|
|
||||||
let post_guard_block = self.bind_pattern(
|
let post_guard_block = self.bind_pattern(
|
||||||
self.source_info(pat.span),
|
self.source_info(pat.span),
|
||||||
|
@ -1984,7 +1988,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||||
Guard::IfLet(ref pat, scrutinee) => {
|
Guard::IfLet(ref pat, scrutinee) => {
|
||||||
let s = &this.thir[scrutinee];
|
let s = &this.thir[scrutinee];
|
||||||
guard_span = s.span;
|
guard_span = s.span;
|
||||||
this.lower_let_expr(block, s, pat, match_scope, None, arm.span)
|
this.lower_let_expr(block, s, pat, match_scope, None, arm.span, false)
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -924,7 +924,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||||
scope,
|
scope,
|
||||||
expr.span,
|
expr.span,
|
||||||
&pat,
|
&pat,
|
||||||
matches::ArmHasGuard(false),
|
None,
|
||||||
Some((Some(&place), span)),
|
Some((Some(&place), span)),
|
||||||
);
|
);
|
||||||
let place_builder = PlaceBuilder::from(local);
|
let place_builder = PlaceBuilder::from(local);
|
||||||
|
|
|
@ -131,12 +131,9 @@ impl<'a, 'b> visit::Visitor<'a> for DefCollector<'a, 'b> {
|
||||||
|
|
||||||
fn visit_fn(&mut self, fn_kind: FnKind<'a>, span: Span, _: NodeId) {
|
fn visit_fn(&mut self, fn_kind: FnKind<'a>, span: Span, _: NodeId) {
|
||||||
if let FnKind::Fn(_, _, sig, _, generics, body) = fn_kind {
|
if let FnKind::Fn(_, _, sig, _, generics, body) = fn_kind {
|
||||||
if let Async::Yes { closure_id, return_impl_trait_id, .. } = sig.header.asyncness {
|
if let Async::Yes { closure_id, .. } = sig.header.asyncness {
|
||||||
self.visit_generics(generics);
|
self.visit_generics(generics);
|
||||||
|
|
||||||
let return_impl_trait_id =
|
|
||||||
self.create_def(return_impl_trait_id, DefPathData::ImplTrait, span);
|
|
||||||
|
|
||||||
// For async functions, we need to create their inner defs inside of a
|
// For async functions, we need to create their inner defs inside of a
|
||||||
// closure to match their desugared representation. Besides that,
|
// closure to match their desugared representation. Besides that,
|
||||||
// we must mirror everything that `visit::walk_fn` below does.
|
// we must mirror everything that `visit::walk_fn` below does.
|
||||||
|
@ -144,9 +141,7 @@ impl<'a, 'b> visit::Visitor<'a> for DefCollector<'a, 'b> {
|
||||||
for param in &sig.decl.inputs {
|
for param in &sig.decl.inputs {
|
||||||
self.visit_param(param);
|
self.visit_param(param);
|
||||||
}
|
}
|
||||||
self.with_parent(return_impl_trait_id, |this| {
|
self.visit_fn_ret_ty(&sig.decl.output);
|
||||||
this.visit_fn_ret_ty(&sig.decl.output)
|
|
||||||
});
|
|
||||||
// If this async fn has no body (i.e. it's an async fn signature in a trait)
|
// If this async fn has no body (i.e. it's an async fn signature in a trait)
|
||||||
// then the closure_def will never be used, and we should avoid generating a
|
// then the closure_def will never be used, and we should avoid generating a
|
||||||
// def-id for it.
|
// def-id for it.
|
||||||
|
|
|
@ -1493,11 +1493,13 @@ mod prim_ref {}
|
||||||
/// However, a direct cast back is not possible. You need to use `transmute`:
|
/// However, a direct cast back is not possible. You need to use `transmute`:
|
||||||
///
|
///
|
||||||
/// ```rust
|
/// ```rust
|
||||||
|
/// # #[cfg(not(miri))] { // FIXME: use strict provenance APIs once they are stable, then remove this `cfg`
|
||||||
/// # let fnptr: fn(i32) -> i32 = |x| x+2;
|
/// # let fnptr: fn(i32) -> i32 = |x| x+2;
|
||||||
/// # let fnptr_addr = fnptr as usize;
|
/// # let fnptr_addr = fnptr as usize;
|
||||||
/// let fnptr = fnptr_addr as *const ();
|
/// let fnptr = fnptr_addr as *const ();
|
||||||
/// let fnptr: fn(i32) -> i32 = unsafe { std::mem::transmute(fnptr) };
|
/// let fnptr: fn(i32) -> i32 = unsafe { std::mem::transmute(fnptr) };
|
||||||
/// assert_eq!(fnptr(40), 42);
|
/// assert_eq!(fnptr(40), 42);
|
||||||
|
/// # }
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// Crucially, we `as`-cast to a raw pointer before `transmute`ing to a function pointer.
|
/// Crucially, we `as`-cast to a raw pointer before `transmute`ing to a function pointer.
|
||||||
|
|
|
@ -112,11 +112,13 @@ impl<T: ?Sized> *const T {
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// #![feature(ptr_to_from_bits)]
|
/// #![feature(ptr_to_from_bits)]
|
||||||
|
/// # #[cfg(not(miri))] { // doctest does not work with strict provenance
|
||||||
/// let array = [13, 42];
|
/// let array = [13, 42];
|
||||||
/// let p0: *const i32 = &array[0];
|
/// let p0: *const i32 = &array[0];
|
||||||
/// assert_eq!(<*const _>::from_bits(p0.to_bits()), p0);
|
/// assert_eq!(<*const _>::from_bits(p0.to_bits()), p0);
|
||||||
/// let p1: *const i32 = &array[1];
|
/// let p1: *const i32 = &array[1];
|
||||||
/// assert_eq!(p1.to_bits() - p0.to_bits(), 4);
|
/// assert_eq!(p1.to_bits() - p0.to_bits(), 4);
|
||||||
|
/// # }
|
||||||
/// ```
|
/// ```
|
||||||
#[unstable(feature = "ptr_to_from_bits", issue = "91126")]
|
#[unstable(feature = "ptr_to_from_bits", issue = "91126")]
|
||||||
#[deprecated(
|
#[deprecated(
|
||||||
|
@ -140,9 +142,11 @@ impl<T: ?Sized> *const T {
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// #![feature(ptr_to_from_bits)]
|
/// #![feature(ptr_to_from_bits)]
|
||||||
|
/// # #[cfg(not(miri))] { // doctest does not work with strict provenance
|
||||||
/// use std::ptr::NonNull;
|
/// use std::ptr::NonNull;
|
||||||
/// let dangling: *const u8 = NonNull::dangling().as_ptr();
|
/// let dangling: *const u8 = NonNull::dangling().as_ptr();
|
||||||
/// assert_eq!(<*const u8>::from_bits(1), dangling);
|
/// assert_eq!(<*const u8>::from_bits(1), dangling);
|
||||||
|
/// # }
|
||||||
/// ```
|
/// ```
|
||||||
#[unstable(feature = "ptr_to_from_bits", issue = "91126")]
|
#[unstable(feature = "ptr_to_from_bits", issue = "91126")]
|
||||||
#[deprecated(
|
#[deprecated(
|
||||||
|
|
|
@ -117,12 +117,14 @@ impl<T: ?Sized> *mut T {
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// #![feature(ptr_to_from_bits)]
|
/// #![feature(ptr_to_from_bits)]
|
||||||
|
/// # #[cfg(not(miri))] { // doctest does not work with strict provenance
|
||||||
/// let mut array = [13, 42];
|
/// let mut array = [13, 42];
|
||||||
/// let mut it = array.iter_mut();
|
/// let mut it = array.iter_mut();
|
||||||
/// let p0: *mut i32 = it.next().unwrap();
|
/// let p0: *mut i32 = it.next().unwrap();
|
||||||
/// assert_eq!(<*mut _>::from_bits(p0.to_bits()), p0);
|
/// assert_eq!(<*mut _>::from_bits(p0.to_bits()), p0);
|
||||||
/// let p1: *mut i32 = it.next().unwrap();
|
/// let p1: *mut i32 = it.next().unwrap();
|
||||||
/// assert_eq!(p1.to_bits() - p0.to_bits(), 4);
|
/// assert_eq!(p1.to_bits() - p0.to_bits(), 4);
|
||||||
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
#[unstable(feature = "ptr_to_from_bits", issue = "91126")]
|
#[unstable(feature = "ptr_to_from_bits", issue = "91126")]
|
||||||
#[deprecated(
|
#[deprecated(
|
||||||
|
@ -146,9 +148,11 @@ impl<T: ?Sized> *mut T {
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// #![feature(ptr_to_from_bits)]
|
/// #![feature(ptr_to_from_bits)]
|
||||||
|
/// # #[cfg(not(miri))] { // doctest does not work with strict provenance
|
||||||
/// use std::ptr::NonNull;
|
/// use std::ptr::NonNull;
|
||||||
/// let dangling: *mut u8 = NonNull::dangling().as_ptr();
|
/// let dangling: *mut u8 = NonNull::dangling().as_ptr();
|
||||||
/// assert_eq!(<*mut u8>::from_bits(1), dangling);
|
/// assert_eq!(<*mut u8>::from_bits(1), dangling);
|
||||||
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
#[unstable(feature = "ptr_to_from_bits", issue = "91126")]
|
#[unstable(feature = "ptr_to_from_bits", issue = "91126")]
|
||||||
#[deprecated(
|
#[deprecated(
|
||||||
|
|
|
@ -1493,11 +1493,13 @@ mod prim_ref {}
|
||||||
/// However, a direct cast back is not possible. You need to use `transmute`:
|
/// However, a direct cast back is not possible. You need to use `transmute`:
|
||||||
///
|
///
|
||||||
/// ```rust
|
/// ```rust
|
||||||
|
/// # #[cfg(not(miri))] { // FIXME: use strict provenance APIs once they are stable, then remove this `cfg`
|
||||||
/// # let fnptr: fn(i32) -> i32 = |x| x+2;
|
/// # let fnptr: fn(i32) -> i32 = |x| x+2;
|
||||||
/// # let fnptr_addr = fnptr as usize;
|
/// # let fnptr_addr = fnptr as usize;
|
||||||
/// let fnptr = fnptr_addr as *const ();
|
/// let fnptr = fnptr_addr as *const ();
|
||||||
/// let fnptr: fn(i32) -> i32 = unsafe { std::mem::transmute(fnptr) };
|
/// let fnptr: fn(i32) -> i32 = unsafe { std::mem::transmute(fnptr) };
|
||||||
/// assert_eq!(fnptr(40), 42);
|
/// assert_eq!(fnptr(40), 42);
|
||||||
|
/// # }
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// Crucially, we `as`-cast to a raw pointer before `transmute`ing to a function pointer.
|
/// Crucially, we `as`-cast to a raw pointer before `transmute`ing to a function pointer.
|
||||||
|
|
|
@ -27,7 +27,10 @@ pub type _Unwind_Trace_Fn =
|
||||||
#[cfg(target_arch = "x86")]
|
#[cfg(target_arch = "x86")]
|
||||||
pub const unwinder_private_data_size: usize = 5;
|
pub const unwinder_private_data_size: usize = 5;
|
||||||
|
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(all(target_arch = "x86_64", not(target_os = "windows")))]
|
||||||
|
pub const unwinder_private_data_size: usize = 2;
|
||||||
|
|
||||||
|
#[cfg(all(target_arch = "x86_64", target_os = "windows"))]
|
||||||
pub const unwinder_private_data_size: usize = 6;
|
pub const unwinder_private_data_size: usize = 6;
|
||||||
|
|
||||||
#[cfg(all(target_arch = "arm", not(any(target_os = "ios", target_os = "watchos"))))]
|
#[cfg(all(target_arch = "arm", not(any(target_os = "ios", target_os = "watchos"))))]
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
#![feature(return_position_impl_trait_in_trait)]
|
||||||
|
#![allow(incomplete_features)]
|
||||||
|
|
||||||
|
struct S;
|
||||||
|
|
||||||
|
trait Foo {
|
||||||
|
fn bar<T>() -> impl Sized;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Foo for S {
|
||||||
|
fn bar() -> impl Sized {}
|
||||||
|
//~^ ERROR method `bar` has 0 type parameters but its trait declaration has 1 type parameter
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
S::bar();
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
error[E0049]: method `bar` has 0 type parameters but its trait declaration has 1 type parameter
|
||||||
|
--> $DIR/trait-more-generics-than-impl.rs:11:11
|
||||||
|
|
|
||||||
|
LL | fn bar<T>() -> impl Sized;
|
||||||
|
| - expected 1 type parameter
|
||||||
|
...
|
||||||
|
LL | fn bar() -> impl Sized {}
|
||||||
|
| ^ found 0 type parameters
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0049`.
|
|
@ -30,4 +30,11 @@ fn main() {
|
||||||
Some(x) if let Foo::Qux(y) = qux(x) => assert_eq!(y, 84),
|
Some(x) if let Foo::Qux(y) = qux(x) => assert_eq!(y, 84),
|
||||||
_ => panic!(),
|
_ => panic!(),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// issue #88015
|
||||||
|
#[allow(irrefutable_let_patterns)]
|
||||||
|
match () {
|
||||||
|
() | () if let x = 42 => assert_eq!(x, 42),
|
||||||
|
_ => panic!()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue