remove some trait solver helpers
they add more complexity then they are worth. It's confusing which of these helpers should be used in which context.
This commit is contained in:
parent
84c47b8279
commit
791ce0b7b5
31 changed files with 199 additions and 289 deletions
|
@ -59,6 +59,7 @@ fn equate_intrinsic_type<'tcx>(
|
|||
require_same_types(
|
||||
tcx,
|
||||
&cause,
|
||||
ty::ParamEnv::empty(), // FIXME: do all intrinsics have an empty param env?
|
||||
tcx.mk_fn_ptr(tcx.fn_sig(it.owner_id).subst_identity()),
|
||||
fty,
|
||||
);
|
||||
|
|
|
@ -11,13 +11,14 @@ use rustc_hir::ItemKind;
|
|||
use rustc_infer::infer::outlives::env::OutlivesEnvironment;
|
||||
use rustc_infer::infer::{self, RegionResolutionError};
|
||||
use rustc_infer::infer::{DefineOpaqueTypes, TyCtxtInferExt};
|
||||
use rustc_infer::traits::Obligation;
|
||||
use rustc_middle::ty::adjustment::CoerceUnsizedInfo;
|
||||
use rustc_middle::ty::{self, suggest_constraining_type_params, Ty, TyCtxt, TypeVisitableExt};
|
||||
use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt;
|
||||
use rustc_trait_selection::traits::misc::{
|
||||
type_allowed_to_implement_copy, CopyImplementationError, InfringingFieldsReason,
|
||||
};
|
||||
use rustc_trait_selection::traits::predicate_for_trait_def;
|
||||
use rustc_trait_selection::traits::ObligationCtxt;
|
||||
use rustc_trait_selection::traits::{self, ObligationCause};
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
|
@ -334,19 +335,19 @@ fn visit_implementation_of_dispatch_from_dyn(tcx: TyCtxt<'_>, impl_did: LocalDef
|
|||
))
|
||||
.emit();
|
||||
} else {
|
||||
let errors = traits::fully_solve_obligations(
|
||||
&infcx,
|
||||
coerced_fields.into_iter().map(|field| {
|
||||
predicate_for_trait_def(
|
||||
tcx,
|
||||
param_env,
|
||||
cause.clone(),
|
||||
let ocx = ObligationCtxt::new(&infcx);
|
||||
for field in coerced_fields {
|
||||
ocx.register_obligation(Obligation::new(
|
||||
tcx,
|
||||
cause.clone(),
|
||||
param_env,
|
||||
ty::Binder::dummy(tcx.mk_trait_ref(
|
||||
dispatch_from_dyn_trait,
|
||||
0,
|
||||
[field.ty(tcx, substs_a), field.ty(tcx, substs_b)],
|
||||
)
|
||||
}),
|
||||
);
|
||||
)),
|
||||
));
|
||||
}
|
||||
let errors = ocx.select_all_or_error();
|
||||
if !errors.is_empty() {
|
||||
infcx.err_ctxt().report_fulfillment_errors(&errors);
|
||||
}
|
||||
|
@ -583,10 +584,12 @@ pub fn coerce_unsized_info<'tcx>(tcx: TyCtxt<'tcx>, impl_did: DefId) -> CoerceUn
|
|||
};
|
||||
|
||||
// Register an obligation for `A: Trait<B>`.
|
||||
let ocx = ObligationCtxt::new(&infcx);
|
||||
let cause = traits::ObligationCause::misc(span, impl_did);
|
||||
let predicate =
|
||||
predicate_for_trait_def(tcx, param_env, cause, trait_def_id, 0, [source, target]);
|
||||
let errors = traits::fully_solve_obligation(&infcx, predicate);
|
||||
let obligation =
|
||||
Obligation::new(tcx, cause, param_env, tcx.mk_trait_ref(trait_def_id, [source, target]));
|
||||
ocx.register_obligation(obligation);
|
||||
let errors = ocx.select_all_or_error();
|
||||
if !errors.is_empty() {
|
||||
infcx.err_ctxt().report_fulfillment_errors(&errors);
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@ use rustc_infer::traits::{ObligationCause, WellFormedLoc};
|
|||
use rustc_middle::ty::query::Providers;
|
||||
use rustc_middle::ty::{self, Region, TyCtxt, TypeFoldable, TypeFolder};
|
||||
use rustc_span::def_id::LocalDefId;
|
||||
use rustc_trait_selection::traits;
|
||||
use rustc_trait_selection::traits::{self, ObligationCtxt};
|
||||
|
||||
pub fn provide(providers: &mut Providers) {
|
||||
*providers = Providers { diagnostic_hir_wf_check, ..*providers };
|
||||
|
@ -66,35 +66,35 @@ fn diagnostic_hir_wf_check<'tcx>(
|
|||
impl<'tcx> Visitor<'tcx> for HirWfCheck<'tcx> {
|
||||
fn visit_ty(&mut self, ty: &'tcx hir::Ty<'tcx>) {
|
||||
let infcx = self.tcx.infer_ctxt().build();
|
||||
let ocx = ObligationCtxt::new(&infcx);
|
||||
|
||||
let tcx_ty = self.icx.to_ty(ty).fold_with(&mut EraseAllBoundRegions { tcx: self.tcx });
|
||||
let cause = traits::ObligationCause::new(
|
||||
ty.span,
|
||||
self.def_id,
|
||||
traits::ObligationCauseCode::WellFormed(None),
|
||||
);
|
||||
let errors = traits::fully_solve_obligation(
|
||||
&infcx,
|
||||
traits::Obligation::new(
|
||||
self.tcx,
|
||||
cause,
|
||||
self.param_env,
|
||||
ty::Binder::dummy(ty::PredicateKind::WellFormed(tcx_ty.into())),
|
||||
),
|
||||
);
|
||||
if !errors.is_empty() {
|
||||
debug!("Wf-check got errors for {:?}: {:?}", ty, errors);
|
||||
for error in errors {
|
||||
if error.obligation.predicate == self.predicate {
|
||||
// Save the cause from the greatest depth - this corresponds
|
||||
// to picking more-specific types (e.g. `MyStruct<u8>`)
|
||||
// over less-specific types (e.g. `Option<MyStruct<u8>>`)
|
||||
if self.depth >= self.cause_depth {
|
||||
self.cause = Some(error.obligation.cause);
|
||||
self.cause_depth = self.depth
|
||||
}
|
||||
|
||||
ocx.register_obligation(traits::Obligation::new(
|
||||
self.tcx,
|
||||
cause,
|
||||
self.param_env,
|
||||
ty::PredicateKind::WellFormed(tcx_ty.into()),
|
||||
));
|
||||
|
||||
for error in ocx.select_all_or_error() {
|
||||
debug!("Wf-check got error for {:?}: {:?}", ty, error);
|
||||
if error.obligation.predicate == self.predicate {
|
||||
// Save the cause from the greatest depth - this corresponds
|
||||
// to picking more-specific types (e.g. `MyStruct<u8>`)
|
||||
// over less-specific types (e.g. `Option<MyStruct<u8>>`)
|
||||
if self.depth >= self.cause_depth {
|
||||
self.cause = Some(error.obligation.cause);
|
||||
self.cause_depth = self.depth
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
self.depth += 1;
|
||||
intravisit::walk_ty(self, ty);
|
||||
self.depth -= 1;
|
||||
|
|
|
@ -102,7 +102,7 @@ use rustc_errors::ErrorGuaranteed;
|
|||
use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage};
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::Node;
|
||||
use rustc_infer::infer::{DefineOpaqueTypes, InferOk, TyCtxtInferExt};
|
||||
use rustc_infer::infer::TyCtxtInferExt;
|
||||
use rustc_macros::fluent_messages;
|
||||
use rustc_middle::middle;
|
||||
use rustc_middle::ty::query::Providers;
|
||||
|
@ -113,7 +113,7 @@ use rustc_span::def_id::{DefId, LocalDefId, CRATE_DEF_ID};
|
|||
use rustc_span::{symbol::sym, Span, DUMMY_SP};
|
||||
use rustc_target::spec::abi::Abi;
|
||||
use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt as _;
|
||||
use rustc_trait_selection::traits::{self, ObligationCause, ObligationCauseCode};
|
||||
use rustc_trait_selection::traits::{self, ObligationCause, ObligationCauseCode, ObligationCtxt};
|
||||
|
||||
use std::ops::Not;
|
||||
|
||||
|
@ -160,24 +160,21 @@ fn require_c_abi_if_c_variadic(tcx: TyCtxt<'_>, decl: &hir::FnDecl<'_>, abi: Abi
|
|||
fn require_same_types<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
cause: &ObligationCause<'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
expected: Ty<'tcx>,
|
||||
actual: Ty<'tcx>,
|
||||
) -> bool {
|
||||
) {
|
||||
let infcx = &tcx.infer_ctxt().build();
|
||||
let param_env = ty::ParamEnv::empty();
|
||||
let errors = match infcx.at(cause, param_env).eq(DefineOpaqueTypes::No, expected, actual) {
|
||||
Ok(InferOk { obligations, .. }) => traits::fully_solve_obligations(infcx, obligations),
|
||||
let ocx = ObligationCtxt::new(infcx);
|
||||
match ocx.eq(cause, param_env, expected, actual) {
|
||||
Ok(()) => {
|
||||
let errors = ocx.select_all_or_error();
|
||||
if !errors.is_empty() {
|
||||
infcx.err_ctxt().report_fulfillment_errors(&errors);
|
||||
}
|
||||
}
|
||||
Err(err) => {
|
||||
infcx.err_ctxt().report_mismatched_types(cause, expected, actual, err).emit();
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
match &errors[..] {
|
||||
[] => true,
|
||||
errors => {
|
||||
infcx.err_ctxt().report_fulfillment_errors(errors);
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -296,6 +293,8 @@ fn check_main_fn_ty(tcx: TyCtxt<'_>, main_def_id: DefId) {
|
|||
return;
|
||||
}
|
||||
|
||||
// Main should have no WC, so empty param env is OK here.
|
||||
let param_env = ty::ParamEnv::empty();
|
||||
let expected_return_type;
|
||||
if let Some(term_did) = tcx.lang_items().termination() {
|
||||
let return_ty = main_fnsig.output();
|
||||
|
@ -306,8 +305,6 @@ fn check_main_fn_ty(tcx: TyCtxt<'_>, main_def_id: DefId) {
|
|||
}
|
||||
let return_ty = return_ty.skip_binder();
|
||||
let infcx = tcx.infer_ctxt().build();
|
||||
// Main should have no WC, so empty param env is OK here.
|
||||
let param_env = ty::ParamEnv::empty();
|
||||
let cause = traits::ObligationCause::new(
|
||||
return_ty_span,
|
||||
main_diagnostics_def_id,
|
||||
|
@ -343,6 +340,7 @@ fn check_main_fn_ty(tcx: TyCtxt<'_>, main_def_id: DefId) {
|
|||
main_diagnostics_def_id,
|
||||
ObligationCauseCode::MainFunctionType,
|
||||
),
|
||||
param_env,
|
||||
se_ty,
|
||||
tcx.mk_fn_ptr(main_fnsig),
|
||||
);
|
||||
|
@ -417,6 +415,7 @@ fn check_start_fn_ty(tcx: TyCtxt<'_>, start_def_id: DefId) {
|
|||
start_def_id,
|
||||
ObligationCauseCode::StartFunctionType,
|
||||
),
|
||||
ty::ParamEnv::empty(), // start should not have any where bounds.
|
||||
se_ty,
|
||||
tcx.mk_fn_ptr(tcx.fn_sig(start_def_id).subst_identity()),
|
||||
);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue