mirror of
https://github.com/rust-lang/rust.git
synced 2025-06-04 19:29:07 +00:00
Move autoderef to rustc_hir_analysis
This commit is contained in:
parent
ef4046e4f3
commit
c8334ce60c
@ -120,3 +120,7 @@ hir_analysis_self_in_impl_self =
|
|||||||
|
|
||||||
hir_analysis_linkage_type =
|
hir_analysis_linkage_type =
|
||||||
invalid type for variable with `#[linkage]` attribute
|
invalid type for variable with `#[linkage]` attribute
|
||||||
|
|
||||||
|
hir_analysis_auto_deref_reached_recursion_limit = reached the recursion limit while auto-dereferencing `{$ty}`
|
||||||
|
.label = deref recursion limit reached
|
||||||
|
.help = consider increasing the recursion limit by adding a `#![recursion_limit = "{$suggested_limit}"]` attribute to your crate (`{$crate_name}`)
|
||||||
|
@ -2,10 +2,6 @@ trait_selection_dump_vtable_entries = vtable entries for `{$trait_ref}`: {$entri
|
|||||||
|
|
||||||
trait_selection_unable_to_construct_constant_value = unable to construct a constant value for the unevaluated constant {$unevaluated}
|
trait_selection_unable_to_construct_constant_value = unable to construct a constant value for the unevaluated constant {$unevaluated}
|
||||||
|
|
||||||
trait_selection_auto_deref_reached_recursion_limit = reached the recursion limit while auto-dereferencing `{$ty}`
|
|
||||||
.label = deref recursion limit reached
|
|
||||||
.help = consider increasing the recursion limit by adding a `#![recursion_limit = "{$suggested_limit}"]` attribute to your crate (`{$crate_name}`)
|
|
||||||
|
|
||||||
trait_selection_empty_on_clause_in_rustc_on_unimplemented = empty `on`-clause in `#[rustc_on_unimplemented]`
|
trait_selection_empty_on_clause_in_rustc_on_unimplemented = empty `on`-clause in `#[rustc_on_unimplemented]`
|
||||||
.label = empty on-clause here
|
.label = empty on-clause here
|
||||||
|
|
||||||
|
@ -178,6 +178,10 @@ impl<'a, 'tcx> Autoderef<'a, 'tcx> {
|
|||||||
self.state.obligations
|
self.state.obligations
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn current_obligations(&self) -> Vec<traits::PredicateObligation<'tcx>> {
|
||||||
|
self.state.obligations.clone()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn steps(&self) -> &[(Ty<'tcx>, AutoderefKind)] {
|
pub fn steps(&self) -> &[(Ty<'tcx>, AutoderefKind)] {
|
||||||
&self.state.steps
|
&self.state.steps
|
||||||
}
|
}
|
@ -1,4 +1,6 @@
|
|||||||
|
use crate::autoderef::Autoderef;
|
||||||
use crate::constrained_generic_params::{identify_constrained_generic_params, Parameter};
|
use crate::constrained_generic_params::{identify_constrained_generic_params, Parameter};
|
||||||
|
|
||||||
use hir::def::DefKind;
|
use hir::def::DefKind;
|
||||||
use rustc_ast as ast;
|
use rustc_ast as ast;
|
||||||
use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexSet};
|
use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexSet};
|
||||||
@ -22,7 +24,6 @@ use rustc_session::parse::feature_err;
|
|||||||
use rustc_span::symbol::{sym, Ident, Symbol};
|
use rustc_span::symbol::{sym, Ident, Symbol};
|
||||||
use rustc_span::{Span, DUMMY_SP};
|
use rustc_span::{Span, DUMMY_SP};
|
||||||
use rustc_target::spec::abi::Abi;
|
use rustc_target::spec::abi::Abi;
|
||||||
use rustc_trait_selection::autoderef::Autoderef;
|
|
||||||
use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt;
|
use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt;
|
||||||
use rustc_trait_selection::traits::outlives_bounds::InferCtxtExt as _;
|
use rustc_trait_selection::traits::outlives_bounds::InferCtxtExt as _;
|
||||||
use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt as _;
|
use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt as _;
|
||||||
|
@ -300,3 +300,15 @@ pub(crate) struct LinkageType {
|
|||||||
#[primary_span]
|
#[primary_span]
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Diagnostic)]
|
||||||
|
#[help]
|
||||||
|
#[diag(hir_analysis_auto_deref_reached_recursion_limit, code = "E0055")]
|
||||||
|
pub struct AutoDerefReachedRecursionLimit<'a> {
|
||||||
|
#[primary_span]
|
||||||
|
#[label]
|
||||||
|
pub span: Span,
|
||||||
|
pub ty: Ty<'a>,
|
||||||
|
pub suggested_limit: rustc_session::Limit,
|
||||||
|
pub crate_name: Symbol,
|
||||||
|
}
|
||||||
|
@ -84,6 +84,7 @@ extern crate rustc_middle;
|
|||||||
pub mod check;
|
pub mod check;
|
||||||
|
|
||||||
pub mod astconv;
|
pub mod astconv;
|
||||||
|
pub mod autoderef;
|
||||||
mod bounds;
|
mod bounds;
|
||||||
mod check_unused;
|
mod check_unused;
|
||||||
mod coherence;
|
mod coherence;
|
||||||
|
@ -2,11 +2,11 @@
|
|||||||
use super::method::MethodCallee;
|
use super::method::MethodCallee;
|
||||||
use super::{FnCtxt, PlaceOp};
|
use super::{FnCtxt, PlaceOp};
|
||||||
|
|
||||||
|
use rustc_hir_analysis::autoderef::{Autoderef, AutoderefKind};
|
||||||
use rustc_infer::infer::InferOk;
|
use rustc_infer::infer::InferOk;
|
||||||
use rustc_middle::ty::adjustment::{Adjust, Adjustment, OverloadedDeref};
|
use rustc_middle::ty::adjustment::{Adjust, Adjustment, OverloadedDeref};
|
||||||
use rustc_middle::ty::{self, Ty};
|
use rustc_middle::ty::{self, Ty};
|
||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
use rustc_trait_selection::autoderef::{Autoderef, AutoderefKind};
|
|
||||||
|
|
||||||
use std::iter;
|
use std::iter;
|
||||||
|
|
||||||
|
@ -8,6 +8,7 @@ use rustc_errors::{struct_span_err, Applicability, Diagnostic, ErrorGuaranteed,
|
|||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
use rustc_hir::def::{self, CtorKind, Namespace, Res};
|
use rustc_hir::def::{self, CtorKind, Namespace, Res};
|
||||||
use rustc_hir::def_id::DefId;
|
use rustc_hir::def_id::DefId;
|
||||||
|
use rustc_hir_analysis::autoderef::Autoderef;
|
||||||
use rustc_infer::{
|
use rustc_infer::{
|
||||||
infer,
|
infer,
|
||||||
traits::{self, Obligation},
|
traits::{self, Obligation},
|
||||||
@ -25,7 +26,6 @@ use rustc_span::def_id::LocalDefId;
|
|||||||
use rustc_span::symbol::{sym, Ident};
|
use rustc_span::symbol::{sym, Ident};
|
||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
use rustc_target::spec::abi;
|
use rustc_target::spec::abi;
|
||||||
use rustc_trait_selection::autoderef::Autoderef;
|
|
||||||
use rustc_trait_selection::infer::InferCtxtExt as _;
|
use rustc_trait_selection::infer::InferCtxtExt as _;
|
||||||
use rustc_trait_selection::traits::error_reporting::DefIdOrName;
|
use rustc_trait_selection::traits::error_reporting::DefIdOrName;
|
||||||
use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt as _;
|
use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt as _;
|
||||||
|
@ -20,7 +20,7 @@ use rustc_middle::ty::subst::GenericArgKind;
|
|||||||
use rustc_middle::ty::{self, Const, Ty, TyCtxt, TypeVisitable};
|
use rustc_middle::ty::{self, Const, Ty, TyCtxt, TypeVisitable};
|
||||||
use rustc_session::Session;
|
use rustc_session::Session;
|
||||||
use rustc_span::symbol::Ident;
|
use rustc_span::symbol::Ident;
|
||||||
use rustc_span::{self, Span};
|
use rustc_span::{self, Span, DUMMY_SP};
|
||||||
use rustc_trait_selection::traits::{ObligationCause, ObligationCauseCode, ObligationCtxt};
|
use rustc_trait_selection::traits::{ObligationCause, ObligationCauseCode, ObligationCtxt};
|
||||||
|
|
||||||
use std::cell::{Cell, RefCell};
|
use std::cell::{Cell, RefCell};
|
||||||
@ -175,6 +175,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
fn_sig
|
fn_sig
|
||||||
})
|
})
|
||||||
}),
|
}),
|
||||||
|
autoderef_steps: Box::new(|ty| {
|
||||||
|
let mut autoderef = self.autoderef(DUMMY_SP, ty).silence_errors();
|
||||||
|
let mut steps = vec![];
|
||||||
|
while let Some((ty, _)) = autoderef.next() {
|
||||||
|
steps.push((ty, autoderef.current_obligations()));
|
||||||
|
}
|
||||||
|
steps
|
||||||
|
}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,6 +9,7 @@ use rustc_data_structures::fx::FxHashSet;
|
|||||||
use rustc_errors::Applicability;
|
use rustc_errors::Applicability;
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
use rustc_hir::def::DefKind;
|
use rustc_hir::def::DefKind;
|
||||||
|
use rustc_hir_analysis::autoderef::{self, Autoderef};
|
||||||
use rustc_infer::infer::canonical::OriginalQueryValues;
|
use rustc_infer::infer::canonical::OriginalQueryValues;
|
||||||
use rustc_infer::infer::canonical::{Canonical, QueryResponse};
|
use rustc_infer::infer::canonical::{Canonical, QueryResponse};
|
||||||
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
|
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
|
||||||
@ -29,7 +30,6 @@ use rustc_span::lev_distance::{
|
|||||||
};
|
};
|
||||||
use rustc_span::symbol::sym;
|
use rustc_span::symbol::sym;
|
||||||
use rustc_span::{symbol::Ident, Span, Symbol, DUMMY_SP};
|
use rustc_span::{symbol::Ident, Span, Symbol, DUMMY_SP};
|
||||||
use rustc_trait_selection::autoderef::{self, Autoderef};
|
|
||||||
use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt;
|
use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt;
|
||||||
use rustc_trait_selection::traits::query::method_autoderef::MethodAutoderefBadTy;
|
use rustc_trait_selection::traits::query::method_autoderef::MethodAutoderefBadTy;
|
||||||
use rustc_trait_selection::traits::query::method_autoderef::{
|
use rustc_trait_selection::traits::query::method_autoderef::{
|
||||||
|
@ -3,6 +3,7 @@ use crate::{has_expected_num_generic_args, FnCtxt, PlaceOp};
|
|||||||
use rustc_ast as ast;
|
use rustc_ast as ast;
|
||||||
use rustc_errors::Applicability;
|
use rustc_errors::Applicability;
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
|
use rustc_hir_analysis::autoderef::Autoderef;
|
||||||
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
|
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
|
||||||
use rustc_infer::infer::InferOk;
|
use rustc_infer::infer::InferOk;
|
||||||
use rustc_middle::ty::adjustment::{Adjust, Adjustment, OverloadedDeref, PointerCast};
|
use rustc_middle::ty::adjustment::{Adjust, Adjustment, OverloadedDeref, PointerCast};
|
||||||
@ -10,7 +11,6 @@ use rustc_middle::ty::adjustment::{AllowTwoPhase, AutoBorrow, AutoBorrowMutabili
|
|||||||
use rustc_middle::ty::{self, Ty};
|
use rustc_middle::ty::{self, Ty};
|
||||||
use rustc_span::symbol::{sym, Ident};
|
use rustc_span::symbol::{sym, Ident};
|
||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
use rustc_trait_selection::autoderef::Autoderef;
|
|
||||||
use std::slice;
|
use std::slice;
|
||||||
|
|
||||||
impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
|
@ -55,6 +55,7 @@ use crate::infer::ExpectedFound;
|
|||||||
use crate::traits::error_reporting::report_object_safety_error;
|
use crate::traits::error_reporting::report_object_safety_error;
|
||||||
use crate::traits::{
|
use crate::traits::{
|
||||||
IfExpressionCause, MatchExpressionArmCause, ObligationCause, ObligationCauseCode,
|
IfExpressionCause, MatchExpressionArmCause, ObligationCause, ObligationCauseCode,
|
||||||
|
PredicateObligation,
|
||||||
};
|
};
|
||||||
|
|
||||||
use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
|
use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
|
||||||
@ -91,8 +92,12 @@ pub mod nice_region_error;
|
|||||||
pub struct TypeErrCtxt<'a, 'tcx> {
|
pub struct TypeErrCtxt<'a, 'tcx> {
|
||||||
pub infcx: &'a InferCtxt<'tcx>,
|
pub infcx: &'a InferCtxt<'tcx>,
|
||||||
pub typeck_results: Option<std::cell::Ref<'a, ty::TypeckResults<'tcx>>>,
|
pub typeck_results: Option<std::cell::Ref<'a, ty::TypeckResults<'tcx>>>,
|
||||||
pub normalize_fn_sig: Box<dyn Fn(ty::PolyFnSig<'tcx>) -> ty::PolyFnSig<'tcx> + 'a>,
|
|
||||||
pub fallback_has_occurred: bool,
|
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 TypeErrCtxt<'_, '_> {
|
impl TypeErrCtxt<'_, '_> {
|
||||||
|
@ -688,6 +688,10 @@ impl<'tcx> InferCtxt<'tcx> {
|
|||||||
typeck_results: None,
|
typeck_results: None,
|
||||||
fallback_has_occurred: false,
|
fallback_has_occurred: false,
|
||||||
normalize_fn_sig: Box::new(|fn_sig| fn_sig),
|
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![])]
|
||||||
|
}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
use rustc_errors::{fluent, ErrorGuaranteed, Handler, IntoDiagnostic};
|
use rustc_errors::{fluent, ErrorGuaranteed, Handler, IntoDiagnostic};
|
||||||
use rustc_macros::Diagnostic;
|
use rustc_macros::Diagnostic;
|
||||||
use rustc_middle::ty::{self, PolyTraitRef, Ty};
|
use rustc_middle::ty::{self, PolyTraitRef, Ty};
|
||||||
use rustc_session::Limit;
|
|
||||||
use rustc_span::{Span, Symbol};
|
use rustc_span::{Span, Symbol};
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
@ -21,18 +20,6 @@ pub struct UnableToConstructConstantValue<'a> {
|
|||||||
pub unevaluated: ty::UnevaluatedConst<'a>,
|
pub unevaluated: ty::UnevaluatedConst<'a>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
|
||||||
#[help]
|
|
||||||
#[diag(trait_selection_auto_deref_reached_recursion_limit, code = "E0055")]
|
|
||||||
pub struct AutoDerefReachedRecursionLimit<'a> {
|
|
||||||
#[primary_span]
|
|
||||||
#[label]
|
|
||||||
pub span: Span,
|
|
||||||
pub ty: Ty<'a>,
|
|
||||||
pub suggested_limit: Limit,
|
|
||||||
pub crate_name: Symbol,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(trait_selection_empty_on_clause_in_rustc_on_unimplemented, code = "E0232")]
|
#[diag(trait_selection_empty_on_clause_in_rustc_on_unimplemented, code = "E0232")]
|
||||||
pub struct EmptyOnClauseInOnUnimplemented {
|
pub struct EmptyOnClauseInOnUnimplemented {
|
||||||
|
@ -35,7 +35,6 @@ extern crate rustc_middle;
|
|||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate smallvec;
|
extern crate smallvec;
|
||||||
|
|
||||||
pub mod autoderef;
|
|
||||||
pub mod errors;
|
pub mod errors;
|
||||||
pub mod infer;
|
pub mod infer;
|
||||||
pub mod solve;
|
pub mod solve;
|
||||||
|
@ -5,7 +5,6 @@ use super::{
|
|||||||
PredicateObligation,
|
PredicateObligation,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::autoderef::Autoderef;
|
|
||||||
use crate::infer::InferCtxt;
|
use crate::infer::InferCtxt;
|
||||||
use crate::traits::{NormalizeExt, ObligationCtxt};
|
use crate::traits::{NormalizeExt, ObligationCtxt};
|
||||||
|
|
||||||
@ -750,26 +749,30 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if let ty::Ref(region, base_ty, mutbl) = *real_ty.skip_binder().kind() {
|
if let ty::Ref(region, base_ty, mutbl) = *real_ty.skip_binder().kind() {
|
||||||
let mut autoderef = Autoderef::new(
|
let autoderef = (self.autoderef_steps)(base_ty);
|
||||||
self,
|
if let Some(steps) =
|
||||||
obligation.param_env,
|
autoderef.into_iter().enumerate().find_map(|(steps, (ty, obligations))| {
|
||||||
obligation.cause.body_id,
|
// Re-add the `&`
|
||||||
span,
|
let ty = self.tcx.mk_ref(region, TypeAndMut { ty, mutbl });
|
||||||
base_ty,
|
|
||||||
);
|
|
||||||
if let Some(steps) = autoderef.find_map(|(ty, steps)| {
|
|
||||||
// Re-add the `&`
|
|
||||||
let ty = self.tcx.mk_ref(region, TypeAndMut { ty, mutbl });
|
|
||||||
|
|
||||||
// Remapping bound vars here
|
// Remapping bound vars here
|
||||||
let real_trait_pred_and_ty =
|
let real_trait_pred_and_ty =
|
||||||
real_trait_pred.map_bound(|inner_trait_pred| (inner_trait_pred, ty));
|
real_trait_pred.map_bound(|inner_trait_pred| (inner_trait_pred, ty));
|
||||||
let obligation = self.mk_trait_obligation_with_new_self_ty(
|
let obligation = self.mk_trait_obligation_with_new_self_ty(
|
||||||
obligation.param_env,
|
obligation.param_env,
|
||||||
real_trait_pred_and_ty,
|
real_trait_pred_and_ty,
|
||||||
);
|
);
|
||||||
Some(steps).filter(|_| self.predicate_may_hold(&obligation))
|
if obligations
|
||||||
}) {
|
.iter()
|
||||||
|
.chain([&obligation])
|
||||||
|
.all(|obligation| self.predicate_may_hold(obligation))
|
||||||
|
{
|
||||||
|
Some(steps)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
})
|
||||||
|
{
|
||||||
if steps > 0 {
|
if steps > 0 {
|
||||||
// Don't care about `&mut` because `DerefMut` is used less
|
// Don't care about `&mut` because `DerefMut` is used less
|
||||||
// often and user will not expect autoderef happens.
|
// often and user will not expect autoderef happens.
|
||||||
|
Loading…
Reference in New Issue
Block a user