Auto merge of #112625 - matthiaskrgr:rollup-jcobj3g, r=matthiaskrgr
Rollup of 7 pull requests Successful merges: - #112584 (loongarch64-none*: Remove environment component from llvm target) - #112600 (Introduce a `Stable` trait to translate MIR to SMIR) - #112605 (Improve docs/clean up negative overlap functions) - #112611 (Error on unconstrained lifetime in RPITIT) - #112612 (Fix explicit-outlives-requirements lint span) - #112613 (Fix rustdoc-gui tests on Windows) - #112620 (Fix small typo) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
8c74a5d27c
25 changed files with 539 additions and 414 deletions
|
@ -45,12 +45,7 @@ pub(super) fn compare_impl_method<'tcx>(
|
|||
debug!("compare_impl_method(impl_trait_ref={:?})", impl_trait_ref);
|
||||
|
||||
let _: Result<_, ErrorGuaranteed> = try {
|
||||
compare_self_type(tcx, impl_m, trait_m, impl_trait_ref)?;
|
||||
compare_number_of_generics(tcx, impl_m, trait_m, false)?;
|
||||
compare_generic_param_kinds(tcx, impl_m, trait_m, false)?;
|
||||
compare_number_of_method_arguments(tcx, impl_m, trait_m)?;
|
||||
compare_synthetic_generics(tcx, impl_m, trait_m)?;
|
||||
compare_asyncness(tcx, impl_m, trait_m)?;
|
||||
check_method_is_structurally_compatible(tcx, impl_m, trait_m, impl_trait_ref, false)?;
|
||||
compare_method_predicate_entailment(
|
||||
tcx,
|
||||
impl_m,
|
||||
|
@ -61,6 +56,26 @@ pub(super) fn compare_impl_method<'tcx>(
|
|||
};
|
||||
}
|
||||
|
||||
/// Checks a bunch of different properties of the impl/trait methods for
|
||||
/// compatibility, such as asyncness, number of argument, self receiver kind,
|
||||
/// and number of early- and late-bound generics.
|
||||
fn check_method_is_structurally_compatible<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
impl_m: ty::AssocItem,
|
||||
trait_m: ty::AssocItem,
|
||||
impl_trait_ref: ty::TraitRef<'tcx>,
|
||||
delay: bool,
|
||||
) -> Result<(), ErrorGuaranteed> {
|
||||
compare_self_type(tcx, impl_m, trait_m, impl_trait_ref, delay)?;
|
||||
compare_number_of_generics(tcx, impl_m, trait_m, delay)?;
|
||||
compare_generic_param_kinds(tcx, impl_m, trait_m, delay)?;
|
||||
compare_number_of_method_arguments(tcx, impl_m, trait_m, delay)?;
|
||||
compare_synthetic_generics(tcx, impl_m, trait_m, delay)?;
|
||||
compare_asyncness(tcx, impl_m, trait_m, delay)?;
|
||||
check_region_bounds_on_impl_item(tcx, impl_m, trait_m, delay)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// This function is best explained by example. Consider a trait with it's implementation:
|
||||
///
|
||||
/// ```rust
|
||||
|
@ -177,9 +192,6 @@ fn compare_method_predicate_entailment<'tcx>(
|
|||
let impl_m_predicates = tcx.predicates_of(impl_m.def_id);
|
||||
let trait_m_predicates = tcx.predicates_of(trait_m.def_id);
|
||||
|
||||
// Check region bounds.
|
||||
check_region_bounds_on_impl_item(tcx, impl_m, trait_m, false)?;
|
||||
|
||||
// Create obligations for each predicate declared by the impl
|
||||
// definition in the context of the trait's parameter
|
||||
// environment. We can't just use `impl_env.caller_bounds`,
|
||||
|
@ -534,6 +546,7 @@ fn compare_asyncness<'tcx>(
|
|||
tcx: TyCtxt<'tcx>,
|
||||
impl_m: ty::AssocItem,
|
||||
trait_m: ty::AssocItem,
|
||||
delay: bool,
|
||||
) -> Result<(), ErrorGuaranteed> {
|
||||
if tcx.asyncness(trait_m.def_id) == hir::IsAsync::Async {
|
||||
match tcx.fn_sig(impl_m.def_id).skip_binder().skip_binder().output().kind() {
|
||||
|
@ -544,11 +557,14 @@ fn compare_asyncness<'tcx>(
|
|||
// We don't know if it's ok, but at least it's already an error.
|
||||
}
|
||||
_ => {
|
||||
return Err(tcx.sess.emit_err(crate::errors::AsyncTraitImplShouldBeAsync {
|
||||
span: tcx.def_span(impl_m.def_id),
|
||||
method_name: trait_m.name,
|
||||
trait_item_span: tcx.hir().span_if_local(trait_m.def_id),
|
||||
}));
|
||||
return Err(tcx
|
||||
.sess
|
||||
.create_err(crate::errors::AsyncTraitImplShouldBeAsync {
|
||||
span: tcx.def_span(impl_m.def_id),
|
||||
method_name: trait_m.name,
|
||||
trait_item_span: tcx.hir().span_if_local(trait_m.def_id),
|
||||
})
|
||||
.emit_unless(delay));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -602,9 +618,7 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
|
|||
|
||||
// First, check a few of the same things as `compare_impl_method`,
|
||||
// just so we don't ICE during substitution later.
|
||||
compare_number_of_generics(tcx, impl_m, trait_m, true)?;
|
||||
compare_generic_param_kinds(tcx, impl_m, trait_m, true)?;
|
||||
check_region_bounds_on_impl_item(tcx, impl_m, trait_m, true)?;
|
||||
check_method_is_structurally_compatible(tcx, impl_m, trait_m, impl_trait_ref, true)?;
|
||||
|
||||
let trait_to_impl_substs = impl_trait_ref.substs;
|
||||
|
||||
|
@ -1097,6 +1111,7 @@ fn compare_self_type<'tcx>(
|
|||
impl_m: ty::AssocItem,
|
||||
trait_m: ty::AssocItem,
|
||||
impl_trait_ref: ty::TraitRef<'tcx>,
|
||||
delay: bool,
|
||||
) -> Result<(), ErrorGuaranteed> {
|
||||
// Try to give more informative error messages about self typing
|
||||
// mismatches. Note that any mismatch will also be detected
|
||||
|
@ -1145,7 +1160,7 @@ fn compare_self_type<'tcx>(
|
|||
} else {
|
||||
err.note_trait_signature(trait_m.name, trait_m.signature(tcx));
|
||||
}
|
||||
return Err(err.emit());
|
||||
return Err(err.emit_unless(delay));
|
||||
}
|
||||
|
||||
(true, false) => {
|
||||
|
@ -1166,7 +1181,7 @@ fn compare_self_type<'tcx>(
|
|||
err.note_trait_signature(trait_m.name, trait_m.signature(tcx));
|
||||
}
|
||||
|
||||
return Err(err.emit());
|
||||
return Err(err.emit_unless(delay));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1352,6 +1367,7 @@ fn compare_number_of_method_arguments<'tcx>(
|
|||
tcx: TyCtxt<'tcx>,
|
||||
impl_m: ty::AssocItem,
|
||||
trait_m: ty::AssocItem,
|
||||
delay: bool,
|
||||
) -> Result<(), ErrorGuaranteed> {
|
||||
let impl_m_fty = tcx.fn_sig(impl_m.def_id);
|
||||
let trait_m_fty = tcx.fn_sig(trait_m.def_id);
|
||||
|
@ -1422,7 +1438,7 @@ fn compare_number_of_method_arguments<'tcx>(
|
|||
),
|
||||
);
|
||||
|
||||
return Err(err.emit());
|
||||
return Err(err.emit_unless(delay));
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
@ -1432,6 +1448,7 @@ fn compare_synthetic_generics<'tcx>(
|
|||
tcx: TyCtxt<'tcx>,
|
||||
impl_m: ty::AssocItem,
|
||||
trait_m: ty::AssocItem,
|
||||
delay: bool,
|
||||
) -> Result<(), ErrorGuaranteed> {
|
||||
// FIXME(chrisvittal) Clean up this function, list of FIXME items:
|
||||
// 1. Better messages for the span labels
|
||||
|
@ -1551,7 +1568,7 @@ fn compare_synthetic_generics<'tcx>(
|
|||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
error_found = Some(err.emit());
|
||||
error_found = Some(err.emit_unless(delay));
|
||||
}
|
||||
}
|
||||
if let Some(reported) = error_found { Err(reported) } else { Ok(()) }
|
||||
|
|
|
@ -106,10 +106,23 @@ fn enforce_impl_params_are_constrained(tcx: TyCtxt<'_>, impl_def_id: LocalDefId)
|
|||
if item.defaultness(tcx).has_value() {
|
||||
cgp::parameters_for(&tcx.type_of(def_id).subst_identity(), true)
|
||||
} else {
|
||||
Vec::new()
|
||||
vec![]
|
||||
}
|
||||
}
|
||||
ty::AssocKind::Fn | ty::AssocKind::Const => Vec::new(),
|
||||
ty::AssocKind::Fn => {
|
||||
if !tcx.lower_impl_trait_in_trait_to_assoc_ty()
|
||||
&& item.defaultness(tcx).has_value()
|
||||
&& tcx.impl_method_has_trait_impl_trait_tys(item.def_id)
|
||||
&& let Ok(table) = tcx.collect_return_position_impl_trait_in_trait_tys(def_id)
|
||||
{
|
||||
table.values().copied().flat_map(|ty| {
|
||||
cgp::parameters_for(&ty.subst_identity(), true)
|
||||
}).collect()
|
||||
} else {
|
||||
vec![]
|
||||
}
|
||||
}
|
||||
ty::AssocKind::Const => vec![],
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue