mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-21 22:34:05 +00:00
Move all error reporting into rustc_trait_selection
This commit is contained in:
parent
f49738ba6c
commit
ce8a625092
@ -1,6 +1,5 @@
|
||||
use rustc_errors::Diag;
|
||||
use rustc_hir::def_id::LocalDefId;
|
||||
use rustc_infer::error_reporting::infer::nice_region_error::NiceRegionError;
|
||||
use rustc_infer::infer::canonical::Canonical;
|
||||
use rustc_infer::infer::region_constraints::Constraint;
|
||||
use rustc_infer::infer::region_constraints::RegionConstraintData;
|
||||
@ -14,6 +13,8 @@ use rustc_middle::ty::RegionVid;
|
||||
use rustc_middle::ty::UniverseIndex;
|
||||
use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable};
|
||||
use rustc_span::Span;
|
||||
use rustc_trait_selection::error_reporting::infer::nice_region_error::NiceRegionError;
|
||||
use rustc_trait_selection::error_reporting::InferCtxtErrorExt;
|
||||
use rustc_trait_selection::traits::query::type_op;
|
||||
use rustc_trait_selection::traits::ObligationCtxt;
|
||||
use rustc_traits::{type_op_ascribe_user_type_with_span, type_op_prove_predicate_with_cause};
|
||||
|
@ -35,8 +35,8 @@ use rustc_span::def_id::LocalDefId;
|
||||
use rustc_span::hygiene::DesugaringKind;
|
||||
use rustc_span::symbol::{kw, sym, Ident};
|
||||
use rustc_span::{BytePos, Span, Symbol};
|
||||
use rustc_trait_selection::error_reporting::traits::suggestions::TypeErrCtxtExt;
|
||||
use rustc_trait_selection::error_reporting::traits::FindExprBySpan;
|
||||
use rustc_trait_selection::error_reporting::InferCtxtErrorExt;
|
||||
use rustc_trait_selection::infer::InferCtxtExt;
|
||||
use rustc_trait_selection::traits::{Obligation, ObligationCause, ObligationCtxt};
|
||||
use std::iter;
|
||||
|
@ -27,7 +27,7 @@ use rustc_span::def_id::LocalDefId;
|
||||
use rustc_span::source_map::Spanned;
|
||||
use rustc_span::{symbol::sym, Span, Symbol, DUMMY_SP};
|
||||
use rustc_target::abi::{FieldIdx, VariantIdx};
|
||||
use rustc_trait_selection::error_reporting::traits::suggestions::TypeErrCtxtExt as _;
|
||||
use rustc_trait_selection::error_reporting::InferCtxtErrorExt;
|
||||
use rustc_trait_selection::infer::InferCtxtExt;
|
||||
use rustc_trait_selection::traits::{
|
||||
type_known_to_meet_bound_modulo_regions, FulfillmentErrorCode,
|
||||
|
@ -16,7 +16,7 @@ use rustc_middle::{
|
||||
use rustc_span::symbol::{kw, Symbol};
|
||||
use rustc_span::{sym, BytePos, DesugaringKind, Span};
|
||||
use rustc_target::abi::FieldIdx;
|
||||
use rustc_trait_selection::error_reporting::traits::suggestions::TypeErrCtxtExt;
|
||||
use rustc_trait_selection::error_reporting::InferCtxtErrorExt;
|
||||
use rustc_trait_selection::infer::InferCtxtExt;
|
||||
use rustc_trait_selection::traits;
|
||||
|
||||
|
@ -10,11 +10,6 @@ use rustc_hir::GenericBound::Trait;
|
||||
use rustc_hir::QPath::Resolved;
|
||||
use rustc_hir::WherePredicate::BoundPredicate;
|
||||
use rustc_hir::{PolyTraitRef, TyKind, WhereBoundPredicate};
|
||||
use rustc_infer::error_reporting::infer::nice_region_error::{
|
||||
self, find_anon_type, find_param_with_region, suggest_adding_lifetime_params,
|
||||
HirTraitObjectVisitor, NiceRegionError, TraitObjectVisitor,
|
||||
};
|
||||
use rustc_infer::error_reporting::infer::region::unexpected_hidden_region_diagnostic;
|
||||
use rustc_infer::infer::{NllRegionVariableOrigin, RelateParamBound};
|
||||
use rustc_middle::bug;
|
||||
use rustc_middle::hir::place::PlaceBase;
|
||||
@ -25,6 +20,12 @@ use rustc_middle::ty::{self, RegionVid, Ty};
|
||||
use rustc_middle::ty::{Region, TyCtxt};
|
||||
use rustc_span::symbol::{kw, Ident};
|
||||
use rustc_span::Span;
|
||||
use rustc_trait_selection::error_reporting::infer::nice_region_error::{
|
||||
self, find_anon_type, find_param_with_region, suggest_adding_lifetime_params,
|
||||
HirTraitObjectVisitor, NiceRegionError, TraitObjectVisitor,
|
||||
};
|
||||
use rustc_trait_selection::error_reporting::infer::region::unexpected_hidden_region_diagnostic;
|
||||
use rustc_trait_selection::error_reporting::InferCtxtErrorExt;
|
||||
use rustc_trait_selection::infer::InferCtxtExt;
|
||||
use rustc_trait_selection::traits::{Obligation, ObligationCtxt};
|
||||
|
||||
|
@ -14,6 +14,7 @@ use rustc_middle::ty::{GenericArgKind, GenericArgsRef};
|
||||
use rustc_middle::{bug, span_bug};
|
||||
use rustc_span::symbol::{kw, sym, Symbol};
|
||||
use rustc_span::{Span, DUMMY_SP};
|
||||
use rustc_trait_selection::error_reporting::InferCtxtErrorExt;
|
||||
|
||||
use crate::{universal_regions::DefiningTy, MirBorrowckCtxt};
|
||||
|
||||
|
@ -11,7 +11,7 @@ use rustc_middle::ty::visit::TypeVisitableExt;
|
||||
use rustc_middle::ty::{self, OpaqueHiddenType, OpaqueTypeKey, Ty, TyCtxt, TypeFoldable};
|
||||
use rustc_middle::ty::{GenericArgKind, GenericArgs};
|
||||
use rustc_span::Span;
|
||||
use rustc_trait_selection::error_reporting::traits::TypeErrCtxtExt as _;
|
||||
use rustc_trait_selection::error_reporting::InferCtxtErrorExt;
|
||||
use rustc_trait_selection::traits::ObligationCtxt;
|
||||
|
||||
use crate::session_diagnostics::LifetimeMismatchOpaqueParam;
|
||||
|
@ -11,7 +11,7 @@ use rustc_middle::traits::query::OutlivesBound;
|
||||
use rustc_middle::traits::ObligationCause;
|
||||
use rustc_middle::ty::{self, RegionVid, Ty, TypeVisitableExt};
|
||||
use rustc_span::{ErrorGuaranteed, Span};
|
||||
use rustc_trait_selection::error_reporting::traits::TypeErrCtxtExt;
|
||||
use rustc_trait_selection::error_reporting::InferCtxtErrorExt;
|
||||
use rustc_trait_selection::solve::deeply_normalize;
|
||||
use rustc_trait_selection::traits::query::type_op::{self, TypeOp};
|
||||
use std::rc::Rc;
|
||||
|
@ -13,7 +13,7 @@ use rustc_middle::ty::{self, adjustment::PointerCoercion, Ty, TyCtxt};
|
||||
use rustc_middle::ty::{Instance, InstanceKind, TypeVisitableExt};
|
||||
use rustc_mir_dataflow::Analysis;
|
||||
use rustc_span::{sym, Span, Symbol, DUMMY_SP};
|
||||
use rustc_trait_selection::error_reporting::traits::TypeErrCtxtExt as _;
|
||||
use rustc_trait_selection::error_reporting::InferCtxtErrorExt;
|
||||
use rustc_trait_selection::traits::{self, ObligationCauseCode, ObligationCtxt};
|
||||
use rustc_type_ir::visit::{TypeSuperVisitable, TypeVisitor};
|
||||
|
||||
|
@ -26,7 +26,7 @@ use rustc_middle::ty::{
|
||||
use rustc_session::lint::builtin::{UNINHABITED_STATIC, UNSUPPORTED_CALLING_CONVENTIONS};
|
||||
use rustc_target::abi::FieldIdx;
|
||||
use rustc_trait_selection::error_reporting::traits::on_unimplemented::OnUnimplementedDirective;
|
||||
use rustc_trait_selection::error_reporting::traits::TypeErrCtxtExt as _;
|
||||
use rustc_trait_selection::error_reporting::InferCtxtErrorExt;
|
||||
use rustc_trait_selection::traits;
|
||||
use rustc_trait_selection::traits::outlives_bounds::InferCtxtExt as _;
|
||||
use rustc_type_ir::fold::TypeFoldable;
|
||||
|
@ -21,7 +21,7 @@ use rustc_middle::ty::{
|
||||
use rustc_middle::ty::{GenericParamDefKind, TyCtxt};
|
||||
use rustc_middle::{bug, span_bug};
|
||||
use rustc_span::Span;
|
||||
use rustc_trait_selection::error_reporting::traits::TypeErrCtxtExt;
|
||||
use rustc_trait_selection::error_reporting::InferCtxtErrorExt;
|
||||
use rustc_trait_selection::infer::InferCtxtExt;
|
||||
use rustc_trait_selection::regions::InferCtxtRegionExt;
|
||||
use rustc_trait_selection::traits::outlives_bounds::InferCtxtExt as _;
|
||||
|
@ -7,7 +7,7 @@ use rustc_session::config::EntryFnType;
|
||||
use rustc_span::def_id::{DefId, LocalDefId, CRATE_DEF_ID};
|
||||
use rustc_span::{symbol::sym, Span};
|
||||
use rustc_target::spec::abi::Abi;
|
||||
use rustc_trait_selection::error_reporting::traits::TypeErrCtxtExt as _;
|
||||
use rustc_trait_selection::error_reporting::InferCtxtErrorExt;
|
||||
use rustc_trait_selection::traits::{self, ObligationCause, ObligationCauseCode};
|
||||
|
||||
use std::ops::Not;
|
||||
|
@ -82,7 +82,6 @@ use rustc_errors::{pluralize, struct_span_code_err, Diag};
|
||||
use rustc_hir::def_id::{DefId, LocalDefId};
|
||||
use rustc_hir::intravisit::Visitor;
|
||||
use rustc_index::bit_set::BitSet;
|
||||
use rustc_infer::error_reporting::infer::ObligationCauseExt as _;
|
||||
use rustc_infer::infer::outlives::env::OutlivesEnvironment;
|
||||
use rustc_infer::infer::{self, TyCtxtInferExt as _};
|
||||
use rustc_infer::traits::ObligationCause;
|
||||
@ -96,10 +95,9 @@ use rustc_span::symbol::{kw, sym, Ident};
|
||||
use rustc_span::{def_id::CRATE_DEF_ID, BytePos, Span, Symbol, DUMMY_SP};
|
||||
use rustc_target::abi::VariantIdx;
|
||||
use rustc_target::spec::abi::Abi;
|
||||
use rustc_trait_selection::error_reporting::traits::suggestions::{
|
||||
ReturnsVisitor, TypeErrCtxtExt as _,
|
||||
};
|
||||
use rustc_trait_selection::error_reporting::traits::TypeErrCtxtExt as _;
|
||||
use rustc_trait_selection::error_reporting::infer::ObligationCauseExt as _;
|
||||
use rustc_trait_selection::error_reporting::traits::suggestions::ReturnsVisitor;
|
||||
use rustc_trait_selection::error_reporting::InferCtxtErrorExt;
|
||||
use rustc_trait_selection::traits::ObligationCtxt;
|
||||
|
||||
use crate::errors;
|
||||
|
@ -29,7 +29,7 @@ use rustc_session::parse::feature_err;
|
||||
use rustc_span::symbol::{sym, Ident};
|
||||
use rustc_span::{Span, DUMMY_SP};
|
||||
use rustc_target::spec::abi::Abi;
|
||||
use rustc_trait_selection::error_reporting::traits::TypeErrCtxtExt;
|
||||
use rustc_trait_selection::error_reporting::InferCtxtErrorExt;
|
||||
use rustc_trait_selection::regions::InferCtxtRegionExt;
|
||||
use rustc_trait_selection::traits::misc::{
|
||||
type_allowed_to_implement_const_param_ty, ConstParamTyImplementationError,
|
||||
|
@ -17,7 +17,7 @@ use rustc_middle::ty::adjustment::CoerceUnsizedInfo;
|
||||
use rustc_middle::ty::print::PrintTraitRefExt as _;
|
||||
use rustc_middle::ty::{self, suggest_constraining_type_params, Ty, TyCtxt, TypeVisitableExt};
|
||||
use rustc_span::{Span, DUMMY_SP};
|
||||
use rustc_trait_selection::error_reporting::traits::TypeErrCtxtExt;
|
||||
use rustc_trait_selection::error_reporting::InferCtxtErrorExt;
|
||||
use rustc_trait_selection::traits::misc::{
|
||||
type_allowed_to_implement_const_param_ty, type_allowed_to_implement_copy,
|
||||
ConstParamTyImplementationError, CopyImplementationError, InfringingFieldsReason,
|
||||
|
@ -78,7 +78,7 @@ use rustc_middle::ty::trait_def::TraitSpecializationKind;
|
||||
use rustc_middle::ty::{self, TyCtxt, TypeVisitableExt};
|
||||
use rustc_middle::ty::{GenericArg, GenericArgs, GenericArgsRef};
|
||||
use rustc_span::{ErrorGuaranteed, Span};
|
||||
use rustc_trait_selection::error_reporting::traits::TypeErrCtxtExt;
|
||||
use rustc_trait_selection::error_reporting::InferCtxtErrorExt;
|
||||
use rustc_trait_selection::traits::outlives_bounds::InferCtxtExt as _;
|
||||
use rustc_trait_selection::traits::{self, translate_args_with_cause, wf, ObligationCtxt};
|
||||
|
||||
|
@ -58,8 +58,6 @@ use rustc_session::parse::feature_err;
|
||||
use rustc_span::symbol::sym;
|
||||
use rustc_span::{BytePos, DesugaringKind, Span, DUMMY_SP};
|
||||
use rustc_target::spec::abi::Abi;
|
||||
use rustc_trait_selection::error_reporting::traits::suggestions::TypeErrCtxtExt;
|
||||
use rustc_trait_selection::error_reporting::traits::TypeErrCtxtSelectionErrExt as _;
|
||||
use rustc_trait_selection::infer::InferCtxtExt as _;
|
||||
use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt;
|
||||
use rustc_trait_selection::traits::{
|
||||
|
@ -53,8 +53,6 @@ use rustc_span::source_map::Spanned;
|
||||
use rustc_span::symbol::{kw, sym, Ident, Symbol};
|
||||
use rustc_span::Span;
|
||||
use rustc_target::abi::{FieldIdx, FIRST_VARIANT};
|
||||
use rustc_trait_selection::error_reporting::traits::suggestions::TypeErrCtxtExt as _;
|
||||
use rustc_trait_selection::error_reporting::traits::TypeErrCtxtExt;
|
||||
use rustc_trait_selection::infer::InferCtxtExt;
|
||||
use rustc_trait_selection::traits::ObligationCtxt;
|
||||
use rustc_trait_selection::traits::{self, ObligationCauseCode};
|
||||
|
@ -18,7 +18,6 @@ use rustc_hir_analysis::hir_ty_lowering::{
|
||||
ExplicitLateBound, GenericArgCountMismatch, GenericArgCountResult, GenericArgsLowerer,
|
||||
GenericPathSegment, HirTyLowerer, IsMethodCall, RegionInferReason,
|
||||
};
|
||||
use rustc_infer::error_reporting::infer::need_type_info::TypeAnnotationNeeded;
|
||||
use rustc_infer::infer::canonical::{Canonical, OriginalQueryValues, QueryResponse};
|
||||
use rustc_infer::infer::{DefineOpaqueTypes, InferResult};
|
||||
use rustc_lint::builtin::SELF_CONSTRUCTOR_FROM_OUTER_ITEM;
|
||||
@ -37,7 +36,7 @@ use rustc_span::hygiene::DesugaringKind;
|
||||
use rustc_span::symbol::{kw, sym};
|
||||
use rustc_span::Span;
|
||||
use rustc_target::abi::FieldIdx;
|
||||
use rustc_trait_selection::error_reporting::traits::TypeErrCtxtExt as _;
|
||||
use rustc_trait_selection::error_reporting::infer::need_type_info::TypeAnnotationNeeded;
|
||||
use rustc_trait_selection::traits::{
|
||||
self, NormalizeExt, ObligationCauseCode, ObligationCtxt, StructurallyNormalizeExt,
|
||||
};
|
||||
|
@ -29,7 +29,6 @@ use rustc_hir_analysis::check::intrinsicck::InlineAsmCtxt;
|
||||
use rustc_hir_analysis::check::potentially_plural_count;
|
||||
use rustc_hir_analysis::hir_ty_lowering::HirTyLowerer;
|
||||
use rustc_index::IndexVec;
|
||||
use rustc_infer::error_reporting::infer::{FailureCode, ObligationCauseExt};
|
||||
use rustc_infer::infer::TypeTrace;
|
||||
use rustc_infer::infer::{DefineOpaqueTypes, InferOk};
|
||||
use rustc_middle::ty::adjustment::AllowTwoPhase;
|
||||
@ -39,6 +38,7 @@ use rustc_middle::{bug, span_bug};
|
||||
use rustc_session::Session;
|
||||
use rustc_span::symbol::{kw, Ident};
|
||||
use rustc_span::{sym, BytePos, Span, DUMMY_SP};
|
||||
use rustc_trait_selection::error_reporting::infer::{FailureCode, ObligationCauseExt};
|
||||
use rustc_trait_selection::infer::InferCtxtExt;
|
||||
use rustc_trait_selection::traits::{self, ObligationCauseCode, SelectionContext};
|
||||
|
||||
|
@ -15,13 +15,13 @@ use hir::def_id::CRATE_DEF_ID;
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def_id::{DefId, LocalDefId};
|
||||
use rustc_hir_analysis::hir_ty_lowering::{HirTyLowerer, RegionInferReason};
|
||||
use rustc_infer::error_reporting::infer::sub_relations::SubRelations;
|
||||
use rustc_infer::error_reporting::infer::TypeErrCtxt;
|
||||
use rustc_infer::infer;
|
||||
use rustc_middle::ty::{self, Const, Ty, TyCtxt, TypeVisitableExt};
|
||||
use rustc_session::Session;
|
||||
use rustc_span::symbol::Ident;
|
||||
use rustc_span::{self, sym, Span, DUMMY_SP};
|
||||
use rustc_trait_selection::error_reporting::infer::sub_relations::SubRelations;
|
||||
use rustc_trait_selection::error_reporting::TypeErrCtxt;
|
||||
use rustc_trait_selection::traits::{ObligationCause, ObligationCauseCode, ObligationCtxt};
|
||||
|
||||
use std::cell::{Cell, RefCell};
|
||||
@ -162,9 +162,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
|
||||
/// Creates an `TypeErrCtxt` with a reference to the in-progress
|
||||
/// `TypeckResults` which is used for diagnostics.
|
||||
/// Use [`InferCtxt::err_ctxt`] to start one without a `TypeckResults`.
|
||||
/// Use [`InferCtxtErrorExt::err_ctxt`] to start one without a `TypeckResults`.
|
||||
///
|
||||
/// [`InferCtxt::err_ctxt`]: infer::InferCtxt::err_ctxt
|
||||
/// [`InferCtxtErrorExt::err_ctxt`]: rustc_trait_selection::error_reporting::InferCtxtErrorExt::err_ctxt
|
||||
pub fn err_ctxt(&'a self) -> TypeErrCtxt<'a, 'tcx> {
|
||||
let mut sub_relations = SubRelations::default();
|
||||
sub_relations.add_constraints(
|
||||
|
@ -32,8 +32,8 @@ use rustc_session::errors::ExprParenthesesNeeded;
|
||||
use rustc_span::source_map::Spanned;
|
||||
use rustc_span::symbol::{sym, Ident};
|
||||
use rustc_span::{Span, Symbol};
|
||||
use rustc_trait_selection::error_reporting::traits::suggestions::TypeErrCtxtExt;
|
||||
use rustc_trait_selection::error_reporting::traits::DefIdOrName;
|
||||
use rustc_trait_selection::error_reporting::InferCtxtErrorExt;
|
||||
use rustc_trait_selection::infer::InferCtxtExt;
|
||||
use rustc_trait_selection::traits;
|
||||
use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt as _;
|
||||
|
@ -10,7 +10,6 @@ use rustc_hir as hir;
|
||||
use rustc_hir::def::DefKind;
|
||||
use rustc_hir::HirId;
|
||||
use rustc_hir_analysis::autoderef::{self, Autoderef};
|
||||
use rustc_infer::error_reporting::infer::need_type_info::TypeAnnotationNeeded;
|
||||
use rustc_infer::infer::canonical::OriginalQueryValues;
|
||||
use rustc_infer::infer::canonical::{Canonical, QueryResponse};
|
||||
use rustc_infer::infer::DefineOpaqueTypes;
|
||||
@ -34,6 +33,7 @@ use rustc_span::edit_distance::{
|
||||
};
|
||||
use rustc_span::symbol::sym;
|
||||
use rustc_span::{symbol::Ident, Span, Symbol, DUMMY_SP};
|
||||
use rustc_trait_selection::error_reporting::infer::need_type_info::TypeAnnotationNeeded;
|
||||
use rustc_trait_selection::infer::InferCtxtExt as _;
|
||||
use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt;
|
||||
use rustc_trait_selection::traits::query::method_autoderef::MethodAutoderefBadTy;
|
||||
|
@ -36,7 +36,6 @@ use rustc_span::symbol::{kw, sym, Ident};
|
||||
use rustc_span::{edit_distance, ErrorGuaranteed, ExpnKind, FileName, MacroKind, Span};
|
||||
use rustc_span::{Symbol, DUMMY_SP};
|
||||
use rustc_trait_selection::error_reporting::traits::on_unimplemented::OnUnimplementedNote;
|
||||
use rustc_trait_selection::error_reporting::traits::on_unimplemented::TypeErrCtxtExt as _;
|
||||
use rustc_trait_selection::infer::InferCtxtExt;
|
||||
use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt as _;
|
||||
use rustc_trait_selection::traits::{
|
||||
|
@ -18,7 +18,6 @@ use rustc_session::errors::ExprParenthesesNeeded;
|
||||
use rustc_span::source_map::Spanned;
|
||||
use rustc_span::symbol::{sym, Ident};
|
||||
use rustc_span::Span;
|
||||
use rustc_trait_selection::error_reporting::traits::suggestions::TypeErrCtxtExt as _;
|
||||
use rustc_trait_selection::infer::InferCtxtExt;
|
||||
use rustc_trait_selection::traits::{FulfillmentError, ObligationCtxt};
|
||||
use rustc_type_ir::TyKind::*;
|
||||
|
@ -8,7 +8,6 @@ use rustc_errors::{ErrorGuaranteed, StashKey};
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::intravisit::{self, Visitor};
|
||||
use rustc_hir::HirId;
|
||||
use rustc_infer::error_reporting::infer::need_type_info::TypeAnnotationNeeded;
|
||||
use rustc_middle::span_bug;
|
||||
use rustc_middle::traits::ObligationCause;
|
||||
use rustc_middle::ty::adjustment::{Adjust, Adjustment, PointerCoercion};
|
||||
@ -18,7 +17,7 @@ use rustc_middle::ty::TypeSuperFoldable;
|
||||
use rustc_middle::ty::{self, Ty, TyCtxt};
|
||||
use rustc_span::symbol::sym;
|
||||
use rustc_span::Span;
|
||||
use rustc_trait_selection::error_reporting::traits::TypeErrCtxtExt;
|
||||
use rustc_trait_selection::error_reporting::infer::need_type_info::TypeAnnotationNeeded;
|
||||
use rustc_trait_selection::solve;
|
||||
|
||||
use std::mem;
|
||||
|
@ -1,397 +1,5 @@
|
||||
infer_actual_impl_expl_but_actually_implemented_for_ty = ...but `{$trait_path}` is actually implemented for the type `{$ty}`{$has_lifetime ->
|
||||
[true] , for some specific lifetime `'{$lifetime}`
|
||||
*[false] {""}
|
||||
}
|
||||
infer_actual_impl_expl_but_actually_implements_trait = ...but it actually implements `{$trait_path}`{$has_lifetime ->
|
||||
[true] , for some specific lifetime `'{$lifetime}`
|
||||
*[false] {""}
|
||||
}
|
||||
infer_actual_impl_expl_but_actually_ty_implements = ...but `{$ty}` actually implements `{$trait_path}`{$has_lifetime ->
|
||||
[true] , for some specific lifetime `'{$lifetime}`
|
||||
*[false] {""}
|
||||
}
|
||||
|
||||
infer_actual_impl_expl_expected_other_any = {$leading_ellipsis ->
|
||||
[true] ...
|
||||
*[false] {""}
|
||||
}`{$ty_or_sig}` must implement `{$trait_path}`, for any lifetime `'{$lifetime_1}`...
|
||||
infer_actual_impl_expl_expected_other_nothing = {$leading_ellipsis ->
|
||||
[true] ...
|
||||
*[false] {""}
|
||||
}`{$ty_or_sig}` must implement `{$trait_path}`
|
||||
|
||||
infer_actual_impl_expl_expected_other_some = {$leading_ellipsis ->
|
||||
[true] ...
|
||||
*[false] {""}
|
||||
}`{$ty_or_sig}` must implement `{$trait_path}`, for some specific lifetime `'{$lifetime_1}`...
|
||||
infer_actual_impl_expl_expected_other_two = {$leading_ellipsis ->
|
||||
[true] ...
|
||||
*[false] {""}
|
||||
}`{$ty_or_sig}` must implement `{$trait_path}`, for any two lifetimes `'{$lifetime_1}` and `'{$lifetime_2}`...
|
||||
infer_actual_impl_expl_expected_passive_any = {$leading_ellipsis ->
|
||||
[true] ...
|
||||
*[false] {""}
|
||||
}`{$trait_path}` would have to be implemented for the type `{$ty_or_sig}`, for any lifetime `'{$lifetime_1}`...
|
||||
infer_actual_impl_expl_expected_passive_nothing = {$leading_ellipsis ->
|
||||
[true] ...
|
||||
*[false] {""}
|
||||
}`{$trait_path}` would have to be implemented for the type `{$ty_or_sig}`
|
||||
infer_actual_impl_expl_expected_passive_some = {$leading_ellipsis ->
|
||||
[true] ...
|
||||
*[false] {""}
|
||||
}`{$trait_path}` would have to be implemented for the type `{$ty_or_sig}`, for some specific lifetime `'{$lifetime_1}`...
|
||||
infer_actual_impl_expl_expected_passive_two = {$leading_ellipsis ->
|
||||
[true] ...
|
||||
*[false] {""}
|
||||
}`{$trait_path}` would have to be implemented for the type `{$ty_or_sig}`, for any two lifetimes `'{$lifetime_1}` and `'{$lifetime_2}`...
|
||||
infer_actual_impl_expl_expected_signature_any = {$leading_ellipsis ->
|
||||
[true] ...
|
||||
*[false] {""}
|
||||
}closure with signature `{$ty_or_sig}` must implement `{$trait_path}`, for any lifetime `'{$lifetime_1}`...
|
||||
infer_actual_impl_expl_expected_signature_nothing = {$leading_ellipsis ->
|
||||
[true] ...
|
||||
*[false] {""}
|
||||
}closure with signature `{$ty_or_sig}` must implement `{$trait_path}`
|
||||
infer_actual_impl_expl_expected_signature_some = {$leading_ellipsis ->
|
||||
[true] ...
|
||||
*[false] {""}
|
||||
}closure with signature `{$ty_or_sig}` must implement `{$trait_path}`, for some specific lifetime `'{$lifetime_1}`...
|
||||
infer_actual_impl_expl_expected_signature_two = {$leading_ellipsis ->
|
||||
[true] ...
|
||||
*[false] {""}
|
||||
}closure with signature `{$ty_or_sig}` must implement `{$trait_path}`, for any two lifetimes `'{$lifetime_1}` and `'{$lifetime_2}`...
|
||||
infer_ascribe_user_type_prove_predicate = ...so that the where clause holds
|
||||
|
||||
infer_await_both_futures = consider `await`ing on both `Future`s
|
||||
infer_await_future = consider `await`ing on the `Future`
|
||||
infer_await_note = calling an async function returns a future
|
||||
|
||||
infer_but_calling_introduces = {$has_param_name ->
|
||||
[true] `{$param_name}`
|
||||
*[false] `fn` parameter
|
||||
} has {$lifetime_kind ->
|
||||
[true] lifetime `{$lifetime}`
|
||||
*[false] an anonymous lifetime `'_`
|
||||
} but calling `{$assoc_item}` introduces an implicit `'static` lifetime requirement
|
||||
.label1 = {$has_lifetime ->
|
||||
[true] lifetime `{$lifetime}`
|
||||
*[false] an anonymous lifetime `'_`
|
||||
}
|
||||
.label2 = ...is used and required to live as long as `'static` here because of an implicit lifetime bound on the {$has_impl_path ->
|
||||
[true] `impl` of `{$impl_path}`
|
||||
*[false] inherent `impl`
|
||||
}
|
||||
|
||||
infer_but_needs_to_satisfy = {$has_param_name ->
|
||||
[true] `{$param_name}`
|
||||
*[false] `fn` parameter
|
||||
} has {$has_lifetime ->
|
||||
[true] lifetime `{$lifetime}`
|
||||
*[false] an anonymous lifetime `'_`
|
||||
} but it needs to satisfy a `'static` lifetime requirement
|
||||
.influencer = this data with {$has_lifetime ->
|
||||
[true] lifetime `{$lifetime}`
|
||||
*[false] an anonymous lifetime `'_`
|
||||
}...
|
||||
.require = {$spans_empty ->
|
||||
*[true] ...is used and required to live as long as `'static` here
|
||||
[false] ...and is required to live as long as `'static` here
|
||||
}
|
||||
.used_here = ...is used here...
|
||||
.introduced_by_bound = `'static` lifetime requirement introduced by this bound
|
||||
|
||||
infer_compare_impl_item_obligation = ...so that the definition in impl matches the definition from the trait
|
||||
infer_consider_specifying_length = consider specifying the actual array length
|
||||
infer_data_flows = ...but data{$label_var1_exists ->
|
||||
[true] {" "}from `{$label_var1}`
|
||||
*[false] {""}
|
||||
} flows{$label_var2_exists ->
|
||||
[true] {" "}into `{$label_var2}`
|
||||
*[false] {""}
|
||||
} here
|
||||
|
||||
infer_data_lifetime_flow = ...but data with one lifetime flows into the other here
|
||||
infer_data_returned = ...but data{$label_var1_exists ->
|
||||
[true] {" "}from `{$label_var1}`
|
||||
*[false] {""}
|
||||
} is returned here
|
||||
|
||||
infer_declared_different = this parameter and the return type are declared with different lifetimes...
|
||||
infer_declared_multiple = this type is declared with multiple lifetimes...
|
||||
infer_does_not_outlive_static_from_impl = ...does not necessarily outlive the static lifetime introduced by the compatible `impl`
|
||||
infer_dtcs_has_lifetime_req_label = this has an implicit `'static` lifetime requirement
|
||||
infer_dtcs_has_req_note = the used `impl` has a `'static` requirement
|
||||
infer_dtcs_introduces_requirement = calling this method introduces the `impl`'s `'static` requirement
|
||||
infer_dtcs_suggestion = consider relaxing the implicit `'static` requirement
|
||||
|
||||
infer_explicit_lifetime_required_sugg_with_ident = add explicit lifetime `{$named}` to the type of `{$simple_ident}`
|
||||
|
||||
infer_explicit_lifetime_required_sugg_with_param_type = add explicit lifetime `{$named}` to type
|
||||
|
||||
infer_explicit_lifetime_required_with_ident = explicit lifetime required in the type of `{$simple_ident}`
|
||||
.label = lifetime `{$named}` required
|
||||
|
||||
infer_explicit_lifetime_required_with_param_type = explicit lifetime required in parameter type
|
||||
.label = lifetime `{$named}` required
|
||||
|
||||
infer_fn_consider_casting = consider casting the fn item to a fn pointer: `{$casting}`
|
||||
|
||||
infer_fn_uniq_types = different fn items have unique types, even if their signatures are the same
|
||||
infer_fps_cast = consider casting to a fn pointer
|
||||
infer_fps_cast_both = consider casting both fn items to fn pointers using `as {$expected_sig}`
|
||||
|
||||
infer_fps_items_are_distinct = fn items are distinct from fn pointers
|
||||
infer_fps_remove_ref = consider removing the reference
|
||||
infer_fps_use_ref = consider using a reference
|
||||
infer_fulfill_req_lifetime = the type `{$ty}` does not fulfill the required lifetime
|
||||
|
||||
infer_full_type_written = the full type name has been written to '{$path}'
|
||||
|
||||
infer_implicit_static_lifetime_note = this has an implicit `'static` lifetime requirement
|
||||
infer_implicit_static_lifetime_suggestion = consider relaxing the implicit `'static` requirement
|
||||
infer_label_bad = {$bad_kind ->
|
||||
*[other] cannot infer type
|
||||
[more_info] cannot infer {$prefix_kind ->
|
||||
*[type] type for {$prefix}
|
||||
[const_with_param] the value of const parameter
|
||||
[const] the value of the constant
|
||||
} `{$name}`{$has_parent ->
|
||||
[true] {" "}declared on the {$parent_prefix} `{$parent_name}`
|
||||
*[false] {""}
|
||||
}
|
||||
}
|
||||
|
||||
infer_lf_bound_not_satisfied = lifetime bound not satisfied
|
||||
infer_lifetime_mismatch = lifetime mismatch
|
||||
|
||||
infer_lifetime_param_suggestion = consider {$is_reuse ->
|
||||
[true] reusing
|
||||
*[false] introducing
|
||||
} a named lifetime parameter{$is_impl ->
|
||||
[true] {" "}and update trait if needed
|
||||
*[false] {""}
|
||||
}
|
||||
infer_lifetime_param_suggestion_elided = each elided lifetime in input position becomes a distinct lifetime
|
||||
|
||||
infer_meant_byte_literal = if you meant to write a byte literal, prefix with `b`
|
||||
infer_meant_char_literal = if you meant to write a `char` literal, use single quotes
|
||||
infer_meant_str_literal = if you meant to write a string literal, use double quotes
|
||||
infer_mismatched_static_lifetime = incompatible lifetime on type
|
||||
infer_more_targeted = {$has_param_name ->
|
||||
[true] `{$param_name}`
|
||||
*[false] `fn` parameter
|
||||
} has {$has_lifetime ->
|
||||
[true] lifetime `{$lifetime}`
|
||||
*[false] an anonymous lifetime `'_`
|
||||
} but calling `{$ident}` introduces an implicit `'static` lifetime requirement
|
||||
|
||||
infer_msl_introduces_static = introduces a `'static` lifetime requirement
|
||||
infer_msl_unmet_req = because this has an unmet lifetime requirement
|
||||
|
||||
infer_nothing = {""}
|
||||
|
||||
infer_oc_cant_coerce = cannot coerce intrinsics to function pointers
|
||||
infer_oc_closure_selfref = closure/coroutine type that references itself
|
||||
infer_oc_const_compat = const not compatible with trait
|
||||
infer_oc_fn_lang_correct_type = {$lang_item_name ->
|
||||
[panic_impl] `#[panic_handler]`
|
||||
*[lang_item_name] lang item `{$lang_item_name}`
|
||||
} function has wrong type
|
||||
infer_oc_fn_main_correct_type = `main` function has wrong type
|
||||
infer_oc_fn_start_correct_type = `#[start]` function has wrong type
|
||||
infer_oc_generic = mismatched types
|
||||
|
||||
infer_oc_if_else_different = `if` and `else` have incompatible types
|
||||
infer_oc_intrinsic_correct_type = intrinsic has wrong type
|
||||
infer_oc_match_compat = `match` arms have incompatible types
|
||||
infer_oc_method_compat = method not compatible with trait
|
||||
infer_oc_method_correct_type = mismatched `self` parameter type
|
||||
infer_oc_no_diverge = `else` clause of `let...else` does not diverge
|
||||
infer_oc_no_else = `if` may be missing an `else` clause
|
||||
infer_oc_try_compat = `?` operator has incompatible types
|
||||
infer_oc_type_compat = type not compatible with trait
|
||||
infer_opaque_captures_lifetime = hidden type for `{$opaque_ty}` captures lifetime that does not appear in bounds
|
||||
.label = opaque type defined here
|
||||
|
||||
infer_opaque_hidden_type =
|
||||
opaque type's hidden type cannot be another opaque type from the same scope
|
||||
.label = one of the two opaque types used here has to be outside its defining scope
|
||||
.opaque_type = opaque type whose hidden type is being assigned
|
||||
.hidden_type = opaque type being used as hidden type
|
||||
|
||||
infer_outlives_bound = lifetime of the source pointer does not outlive lifetime bound of the object type
|
||||
infer_outlives_content = lifetime of reference outlives lifetime of borrowed content...
|
||||
|
||||
infer_precise_capturing_existing = add `{$new_lifetime}` to the `use<...>` bound to explicitly capture it
|
||||
infer_precise_capturing_new = add a `use<...>` bound to explicitly capture `{$new_lifetime}`
|
||||
|
||||
infer_precise_capturing_new_but_apit = add a `use<...>` bound to explicitly capture `{$new_lifetime}` after turning all argument-position `impl Trait` into type parameters, noting that this possibly affects the API of this crate
|
||||
|
||||
infer_prlf_defined_with_sub = the lifetime `{$sub_symbol}` defined here...
|
||||
infer_prlf_defined_without_sub = the lifetime defined here...
|
||||
infer_prlf_known_limitation = this is a known limitation that will be removed in the future (see issue #100013 <https://github.com/rust-lang/rust/issues/100013> for more information)
|
||||
|
||||
infer_prlf_must_outlive_with_sup = ...must outlive the lifetime `{$sup_symbol}` defined here
|
||||
infer_prlf_must_outlive_without_sup = ...must outlive the lifetime defined here
|
||||
infer_reborrow = ...so that reference does not outlive borrowed content
|
||||
infer_ref_longer_than_data = in type `{$ty}`, reference has a longer lifetime than the data it references
|
||||
|
||||
infer_reference_outlives_referent = ...so that the reference type `{$name}` does not outlive the data it points at
|
||||
infer_region_explanation = {$pref_kind ->
|
||||
*[should_not_happen] [{$pref_kind}]
|
||||
[ref_valid_for] ...the reference is valid for
|
||||
[content_valid_for] ...but the borrowed content is only valid for
|
||||
[type_obj_valid_for] object type is valid for
|
||||
[source_pointer_valid_for] source pointer is only valid for
|
||||
[type_satisfy] type must satisfy
|
||||
[type_outlive] type must outlive
|
||||
[lf_param_instantiated_with] lifetime parameter instantiated with
|
||||
[lf_param_must_outlive] but lifetime parameter must outlive
|
||||
[lf_instantiated_with] lifetime instantiated with
|
||||
[lf_must_outlive] but lifetime must outlive
|
||||
[pointer_valid_for] the pointer is valid for
|
||||
[data_valid_for] but the referenced data is only valid for
|
||||
[empty] {""}
|
||||
}{$pref_kind ->
|
||||
[empty] {""}
|
||||
*[other] {" "}
|
||||
}{$desc_kind ->
|
||||
*[should_not_happen] [{$desc_kind}]
|
||||
[restatic] the static lifetime
|
||||
[revar] lifetime {$desc_arg}
|
||||
[as_defined] the lifetime `{$desc_arg}` as defined here
|
||||
[as_defined_anon] the anonymous lifetime as defined here
|
||||
[defined_here] the anonymous lifetime defined here
|
||||
[defined_here_reg] the lifetime `{$desc_arg}` as defined here
|
||||
}{$suff_kind ->
|
||||
*[should_not_happen] [{$suff_kind}]
|
||||
[empty]{""}
|
||||
[continues] ...
|
||||
[req_by_binding] {" "}as required by this binding
|
||||
}
|
||||
|
||||
infer_relate_object_bound = ...so that it can be closed over into an object
|
||||
infer_relate_param_bound = ...so that the type `{$name}` will meet its required lifetime bounds{$continues ->
|
||||
[true] ...
|
||||
*[false] {""}
|
||||
}
|
||||
infer_relate_param_bound_2 = ...that is required by this bound
|
||||
infer_relate_region_param_bound = ...so that the declared lifetime parameter bounds are satisfied
|
||||
infer_ril_because_of = because of this returned expression
|
||||
infer_ril_introduced_by = requirement introduced by this return type
|
||||
infer_ril_introduced_here = `'static` requirement introduced here
|
||||
infer_ril_static_introduced_by = "`'static` lifetime requirement introduced by the return type
|
||||
|
||||
infer_source_kind_closure_return =
|
||||
try giving this closure an explicit return type
|
||||
|
||||
# coroutine_kind may need to be translated
|
||||
infer_source_kind_fully_qualified =
|
||||
try using a fully qualified path to specify the expected types
|
||||
|
||||
infer_source_kind_subdiag_generic_label =
|
||||
cannot infer {$is_type ->
|
||||
[true] type
|
||||
*[false] the value
|
||||
} of the {$is_type ->
|
||||
[true] type
|
||||
*[false] const
|
||||
} {$parent_exists ->
|
||||
[true] parameter `{$param_name}` declared on the {$parent_prefix} `{$parent_name}`
|
||||
*[false] parameter {$param_name}
|
||||
}
|
||||
|
||||
infer_source_kind_subdiag_generic_suggestion =
|
||||
consider specifying the generic {$arg_count ->
|
||||
[one] argument
|
||||
*[other] arguments
|
||||
}
|
||||
|
||||
infer_source_kind_subdiag_let = {$kind ->
|
||||
[with_pattern] consider giving `{$name}` an explicit type
|
||||
[closure] consider giving this closure parameter an explicit type
|
||||
*[other] consider giving this pattern a type
|
||||
}{$x_kind ->
|
||||
[has_name] , where the {$prefix_kind ->
|
||||
*[type] type for {$prefix}
|
||||
[const_with_param] value of const parameter
|
||||
[const] value of the constant
|
||||
} `{$arg_name}` is specified
|
||||
[underscore] , where the placeholders `_` are specified
|
||||
*[empty] {""}
|
||||
}
|
||||
|
||||
infer_srs_add = consider returning the local binding `{$ident}`
|
||||
infer_srs_add_one = consider returning one of these bindings
|
||||
|
||||
infer_srs_remove = consider removing this semicolon
|
||||
infer_srs_remove_and_box = consider removing this semicolon and boxing the expressions
|
||||
infer_stp_wrap_many = try wrapping the pattern in a variant of `{$path}`
|
||||
|
||||
infer_stp_wrap_one = try wrapping the pattern in `{$variant}`
|
||||
infer_subtype = ...so that the {$requirement ->
|
||||
[method_compat] method type is compatible with trait
|
||||
[type_compat] associated type is compatible with trait
|
||||
[const_compat] const is compatible with trait
|
||||
[expr_assignable] expression is assignable
|
||||
[if_else_different] `if` and `else` have incompatible types
|
||||
[no_else] `if` missing an `else` returns `()`
|
||||
[fn_main_correct_type] `main` function has the correct type
|
||||
[fn_start_correct_type] `#[start]` function has the correct type
|
||||
[fn_lang_correct_type] lang item function has the correct type
|
||||
[intrinsic_correct_type] intrinsic has the correct type
|
||||
[method_correct_type] method receiver has the correct type
|
||||
*[other] types are compatible
|
||||
}
|
||||
infer_subtype_2 = ...so that {$requirement ->
|
||||
[method_compat] method type is compatible with trait
|
||||
[type_compat] associated type is compatible with trait
|
||||
[const_compat] const is compatible with trait
|
||||
[expr_assignable] expression is assignable
|
||||
[if_else_different] `if` and `else` have incompatible types
|
||||
[no_else] `if` missing an `else` returns `()`
|
||||
[fn_main_correct_type] `main` function has the correct type
|
||||
[fn_start_correct_type] `#[start]` function has the correct type
|
||||
[fn_lang_correct_type] lang item function has the correct type
|
||||
[intrinsic_correct_type] intrinsic has the correct type
|
||||
[method_correct_type] method receiver has the correct type
|
||||
*[other] types are compatible
|
||||
}
|
||||
|
||||
infer_suggest_accessing_field = you might have meant to use field `{$name}` whose type is `{$ty}`
|
||||
|
||||
infer_suggest_add_let_for_letchains = consider adding `let`
|
||||
|
||||
infer_tid_consider_borrowing = consider borrowing this type parameter in the trait
|
||||
infer_tid_param_help = the lifetime requirements from the `impl` do not correspond to the requirements in the `trait`
|
||||
|
||||
infer_tid_rel_help = verify the lifetime relationships in the `trait` and `impl` between the `self` argument, the other inputs and its output
|
||||
infer_trait_impl_diff = `impl` item signature doesn't match `trait` item signature
|
||||
.found = found `{$found}`
|
||||
.expected = expected `{$expected}`
|
||||
.expected_found = expected signature `{$expected}`
|
||||
{" "}found signature `{$found}`
|
||||
|
||||
infer_trait_placeholder_mismatch = implementation of `{$trait_def_id}` is not general enough
|
||||
.label_satisfy = doesn't satisfy where-clause
|
||||
.label_where = due to a where-clause on `{$def_id}`...
|
||||
.label_dup = implementation of `{$trait_def_id}` is not general enough
|
||||
|
||||
infer_try_cannot_convert = `?` operator cannot convert from `{$found}` to `{$expected}`
|
||||
|
||||
infer_tuple_trailing_comma = use a trailing comma to create a tuple with one element
|
||||
|
||||
infer_type_annotations_needed = {$source_kind ->
|
||||
[closure] type annotations needed for the closure `{$source_name}`
|
||||
[normal] type annotations needed for `{$source_name}`
|
||||
*[other] type annotations needed
|
||||
}
|
||||
.label = type must be known at this point
|
||||
|
||||
infer_types_declared_different = these two types are declared with different lifetimes...
|
||||
|
||||
infer_warn_removing_apit_params = you could use a `use<...>` bound to explicitly capture `{$new_lifetime}`, but argument-position `impl Trait`s are not nameable
|
||||
|
||||
infer_where_copy_predicates = copy the `where` clause predicates from the trait
|
||||
|
||||
infer_where_remove = remove the `where` clause
|
||||
|
@ -1 +0,0 @@
|
||||
pub mod infer;
|
File diff suppressed because it is too large
Load Diff
@ -11,7 +11,6 @@ pub use BoundRegionConversionTime::*;
|
||||
pub use RegionVariableOrigin::*;
|
||||
pub use SubregionOrigin::*;
|
||||
|
||||
use crate::error_reporting::infer::TypeErrCtxt;
|
||||
use crate::infer::relate::RelateResult;
|
||||
use crate::traits::{self, ObligationCause, ObligationInspector, PredicateObligation, TraitEngine};
|
||||
use free_regions::RegionRelations;
|
||||
@ -24,7 +23,8 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap};
|
||||
use rustc_data_structures::sync::Lrc;
|
||||
use rustc_data_structures::undo_log::Rollback;
|
||||
use rustc_data_structures::unify as ut;
|
||||
use rustc_errors::{Diag, ErrorGuaranteed};
|
||||
use rustc_errors::ErrorGuaranteed;
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def_id::{DefId, LocalDefId};
|
||||
use rustc_macros::extension;
|
||||
use rustc_middle::infer::canonical::{Canonical, CanonicalVarValues};
|
||||
@ -696,22 +696,6 @@ impl<'tcx> InferCtxt<'tcx> {
|
||||
self.next_trait_solver
|
||||
}
|
||||
|
||||
/// Creates a `TypeErrCtxt` for emitting various inference errors.
|
||||
/// During typeck, use `FnCtxt::err_ctxt` instead.
|
||||
pub fn err_ctxt(&self) -> TypeErrCtxt<'_, 'tcx> {
|
||||
TypeErrCtxt {
|
||||
infcx: self,
|
||||
sub_relations: Default::default(),
|
||||
typeck_results: None,
|
||||
fallback_has_occurred: false,
|
||||
normalize_fn_sig: Box::new(|fn_sig| fn_sig),
|
||||
autoderef_steps: Box::new(|ty| {
|
||||
debug_assert!(false, "shouldn't be using autoderef_steps outside of typeck");
|
||||
vec![(ty, vec![])]
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn freshen<T: TypeFoldable<TyCtxt<'tcx>>>(&self, t: T) -> T {
|
||||
t.fold_with(&mut self.freshener())
|
||||
}
|
||||
@ -1591,60 +1575,6 @@ impl<'tcx> InferCtxt<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
||||
// [Note-Type-error-reporting]
|
||||
// An invariant is that anytime the expected or actual type is Error (the special
|
||||
// error type, meaning that an error occurred when typechecking this expression),
|
||||
// this is a derived error. The error cascaded from another error (that was already
|
||||
// reported), so it's not useful to display it to the user.
|
||||
// The following methods implement this logic.
|
||||
// They check if either the actual or expected type is Error, and don't print the error
|
||||
// in this case. The typechecker should only ever report type errors involving mismatched
|
||||
// types using one of these methods, and should not call span_err directly for such
|
||||
// errors.
|
||||
pub fn type_error_struct_with_diag<M>(
|
||||
&self,
|
||||
sp: Span,
|
||||
mk_diag: M,
|
||||
actual_ty: Ty<'tcx>,
|
||||
) -> Diag<'a>
|
||||
where
|
||||
M: FnOnce(String) -> Diag<'a>,
|
||||
{
|
||||
let actual_ty = self.resolve_vars_if_possible(actual_ty);
|
||||
debug!("type_error_struct_with_diag({:?}, {:?})", sp, actual_ty);
|
||||
|
||||
let mut err = mk_diag(self.ty_to_string(actual_ty));
|
||||
|
||||
// Don't report an error if actual type is `Error`.
|
||||
if actual_ty.references_error() {
|
||||
err.downgrade_to_delayed_bug();
|
||||
}
|
||||
|
||||
err
|
||||
}
|
||||
|
||||
pub fn report_mismatched_types(
|
||||
&self,
|
||||
cause: &ObligationCause<'tcx>,
|
||||
expected: Ty<'tcx>,
|
||||
actual: Ty<'tcx>,
|
||||
err: TypeError<'tcx>,
|
||||
) -> Diag<'a> {
|
||||
self.report_and_explain_type_error(TypeTrace::types(cause, true, expected, actual), err)
|
||||
}
|
||||
|
||||
pub fn report_mismatched_consts(
|
||||
&self,
|
||||
cause: &ObligationCause<'tcx>,
|
||||
expected: ty::Const<'tcx>,
|
||||
actual: ty::Const<'tcx>,
|
||||
err: TypeError<'tcx>,
|
||||
) -> Diag<'a> {
|
||||
self.report_and_explain_type_error(TypeTrace::consts(cause, true, expected, actual), err)
|
||||
}
|
||||
}
|
||||
|
||||
/// Helper for [InferCtxt::ty_or_const_infer_var_changed] (see comment on that), currently
|
||||
/// used only for `traits::fulfill`'s list of `stalled_on` inference variables.
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
@ -1890,3 +1820,32 @@ fn replace_param_and_infer_args_with_placeholder<'tcx>(
|
||||
|
||||
args.fold_with(&mut ReplaceParamAndInferWithPlaceholder { tcx, idx: 0 })
|
||||
}
|
||||
|
||||
impl<'tcx> InferCtxt<'tcx> {
|
||||
/// Given a [`hir::Block`], get the span of its last expression or
|
||||
/// statement, peeling off any inner blocks.
|
||||
pub fn find_block_span(&self, block: &'tcx hir::Block<'tcx>) -> Span {
|
||||
let block = block.innermost_block();
|
||||
if let Some(expr) = &block.expr {
|
||||
expr.span
|
||||
} else if let Some(stmt) = block.stmts.last() {
|
||||
// possibly incorrect trailing `;` in the else arm
|
||||
stmt.span
|
||||
} else {
|
||||
// empty block; point at its entirety
|
||||
block.span
|
||||
}
|
||||
}
|
||||
|
||||
/// Given a [`hir::HirId`] for a block, get the span of its last expression
|
||||
/// or statement, peeling off any inner blocks.
|
||||
pub fn find_block_span_from_hir_id(&self, hir_id: hir::HirId) -> Span {
|
||||
match self.tcx.hir_node(hir_id) {
|
||||
hir::Node::Block(blk) => self.find_block_span(blk),
|
||||
// The parser was in a weird state if either of these happen, but
|
||||
// it's better not to panic.
|
||||
hir::Node::Expr(e) => e.span,
|
||||
_ => rustc_span::DUMMY_SP,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -34,7 +34,6 @@
|
||||
#[macro_use]
|
||||
extern crate tracing;
|
||||
|
||||
pub mod error_reporting;
|
||||
mod errors;
|
||||
pub mod infer;
|
||||
pub mod traits;
|
||||
|
@ -1,203 +0,0 @@
|
||||
use super::ObjectSafetyViolation;
|
||||
|
||||
use crate::error_reporting::infer::TypeErrCtxt;
|
||||
use rustc_data_structures::fx::FxIndexSet;
|
||||
use rustc_errors::{codes::*, struct_span_code_err, Applicability, Diag, MultiSpan};
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def_id::{DefId, LocalDefId};
|
||||
use rustc_middle::ty::print::with_no_trimmed_paths;
|
||||
use rustc_middle::ty::{self, TyCtxt};
|
||||
use rustc_span::Span;
|
||||
use std::fmt;
|
||||
use std::iter;
|
||||
|
||||
impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
||||
pub fn report_extra_impl_obligation(
|
||||
&self,
|
||||
error_span: Span,
|
||||
impl_item_def_id: LocalDefId,
|
||||
trait_item_def_id: DefId,
|
||||
requirement: &dyn fmt::Display,
|
||||
) -> Diag<'a> {
|
||||
let mut err = struct_span_code_err!(
|
||||
self.dcx(),
|
||||
error_span,
|
||||
E0276,
|
||||
"impl has stricter requirements than trait"
|
||||
);
|
||||
|
||||
if !self.tcx.is_impl_trait_in_trait(trait_item_def_id) {
|
||||
if let Some(span) = self.tcx.hir().span_if_local(trait_item_def_id) {
|
||||
let item_name = self.tcx.item_name(impl_item_def_id.to_def_id());
|
||||
err.span_label(span, format!("definition of `{item_name}` from trait"));
|
||||
}
|
||||
}
|
||||
|
||||
err.span_label(error_span, format!("impl has extra requirement {requirement}"));
|
||||
|
||||
err
|
||||
}
|
||||
}
|
||||
|
||||
pub fn report_object_safety_error<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
span: Span,
|
||||
hir_id: Option<hir::HirId>,
|
||||
trait_def_id: DefId,
|
||||
violations: &[ObjectSafetyViolation],
|
||||
) -> Diag<'tcx> {
|
||||
let trait_str = tcx.def_path_str(trait_def_id);
|
||||
let trait_span = tcx.hir().get_if_local(trait_def_id).and_then(|node| match node {
|
||||
hir::Node::Item(item) => Some(item.ident.span),
|
||||
_ => None,
|
||||
});
|
||||
let mut err = struct_span_code_err!(
|
||||
tcx.dcx(),
|
||||
span,
|
||||
E0038,
|
||||
"the trait `{}` cannot be made into an object",
|
||||
trait_str
|
||||
);
|
||||
err.span_label(span, format!("`{trait_str}` cannot be made into an object"));
|
||||
|
||||
if let Some(hir_id) = hir_id
|
||||
&& let hir::Node::Ty(ty) = tcx.hir_node(hir_id)
|
||||
&& let hir::TyKind::TraitObject([trait_ref, ..], ..) = ty.kind
|
||||
{
|
||||
let mut hir_id = hir_id;
|
||||
while let hir::Node::Ty(ty) = tcx.parent_hir_node(hir_id) {
|
||||
hir_id = ty.hir_id;
|
||||
}
|
||||
if tcx.parent_hir_node(hir_id).fn_sig().is_some() {
|
||||
// Do not suggest `impl Trait` when dealing with things like super-traits.
|
||||
err.span_suggestion_verbose(
|
||||
ty.span.until(trait_ref.span),
|
||||
"consider using an opaque type instead",
|
||||
"impl ",
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
}
|
||||
}
|
||||
let mut reported_violations = FxIndexSet::default();
|
||||
let mut multi_span = vec![];
|
||||
let mut messages = vec![];
|
||||
for violation in violations {
|
||||
if let ObjectSafetyViolation::SizedSelf(sp) = &violation
|
||||
&& !sp.is_empty()
|
||||
{
|
||||
// Do not report `SizedSelf` without spans pointing at `SizedSelf` obligations
|
||||
// with a `Span`.
|
||||
reported_violations.insert(ObjectSafetyViolation::SizedSelf(vec![].into()));
|
||||
}
|
||||
if reported_violations.insert(violation.clone()) {
|
||||
let spans = violation.spans();
|
||||
let msg = if trait_span.is_none() || spans.is_empty() {
|
||||
format!("the trait cannot be made into an object because {}", violation.error_msg())
|
||||
} else {
|
||||
format!("...because {}", violation.error_msg())
|
||||
};
|
||||
if spans.is_empty() {
|
||||
err.note(msg);
|
||||
} else {
|
||||
for span in spans {
|
||||
multi_span.push(span);
|
||||
messages.push(msg.clone());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
let has_multi_span = !multi_span.is_empty();
|
||||
let mut note_span = MultiSpan::from_spans(multi_span.clone());
|
||||
if let (Some(trait_span), true) = (trait_span, has_multi_span) {
|
||||
note_span.push_span_label(trait_span, "this trait cannot be made into an object...");
|
||||
}
|
||||
for (span, msg) in iter::zip(multi_span, messages) {
|
||||
note_span.push_span_label(span, msg);
|
||||
}
|
||||
err.span_note(
|
||||
note_span,
|
||||
"for a trait to be \"object safe\" it needs to allow building a vtable to allow the call \
|
||||
to be resolvable dynamically; for more information visit \
|
||||
<https://doc.rust-lang.org/reference/items/traits.html#object-safety>",
|
||||
);
|
||||
|
||||
// Only provide the help if its a local trait, otherwise it's not actionable.
|
||||
if trait_span.is_some() {
|
||||
let mut reported_violations: Vec<_> = reported_violations.into_iter().collect();
|
||||
reported_violations.sort();
|
||||
|
||||
let mut potential_solutions: Vec<_> =
|
||||
reported_violations.into_iter().map(|violation| violation.solution()).collect();
|
||||
potential_solutions.sort();
|
||||
// Allows us to skip suggesting that the same item should be moved to another trait multiple times.
|
||||
potential_solutions.dedup();
|
||||
for solution in potential_solutions {
|
||||
solution.add_to(&mut err);
|
||||
}
|
||||
}
|
||||
|
||||
let impls_of = tcx.trait_impls_of(trait_def_id);
|
||||
let impls = if impls_of.blanket_impls().is_empty() {
|
||||
impls_of
|
||||
.non_blanket_impls()
|
||||
.values()
|
||||
.flatten()
|
||||
.filter(|def_id| {
|
||||
!matches!(tcx.type_of(*def_id).instantiate_identity().kind(), ty::Dynamic(..))
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
} else {
|
||||
vec![]
|
||||
};
|
||||
let externally_visible = if !impls.is_empty()
|
||||
&& let Some(def_id) = trait_def_id.as_local()
|
||||
// We may be executing this during typeck, which would result in cycle
|
||||
// if we used effective_visibilities query, which looks into opaque types
|
||||
// (and therefore calls typeck).
|
||||
&& tcx.resolutions(()).effective_visibilities.is_exported(def_id)
|
||||
{
|
||||
true
|
||||
} else {
|
||||
false
|
||||
};
|
||||
match &impls[..] {
|
||||
[] => {}
|
||||
_ if impls.len() > 9 => {}
|
||||
[only] if externally_visible => {
|
||||
err.help(with_no_trimmed_paths!(format!(
|
||||
"only type `{}` is seen to implement the trait in this crate, consider using it \
|
||||
directly instead",
|
||||
tcx.type_of(*only).instantiate_identity(),
|
||||
)));
|
||||
}
|
||||
[only] => {
|
||||
err.help(with_no_trimmed_paths!(format!(
|
||||
"only type `{}` implements the trait, consider using it directly instead",
|
||||
tcx.type_of(*only).instantiate_identity(),
|
||||
)));
|
||||
}
|
||||
impls => {
|
||||
let types = impls
|
||||
.iter()
|
||||
.map(|t| {
|
||||
with_no_trimmed_paths!(format!(" {}", tcx.type_of(*t).instantiate_identity(),))
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
err.help(format!(
|
||||
"the following types implement the trait, consider defining an enum where each \
|
||||
variant holds one of these types, implementing `{}` for this new enum and using \
|
||||
it instead:\n{}",
|
||||
trait_str,
|
||||
types.join("\n"),
|
||||
));
|
||||
}
|
||||
}
|
||||
if externally_visible {
|
||||
err.note(format!(
|
||||
"`{trait_str}` can be implemented in other crates; if you want to support your users \
|
||||
passing their own types here, you can't refer to a specific type",
|
||||
));
|
||||
}
|
||||
|
||||
err
|
||||
}
|
@ -3,7 +3,6 @@
|
||||
//! [rustc-dev-guide]: https://rustc-dev-guide.rust-lang.org/traits/resolution.html
|
||||
|
||||
mod engine;
|
||||
pub mod error_reporting;
|
||||
mod project;
|
||||
mod structural_impls;
|
||||
pub mod util;
|
||||
|
@ -81,7 +81,7 @@ use rustc_span::symbol::sym;
|
||||
use rustc_span::Span;
|
||||
use rustc_target::abi::{FieldIdx, VariantIdx};
|
||||
use rustc_target::spec::PanicStrategy;
|
||||
use rustc_trait_selection::error_reporting::traits::TypeErrCtxtExt as _;
|
||||
use rustc_trait_selection::error_reporting::InferCtxtErrorExt;
|
||||
use rustc_trait_selection::infer::TyCtxtInferExt as _;
|
||||
use rustc_trait_selection::traits::ObligationCtxt;
|
||||
use rustc_trait_selection::traits::{ObligationCause, ObligationCauseCode};
|
||||
|
@ -34,7 +34,7 @@ use rustc_session::parse::feature_err;
|
||||
use rustc_span::symbol::{kw, sym, Symbol};
|
||||
use rustc_span::{BytePos, Span, DUMMY_SP};
|
||||
use rustc_target::spec::abi::Abi;
|
||||
use rustc_trait_selection::error_reporting::traits::TypeErrCtxtExt;
|
||||
use rustc_trait_selection::error_reporting::InferCtxtErrorExt;
|
||||
use rustc_trait_selection::infer::{TyCtxtInferExt, ValuePairs};
|
||||
use rustc_trait_selection::traits::ObligationCtxt;
|
||||
use std::cell::Cell;
|
||||
|
@ -8,7 +8,7 @@ use rustc_span::source_map::Spanned;
|
||||
use rustc_span::symbol::sym;
|
||||
use rustc_span::Span;
|
||||
use rustc_target::abi::{HasDataLayout, TargetDataLayout};
|
||||
use rustc_trait_selection::error_reporting::traits::TypeErrCtxtExt;
|
||||
use rustc_trait_selection::error_reporting::InferCtxtErrorExt;
|
||||
use rustc_trait_selection::{infer::TyCtxtInferExt, traits};
|
||||
|
||||
use crate::errors::{
|
||||
|
@ -1,3 +1,65 @@
|
||||
trait_selection_actual_impl_expl_but_actually_implemented_for_ty = ...but `{$trait_path}` is actually implemented for the type `{$ty}`{$has_lifetime ->
|
||||
[true] , for some specific lifetime `'{$lifetime}`
|
||||
*[false] {""}
|
||||
}
|
||||
trait_selection_actual_impl_expl_but_actually_implements_trait = ...but it actually implements `{$trait_path}`{$has_lifetime ->
|
||||
[true] , for some specific lifetime `'{$lifetime}`
|
||||
*[false] {""}
|
||||
}
|
||||
trait_selection_actual_impl_expl_but_actually_ty_implements = ...but `{$ty}` actually implements `{$trait_path}`{$has_lifetime ->
|
||||
[true] , for some specific lifetime `'{$lifetime}`
|
||||
*[false] {""}
|
||||
}
|
||||
|
||||
trait_selection_actual_impl_expl_expected_other_any = {$leading_ellipsis ->
|
||||
[true] ...
|
||||
*[false] {""}
|
||||
}`{$ty_or_sig}` must implement `{$trait_path}`, for any lifetime `'{$lifetime_1}`...
|
||||
trait_selection_actual_impl_expl_expected_other_nothing = {$leading_ellipsis ->
|
||||
[true] ...
|
||||
*[false] {""}
|
||||
}`{$ty_or_sig}` must implement `{$trait_path}`
|
||||
|
||||
trait_selection_actual_impl_expl_expected_other_some = {$leading_ellipsis ->
|
||||
[true] ...
|
||||
*[false] {""}
|
||||
}`{$ty_or_sig}` must implement `{$trait_path}`, for some specific lifetime `'{$lifetime_1}`...
|
||||
trait_selection_actual_impl_expl_expected_other_two = {$leading_ellipsis ->
|
||||
[true] ...
|
||||
*[false] {""}
|
||||
}`{$ty_or_sig}` must implement `{$trait_path}`, for any two lifetimes `'{$lifetime_1}` and `'{$lifetime_2}`...
|
||||
trait_selection_actual_impl_expl_expected_passive_any = {$leading_ellipsis ->
|
||||
[true] ...
|
||||
*[false] {""}
|
||||
}`{$trait_path}` would have to be implemented for the type `{$ty_or_sig}`, for any lifetime `'{$lifetime_1}`...
|
||||
trait_selection_actual_impl_expl_expected_passive_nothing = {$leading_ellipsis ->
|
||||
[true] ...
|
||||
*[false] {""}
|
||||
}`{$trait_path}` would have to be implemented for the type `{$ty_or_sig}`
|
||||
trait_selection_actual_impl_expl_expected_passive_some = {$leading_ellipsis ->
|
||||
[true] ...
|
||||
*[false] {""}
|
||||
}`{$trait_path}` would have to be implemented for the type `{$ty_or_sig}`, for some specific lifetime `'{$lifetime_1}`...
|
||||
trait_selection_actual_impl_expl_expected_passive_two = {$leading_ellipsis ->
|
||||
[true] ...
|
||||
*[false] {""}
|
||||
}`{$trait_path}` would have to be implemented for the type `{$ty_or_sig}`, for any two lifetimes `'{$lifetime_1}` and `'{$lifetime_2}`...
|
||||
trait_selection_actual_impl_expl_expected_signature_any = {$leading_ellipsis ->
|
||||
[true] ...
|
||||
*[false] {""}
|
||||
}closure with signature `{$ty_or_sig}` must implement `{$trait_path}`, for any lifetime `'{$lifetime_1}`...
|
||||
trait_selection_actual_impl_expl_expected_signature_nothing = {$leading_ellipsis ->
|
||||
[true] ...
|
||||
*[false] {""}
|
||||
}closure with signature `{$ty_or_sig}` must implement `{$trait_path}`
|
||||
trait_selection_actual_impl_expl_expected_signature_some = {$leading_ellipsis ->
|
||||
[true] ...
|
||||
*[false] {""}
|
||||
}closure with signature `{$ty_or_sig}` must implement `{$trait_path}`, for some specific lifetime `'{$lifetime_1}`...
|
||||
trait_selection_actual_impl_expl_expected_signature_two = {$leading_ellipsis ->
|
||||
[true] ...
|
||||
*[false] {""}
|
||||
}closure with signature `{$ty_or_sig}` must implement `{$trait_path}`, for any two lifetimes `'{$lifetime_1}` and `'{$lifetime_2}`...
|
||||
trait_selection_adjust_signature_borrow = consider adjusting the signature so it borrows its {$len ->
|
||||
[one] argument
|
||||
*[other] arguments
|
||||
@ -8,8 +70,48 @@ trait_selection_adjust_signature_remove_borrow = consider adjusting the signatur
|
||||
*[other] arguments
|
||||
}
|
||||
|
||||
trait_selection_ascribe_user_type_prove_predicate = ...so that the where clause holds
|
||||
|
||||
trait_selection_async_closure_not_fn = async closure does not implement `{$kind}` because it captures state from its environment
|
||||
|
||||
trait_selection_await_both_futures = consider `await`ing on both `Future`s
|
||||
trait_selection_await_future = consider `await`ing on the `Future`
|
||||
trait_selection_await_note = calling an async function returns a future
|
||||
|
||||
trait_selection_but_calling_introduces = {$has_param_name ->
|
||||
[true] `{$param_name}`
|
||||
*[false] `fn` parameter
|
||||
} has {$lifetime_kind ->
|
||||
[true] lifetime `{$lifetime}`
|
||||
*[false] an anonymous lifetime `'_`
|
||||
} but calling `{$assoc_item}` introduces an implicit `'static` lifetime requirement
|
||||
.label1 = {$has_lifetime ->
|
||||
[true] lifetime `{$lifetime}`
|
||||
*[false] an anonymous lifetime `'_`
|
||||
}
|
||||
.label2 = ...is used and required to live as long as `'static` here because of an implicit lifetime bound on the {$has_impl_path ->
|
||||
[true] `impl` of `{$impl_path}`
|
||||
*[false] inherent `impl`
|
||||
}
|
||||
|
||||
trait_selection_but_needs_to_satisfy = {$has_param_name ->
|
||||
[true] `{$param_name}`
|
||||
*[false] `fn` parameter
|
||||
} has {$has_lifetime ->
|
||||
[true] lifetime `{$lifetime}`
|
||||
*[false] an anonymous lifetime `'_`
|
||||
} but it needs to satisfy a `'static` lifetime requirement
|
||||
.influencer = this data with {$has_lifetime ->
|
||||
[true] lifetime `{$lifetime}`
|
||||
*[false] an anonymous lifetime `'_`
|
||||
}...
|
||||
.require = {$spans_empty ->
|
||||
*[true] ...is used and required to live as long as `'static` here
|
||||
[false] ...and is required to live as long as `'static` here
|
||||
}
|
||||
.used_here = ...is used here...
|
||||
.introduced_by_bound = `'static` lifetime requirement introduced by this bound
|
||||
|
||||
trait_selection_closure_fn_mut_label = closure is `{$trait_prefix}FnMut` because it mutates the variable `{$place}` here
|
||||
|
||||
trait_selection_closure_fn_once_label = closure is `{$trait_prefix}FnOnce` because it moves the variable `{$place}` out of its environment
|
||||
@ -19,18 +121,67 @@ trait_selection_closure_kind_mismatch = expected a closure that implements the `
|
||||
|
||||
trait_selection_closure_kind_requirement = the requirement to implement `{$trait_prefix}{$expected}` derives from here
|
||||
|
||||
trait_selection_compare_impl_item_obligation = ...so that the definition in impl matches the definition from the trait
|
||||
trait_selection_consider_specifying_length = consider specifying the actual array length
|
||||
trait_selection_data_flows = ...but data{$label_var1_exists ->
|
||||
[true] {" "}from `{$label_var1}`
|
||||
*[false] {""}
|
||||
} flows{$label_var2_exists ->
|
||||
[true] {" "}into `{$label_var2}`
|
||||
*[false] {""}
|
||||
} here
|
||||
|
||||
trait_selection_data_lifetime_flow = ...but data with one lifetime flows into the other here
|
||||
trait_selection_data_returned = ...but data{$label_var1_exists ->
|
||||
[true] {" "}from `{$label_var1}`
|
||||
*[false] {""}
|
||||
} is returned here
|
||||
|
||||
trait_selection_declared_different = this parameter and the return type are declared with different lifetimes...
|
||||
trait_selection_declared_multiple = this type is declared with multiple lifetimes...
|
||||
trait_selection_disallowed_positional_argument = positional format arguments are not allowed here
|
||||
.help = only named format arguments with the name of one of the generic types are allowed in this context
|
||||
|
||||
trait_selection_does_not_outlive_static_from_impl = ...does not necessarily outlive the static lifetime introduced by the compatible `impl`
|
||||
trait_selection_dtcs_has_lifetime_req_label = this has an implicit `'static` lifetime requirement
|
||||
trait_selection_dtcs_has_req_note = the used `impl` has a `'static` requirement
|
||||
trait_selection_dtcs_introduces_requirement = calling this method introduces the `impl`'s `'static` requirement
|
||||
trait_selection_dtcs_suggestion = consider relaxing the implicit `'static` requirement
|
||||
|
||||
trait_selection_dump_vtable_entries = vtable entries for `{$trait_ref}`: {$entries}
|
||||
|
||||
trait_selection_empty_on_clause_in_rustc_on_unimplemented = empty `on`-clause in `#[rustc_on_unimplemented]`
|
||||
.label = empty on-clause here
|
||||
|
||||
trait_selection_explicit_lifetime_required_sugg_with_ident = add explicit lifetime `{$named}` to the type of `{$simple_ident}`
|
||||
|
||||
trait_selection_explicit_lifetime_required_sugg_with_param_type = add explicit lifetime `{$named}` to type
|
||||
|
||||
trait_selection_explicit_lifetime_required_with_ident = explicit lifetime required in the type of `{$simple_ident}`
|
||||
.label = lifetime `{$named}` required
|
||||
|
||||
trait_selection_explicit_lifetime_required_with_param_type = explicit lifetime required in parameter type
|
||||
.label = lifetime `{$named}` required
|
||||
|
||||
trait_selection_fn_consider_casting = consider casting the fn item to a fn pointer: `{$casting}`
|
||||
|
||||
trait_selection_fn_uniq_types = different fn items have unique types, even if their signatures are the same
|
||||
trait_selection_fps_cast = consider casting to a fn pointer
|
||||
trait_selection_fps_cast_both = consider casting both fn items to fn pointers using `as {$expected_sig}`
|
||||
|
||||
trait_selection_fps_items_are_distinct = fn items are distinct from fn pointers
|
||||
trait_selection_fps_remove_ref = consider removing the reference
|
||||
trait_selection_fps_use_ref = consider using a reference
|
||||
trait_selection_fulfill_req_lifetime = the type `{$ty}` does not fulfill the required lifetime
|
||||
|
||||
trait_selection_full_type_written = the full type name has been written to '{$path}'
|
||||
|
||||
trait_selection_ignored_diagnostic_option = `{$option_name}` is ignored due to previous definition of `{$option_name}`
|
||||
.other_label = `{$option_name}` is first declared here
|
||||
.label = `{$option_name}` is already declared here
|
||||
|
||||
trait_selection_implicit_static_lifetime_note = this has an implicit `'static` lifetime requirement
|
||||
trait_selection_implicit_static_lifetime_suggestion = consider relaxing the implicit `'static` requirement
|
||||
trait_selection_inherent_projection_normalization_overflow = overflow evaluating associated type `{$ty}`
|
||||
|
||||
trait_selection_invalid_format_specifier = invalid format specifier
|
||||
@ -39,13 +190,52 @@ trait_selection_invalid_format_specifier = invalid format specifier
|
||||
trait_selection_invalid_on_clause_in_rustc_on_unimplemented = invalid `on`-clause in `#[rustc_on_unimplemented]`
|
||||
.label = invalid on-clause here
|
||||
|
||||
trait_selection_label_bad = {$bad_kind ->
|
||||
*[other] cannot infer type
|
||||
[more_info] cannot infer {$prefix_kind ->
|
||||
*[type] type for {$prefix}
|
||||
[const_with_param] the value of const parameter
|
||||
[const] the value of the constant
|
||||
} `{$name}`{$has_parent ->
|
||||
[true] {" "}declared on the {$parent_prefix} `{$parent_name}`
|
||||
*[false] {""}
|
||||
}
|
||||
}
|
||||
|
||||
trait_selection_lf_bound_not_satisfied = lifetime bound not satisfied
|
||||
trait_selection_lifetime_mismatch = lifetime mismatch
|
||||
|
||||
trait_selection_lifetime_param_suggestion = consider {$is_reuse ->
|
||||
[true] reusing
|
||||
*[false] introducing
|
||||
} a named lifetime parameter{$is_impl ->
|
||||
[true] {" "}and update trait if needed
|
||||
*[false] {""}
|
||||
}
|
||||
trait_selection_lifetime_param_suggestion_elided = each elided lifetime in input position becomes a distinct lifetime
|
||||
|
||||
trait_selection_malformed_on_unimplemented_attr = malformed `on_unimplemented` attribute
|
||||
.help = only `message`, `note` and `label` are allowed as options
|
||||
.label = invalid option found here
|
||||
|
||||
trait_selection_meant_byte_literal = if you meant to write a byte literal, prefix with `b`
|
||||
trait_selection_meant_char_literal = if you meant to write a `char` literal, use single quotes
|
||||
trait_selection_meant_str_literal = if you meant to write a string literal, use double quotes
|
||||
trait_selection_mismatched_static_lifetime = incompatible lifetime on type
|
||||
trait_selection_missing_options_for_on_unimplemented_attr = missing options for `on_unimplemented` attribute
|
||||
.help = at least one of the `message`, `note` and `label` options are expected
|
||||
|
||||
trait_selection_more_targeted = {$has_param_name ->
|
||||
[true] `{$param_name}`
|
||||
*[false] `fn` parameter
|
||||
} has {$has_lifetime ->
|
||||
[true] lifetime `{$lifetime}`
|
||||
*[false] an anonymous lifetime `'_`
|
||||
} but calling `{$ident}` introduces an implicit `'static` lifetime requirement
|
||||
|
||||
trait_selection_msl_introduces_static = introduces a `'static` lifetime requirement
|
||||
trait_selection_msl_unmet_req = because this has an unmet lifetime requirement
|
||||
|
||||
trait_selection_negative_positive_conflict = found both positive and negative implementation of trait `{$trait_desc}`{$self_desc ->
|
||||
[none] {""}
|
||||
*[default] {" "}for type `{$self_desc}`
|
||||
@ -59,13 +249,214 @@ trait_selection_no_value_in_rustc_on_unimplemented = this attribute must have a
|
||||
.label = expected value here
|
||||
.note = eg `#[rustc_on_unimplemented(message="foo")]`
|
||||
|
||||
trait_selection_nothing = {""}
|
||||
|
||||
trait_selection_oc_cant_coerce = cannot coerce intrinsics to function pointers
|
||||
trait_selection_oc_closure_selfref = closure/coroutine type that references itself
|
||||
trait_selection_oc_const_compat = const not compatible with trait
|
||||
trait_selection_oc_fn_lang_correct_type = {$lang_item_name ->
|
||||
[panic_impl] `#[panic_handler]`
|
||||
*[lang_item_name] lang item `{$lang_item_name}`
|
||||
} function has wrong type
|
||||
trait_selection_oc_fn_main_correct_type = `main` function has wrong type
|
||||
trait_selection_oc_fn_start_correct_type = `#[start]` function has wrong type
|
||||
trait_selection_oc_generic = mismatched types
|
||||
|
||||
trait_selection_oc_if_else_different = `if` and `else` have incompatible types
|
||||
trait_selection_oc_intrinsic_correct_type = intrinsic has wrong type
|
||||
trait_selection_oc_match_compat = `match` arms have incompatible types
|
||||
trait_selection_oc_method_compat = method not compatible with trait
|
||||
trait_selection_oc_method_correct_type = mismatched `self` parameter type
|
||||
trait_selection_oc_no_diverge = `else` clause of `let...else` does not diverge
|
||||
trait_selection_oc_no_else = `if` may be missing an `else` clause
|
||||
trait_selection_oc_try_compat = `?` operator has incompatible types
|
||||
trait_selection_oc_type_compat = type not compatible with trait
|
||||
trait_selection_opaque_captures_lifetime = hidden type for `{$opaque_ty}` captures lifetime that does not appear in bounds
|
||||
.label = opaque type defined here
|
||||
|
||||
trait_selection_outlives_bound = lifetime of the source pointer does not outlive lifetime bound of the object type
|
||||
trait_selection_outlives_content = lifetime of reference outlives lifetime of borrowed content...
|
||||
|
||||
trait_selection_precise_capturing_existing = add `{$new_lifetime}` to the `use<...>` bound to explicitly capture it
|
||||
trait_selection_precise_capturing_new = add a `use<...>` bound to explicitly capture `{$new_lifetime}`
|
||||
|
||||
trait_selection_precise_capturing_new_but_apit = add a `use<...>` bound to explicitly capture `{$new_lifetime}` after turning all argument-position `impl Trait` into type parameters, noting that this possibly affects the API of this crate
|
||||
|
||||
trait_selection_prlf_defined_with_sub = the lifetime `{$sub_symbol}` defined here...
|
||||
trait_selection_prlf_defined_without_sub = the lifetime defined here...
|
||||
trait_selection_prlf_known_limitation = this is a known limitation that will be removed in the future (see issue #100013 <https://github.com/rust-lang/rust/issues/100013> for more information)
|
||||
|
||||
trait_selection_prlf_must_outlive_with_sup = ...must outlive the lifetime `{$sup_symbol}` defined here
|
||||
trait_selection_prlf_must_outlive_without_sup = ...must outlive the lifetime defined here
|
||||
trait_selection_reborrow = ...so that reference does not outlive borrowed content
|
||||
trait_selection_ref_longer_than_data = in type `{$ty}`, reference has a longer lifetime than the data it references
|
||||
|
||||
trait_selection_reference_outlives_referent = ...so that the reference type `{$name}` does not outlive the data it points at
|
||||
trait_selection_region_explanation = {$pref_kind ->
|
||||
*[should_not_happen] [{$pref_kind}]
|
||||
[ref_valid_for] ...the reference is valid for
|
||||
[content_valid_for] ...but the borrowed content is only valid for
|
||||
[type_obj_valid_for] object type is valid for
|
||||
[source_pointer_valid_for] source pointer is only valid for
|
||||
[type_satisfy] type must satisfy
|
||||
[type_outlive] type must outlive
|
||||
[lf_param_instantiated_with] lifetime parameter instantiated with
|
||||
[lf_param_must_outlive] but lifetime parameter must outlive
|
||||
[lf_instantiated_with] lifetime instantiated with
|
||||
[lf_must_outlive] but lifetime must outlive
|
||||
[pointer_valid_for] the pointer is valid for
|
||||
[data_valid_for] but the referenced data is only valid for
|
||||
[empty] {""}
|
||||
}{$pref_kind ->
|
||||
[empty] {""}
|
||||
*[other] {" "}
|
||||
}{$desc_kind ->
|
||||
*[should_not_happen] [{$desc_kind}]
|
||||
[restatic] the static lifetime
|
||||
[revar] lifetime {$desc_arg}
|
||||
[as_defined] the lifetime `{$desc_arg}` as defined here
|
||||
[as_defined_anon] the anonymous lifetime as defined here
|
||||
[defined_here] the anonymous lifetime defined here
|
||||
[defined_here_reg] the lifetime `{$desc_arg}` as defined here
|
||||
}{$suff_kind ->
|
||||
*[should_not_happen] [{$suff_kind}]
|
||||
[empty]{""}
|
||||
[continues] ...
|
||||
[req_by_binding] {" "}as required by this binding
|
||||
}
|
||||
|
||||
trait_selection_relate_object_bound = ...so that it can be closed over into an object
|
||||
trait_selection_relate_param_bound = ...so that the type `{$name}` will meet its required lifetime bounds{$continues ->
|
||||
[true] ...
|
||||
*[false] {""}
|
||||
}
|
||||
trait_selection_relate_param_bound_2 = ...that is required by this bound
|
||||
trait_selection_relate_region_param_bound = ...so that the declared lifetime parameter bounds are satisfied
|
||||
trait_selection_ril_because_of = because of this returned expression
|
||||
trait_selection_ril_introduced_by = requirement introduced by this return type
|
||||
trait_selection_ril_introduced_here = `'static` requirement introduced here
|
||||
trait_selection_ril_static_introduced_by = "`'static` lifetime requirement introduced by the return type
|
||||
|
||||
trait_selection_source_kind_closure_return =
|
||||
try giving this closure an explicit return type
|
||||
|
||||
# coroutine_kind may need to be translated
|
||||
trait_selection_source_kind_fully_qualified =
|
||||
try using a fully qualified path to specify the expected types
|
||||
|
||||
trait_selection_source_kind_subdiag_generic_label =
|
||||
cannot infer {$is_type ->
|
||||
[true] type
|
||||
*[false] the value
|
||||
} of the {$is_type ->
|
||||
[true] type
|
||||
*[false] const
|
||||
} {$parent_exists ->
|
||||
[true] parameter `{$param_name}` declared on the {$parent_prefix} `{$parent_name}`
|
||||
*[false] parameter {$param_name}
|
||||
}
|
||||
|
||||
trait_selection_source_kind_subdiag_generic_suggestion =
|
||||
consider specifying the generic {$arg_count ->
|
||||
[one] argument
|
||||
*[other] arguments
|
||||
}
|
||||
|
||||
trait_selection_source_kind_subdiag_let = {$kind ->
|
||||
[with_pattern] consider giving `{$name}` an explicit type
|
||||
[closure] consider giving this closure parameter an explicit type
|
||||
*[other] consider giving this pattern a type
|
||||
}{$x_kind ->
|
||||
[has_name] , where the {$prefix_kind ->
|
||||
*[type] type for {$prefix}
|
||||
[const_with_param] value of const parameter
|
||||
[const] value of the constant
|
||||
} `{$arg_name}` is specified
|
||||
[underscore] , where the placeholders `_` are specified
|
||||
*[empty] {""}
|
||||
}
|
||||
|
||||
trait_selection_srs_add = consider returning the local binding `{$ident}`
|
||||
trait_selection_srs_add_one = consider returning one of these bindings
|
||||
|
||||
trait_selection_srs_remove = consider removing this semicolon
|
||||
trait_selection_srs_remove_and_box = consider removing this semicolon and boxing the expressions
|
||||
trait_selection_stp_wrap_many = try wrapping the pattern in a variant of `{$path}`
|
||||
|
||||
trait_selection_stp_wrap_one = try wrapping the pattern in `{$variant}`
|
||||
trait_selection_subtype = ...so that the {$requirement ->
|
||||
[method_compat] method type is compatible with trait
|
||||
[type_compat] associated type is compatible with trait
|
||||
[const_compat] const is compatible with trait
|
||||
[expr_assignable] expression is assignable
|
||||
[if_else_different] `if` and `else` have incompatible types
|
||||
[no_else] `if` missing an `else` returns `()`
|
||||
[fn_main_correct_type] `main` function has the correct type
|
||||
[fn_start_correct_type] `#[start]` function has the correct type
|
||||
[fn_lang_correct_type] lang item function has the correct type
|
||||
[intrinsic_correct_type] intrinsic has the correct type
|
||||
[method_correct_type] method receiver has the correct type
|
||||
*[other] types are compatible
|
||||
}
|
||||
trait_selection_subtype_2 = ...so that {$requirement ->
|
||||
[method_compat] method type is compatible with trait
|
||||
[type_compat] associated type is compatible with trait
|
||||
[const_compat] const is compatible with trait
|
||||
[expr_assignable] expression is assignable
|
||||
[if_else_different] `if` and `else` have incompatible types
|
||||
[no_else] `if` missing an `else` returns `()`
|
||||
[fn_main_correct_type] `main` function has the correct type
|
||||
[fn_start_correct_type] `#[start]` function has the correct type
|
||||
[fn_lang_correct_type] lang item function has the correct type
|
||||
[intrinsic_correct_type] intrinsic has the correct type
|
||||
[method_correct_type] method receiver has the correct type
|
||||
*[other] types are compatible
|
||||
}
|
||||
|
||||
trait_selection_suggest_accessing_field = you might have meant to use field `{$name}` whose type is `{$ty}`
|
||||
|
||||
trait_selection_suggest_add_let_for_letchains = consider adding `let`
|
||||
|
||||
trait_selection_tid_consider_borrowing = consider borrowing this type parameter in the trait
|
||||
trait_selection_tid_param_help = the lifetime requirements from the `impl` do not correspond to the requirements in the `trait`
|
||||
|
||||
trait_selection_tid_rel_help = verify the lifetime relationships in the `trait` and `impl` between the `self` argument, the other inputs and its output
|
||||
trait_selection_trait_has_no_impls = this trait has no implementations, consider adding one
|
||||
|
||||
trait_selection_trait_impl_diff = `impl` item signature doesn't match `trait` item signature
|
||||
.found = found `{$found}`
|
||||
.expected = expected `{$expected}`
|
||||
.expected_found = expected signature `{$expected}`
|
||||
{" "}found signature `{$found}`
|
||||
|
||||
trait_selection_trait_placeholder_mismatch = implementation of `{$trait_def_id}` is not general enough
|
||||
.label_satisfy = doesn't satisfy where-clause
|
||||
.label_where = due to a where-clause on `{$def_id}`...
|
||||
.label_dup = implementation of `{$trait_def_id}` is not general enough
|
||||
|
||||
trait_selection_try_cannot_convert = `?` operator cannot convert from `{$found}` to `{$expected}`
|
||||
|
||||
trait_selection_tuple_trailing_comma = use a trailing comma to create a tuple with one element
|
||||
|
||||
trait_selection_ty_alias_overflow = in case this is a recursive type alias, consider using a struct, enum, or union instead
|
||||
trait_selection_type_annotations_needed = {$source_kind ->
|
||||
[closure] type annotations needed for the closure `{$source_name}`
|
||||
[normal] type annotations needed for `{$source_name}`
|
||||
*[other] type annotations needed
|
||||
}
|
||||
.label = type must be known at this point
|
||||
|
||||
trait_selection_types_declared_different = these two types are declared with different lifetimes...
|
||||
|
||||
trait_selection_unable_to_construct_constant_value = unable to construct a constant value for the unevaluated constant {$unevaluated}
|
||||
|
||||
trait_selection_unknown_format_parameter_for_on_unimplemented_attr = there is no parameter `{$argument_name}` on trait `{$trait_name}`
|
||||
.help = expect either a generic argument name or {"`{Self}`"} as format argument
|
||||
|
||||
trait_selection_warn_removing_apit_params = you could use a `use<...>` bound to explicitly capture `{$new_lifetime}`, but argument-position `impl Trait`s are not nameable
|
||||
|
||||
trait_selection_where_copy_predicates = copy the `where` clause predicates from the trait
|
||||
|
||||
trait_selection_where_remove = remove the `where` clause
|
||||
trait_selection_wrapped_parser_error = {$description}
|
||||
.label = {$label}
|
||||
|
@ -46,14 +46,12 @@
|
||||
//! time of error detection.
|
||||
|
||||
use std::borrow::Cow;
|
||||
use std::ops::{ControlFlow, Deref};
|
||||
use std::ops::ControlFlow;
|
||||
use std::path::PathBuf;
|
||||
use std::{cmp, fmt, iter};
|
||||
|
||||
use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
|
||||
use rustc_errors::{
|
||||
pluralize, Applicability, Diag, DiagCtxtHandle, DiagStyledString, IntoDiagArg, StringPart,
|
||||
};
|
||||
use rustc_errors::{pluralize, Applicability, Diag, DiagStyledString, IntoDiagArg, StringPart};
|
||||
use rustc_hir::def::DefKind;
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_hir::intravisit::Visitor;
|
||||
@ -72,13 +70,13 @@ use rustc_middle::ty::{
|
||||
use rustc_span::{sym, BytePos, DesugaringKind, Pos, Span};
|
||||
use rustc_target::spec::abi;
|
||||
|
||||
use crate::error_reporting::TypeErrCtxt;
|
||||
use crate::errors::{ObligationCauseFailureCode, TypeErrorAdditionalDiags};
|
||||
use crate::infer;
|
||||
use crate::infer::relate::{self, RelateResult, TypeRelation};
|
||||
use crate::infer::{InferCtxt, TypeTrace, ValuePairs};
|
||||
use crate::traits::{
|
||||
IfExpressionCause, MatchExpressionArmCause, ObligationCause, ObligationCauseCode,
|
||||
PredicateObligation,
|
||||
};
|
||||
|
||||
mod note_and_explain;
|
||||
@ -111,48 +109,59 @@ fn escape_literal(s: &str) -> String {
|
||||
escaped
|
||||
}
|
||||
|
||||
/// A helper for building type related errors. The `typeck_results`
|
||||
/// field is only populated during an in-progress typeck.
|
||||
/// Get an instance by calling `InferCtxt::err_ctxt` or `FnCtxt::err_ctxt`.
|
||||
///
|
||||
/// You must only create this if you intend to actually emit an error (or
|
||||
/// perhaps a warning, though preferably not.) It provides a lot of utility
|
||||
/// methods which should not be used during the happy path.
|
||||
pub struct TypeErrCtxt<'a, 'tcx> {
|
||||
pub infcx: &'a InferCtxt<'tcx>,
|
||||
pub sub_relations: std::cell::RefCell<sub_relations::SubRelations>,
|
||||
|
||||
pub typeck_results: Option<std::cell::Ref<'a, ty::TypeckResults<'tcx>>>,
|
||||
pub fallback_has_occurred: bool,
|
||||
|
||||
pub normalize_fn_sig: Box<dyn Fn(ty::PolyFnSig<'tcx>) -> ty::PolyFnSig<'tcx> + 'a>,
|
||||
|
||||
pub autoderef_steps:
|
||||
Box<dyn Fn(Ty<'tcx>) -> Vec<(Ty<'tcx>, Vec<PredicateObligation<'tcx>>)> + 'a>,
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
||||
pub fn dcx(&self) -> DiagCtxtHandle<'a> {
|
||||
self.infcx.dcx()
|
||||
// [Note-Type-error-reporting]
|
||||
// An invariant is that anytime the expected or actual type is Error (the special
|
||||
// error type, meaning that an error occurred when typechecking this expression),
|
||||
// this is a derived error. The error cascaded from another error (that was already
|
||||
// reported), so it's not useful to display it to the user.
|
||||
// The following methods implement this logic.
|
||||
// They check if either the actual or expected type is Error, and don't print the error
|
||||
// in this case. The typechecker should only ever report type errors involving mismatched
|
||||
// types using one of these methods, and should not call span_err directly for such
|
||||
// errors.
|
||||
pub fn type_error_struct_with_diag<M>(
|
||||
&self,
|
||||
sp: Span,
|
||||
mk_diag: M,
|
||||
actual_ty: Ty<'tcx>,
|
||||
) -> Diag<'a>
|
||||
where
|
||||
M: FnOnce(String) -> Diag<'a>,
|
||||
{
|
||||
let actual_ty = self.resolve_vars_if_possible(actual_ty);
|
||||
debug!("type_error_struct_with_diag({:?}, {:?})", sp, actual_ty);
|
||||
|
||||
let mut err = mk_diag(self.ty_to_string(actual_ty));
|
||||
|
||||
// Don't report an error if actual type is `Error`.
|
||||
if actual_ty.references_error() {
|
||||
err.downgrade_to_delayed_bug();
|
||||
}
|
||||
|
||||
/// This is just to avoid a potential footgun of accidentally
|
||||
/// dropping `typeck_results` by calling `InferCtxt::err_ctxt`
|
||||
#[deprecated(note = "you already have a `TypeErrCtxt`")]
|
||||
#[allow(unused)]
|
||||
pub fn err_ctxt(&self) -> ! {
|
||||
bug!("called `err_ctxt` on `TypeErrCtxt`. Try removing the call");
|
||||
err
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> Deref for TypeErrCtxt<'_, 'tcx> {
|
||||
type Target = InferCtxt<'tcx>;
|
||||
fn deref(&self) -> &InferCtxt<'tcx> {
|
||||
self.infcx
|
||||
pub fn report_mismatched_types(
|
||||
&self,
|
||||
cause: &ObligationCause<'tcx>,
|
||||
expected: Ty<'tcx>,
|
||||
actual: Ty<'tcx>,
|
||||
err: TypeError<'tcx>,
|
||||
) -> Diag<'a> {
|
||||
self.report_and_explain_type_error(TypeTrace::types(cause, true, expected, actual), err)
|
||||
}
|
||||
|
||||
pub fn report_mismatched_consts(
|
||||
&self,
|
||||
cause: &ObligationCause<'tcx>,
|
||||
expected: ty::Const<'tcx>,
|
||||
actual: ty::Const<'tcx>,
|
||||
err: TypeError<'tcx>,
|
||||
) -> Diag<'a> {
|
||||
self.report_and_explain_type_error(TypeTrace::consts(cause, true, expected, actual), err)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
||||
pub fn get_impl_future_output_ty(&self, ty: Ty<'tcx>) -> Option<Ty<'tcx>> {
|
||||
let (def_id, args) = match *ty.kind() {
|
||||
ty::Alias(_, ty::AliasTy { def_id, args, .. })
|
||||
@ -2188,32 +2197,3 @@ impl TyCategory {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> InferCtxt<'tcx> {
|
||||
/// Given a [`hir::Block`], get the span of its last expression or
|
||||
/// statement, peeling off any inner blocks.
|
||||
pub fn find_block_span(&self, block: &'tcx hir::Block<'tcx>) -> Span {
|
||||
let block = block.innermost_block();
|
||||
if let Some(expr) = &block.expr {
|
||||
expr.span
|
||||
} else if let Some(stmt) = block.stmts.last() {
|
||||
// possibly incorrect trailing `;` in the else arm
|
||||
stmt.span
|
||||
} else {
|
||||
// empty block; point at its entirety
|
||||
block.span
|
||||
}
|
||||
}
|
||||
|
||||
/// Given a [`hir::HirId`] for a block, get the span of its last expression
|
||||
/// or statement, peeling off any inner blocks.
|
||||
pub fn find_block_span_from_hir_id(&self, hir_id: hir::HirId) -> Span {
|
||||
match self.tcx.hir_node(hir_id) {
|
||||
hir::Node::Block(blk) => self.find_block_span(blk),
|
||||
// The parser was in a weird state if either of these happen, but
|
||||
// it's better not to panic.
|
||||
hir::Node::Expr(e) => e.span,
|
||||
_ => rustc_span::DUMMY_SP,
|
||||
}
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
use crate::error_reporting::infer::TypeErrCtxt;
|
||||
use crate::error_reporting::TypeErrCtxt;
|
||||
use crate::errors::{
|
||||
AmbiguousImpl, AmbiguousReturn, AnnotationRequired, InferenceBadError,
|
||||
SourceKindMultiSuggestion, SourceKindSubdiag,
|
@ -1,4 +1,4 @@
|
||||
use crate::error_reporting::infer::TypeErrCtxt;
|
||||
use crate::error_reporting::TypeErrCtxt;
|
||||
use crate::infer::RegionResolutionError;
|
||||
use crate::infer::RegionResolutionError::*;
|
||||
use rustc_errors::{Diag, ErrorGuaranteed};
|
@ -1,4 +1,3 @@
|
||||
use super::TypeErrCtxt;
|
||||
use rustc_errors::Applicability::{MachineApplicable, MaybeIncorrect};
|
||||
use rustc_errors::{pluralize, Diag, MultiSpan};
|
||||
use rustc_hir as hir;
|
||||
@ -12,6 +11,8 @@ use rustc_middle::{
|
||||
};
|
||||
use rustc_span::{def_id::DefId, sym, BytePos, Span, Symbol};
|
||||
|
||||
use crate::error_reporting::TypeErrCtxt;
|
||||
|
||||
impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
||||
pub fn note_and_explain_type_err(
|
||||
&self,
|
@ -18,7 +18,8 @@ use rustc_type_ir::Upcast as _;
|
||||
|
||||
use super::nice_region_error::find_anon_type;
|
||||
use super::{nice_region_error, ObligationCauseAsDiagArg};
|
||||
use crate::error_reporting::infer::{ObligationCauseExt as _, TypeErrCtxt};
|
||||
use crate::error_reporting::infer::ObligationCauseExt as _;
|
||||
use crate::error_reporting::TypeErrCtxt;
|
||||
use crate::errors::{
|
||||
self, note_and_explain, FulfillReqLifetime, LfBoundNotSatisfied, OutlivesBound,
|
||||
OutlivesContent, RefLongerThanData, RegionOriginNote, WhereClauseSuggestions,
|
||||
@ -224,16 +225,17 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
||||
}
|
||||
.add_to_diag(err),
|
||||
infer::Reborrow(span) => {
|
||||
RegionOriginNote::Plain { span, msg: fluent::infer_reborrow }.add_to_diag(err)
|
||||
RegionOriginNote::Plain { span, msg: fluent::trait_selection_reborrow }
|
||||
.add_to_diag(err)
|
||||
}
|
||||
infer::RelateObjectBound(span) => {
|
||||
RegionOriginNote::Plain { span, msg: fluent::infer_relate_object_bound }
|
||||
RegionOriginNote::Plain { span, msg: fluent::trait_selection_relate_object_bound }
|
||||
.add_to_diag(err);
|
||||
}
|
||||
infer::ReferenceOutlivesReferent(ty, span) => {
|
||||
RegionOriginNote::WithName {
|
||||
span,
|
||||
msg: fluent::infer_reference_outlives_referent,
|
||||
msg: fluent::trait_selection_reference_outlives_referent,
|
||||
name: &self.ty_to_string(ty),
|
||||
continues: false,
|
||||
}
|
||||
@ -242,22 +244,31 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
||||
infer::RelateParamBound(span, ty, opt_span) => {
|
||||
RegionOriginNote::WithName {
|
||||
span,
|
||||
msg: fluent::infer_relate_param_bound,
|
||||
msg: fluent::trait_selection_relate_param_bound,
|
||||
name: &self.ty_to_string(ty),
|
||||
continues: opt_span.is_some(),
|
||||
}
|
||||
.add_to_diag(err);
|
||||
if let Some(span) = opt_span {
|
||||
RegionOriginNote::Plain { span, msg: fluent::infer_relate_param_bound_2 }
|
||||
RegionOriginNote::Plain {
|
||||
span,
|
||||
msg: fluent::trait_selection_relate_param_bound_2,
|
||||
}
|
||||
.add_to_diag(err);
|
||||
}
|
||||
}
|
||||
infer::RelateRegionParamBound(span) => {
|
||||
RegionOriginNote::Plain { span, msg: fluent::infer_relate_region_param_bound }
|
||||
RegionOriginNote::Plain {
|
||||
span,
|
||||
msg: fluent::trait_selection_relate_region_param_bound,
|
||||
}
|
||||
.add_to_diag(err);
|
||||
}
|
||||
infer::CompareImplItemObligation { span, .. } => {
|
||||
RegionOriginNote::Plain { span, msg: fluent::infer_compare_impl_item_obligation }
|
||||
RegionOriginNote::Plain {
|
||||
span,
|
||||
msg: fluent::trait_selection_compare_impl_item_obligation,
|
||||
}
|
||||
.add_to_diag(err);
|
||||
}
|
||||
infer::CheckAssociatedTypeBounds { ref parent, .. } => {
|
||||
@ -266,7 +277,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
||||
infer::AscribeUserTypeProvePredicate(span) => {
|
||||
RegionOriginNote::Plain {
|
||||
span,
|
||||
msg: fluent::infer_ascribe_user_type_prove_predicate,
|
||||
msg: fluent::trait_selection_ascribe_user_type_prove_predicate,
|
||||
}
|
||||
.add_to_diag(err);
|
||||
}
|
@ -17,14 +17,13 @@ use rustc_middle::ty::print::with_no_trimmed_paths;
|
||||
use rustc_middle::ty::{self as ty, GenericArgKind, IsSuggestable, Ty, TypeVisitableExt};
|
||||
use rustc_span::{sym, Span};
|
||||
|
||||
use crate::error_reporting::TypeErrCtxt;
|
||||
use crate::errors::{
|
||||
ConsiderAddingAwait, FnConsiderCasting, FnItemsAreDistinct, FnUniqTypes,
|
||||
FunctionPointerSuggestion, SuggestAccessingField, SuggestRemoveSemiOrReturnBinding,
|
||||
SuggestTuplePatternMany, SuggestTuplePatternOne, TypeErrorAdditionalDiags,
|
||||
};
|
||||
|
||||
use super::TypeErrCtxt;
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
pub enum SuggestAsRefKind {
|
||||
Option,
|
@ -1 +1,73 @@
|
||||
use std::ops::Deref;
|
||||
|
||||
use rustc_errors::DiagCtxtHandle;
|
||||
use rustc_infer::infer::InferCtxt;
|
||||
use rustc_infer::traits::PredicateObligation;
|
||||
use rustc_macros::extension;
|
||||
use rustc_middle::bug;
|
||||
use rustc_middle::ty::{self, Ty};
|
||||
|
||||
use crate::error_reporting::infer::sub_relations;
|
||||
|
||||
pub mod infer;
|
||||
pub mod traits;
|
||||
|
||||
/// A helper for building type related errors. The `typeck_results`
|
||||
/// field is only populated during an in-progress typeck.
|
||||
/// Get an instance by calling `InferCtxt::err_ctxt` or `FnCtxt::err_ctxt`.
|
||||
///
|
||||
/// You must only create this if you intend to actually emit an error (or
|
||||
/// perhaps a warning, though preferably not.) It provides a lot of utility
|
||||
/// methods which should not be used during the happy path.
|
||||
pub struct TypeErrCtxt<'a, 'tcx> {
|
||||
pub infcx: &'a InferCtxt<'tcx>,
|
||||
pub sub_relations: std::cell::RefCell<sub_relations::SubRelations>,
|
||||
|
||||
pub typeck_results: Option<std::cell::Ref<'a, ty::TypeckResults<'tcx>>>,
|
||||
pub fallback_has_occurred: bool,
|
||||
|
||||
pub normalize_fn_sig: Box<dyn Fn(ty::PolyFnSig<'tcx>) -> ty::PolyFnSig<'tcx> + 'a>,
|
||||
|
||||
pub autoderef_steps:
|
||||
Box<dyn Fn(Ty<'tcx>) -> Vec<(Ty<'tcx>, Vec<PredicateObligation<'tcx>>)> + 'a>,
|
||||
}
|
||||
|
||||
#[extension(pub trait InferCtxtErrorExt<'tcx>)]
|
||||
impl<'tcx> InferCtxt<'tcx> {
|
||||
/// Creates a `TypeErrCtxt` for emitting various inference errors.
|
||||
/// During typeck, use `FnCtxt::err_ctxt` instead.
|
||||
fn err_ctxt(&self) -> TypeErrCtxt<'_, 'tcx> {
|
||||
TypeErrCtxt {
|
||||
infcx: self,
|
||||
sub_relations: Default::default(),
|
||||
typeck_results: None,
|
||||
fallback_has_occurred: false,
|
||||
normalize_fn_sig: Box::new(|fn_sig| fn_sig),
|
||||
autoderef_steps: Box::new(|ty| {
|
||||
debug_assert!(false, "shouldn't be using autoderef_steps outside of typeck");
|
||||
vec![(ty, vec![])]
|
||||
}),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
||||
pub fn dcx(&self) -> DiagCtxtHandle<'a> {
|
||||
self.infcx.dcx()
|
||||
}
|
||||
|
||||
/// This is just to avoid a potential footgun of accidentally
|
||||
/// dropping `typeck_results` by calling `InferCtxt::err_ctxt`
|
||||
#[deprecated(note = "you already have a `TypeErrCtxt`")]
|
||||
#[allow(unused)]
|
||||
pub fn err_ctxt(&self) -> ! {
|
||||
bug!("called `err_ctxt` on `TypeErrCtxt`. Try removing the call");
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> Deref for TypeErrCtxt<'_, 'tcx> {
|
||||
type Target = InferCtxt<'tcx>;
|
||||
fn deref(&self) -> &InferCtxt<'tcx> {
|
||||
self.infcx
|
||||
}
|
||||
}
|
||||
|
@ -8,21 +8,17 @@ use rustc_hir::def::{DefKind, Res};
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_hir::intravisit::Visitor as _;
|
||||
use rustc_hir::LangItem;
|
||||
use rustc_infer::error_reporting::infer::need_type_info::TypeAnnotationNeeded;
|
||||
use rustc_infer::error_reporting::infer::TypeErrCtxt;
|
||||
use rustc_infer::infer::{BoundRegionConversionTime, InferCtxt};
|
||||
use rustc_infer::traits::util::elaborate;
|
||||
use rustc_infer::traits::{
|
||||
Obligation, ObligationCause, ObligationCauseCode, PolyTraitObligation, PredicateObligation,
|
||||
};
|
||||
use rustc_macros::extension;
|
||||
use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitable as _, TypeVisitableExt as _};
|
||||
use rustc_span::{ErrorGuaranteed, Span, DUMMY_SP};
|
||||
|
||||
use crate::error_reporting::traits::suggestions::TypeErrCtxtExt as _;
|
||||
use crate::error_reporting::traits::{
|
||||
to_pretty_impl_header, FindExprBySpan, InferCtxtPrivExt as _,
|
||||
};
|
||||
use crate::error_reporting::infer::need_type_info::TypeAnnotationNeeded;
|
||||
use crate::error_reporting::traits::{to_pretty_impl_header, FindExprBySpan};
|
||||
use crate::error_reporting::TypeErrCtxt;
|
||||
use crate::traits::query::evaluate_obligation::InferCtxtExt;
|
||||
use crate::traits::ObligationCtxt;
|
||||
|
||||
@ -153,10 +149,12 @@ pub fn compute_applicable_impls_for_diagnostics<'tcx>(
|
||||
ambiguities
|
||||
}
|
||||
|
||||
#[extension(pub trait TypeErrCtxtAmbiguityExt<'a, 'tcx>)]
|
||||
impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
||||
#[instrument(skip(self), level = "debug")]
|
||||
fn maybe_report_ambiguity(&self, obligation: &PredicateObligation<'tcx>) -> ErrorGuaranteed {
|
||||
pub(super) fn maybe_report_ambiguity(
|
||||
&self,
|
||||
obligation: &PredicateObligation<'tcx>,
|
||||
) -> ErrorGuaranteed {
|
||||
// Unable to successfully determine, probably means
|
||||
// insufficient type information, but could mean
|
||||
// ambiguous impls. The latter *ought* to be a
|
||||
|
@ -1,6 +1,9 @@
|
||||
use super::on_unimplemented::{AppendConstMessage, OnUnimplementedNote, TypeErrCtxtExt as _};
|
||||
use super::suggestions::{get_explanation_based_on_obligation, TypeErrCtxtExt as _};
|
||||
use super::on_unimplemented::{AppendConstMessage, OnUnimplementedNote};
|
||||
use super::suggestions::get_explanation_based_on_obligation;
|
||||
use crate::error_reporting::infer::TyCategory;
|
||||
use crate::error_reporting::traits::infer_ctxt_ext::InferCtxtExt;
|
||||
use crate::error_reporting::traits::report_object_safety_error;
|
||||
use crate::error_reporting::TypeErrCtxt;
|
||||
use crate::errors::{
|
||||
AsyncClosureNotFn, ClosureFnMutLabel, ClosureFnOnceLabel, ClosureKindMismatch,
|
||||
};
|
||||
@ -24,10 +27,7 @@ use rustc_hir::def_id::{DefId, LocalDefId};
|
||||
use rustc_hir::intravisit::Visitor;
|
||||
use rustc_hir::Node;
|
||||
use rustc_hir::{self as hir, LangItem};
|
||||
use rustc_infer::error_reporting::infer::TyCategory;
|
||||
use rustc_infer::error_reporting::infer::TypeErrCtxt;
|
||||
use rustc_infer::infer::{InferOk, TypeTrace};
|
||||
use rustc_macros::extension;
|
||||
use rustc_middle::traits::select::OverflowError;
|
||||
use rustc_middle::traits::SignatureMismatchData;
|
||||
use rustc_middle::ty::abstract_const::NotConstEvaluatable;
|
||||
@ -49,14 +49,11 @@ use super::{
|
||||
ArgKind, CandidateSimilarity, GetSafeTransmuteErrorAndReason, ImplCandidate, UnsatisfiedConst,
|
||||
};
|
||||
|
||||
pub use rustc_infer::traits::error_reporting::*;
|
||||
|
||||
#[extension(pub trait TypeErrCtxtSelectionErrExt<'a, 'tcx>)]
|
||||
impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
||||
/// The `root_obligation` parameter should be the `root_obligation` field
|
||||
/// from a `FulfillmentError`. If no `FulfillmentError` is available,
|
||||
/// then it should be the same as `obligation`.
|
||||
fn report_selection_error(
|
||||
pub fn report_selection_error(
|
||||
&self,
|
||||
mut obligation: PredicateObligation<'tcx>,
|
||||
root_obligation: &PredicateObligation<'tcx>,
|
||||
@ -682,9 +679,11 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
#[extension(pub(super) trait TypeErrCtxtExt<'a, 'tcx>)]
|
||||
impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
||||
fn apply_do_not_recommend(&self, obligation: &mut PredicateObligation<'tcx>) -> bool {
|
||||
pub(super) fn apply_do_not_recommend(
|
||||
&self,
|
||||
obligation: &mut PredicateObligation<'tcx>,
|
||||
) -> bool {
|
||||
let mut base_cause = obligation.cause.code().clone();
|
||||
let mut applied_do_not_recommend = false;
|
||||
loop {
|
||||
@ -1142,7 +1141,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
#[extension(pub(super) trait InferCtxtPrivExt<'a, 'tcx>)]
|
||||
impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
||||
fn can_match_trait(
|
||||
&self,
|
||||
@ -1182,7 +1180,11 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
||||
// returns if `cond` not occurring implies that `error` does not occur - i.e., that
|
||||
// `error` occurring implies that `cond` occurs.
|
||||
#[instrument(level = "debug", skip(self), ret)]
|
||||
fn error_implies(&self, cond: ty::Predicate<'tcx>, error: ty::Predicate<'tcx>) -> bool {
|
||||
pub(super) fn error_implies(
|
||||
&self,
|
||||
cond: ty::Predicate<'tcx>,
|
||||
error: ty::Predicate<'tcx>,
|
||||
) -> bool {
|
||||
if cond == error {
|
||||
return true;
|
||||
}
|
||||
@ -1205,7 +1207,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
||||
}
|
||||
|
||||
#[instrument(level = "debug", skip_all)]
|
||||
fn report_projection_error(
|
||||
pub(super) fn report_projection_error(
|
||||
&self,
|
||||
obligation: &PredicateObligation<'tcx>,
|
||||
error: &MismatchedProjectionTypes<'tcx>,
|
||||
@ -1455,7 +1457,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
fn fuzzy_match_tys(
|
||||
pub fn fuzzy_match_tys(
|
||||
&self,
|
||||
mut a: Ty<'tcx>,
|
||||
mut b: Ty<'tcx>,
|
||||
@ -1535,7 +1537,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
fn describe_closure(&self, kind: hir::ClosureKind) -> &'static str {
|
||||
pub(super) fn describe_closure(&self, kind: hir::ClosureKind) -> &'static str {
|
||||
match kind {
|
||||
hir::ClosureKind::Closure => "a closure",
|
||||
hir::ClosureKind::Coroutine(hir::CoroutineKind::Coroutine(_)) => "a coroutine",
|
||||
@ -1585,7 +1587,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
fn find_similar_impl_candidates(
|
||||
pub(super) fn find_similar_impl_candidates(
|
||||
&self,
|
||||
trait_pred: ty::PolyTraitPredicate<'tcx>,
|
||||
) -> Vec<ImplCandidate<'tcx>> {
|
||||
@ -1615,7 +1617,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
||||
candidates
|
||||
}
|
||||
|
||||
fn report_similar_impl_candidates(
|
||||
pub(super) fn report_similar_impl_candidates(
|
||||
&self,
|
||||
impl_candidates: &[ImplCandidate<'tcx>],
|
||||
trait_ref: ty::PolyTraitRef<'tcx>,
|
||||
@ -1989,7 +1991,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
||||
/// `trait_ref`.
|
||||
///
|
||||
/// For this to work, `new_self_ty` must have no escaping bound variables.
|
||||
fn mk_trait_obligation_with_new_self_ty(
|
||||
pub(super) fn mk_trait_obligation_with_new_self_ty(
|
||||
&self,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
trait_ref_and_ty: ty::Binder<'tcx, (ty::TraitPredicate<'tcx>, Ty<'tcx>)>,
|
||||
@ -2041,7 +2043,11 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
||||
})
|
||||
}
|
||||
|
||||
fn note_obligation_cause(&self, err: &mut Diag<'_>, obligation: &PredicateObligation<'tcx>) {
|
||||
pub fn note_obligation_cause(
|
||||
&self,
|
||||
err: &mut Diag<'_>,
|
||||
obligation: &PredicateObligation<'tcx>,
|
||||
) {
|
||||
// First, attempt to add note to this error with an async-await-specific
|
||||
// message, and fall back to regular note otherwise.
|
||||
if !self.maybe_note_obligation_cause_for_async_await(err, obligation) {
|
||||
@ -2067,7 +2073,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
fn is_recursive_obligation(
|
||||
pub(super) fn is_recursive_obligation(
|
||||
&self,
|
||||
obligated_types: &mut Vec<Ty<'tcx>>,
|
||||
cause_code: &ObligationCauseCode<'tcx>,
|
||||
|
@ -5,28 +5,24 @@ pub mod on_unimplemented;
|
||||
mod overflow;
|
||||
pub mod suggestions;
|
||||
|
||||
use std::iter;
|
||||
use std::{fmt, iter};
|
||||
|
||||
use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_errors::{struct_span_code_err, Applicability, Diag, MultiSpan, E0038, E0276};
|
||||
use rustc_hir::def_id::{DefId, LocalDefId};
|
||||
use rustc_hir::intravisit::Visitor;
|
||||
use rustc_hir::{self as hir, LangItem};
|
||||
use rustc_infer::error_reporting::infer::TypeErrCtxt;
|
||||
use rustc_infer::traits::{
|
||||
Obligation, ObligationCause, ObligationCauseCode, PredicateObligation, SelectionError,
|
||||
ObjectSafetyViolation, Obligation, ObligationCause, ObligationCauseCode, PredicateObligation,
|
||||
SelectionError,
|
||||
};
|
||||
use rustc_macros::extension;
|
||||
use rustc_middle::ty::print::PrintTraitRefExt as _;
|
||||
use rustc_middle::ty::print::{with_no_trimmed_paths, PrintTraitRefExt as _};
|
||||
use rustc_middle::ty::{self, Ty, TyCtxt};
|
||||
use rustc_span::{ErrorGuaranteed, ExpnKind, Span};
|
||||
|
||||
use ambiguity::TypeErrCtxtAmbiguityExt as _;
|
||||
use fulfillment_errors::TypeErrCtxtExt as _;
|
||||
use suggestions::TypeErrCtxtExt as _;
|
||||
|
||||
use crate::error_reporting::TypeErrCtxt;
|
||||
use crate::traits::{FulfillmentError, FulfillmentErrorCode};
|
||||
|
||||
pub use self::fulfillment_errors::*;
|
||||
pub use self::infer_ctxt_ext::*;
|
||||
pub use self::overflow::*;
|
||||
|
||||
@ -137,9 +133,8 @@ pub enum DefIdOrName {
|
||||
Name(&'static str),
|
||||
}
|
||||
|
||||
#[extension(pub trait TypeErrCtxtExt<'a, 'tcx>)]
|
||||
impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
||||
fn report_fulfillment_errors(
|
||||
pub fn report_fulfillment_errors(
|
||||
&self,
|
||||
mut errors: Vec<FulfillmentError<'tcx>>,
|
||||
) -> ErrorGuaranteed {
|
||||
@ -383,3 +378,194 @@ pub(crate) fn to_pretty_impl_header(tcx: TyCtxt<'_>, impl_def_id: DefId) -> Opti
|
||||
w.push(';');
|
||||
Some(w)
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
||||
pub fn report_extra_impl_obligation(
|
||||
&self,
|
||||
error_span: Span,
|
||||
impl_item_def_id: LocalDefId,
|
||||
trait_item_def_id: DefId,
|
||||
requirement: &dyn fmt::Display,
|
||||
) -> Diag<'a> {
|
||||
let mut err = struct_span_code_err!(
|
||||
self.dcx(),
|
||||
error_span,
|
||||
E0276,
|
||||
"impl has stricter requirements than trait"
|
||||
);
|
||||
|
||||
if !self.tcx.is_impl_trait_in_trait(trait_item_def_id) {
|
||||
if let Some(span) = self.tcx.hir().span_if_local(trait_item_def_id) {
|
||||
let item_name = self.tcx.item_name(impl_item_def_id.to_def_id());
|
||||
err.span_label(span, format!("definition of `{item_name}` from trait"));
|
||||
}
|
||||
}
|
||||
|
||||
err.span_label(error_span, format!("impl has extra requirement {requirement}"));
|
||||
|
||||
err
|
||||
}
|
||||
}
|
||||
|
||||
pub fn report_object_safety_error<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
span: Span,
|
||||
hir_id: Option<hir::HirId>,
|
||||
trait_def_id: DefId,
|
||||
violations: &[ObjectSafetyViolation],
|
||||
) -> Diag<'tcx> {
|
||||
let trait_str = tcx.def_path_str(trait_def_id);
|
||||
let trait_span = tcx.hir().get_if_local(trait_def_id).and_then(|node| match node {
|
||||
hir::Node::Item(item) => Some(item.ident.span),
|
||||
_ => None,
|
||||
});
|
||||
let mut err = struct_span_code_err!(
|
||||
tcx.dcx(),
|
||||
span,
|
||||
E0038,
|
||||
"the trait `{}` cannot be made into an object",
|
||||
trait_str
|
||||
);
|
||||
err.span_label(span, format!("`{trait_str}` cannot be made into an object"));
|
||||
|
||||
if let Some(hir_id) = hir_id
|
||||
&& let hir::Node::Ty(ty) = tcx.hir_node(hir_id)
|
||||
&& let hir::TyKind::TraitObject([trait_ref, ..], ..) = ty.kind
|
||||
{
|
||||
let mut hir_id = hir_id;
|
||||
while let hir::Node::Ty(ty) = tcx.parent_hir_node(hir_id) {
|
||||
hir_id = ty.hir_id;
|
||||
}
|
||||
if tcx.parent_hir_node(hir_id).fn_sig().is_some() {
|
||||
// Do not suggest `impl Trait` when dealing with things like super-traits.
|
||||
err.span_suggestion_verbose(
|
||||
ty.span.until(trait_ref.span),
|
||||
"consider using an opaque type instead",
|
||||
"impl ",
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
}
|
||||
}
|
||||
let mut reported_violations = FxIndexSet::default();
|
||||
let mut multi_span = vec![];
|
||||
let mut messages = vec![];
|
||||
for violation in violations {
|
||||
if let ObjectSafetyViolation::SizedSelf(sp) = &violation
|
||||
&& !sp.is_empty()
|
||||
{
|
||||
// Do not report `SizedSelf` without spans pointing at `SizedSelf` obligations
|
||||
// with a `Span`.
|
||||
reported_violations.insert(ObjectSafetyViolation::SizedSelf(vec![].into()));
|
||||
}
|
||||
if reported_violations.insert(violation.clone()) {
|
||||
let spans = violation.spans();
|
||||
let msg = if trait_span.is_none() || spans.is_empty() {
|
||||
format!("the trait cannot be made into an object because {}", violation.error_msg())
|
||||
} else {
|
||||
format!("...because {}", violation.error_msg())
|
||||
};
|
||||
if spans.is_empty() {
|
||||
err.note(msg);
|
||||
} else {
|
||||
for span in spans {
|
||||
multi_span.push(span);
|
||||
messages.push(msg.clone());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
let has_multi_span = !multi_span.is_empty();
|
||||
let mut note_span = MultiSpan::from_spans(multi_span.clone());
|
||||
if let (Some(trait_span), true) = (trait_span, has_multi_span) {
|
||||
note_span.push_span_label(trait_span, "this trait cannot be made into an object...");
|
||||
}
|
||||
for (span, msg) in iter::zip(multi_span, messages) {
|
||||
note_span.push_span_label(span, msg);
|
||||
}
|
||||
err.span_note(
|
||||
note_span,
|
||||
"for a trait to be \"object safe\" it needs to allow building a vtable to allow the call \
|
||||
to be resolvable dynamically; for more information visit \
|
||||
<https://doc.rust-lang.org/reference/items/traits.html#object-safety>",
|
||||
);
|
||||
|
||||
// Only provide the help if its a local trait, otherwise it's not actionable.
|
||||
if trait_span.is_some() {
|
||||
let mut reported_violations: Vec<_> = reported_violations.into_iter().collect();
|
||||
reported_violations.sort();
|
||||
|
||||
let mut potential_solutions: Vec<_> =
|
||||
reported_violations.into_iter().map(|violation| violation.solution()).collect();
|
||||
potential_solutions.sort();
|
||||
// Allows us to skip suggesting that the same item should be moved to another trait multiple times.
|
||||
potential_solutions.dedup();
|
||||
for solution in potential_solutions {
|
||||
solution.add_to(&mut err);
|
||||
}
|
||||
}
|
||||
|
||||
let impls_of = tcx.trait_impls_of(trait_def_id);
|
||||
let impls = if impls_of.blanket_impls().is_empty() {
|
||||
impls_of
|
||||
.non_blanket_impls()
|
||||
.values()
|
||||
.flatten()
|
||||
.filter(|def_id| {
|
||||
!matches!(tcx.type_of(*def_id).instantiate_identity().kind(), ty::Dynamic(..))
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
} else {
|
||||
vec![]
|
||||
};
|
||||
let externally_visible = if !impls.is_empty()
|
||||
&& let Some(def_id) = trait_def_id.as_local()
|
||||
// We may be executing this during typeck, which would result in cycle
|
||||
// if we used effective_visibilities query, which looks into opaque types
|
||||
// (and therefore calls typeck).
|
||||
&& tcx.resolutions(()).effective_visibilities.is_exported(def_id)
|
||||
{
|
||||
true
|
||||
} else {
|
||||
false
|
||||
};
|
||||
match &impls[..] {
|
||||
[] => {}
|
||||
_ if impls.len() > 9 => {}
|
||||
[only] if externally_visible => {
|
||||
err.help(with_no_trimmed_paths!(format!(
|
||||
"only type `{}` is seen to implement the trait in this crate, consider using it \
|
||||
directly instead",
|
||||
tcx.type_of(*only).instantiate_identity(),
|
||||
)));
|
||||
}
|
||||
[only] => {
|
||||
err.help(with_no_trimmed_paths!(format!(
|
||||
"only type `{}` implements the trait, consider using it directly instead",
|
||||
tcx.type_of(*only).instantiate_identity(),
|
||||
)));
|
||||
}
|
||||
impls => {
|
||||
let types = impls
|
||||
.iter()
|
||||
.map(|t| {
|
||||
with_no_trimmed_paths!(format!(" {}", tcx.type_of(*t).instantiate_identity(),))
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
err.help(format!(
|
||||
"the following types implement the trait, consider defining an enum where each \
|
||||
variant holds one of these types, implementing `{}` for this new enum and using \
|
||||
it instead:\n{}",
|
||||
trait_str,
|
||||
types.join("\n"),
|
||||
));
|
||||
}
|
||||
}
|
||||
if externally_visible {
|
||||
err.note(format!(
|
||||
"`{trait_str}` can be implemented in other crates; if you want to support your users \
|
||||
passing their own types here, you can't refer to a specific type",
|
||||
));
|
||||
}
|
||||
|
||||
err
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
use super::{ObligationCauseCode, PredicateObligation};
|
||||
use crate::error_reporting::traits::fulfillment_errors::InferCtxtPrivExt;
|
||||
use crate::error_reporting::TypeErrCtxt;
|
||||
use crate::errors::{
|
||||
EmptyOnClauseInOnUnimplemented, InvalidOnClauseInOnUnimplemented, NoValueInOnUnimplemented,
|
||||
};
|
||||
@ -13,8 +13,7 @@ use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_errors::{codes::*, struct_span_code_err, ErrorGuaranteed};
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def_id::{DefId, LocalDefId};
|
||||
use rustc_infer::error_reporting::infer::TypeErrCtxt;
|
||||
use rustc_macros::{extension, LintDiagnostic};
|
||||
use rustc_macros::LintDiagnostic;
|
||||
use rustc_middle::bug;
|
||||
use rustc_middle::ty::print::PrintTraitRefExt as _;
|
||||
use rustc_middle::ty::GenericArgsRef;
|
||||
@ -41,7 +40,6 @@ static ALLOWED_FORMAT_SYMBOLS: &[Symbol] = &[
|
||||
sym::Trait,
|
||||
];
|
||||
|
||||
#[extension(pub trait TypeErrCtxtExt<'tcx>)]
|
||||
impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
||||
fn impl_similar_to(
|
||||
&self,
|
||||
@ -109,7 +107,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
fn on_unimplemented_note(
|
||||
pub fn on_unimplemented_note(
|
||||
&self,
|
||||
trait_ref: ty::PolyTraitRef<'tcx>,
|
||||
obligation: &PredicateObligation<'tcx>,
|
||||
|
@ -5,17 +5,14 @@ use rustc_errors::{
|
||||
};
|
||||
use rustc_hir::def::Namespace;
|
||||
use rustc_hir::def_id::LOCAL_CRATE;
|
||||
use rustc_infer::error_reporting::infer::TypeErrCtxt;
|
||||
use rustc_infer::traits::{Obligation, PredicateObligation};
|
||||
use rustc_macros::extension;
|
||||
use rustc_middle::ty::print::{FmtPrinter, Print};
|
||||
use rustc_middle::ty::{self, TyCtxt};
|
||||
use rustc_session::Limit;
|
||||
use rustc_span::Span;
|
||||
use rustc_type_ir::Upcast;
|
||||
|
||||
use super::InferCtxtPrivExt;
|
||||
use crate::error_reporting::traits::suggestions::TypeErrCtxtExt;
|
||||
use crate::error_reporting::TypeErrCtxt;
|
||||
|
||||
pub enum OverflowCause<'tcx> {
|
||||
DeeplyNormalize(ty::AliasTerm<'tcx>),
|
||||
@ -38,7 +35,6 @@ pub fn suggest_new_overflow_limit<'tcx, G: EmissionGuarantee>(
|
||||
));
|
||||
}
|
||||
|
||||
#[extension(pub trait TypeErrCtxtOverflowExt<'a, 'tcx>)]
|
||||
impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
||||
/// Reports that an overflow has occurred and halts compilation. We
|
||||
/// halt compilation unconditionally because it is important that
|
||||
@ -46,7 +42,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
||||
/// whose result could not be truly determined and thus we can't say
|
||||
/// if the program type checks or not -- and they are unusual
|
||||
/// occurrences in any case.
|
||||
fn report_overflow_error(
|
||||
pub fn report_overflow_error(
|
||||
&self,
|
||||
cause: OverflowCause<'tcx>,
|
||||
span: Span,
|
||||
@ -59,7 +55,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
||||
FatalError.raise();
|
||||
}
|
||||
|
||||
fn build_overflow_error(
|
||||
pub fn build_overflow_error(
|
||||
&self,
|
||||
cause: OverflowCause<'tcx>,
|
||||
span: Span,
|
||||
@ -132,7 +128,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
||||
/// whose result could not be truly determined and thus we can't say
|
||||
/// if the program type checks or not -- and they are unusual
|
||||
/// occurrences in any case.
|
||||
fn report_overflow_obligation<T>(
|
||||
pub fn report_overflow_obligation<T>(
|
||||
&self,
|
||||
obligation: &Obligation<'tcx, T>,
|
||||
suggest_increasing_limit: bool,
|
||||
@ -165,7 +161,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
||||
/// that we can give a more helpful error message (and, in particular,
|
||||
/// we do not suggest increasing the overflow limit, which is not
|
||||
/// going to help).
|
||||
fn report_overflow_obligation_cycle(&self, cycle: &[PredicateObligation<'tcx>]) -> ! {
|
||||
pub fn report_overflow_obligation_cycle(&self, cycle: &[PredicateObligation<'tcx>]) -> ! {
|
||||
let cycle = self.resolve_vars_if_possible(cycle.to_owned());
|
||||
assert!(!cycle.is_empty());
|
||||
|
||||
@ -179,7 +175,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
||||
);
|
||||
}
|
||||
|
||||
fn report_overflow_no_abort(
|
||||
pub fn report_overflow_no_abort(
|
||||
&self,
|
||||
obligation: PredicateObligation<'tcx>,
|
||||
suggest_increasing_limit: bool,
|
||||
|
@ -5,11 +5,10 @@ use super::{
|
||||
PredicateObligation,
|
||||
};
|
||||
|
||||
use crate::error_reporting::TypeErrCtxt;
|
||||
use crate::errors;
|
||||
use crate::infer::InferCtxt;
|
||||
use crate::traits::{ImplDerivedCause, NormalizeExt, ObligationCtxt};
|
||||
|
||||
use hir::def::CtorOf;
|
||||
use rustc_data_structures::fx::FxHashSet;
|
||||
use rustc_data_structures::stack::ensure_sufficient_stack;
|
||||
use rustc_errors::{
|
||||
@ -17,15 +16,15 @@ use rustc_errors::{
|
||||
Style, SuggestionStyle,
|
||||
};
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def::CtorOf;
|
||||
use rustc_hir::def::{DefKind, Res};
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_hir::intravisit::Visitor;
|
||||
use rustc_hir::is_range_literal;
|
||||
use rustc_hir::lang_items::LangItem;
|
||||
use rustc_hir::{CoroutineDesugaring, CoroutineKind, CoroutineSource, Expr, HirId, Node};
|
||||
use rustc_infer::error_reporting::infer::TypeErrCtxt;
|
||||
use rustc_infer::infer::InferCtxt;
|
||||
use rustc_infer::infer::{BoundRegionConversionTime, DefineOpaqueTypes, InferOk};
|
||||
use rustc_macros::extension;
|
||||
use rustc_middle::hir::map;
|
||||
use rustc_middle::traits::IsConstable;
|
||||
use rustc_middle::ty::error::TypeError;
|
||||
@ -44,7 +43,6 @@ use std::assert_matches::debug_assert_matches;
|
||||
use std::borrow::Cow;
|
||||
use std::iter;
|
||||
|
||||
use crate::error_reporting::traits::fulfillment_errors::InferCtxtPrivExt;
|
||||
use crate::infer::InferCtxtExt as _;
|
||||
use crate::traits::query::evaluate_obligation::InferCtxtExt as _;
|
||||
use rustc_middle::ty::print::{
|
||||
@ -241,9 +239,8 @@ pub fn suggest_restriction<'tcx, G: EmissionGuarantee>(
|
||||
}
|
||||
}
|
||||
|
||||
#[extension(pub trait TypeErrCtxtExt<'a, 'tcx>)]
|
||||
impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
||||
fn suggest_restricting_param_bound(
|
||||
pub fn suggest_restricting_param_bound(
|
||||
&self,
|
||||
err: &mut Diag<'_>,
|
||||
trait_pred: ty::PolyTraitPredicate<'tcx>,
|
||||
@ -453,7 +450,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
||||
/// When after several dereferencing, the reference satisfies the trait
|
||||
/// bound. This function provides dereference suggestion for this
|
||||
/// specific situation.
|
||||
fn suggest_dereferences(
|
||||
pub(super) fn suggest_dereferences(
|
||||
&self,
|
||||
obligation: &PredicateObligation<'tcx>,
|
||||
err: &mut Diag<'_>,
|
||||
@ -782,7 +779,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
||||
/// We tried to apply the bound to an `fn` or closure. Check whether calling it would
|
||||
/// evaluate to a type that *would* satisfy the trait bound. If it would, suggest calling
|
||||
/// it: `bar(foo)` → `bar(foo())`. This case is *very* likely to be hit if `foo` is `async`.
|
||||
fn suggest_fn_call(
|
||||
pub(super) fn suggest_fn_call(
|
||||
&self,
|
||||
obligation: &PredicateObligation<'tcx>,
|
||||
err: &mut Diag<'_>,
|
||||
@ -898,7 +895,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
||||
true
|
||||
}
|
||||
|
||||
fn check_for_binding_assigned_block_without_tail_expression(
|
||||
pub(super) fn check_for_binding_assigned_block_without_tail_expression(
|
||||
&self,
|
||||
obligation: &PredicateObligation<'tcx>,
|
||||
err: &mut Diag<'_>,
|
||||
@ -974,7 +971,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
fn suggest_add_clone_to_arg(
|
||||
pub(super) fn suggest_add_clone_to_arg(
|
||||
&self,
|
||||
obligation: &PredicateObligation<'tcx>,
|
||||
err: &mut Diag<'_>,
|
||||
@ -1074,7 +1071,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
||||
/// Extracts information about a callable type for diagnostics. This is a
|
||||
/// heuristic -- it doesn't necessarily mean that a type is always callable,
|
||||
/// because the callable type must also be well-formed to be called.
|
||||
fn extract_callable_info(
|
||||
pub fn extract_callable_info(
|
||||
&self,
|
||||
body_id: LocalDefId,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
@ -1200,7 +1197,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
||||
if output.is_ty_var() { None } else { Some((def_id_or_name, output, inputs)) }
|
||||
}
|
||||
|
||||
fn suggest_add_reference_to_arg(
|
||||
pub(super) fn suggest_add_reference_to_arg(
|
||||
&self,
|
||||
obligation: &PredicateObligation<'tcx>,
|
||||
err: &mut Diag<'_>,
|
||||
@ -1422,7 +1419,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
||||
}
|
||||
|
||||
// Suggest borrowing the type
|
||||
fn suggest_borrowing_for_object_cast(
|
||||
pub(super) fn suggest_borrowing_for_object_cast(
|
||||
&self,
|
||||
err: &mut Diag<'_>,
|
||||
obligation: &PredicateObligation<'tcx>,
|
||||
@ -1457,7 +1454,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
||||
|
||||
/// Whenever references are used by mistake, like `for (i, e) in &vec.iter().enumerate()`,
|
||||
/// suggest removing these references until we reach a type that implements the trait.
|
||||
fn suggest_remove_reference(
|
||||
pub(super) fn suggest_remove_reference(
|
||||
&self,
|
||||
obligation: &PredicateObligation<'tcx>,
|
||||
err: &mut Diag<'_>,
|
||||
@ -1578,7 +1575,11 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
||||
false
|
||||
}
|
||||
|
||||
fn suggest_remove_await(&self, obligation: &PredicateObligation<'tcx>, err: &mut Diag<'_>) {
|
||||
pub(super) fn suggest_remove_await(
|
||||
&self,
|
||||
obligation: &PredicateObligation<'tcx>,
|
||||
err: &mut Diag<'_>,
|
||||
) {
|
||||
let hir = self.tcx.hir();
|
||||
if let ObligationCauseCode::AwaitableExpr(hir_id) = obligation.cause.code().peel_derives()
|
||||
&& let hir::Node::Expr(expr) = self.tcx.hir_node(*hir_id)
|
||||
@ -1644,7 +1645,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
||||
|
||||
/// Check if the trait bound is implemented for a different mutability and note it in the
|
||||
/// final error.
|
||||
fn suggest_change_mut(
|
||||
pub(super) fn suggest_change_mut(
|
||||
&self,
|
||||
obligation: &PredicateObligation<'tcx>,
|
||||
err: &mut Diag<'_>,
|
||||
@ -1720,7 +1721,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
fn suggest_semicolon_removal(
|
||||
pub(super) fn suggest_semicolon_removal(
|
||||
&self,
|
||||
obligation: &PredicateObligation<'tcx>,
|
||||
err: &mut Diag<'_>,
|
||||
@ -1762,7 +1763,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
||||
false
|
||||
}
|
||||
|
||||
fn return_type_span(&self, obligation: &PredicateObligation<'tcx>) -> Option<Span> {
|
||||
pub(super) fn return_type_span(&self, obligation: &PredicateObligation<'tcx>) -> Option<Span> {
|
||||
let hir::Node::Item(hir::Item { kind: hir::ItemKind::Fn(sig, ..), .. }) =
|
||||
self.tcx.hir_node_by_def_id(obligation.cause.body_id)
|
||||
else {
|
||||
@ -1775,7 +1776,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
||||
/// If all conditions are met to identify a returned `dyn Trait`, suggest using `impl Trait` if
|
||||
/// applicable and signal that the error has been expanded appropriately and needs to be
|
||||
/// emitted.
|
||||
fn suggest_impl_trait(
|
||||
pub(super) fn suggest_impl_trait(
|
||||
&self,
|
||||
err: &mut Diag<'_>,
|
||||
obligation: &PredicateObligation<'tcx>,
|
||||
@ -1865,7 +1866,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
||||
true
|
||||
}
|
||||
|
||||
fn point_at_returns_when_relevant(
|
||||
pub(super) fn point_at_returns_when_relevant(
|
||||
&self,
|
||||
err: &mut Diag<'_>,
|
||||
obligation: &PredicateObligation<'tcx>,
|
||||
@ -1897,7 +1898,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
fn report_closure_arg_mismatch(
|
||||
pub(super) fn report_closure_arg_mismatch(
|
||||
&self,
|
||||
span: Span,
|
||||
found_span: Option<Span>,
|
||||
@ -2176,7 +2177,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
fn suggest_fully_qualified_path(
|
||||
pub(super) fn suggest_fully_qualified_path(
|
||||
&self,
|
||||
err: &mut Diag<'_>,
|
||||
item_def_id: DefId,
|
||||
@ -2243,7 +2244,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
||||
///
|
||||
/// Returns `true` if an async-await specific note was added to the diagnostic.
|
||||
#[instrument(level = "debug", skip_all, fields(?obligation.predicate, ?obligation.cause.span))]
|
||||
fn maybe_note_obligation_cause_for_async_await<G: EmissionGuarantee>(
|
||||
pub(super) fn maybe_note_obligation_cause_for_async_await<G: EmissionGuarantee>(
|
||||
&self,
|
||||
err: &mut Diag<'_, G>,
|
||||
obligation: &PredicateObligation<'tcx>,
|
||||
@ -2712,7 +2713,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
||||
);
|
||||
}
|
||||
|
||||
fn note_obligation_cause_code<G: EmissionGuarantee, T>(
|
||||
pub(super) fn note_obligation_cause_code<G: EmissionGuarantee, T>(
|
||||
&self,
|
||||
body_id: LocalDefId,
|
||||
err: &mut Diag<'_, G>,
|
||||
@ -3554,7 +3555,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
||||
#[instrument(
|
||||
level = "debug", skip(self, err), fields(trait_pred.self_ty = ?trait_pred.self_ty())
|
||||
)]
|
||||
fn suggest_await_before_try(
|
||||
pub(super) fn suggest_await_before_try(
|
||||
&self,
|
||||
err: &mut Diag<'_>,
|
||||
obligation: &PredicateObligation<'tcx>,
|
||||
@ -3611,7 +3612,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
fn suggest_floating_point_literal(
|
||||
pub(super) fn suggest_floating_point_literal(
|
||||
&self,
|
||||
obligation: &PredicateObligation<'tcx>,
|
||||
err: &mut Diag<'_>,
|
||||
@ -3635,7 +3636,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
fn suggest_derive(
|
||||
pub fn suggest_derive(
|
||||
&self,
|
||||
obligation: &PredicateObligation<'tcx>,
|
||||
err: &mut Diag<'_>,
|
||||
@ -3701,7 +3702,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
fn suggest_dereferencing_index(
|
||||
pub(super) fn suggest_dereferencing_index(
|
||||
&self,
|
||||
obligation: &PredicateObligation<'tcx>,
|
||||
err: &mut Diag<'_>,
|
||||
@ -4323,7 +4324,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
||||
/// If the type that failed selection is an array or a reference to an array,
|
||||
/// but the trait is implemented for slices, suggest that the user converts
|
||||
/// the array into a slice.
|
||||
fn suggest_convert_to_slice(
|
||||
pub(super) fn suggest_convert_to_slice(
|
||||
&self,
|
||||
err: &mut Diag<'_>,
|
||||
obligation: &PredicateObligation<'tcx>,
|
||||
@ -4395,7 +4396,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
fn explain_hrtb_projection(
|
||||
pub(super) fn explain_hrtb_projection(
|
||||
&self,
|
||||
diag: &mut Diag<'_>,
|
||||
pred: ty::PolyTraitPredicate<'tcx>,
|
||||
@ -4461,7 +4462,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
fn suggest_desugaring_async_fn_in_trait(
|
||||
pub(super) fn suggest_desugaring_async_fn_in_trait(
|
||||
&self,
|
||||
err: &mut Diag<'_>,
|
||||
trait_ref: ty::PolyTraitRef<'tcx>,
|
||||
@ -4545,7 +4546,11 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
||||
);
|
||||
}
|
||||
|
||||
fn ty_kind_suggestion(&self, param_env: ty::ParamEnv<'tcx>, ty: Ty<'tcx>) -> Option<String> {
|
||||
pub fn ty_kind_suggestion(
|
||||
&self,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
ty: Ty<'tcx>,
|
||||
) -> Option<String> {
|
||||
let tcx = self.infcx.tcx;
|
||||
let implements_default = |ty| {
|
||||
let Some(default_trait) = tcx.get_diagnostic_item(sym::Default) else {
|
||||
@ -4607,7 +4612,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
||||
})
|
||||
}
|
||||
|
||||
fn suggest_add_result_as_return_type(
|
||||
pub(super) fn suggest_add_result_as_return_type(
|
||||
&self,
|
||||
obligation: &PredicateObligation<'tcx>,
|
||||
err: &mut Diag<'_>,
|
||||
@ -4648,7 +4653,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
||||
}
|
||||
|
||||
#[instrument(level = "debug", skip_all)]
|
||||
fn suggest_unsized_bound_if_applicable(
|
||||
pub(super) fn suggest_unsized_bound_if_applicable(
|
||||
&self,
|
||||
err: &mut Diag<'_>,
|
||||
obligation: &PredicateObligation<'tcx>,
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -173,7 +173,7 @@ impl Subdiagnostic for RegionExplanation<'_> {
|
||||
diag.arg("desc_kind", self.desc.kind);
|
||||
diag.arg("desc_arg", self.desc.arg);
|
||||
|
||||
let msg = f(diag, fluent::infer_region_explanation.into());
|
||||
let msg = f(diag, fluent::trait_selection_region_explanation.into());
|
||||
if let Some(span) = self.desc.span {
|
||||
diag.span_note(span, msg);
|
||||
} else {
|
@ -22,11 +22,14 @@
|
||||
#![feature(control_flow_enum)]
|
||||
#![feature(extract_if)]
|
||||
#![feature(if_let_guard)]
|
||||
#![feature(iter_intersperse)]
|
||||
#![feature(let_chains)]
|
||||
#![feature(never_type)]
|
||||
#![feature(rustdoc_internals)]
|
||||
#![feature(try_blocks)]
|
||||
#![feature(type_alias_impl_trait)]
|
||||
#![feature(unwrap_infallible)]
|
||||
#![feature(yeet_expr)]
|
||||
#![recursion_limit = "512"] // For rustdoc
|
||||
// tidy-alphabetical-end
|
||||
|
||||
|
@ -1,7 +1,8 @@
|
||||
use std::fmt::Debug;
|
||||
use std::marker::PhantomData;
|
||||
|
||||
use crate::error_reporting::traits::{OverflowCause, TypeErrCtxtOverflowExt};
|
||||
use crate::error_reporting::traits::OverflowCause;
|
||||
use crate::error_reporting::InferCtxtErrorExt;
|
||||
use crate::traits::query::evaluate_obligation::InferCtxtExt;
|
||||
use crate::traits::{BoundVarReplacer, PlaceholderReplacer, ScrubbedTraitError};
|
||||
use rustc_data_structures::stack::ensure_sufficient_stack;
|
||||
|
@ -3,7 +3,7 @@ use std::fmt::Debug;
|
||||
|
||||
use super::{FromSolverError, TraitEngine};
|
||||
use super::{FulfillmentContext, ScrubbedTraitError};
|
||||
use crate::error_reporting::traits::TypeErrCtxtExt;
|
||||
use crate::error_reporting::InferCtxtErrorExt;
|
||||
use crate::regions::InferCtxtRegionExt;
|
||||
use crate::solve::FulfillmentCtxt as NextFulfillmentCtxt;
|
||||
use crate::solve::NextSolverError;
|
||||
|
@ -1,4 +1,3 @@
|
||||
use crate::error_reporting::traits::TypeErrCtxtOverflowExt;
|
||||
use crate::infer::{InferCtxt, TyOrConstInferVar};
|
||||
use crate::traits::normalize::normalize_with_depth_to;
|
||||
use rustc_data_structures::captures::Captures;
|
||||
@ -25,6 +24,7 @@ use super::Unimplemented;
|
||||
use super::{const_evaluatable, ScrubbedTraitError};
|
||||
use super::{FulfillmentError, FulfillmentErrorCode};
|
||||
|
||||
use crate::error_reporting::InferCtxtErrorExt;
|
||||
use crate::traits::project::PolyProjectionObligation;
|
||||
use crate::traits::project::ProjectionCacheKeyExt as _;
|
||||
use crate::traits::query::evaluate_obligation::InferCtxtExt;
|
||||
|
@ -22,7 +22,7 @@ mod util;
|
||||
pub mod vtable;
|
||||
pub mod wf;
|
||||
|
||||
use crate::error_reporting::traits::TypeErrCtxtExt as _;
|
||||
use crate::error_reporting::InferCtxtErrorExt;
|
||||
use crate::infer::outlives::env::OutlivesEnvironment;
|
||||
use crate::infer::{InferCtxt, TyCtxtInferExt};
|
||||
use crate::regions::InferCtxtRegionExt;
|
||||
|
@ -3,7 +3,7 @@
|
||||
use super::SelectionContext;
|
||||
use super::{project, with_replaced_escaping_bound_vars, BoundVarReplacer, PlaceholderReplacer};
|
||||
use crate::error_reporting::traits::OverflowCause;
|
||||
use crate::error_reporting::traits::TypeErrCtxtOverflowExt;
|
||||
use crate::error_reporting::InferCtxtErrorExt;
|
||||
use crate::solve::NextSolverError;
|
||||
use rustc_data_structures::stack::ensure_sufficient_stack;
|
||||
use rustc_infer::infer::at::At;
|
||||
|
@ -3,7 +3,7 @@
|
||||
//! `normalize_canonicalized_projection_ty` query when it encounters projections.
|
||||
|
||||
use crate::error_reporting::traits::OverflowCause;
|
||||
use crate::error_reporting::traits::TypeErrCtxtOverflowExt;
|
||||
use crate::error_reporting::InferCtxtErrorExt;
|
||||
use crate::infer::at::At;
|
||||
use crate::infer::canonical::OriginalQueryValues;
|
||||
use crate::infer::{InferCtxt, InferOk};
|
||||
|
@ -18,7 +18,7 @@ use super::{
|
||||
TraitQueryMode,
|
||||
};
|
||||
|
||||
use crate::error_reporting::traits::TypeErrCtxtOverflowExt;
|
||||
use crate::error_reporting::InferCtxtErrorExt;
|
||||
use crate::infer::{InferCtxt, InferCtxtExt, InferOk, TypeFreshener};
|
||||
use crate::solve::InferCtxtSelectExt as _;
|
||||
use crate::traits::normalize::normalize_with_depth;
|
||||
|
@ -7,7 +7,7 @@ use rustc_infer::infer::TyCtxtInferExt;
|
||||
use rustc_middle::bug;
|
||||
use rustc_middle::traits::CodegenObligationError;
|
||||
use rustc_middle::ty::{self, TyCtxt, TypeVisitableExt};
|
||||
use rustc_trait_selection::error_reporting::traits::TypeErrCtxtOverflowExt;
|
||||
use rustc_trait_selection::error_reporting::InferCtxtErrorExt;
|
||||
use rustc_trait_selection::traits::{
|
||||
ImplSource, Obligation, ObligationCause, ObligationCtxt, ScrubbedTraitError, SelectionContext,
|
||||
Unimplemented,
|
||||
|
@ -2,7 +2,7 @@ use rustc_infer::infer::canonical::{Canonical, QueryResponse};
|
||||
use rustc_infer::infer::TyCtxtInferExt;
|
||||
use rustc_middle::query::Providers;
|
||||
use rustc_middle::ty::{ParamEnvAnd, TyCtxt};
|
||||
use rustc_trait_selection::error_reporting::traits::TypeErrCtxtOverflowExt;
|
||||
use rustc_trait_selection::error_reporting::InferCtxtErrorExt;
|
||||
use rustc_trait_selection::infer::InferCtxtBuilderExt;
|
||||
use rustc_trait_selection::traits::query::{
|
||||
normalize::NormalizationResult, CanonicalAliasGoal, NoSolution,
|
||||
|
@ -9,7 +9,6 @@ use rustc_middle::ty::{self, AliasTy, ClauseKind, PredicateKind};
|
||||
use rustc_session::declare_lint_pass;
|
||||
use rustc_span::def_id::LocalDefId;
|
||||
use rustc_span::{sym, Span};
|
||||
use rustc_trait_selection::error_reporting::traits::suggestions::TypeErrCtxtExt;
|
||||
use rustc_trait_selection::traits::{self, FulfillmentError, ObligationCtxt};
|
||||
|
||||
declare_clippy_lint! {
|
||||
|
@ -3,7 +3,7 @@ error[E0308]: mismatched types
|
||||
|
|
||||
LL | const S: A = B;
|
||||
| ^ expected `A`, found `B`
|
||||
-Ztrack-diagnostics: created at compiler/rustc_infer/src/error_reporting/infer/mod.rs:LL:CC
|
||||
-Ztrack-diagnostics: created at compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs:LL:CC
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
|
@ -3,7 +3,7 @@ error[E0308]: mismatched types
|
||||
|
|
||||
LL | const S: A = B;
|
||||
| ^ expected `A`, found `B`
|
||||
-Ztrack-diagnostics: created at compiler/rustc_infer/src/error_reporting/infer/mod.rs:LL:CC
|
||||
-Ztrack-diagnostics: created at compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs:LL:CC
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user