Auto merge of #106129 - compiler-errors:compare_method-tweaks, r=BoxyUwU

Some `compare_method` tweaks

1. Make some of the comparison functions' names more regular
2. Reduce pub scope of some of the things in `compare_method`
~3. Remove some unnecessary opaque type handling code -- `InferCtxt` already is in a mode that doesn't define opaque types~
  * moved to a different PR
4. Bubble up `ErrorGuaranteed` for region constraint errors in `compare_method` - Improves a redundant error message in one unit test.
5. Move the `compare_method` module to have a more general name, since it's more like `compare_impl_item` :)
6. Rename `collect_trait_impl_trait_tys`
This commit is contained in:
bors 2022-12-28 13:07:30 +00:00
commit 83a28ef095
17 changed files with 89 additions and 72 deletions

View file

@ -1,8 +1,8 @@
use crate::check::intrinsicck::InlineAsmCtxt;
use crate::errors::LinkageType;
use super::compare_method::check_type_bounds;
use super::compare_method::{compare_impl_method, compare_ty_impl};
use super::compare_impl_item::check_type_bounds;
use super::compare_impl_item::{compare_impl_method, compare_impl_ty};
use super::*;
use rustc_attr as attr;
use rustc_errors::{Applicability, ErrorGuaranteed, MultiSpan};
@ -468,7 +468,7 @@ fn check_opaque_meets_bounds<'tcx>(
// Can have different predicates to their defining use
hir::OpaqueTyOrigin::TyAlias => {
let outlives_environment = OutlivesEnvironment::new(param_env);
infcx.check_region_obligations_and_report_errors(
let _ = infcx.check_region_obligations_and_report_errors(
defining_use_anchor,
&outlives_environment,
);
@ -774,7 +774,7 @@ fn check_impl_items_against_trait<'tcx>(
let impl_item_full = tcx.hir().impl_item(impl_item.id);
match impl_item_full.kind {
hir::ImplItemKind::Const(..) => {
let _ = tcx.compare_assoc_const_impl_item_with_trait_item((
let _ = tcx.compare_impl_const((
impl_item.id.owner_id.def_id,
ty_impl_item.trait_item_def_id.unwrap(),
));
@ -791,7 +791,7 @@ fn check_impl_items_against_trait<'tcx>(
}
hir::ImplItemKind::Type(impl_ty) => {
let opt_trait_span = tcx.hir().span_if_local(ty_trait_item.def_id);
compare_ty_impl(
compare_impl_ty(
tcx,
&ty_impl_item,
impl_ty.span,

View file

@ -34,7 +34,7 @@ use std::iter;
/// - `impl_m_span`: span to use for reporting errors
/// - `trait_m`: the method in the trait
/// - `impl_trait_ref`: the TraitRef corresponding to the trait implementation
pub(crate) fn compare_impl_method<'tcx>(
pub(super) fn compare_impl_method<'tcx>(
tcx: TyCtxt<'tcx>,
impl_m: &ty::AssocItem,
trait_m: &ty::AssocItem,
@ -71,7 +71,7 @@ pub(crate) fn compare_impl_method<'tcx>(
return;
}
if let Err(_) = compare_predicate_entailment(
if let Err(_) = compare_method_predicate_entailment(
tcx,
impl_m,
impl_m_span,
@ -150,7 +150,7 @@ pub(crate) fn compare_impl_method<'tcx>(
/// Finally we register each of these predicates as an obligation and check that
/// they hold.
#[instrument(level = "debug", skip(tcx, impl_m_span, impl_trait_ref))]
fn compare_predicate_entailment<'tcx>(
fn compare_method_predicate_entailment<'tcx>(
tcx: TyCtxt<'tcx>,
impl_m: &ty::AssocItem,
impl_m_span: Span,
@ -337,7 +337,7 @@ fn compare_predicate_entailment<'tcx>(
if !errors.is_empty() {
match check_implied_wf {
CheckImpliedWfMode::Check => {
return compare_predicate_entailment(
return compare_method_predicate_entailment(
tcx,
impl_m,
impl_m_span,
@ -374,7 +374,7 @@ fn compare_predicate_entailment<'tcx>(
// becomes a hard error (i.e. ideally we'd just call `resolve_regions_and_report_errors`
match check_implied_wf {
CheckImpliedWfMode::Check => {
return compare_predicate_entailment(
return compare_method_predicate_entailment(
tcx,
impl_m,
impl_m_span,
@ -407,7 +407,7 @@ enum CheckImpliedWfMode {
/// re-check with `Skip`, and emit a lint if it succeeds.
Check,
/// Skips checking implied well-formedness of the impl method, but will emit
/// a lint if the `compare_predicate_entailment` succeeded. This means that
/// a lint if the `compare_method_predicate_entailment` succeeded. This means that
/// the reason that we had failed earlier during `Check` was due to the impl
/// having stronger requirements than the trait.
Skip,
@ -441,8 +441,41 @@ fn compare_asyncness<'tcx>(
Ok(())
}
/// Given a method def-id in an impl, compare the method signature of the impl
/// against the trait that it's implementing. In doing so, infer the hidden types
/// that this method's signature provides to satisfy each return-position `impl Trait`
/// in the trait signature.
///
/// The method is also responsible for making sure that the hidden types for each
/// RPITIT actually satisfy the bounds of the `impl Trait`, i.e. that if we infer
/// `impl Trait = Foo`, that `Foo: Trait` holds.
///
/// For example, given the sample code:
///
/// ```
/// #![feature(return_position_impl_trait_in_trait)]
///
/// use std::ops::Deref;
///
/// trait Foo {
/// fn bar() -> impl Deref<Target = impl Sized>;
/// // ^- RPITIT #1 ^- RPITIT #2
/// }
///
/// impl Foo for () {
/// fn bar() -> Box<String> { Box::new(String::new()) }
/// }
/// ```
///
/// The hidden types for the RPITITs in `bar` would be inferred to:
/// * `impl Deref` (RPITIT #1) = `Box<String>`
/// * `impl Sized` (RPITIT #2) = `String`
///
/// The relationship between these two types is straightforward in this case, but
/// may be more tenuously connected via other `impl`s and normalization rules for
/// cases of more complicated nested RPITITs.
#[instrument(skip(tcx), level = "debug", ret)]
pub fn collect_trait_impl_trait_tys<'tcx>(
pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
tcx: TyCtxt<'tcx>,
def_id: DefId,
) -> Result<&'tcx FxHashMap<DefId, Ty<'tcx>>, ErrorGuaranteed> {
@ -550,13 +583,13 @@ pub fn collect_trait_impl_trait_tys<'tcx>(
// Unify the whole function signature. We need to do this to fully infer
// the lifetimes of the return type, but do this after unifying just the
// return types, since we want to avoid duplicating errors from
// `compare_predicate_entailment`.
// `compare_method_predicate_entailment`.
match ocx.eq(&cause, param_env, trait_fty, impl_fty) {
Ok(()) => {}
Err(terr) => {
// This function gets called during `compare_predicate_entailment` when normalizing a
// This function gets called during `compare_method_predicate_entailment` when normalizing a
// signature that contains RPITIT. When the method signatures don't match, we have to
// emit an error now because `compare_predicate_entailment` will not report the error
// emit an error now because `compare_method_predicate_entailment` will not report the error
// when normalization fails.
let emitted = report_trait_method_mismatch(
infcx,
@ -589,7 +622,7 @@ pub fn collect_trait_impl_trait_tys<'tcx>(
infcx.check_region_obligations_and_report_errors(
impl_m.def_id.expect_local(),
&outlives_environment,
);
)?;
let mut collected_tys = FxHashMap::default();
for (def_id, (ty, substs)) in collector.types {
@ -1516,8 +1549,8 @@ fn compare_generic_param_kinds<'tcx>(
Ok(())
}
/// Use `tcx.compare_assoc_const_impl_item_with_trait_item` instead
pub(crate) fn raw_compare_const_impl(
/// Use `tcx.compare_impl_const` instead
pub(super) fn compare_impl_const_raw(
tcx: TyCtxt<'_>,
(impl_const_item_def, trait_const_item_def): (LocalDefId, DefId),
) -> Result<(), ErrorGuaranteed> {
@ -1617,13 +1650,13 @@ pub(crate) fn raw_compare_const_impl(
return Err(infcx.err_ctxt().report_fulfillment_errors(&errors, None));
}
// FIXME return `ErrorReported` if region obligations error?
let outlives_environment = OutlivesEnvironment::new(param_env);
infcx.check_region_obligations_and_report_errors(impl_const_item_def, &outlives_environment);
infcx.check_region_obligations_and_report_errors(impl_const_item_def, &outlives_environment)?;
Ok(())
}
pub(crate) fn compare_ty_impl<'tcx>(
pub(super) fn compare_impl_ty<'tcx>(
tcx: TyCtxt<'tcx>,
impl_ty: &ty::AssocItem,
impl_ty_span: Span,
@ -1645,7 +1678,7 @@ pub(crate) fn compare_ty_impl<'tcx>(
})();
}
/// The equivalent of [compare_predicate_entailment], but for associated types
/// The equivalent of [compare_method_predicate_entailment], but for associated types
/// instead of associated functions.
fn compare_type_predicate_entailment<'tcx>(
tcx: TyCtxt<'tcx>,
@ -1730,7 +1763,7 @@ fn compare_type_predicate_entailment<'tcx>(
infcx.check_region_obligations_and_report_errors(
impl_ty.def_id.expect_local(),
&outlives_environment,
);
)?;
Ok(())
}
@ -1749,7 +1782,7 @@ fn compare_type_predicate_entailment<'tcx>(
/// from the impl could be overridden). We also can't normalize generic
/// associated types (yet) because they contain bound parameters.
#[instrument(level = "debug", skip(tcx))]
pub fn check_type_bounds<'tcx>(
pub(super) fn check_type_bounds<'tcx>(
tcx: TyCtxt<'tcx>,
trait_ty: &ty::AssocItem,
impl_ty: &ty::AssocItem,
@ -1944,7 +1977,7 @@ pub fn check_type_bounds<'tcx>(
infcx.check_region_obligations_and_report_errors(
impl_ty.def_id.expect_local(),
&outlives_environment,
);
)?;
let constraints = infcx.inner.borrow_mut().opaque_type_storage.take_opaque_types();
for (key, value) in constraints {

View file

@ -63,7 +63,7 @@ a type parameter).
*/
mod check;
mod compare_method;
mod compare_impl_item;
pub mod dropck;
pub mod intrinsic;
pub mod intrinsicck;
@ -94,7 +94,7 @@ use std::num::NonZeroU32;
use crate::require_c_abi_if_c_variadic;
use crate::util::common::indenter;
use self::compare_method::collect_trait_impl_trait_tys;
use self::compare_impl_item::collect_return_position_impl_trait_in_trait_tys;
use self::region::region_scope_tree;
pub fn provide(providers: &mut Providers) {
@ -103,8 +103,8 @@ pub fn provide(providers: &mut Providers) {
adt_destructor,
check_mod_item_types,
region_scope_tree,
collect_trait_impl_trait_tys,
compare_assoc_const_impl_item_with_trait_item: compare_method::raw_compare_const_impl,
collect_return_position_impl_trait_in_trait_tys,
compare_impl_const: compare_impl_item::compare_impl_const_raw,
..*providers
};
}

View file

@ -115,7 +115,7 @@ pub(super) fn enter_wf_checking_ctxt<'tcx, F>(
let outlives_environment =
OutlivesEnvironment::with_bounds(param_env, Some(infcx), implied_bounds);
infcx.check_region_obligations_and_report_errors(body_def_id, &outlives_environment);
let _ = infcx.check_region_obligations_and_report_errors(body_def_id, &outlives_environment);
}
fn check_well_formed(tcx: TyCtxt<'_>, def_id: hir::OwnerId) {

View file

@ -325,7 +325,7 @@ fn visit_implementation_of_dispatch_from_dyn(tcx: TyCtxt<'_>, impl_did: LocalDef
// Finally, resolve all regions.
let outlives_env = OutlivesEnvironment::new(param_env);
infcx.check_region_obligations_and_report_errors(impl_did, &outlives_env);
let _ = infcx.check_region_obligations_and_report_errors(impl_did, &outlives_env);
}
}
_ => {
@ -565,7 +565,7 @@ pub fn coerce_unsized_info<'tcx>(tcx: TyCtxt<'tcx>, impl_did: DefId) -> CoerceUn
// Finally, resolve all regions.
let outlives_env = OutlivesEnvironment::new(param_env);
infcx.check_region_obligations_and_report_errors(impl_did, &outlives_env);
let _ = infcx.check_region_obligations_and_report_errors(impl_did, &outlives_env);
CoerceUnsizedInfo { custom_kind: kind }
}

View file

@ -181,7 +181,7 @@ fn get_impl_substs(
let implied_bounds = infcx.implied_bounds_tys(param_env, impl1_hir_id, assumed_wf_types);
let outlives_env = OutlivesEnvironment::with_bounds(param_env, Some(infcx), implied_bounds);
infcx.check_region_obligations_and_report_errors(impl1_def_id, &outlives_env);
let _ = infcx.check_region_obligations_and_report_errors(impl1_def_id, &outlives_env);
let Ok(impl2_substs) = infcx.fully_resolve(impl2_substs) else {
let span = tcx.def_span(impl1_def_id);
tcx.sess.emit_err(SubstsOnOverriddenImpl { span });