Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rollup of 6 pull requests #104711

Merged
merged 14 commits into from
Nov 22, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion compiler/rustc_ast_lowering/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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_def_id = self.local_def_id(opaque_ty_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
// to capture all the lifetimes involved in the signature (including in the
// return type). This is done by introducing lifetime parameters for:
Expand Down
80 changes: 37 additions & 43 deletions compiler/rustc_hir_analysis/src/check/compare_method.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,8 @@ use rustc_infer::traits::util;
use rustc_middle::ty::error::{ExpectedFound, TypeError};
use rustc_middle::ty::util::ExplicitSelf;
use rustc_middle::ty::{
self, AssocItem, DefIdTree, TraitRef, Ty, TypeFoldable, TypeFolder, TypeSuperFoldable,
TypeVisitable,
self, DefIdTree, InternalSubsts, Ty, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitable,
};
use rustc_middle::ty::{FnSig, InternalSubsts};
use rustc_middle::ty::{GenericParamDefKind, ToPredicate, TyCtxt};
use rustc_span::Span;
use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt;
Expand Down Expand Up @@ -51,11 +49,11 @@ pub(crate) fn compare_impl_method<'tcx>(
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;
}

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;
}

Expand Down Expand Up @@ -144,9 +142,9 @@ pub(crate) fn compare_impl_method<'tcx>(
#[instrument(level = "debug", skip(tcx, impl_m_span, impl_trait_ref))]
fn compare_predicate_entailment<'tcx>(
tcx: TyCtxt<'tcx>,
impl_m: &AssocItem,
impl_m: &ty::AssocItem,
impl_m_span: Span,
trait_m: &AssocItem,
trait_m: &ty::AssocItem,
impl_trait_ref: ty::TraitRef<'tcx>,
) -> Result<(), ErrorGuaranteed> {
let trait_to_impl_substs = impl_trait_ref.substs;
Expand All @@ -157,8 +155,7 @@ fn compare_predicate_entailment<'tcx>(
// FIXME(@lcnr): remove that after removing `cause.body_id` from
// obligations.
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 mut cause = ObligationCause::new(
let cause = ObligationCause::new(
impl_m_span,
impl_m_hir_id,
ObligationCauseCode::CompareImplItemObligation {
Expand Down Expand Up @@ -291,30 +288,19 @@ fn compare_predicate_entailment<'tcx>(
// 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.
// Fixing this would improve the output of test `issue-83765.rs`.
let mut 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()));
}
let result = ocx.sup(&cause, param_env, trait_fty, impl_fty);

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

let emitted = report_trait_method_mismatch(
tcx,
&mut cause,
&infcx,
cause,
terr,
(trait_m, trait_fty),
(impl_m, impl_fty),
&trait_sig,
&impl_trait_ref,
trait_sig,
impl_trait_ref,
);
return Err(emitted);
}
Expand Down Expand Up @@ -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 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 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 mut cause = ObligationCause::new(
let cause = ObligationCause::new(
return_span,
impl_m_hir_id,
ObligationCauseCode::CompareImplItemObligation {
Expand All @@ -376,6 +366,7 @@ pub fn collect_trait_impl_trait_tys<'tcx>(
let infcx = &tcx.infer_ctxt().build();
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 impl_sig = ocx.normalize(
norm_cause.clone(),
Expand All @@ -388,6 +379,10 @@ pub fn collect_trait_impl_trait_tys<'tcx>(
);
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 unnormalized_trait_sig = tcx
.liberate_late_bound_regions(
Expand Down Expand Up @@ -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
// when normalization fails.
let emitted = report_trait_method_mismatch(
tcx,
&mut cause,
infcx,
cause,
terr,
(trait_m, trait_fty),
(impl_m, impl_fty),
&trait_sig,
&impl_trait_ref,
trait_sig,
impl_trait_ref,
);
return Err(emitted);
}
Expand Down Expand Up @@ -625,23 +619,21 @@ impl<'tcx> TypeFolder<'tcx> for ImplTraitInTraitCollector<'_, 'tcx> {
}

fn report_trait_method_mismatch<'tcx>(
tcx: TyCtxt<'tcx>,
cause: &mut ObligationCause<'tcx>,
infcx: &InferCtxt<'tcx>,
mut cause: ObligationCause<'tcx>,
terr: TypeError<'tcx>,
(trait_m, trait_fty): (&AssocItem, Ty<'tcx>),
(impl_m, impl_fty): (&AssocItem, Ty<'tcx>),
trait_sig: &FnSig<'tcx>,
impl_trait_ref: &TraitRef<'tcx>,
(trait_m, trait_fty): (&ty::AssocItem, Ty<'tcx>),
(impl_m, impl_fty): (&ty::AssocItem, Ty<'tcx>),
trait_sig: ty::FnSig<'tcx>,
impl_trait_ref: ty::TraitRef<'tcx>,
) -> ErrorGuaranteed {
let tcx = infcx.tcx;
let (impl_err_span, trait_err_span) =
extract_spans_for_error_reporting(&infcx, terr, &cause, impl_m, trait_m);

cause.span = impl_err_span;

let mut diag = struct_span_err!(
tcx.sess,
cause.span(),
impl_err_span,
E0053,
"method `{}` has an incompatible type for trait",
trait_m.name
Expand Down Expand Up @@ -712,6 +704,7 @@ fn report_trait_method_mismatch<'tcx>(
_ => {}
}

cause.span = impl_err_span;
infcx.err_ctxt().note_type_err(
&mut diag,
&cause,
Expand Down Expand Up @@ -922,9 +915,9 @@ fn compare_self_type<'tcx>(
fn compare_number_of_generics<'tcx>(
tcx: TyCtxt<'tcx>,
impl_: &ty::AssocItem,
_impl_span: Span,
trait_: &ty::AssocItem,
trait_span: Option<Span>,
delay: bool,
) -> Result<(), ErrorGuaranteed> {
let trait_own_counts = tcx.generics_of(trait_.def_id).own_counts();
let impl_own_counts = tcx.generics_of(impl_.def_id).own_counts();
Expand Down Expand Up @@ -1054,7 +1047,7 @@ fn compare_number_of_generics<'tcx>(
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);
}
}
Expand Down Expand Up @@ -1306,6 +1299,7 @@ fn compare_generic_param_kinds<'tcx>(
tcx: TyCtxt<'tcx>,
impl_item: &ty::AssocItem,
trait_item: &ty::AssocItem,
delay: bool,
) -> Result<(), ErrorGuaranteed> {
assert_eq!(impl_item.kind, trait_item.kind);

Expand Down Expand Up @@ -1363,7 +1357,7 @@ fn compare_generic_param_kinds<'tcx>(
err.span_label(impl_header_span, "");
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);
}
}
Expand Down Expand Up @@ -1489,9 +1483,9 @@ pub(crate) fn compare_ty_impl<'tcx>(
debug!("compare_impl_type(impl_trait_ref={:?})", impl_trait_ref);

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);
compare_type_predicate_entailment(tcx, impl_ty, sp, trait_ty, impl_trait_ref)?;
Expand Down
7 changes: 3 additions & 4 deletions compiler/rustc_mir_build/src/build/block.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
use crate::build::matches::ArmHasGuard;
use crate::build::ForGuard::OutsideGuard;
use crate::build::{BlockAnd, BlockAndExtension, BlockFrame, Builder};
use rustc_middle::middle::region::Scope;
Expand Down Expand Up @@ -231,7 +230,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
visibility_scope,
remainder_span,
pattern,
ArmHasGuard(false),
None,
Some((None, initializer_span)),
);
this.visit_primary_bindings(
Expand Down Expand Up @@ -308,7 +307,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
visibility_scope,
remainder_span,
pattern,
ArmHasGuard(false),
None,
Some((None, initializer_span)),
);
this.expr_into_pattern(block, &pattern, init)
Expand All @@ -324,7 +323,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
visibility_scope,
remainder_span,
pattern,
ArmHasGuard(false),
None,
None,
);
block.unit()
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_mir_build/src/build/expr/into.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
ExprKind::Let { expr, ref pat } => {
let scope = this.local_scope();
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(
Expand Down
26 changes: 15 additions & 11 deletions compiler/rustc_mir_build/src/build/matches/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
break_scope,
Some(variable_source_info.scope),
variable_source_info.span,
true,
),
_ => {
let temp_scope = temp_scope_override.unwrap_or_else(|| this.local_scope());
Expand Down Expand Up @@ -357,7 +358,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
None,
arm.span,
&arm.pattern,
ArmHasGuard(arm.guard.is_some()),
arm.guard.as_ref(),
opt_scrutinee_place,
);

Expand Down Expand Up @@ -645,7 +646,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
mut visibility_scope: Option<SourceScope>,
scope_span: Span,
pattern: &Pat<'tcx>,
has_guard: ArmHasGuard,
guard: Option<&Guard<'tcx>>,
opt_match_place: Option<(Option<&Place<'tcx>>, Span)>,
) -> Option<SourceScope> {
self.visit_primary_bindings(
Expand All @@ -667,12 +668,16 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
var,
ty,
user_ty,
has_guard,
ArmHasGuard(guard.is_some()),
opt_match_place.map(|(x, y)| (x.cloned(), y)),
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
}

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

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(
&mut self,
mut block: BasicBlock,
Expand All @@ -1774,6 +1781,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
else_target: region::Scope,
source_scope: Option<SourceScope>,
span: Span,
declare_bindings: bool,
) -> BlockAnd<()> {
let expr_span = expr.span;
let expr_place_builder = unpack!(block = self.lower_scrutinee(block, expr, expr_span));
Expand All @@ -1797,13 +1805,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
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.declare_bindings(
source_scope,
pat.span.to(span),
pat,
ArmHasGuard(false),
opt_expr_place,
);
if declare_bindings {
self.declare_bindings(source_scope, pat.span.to(span), pat, None, opt_expr_place);
}

let post_guard_block = self.bind_pattern(
self.source_info(pat.span),
Expand Down Expand Up @@ -1984,7 +1988,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
Guard::IfLet(ref pat, scrutinee) => {
let s = &this.thir[scrutinee];
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)
}
});

Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_mir_build/src/build/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -924,7 +924,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
scope,
expr.span,
&pat,
matches::ArmHasGuard(false),
None,
Some((Some(&place), span)),
);
let place_builder = PlaceBuilder::from(local);
Expand Down
9 changes: 2 additions & 7 deletions compiler/rustc_resolve/src/def_collector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -131,22 +131,17 @@ impl<'a, 'b> visit::Visitor<'a> for DefCollector<'a, 'b> {

fn visit_fn(&mut self, fn_kind: FnKind<'a>, span: Span, _: NodeId) {
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);

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
// closure to match their desugared representation. Besides that,
// we must mirror everything that `visit::walk_fn` below does.
self.visit_fn_header(&sig.header);
for param in &sig.decl.inputs {
self.visit_param(param);
}
self.with_parent(return_impl_trait_id, |this| {
this.visit_fn_ret_ty(&sig.decl.output)
});
self.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)
// then the closure_def will never be used, and we should avoid generating a
// def-id for it.
Expand Down
Loading