mirror of https://github.com/rust-lang/rust.git
Actually just make can_eq process obligations (almost) everywhere
This commit is contained in:
parent
fdde66acee
commit
fb8d5f1e13
|
@ -21,6 +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::infer::InferCtxtExt;
|
||||
use rustc_trait_selection::regions::InferCtxtRegionExt;
|
||||
use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt;
|
||||
use rustc_trait_selection::traits::outlives_bounds::InferCtxtExt as _;
|
||||
|
|
|
@ -29,6 +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::infer::InferCtxtExt;
|
||||
use rustc_trait_selection::regions::InferCtxtRegionExt;
|
||||
use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt;
|
||||
use rustc_trait_selection::traits::misc::{
|
||||
|
@ -1712,15 +1713,7 @@ fn receiver_is_valid<'tcx>(
|
|||
let cause =
|
||||
ObligationCause::new(span, wfcx.body_def_id, traits::ObligationCauseCode::MethodReceiver);
|
||||
|
||||
let can_eq_self = |ty| {
|
||||
wfcx.infcx.probe(|_| {
|
||||
let ocx = ObligationCtxt::new(wfcx.infcx);
|
||||
let Ok(()) = ocx.eq(&ObligationCause::dummy(), wfcx.param_env, self_ty, ty) else {
|
||||
return false;
|
||||
};
|
||||
ocx.select_where_possible().is_empty()
|
||||
})
|
||||
};
|
||||
let can_eq_self = |ty| infcx.can_eq(wfcx.param_env, self_ty, ty);
|
||||
|
||||
// `self: Self` is always valid.
|
||||
if can_eq_self(receiver_ty) {
|
||||
|
|
|
@ -49,6 +49,7 @@ use rustc_span::edit_distance::find_best_match_for_name;
|
|||
use rustc_span::symbol::{kw, Ident, Symbol};
|
||||
use rustc_span::{sym, Span, DUMMY_SP};
|
||||
use rustc_target::spec::abi;
|
||||
use rustc_trait_selection::infer::InferCtxtExt;
|
||||
use rustc_trait_selection::traits::wf::object_region_bounds;
|
||||
use rustc_trait_selection::traits::{self, ObligationCtxt};
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@ use rustc_middle::ty::print::with_no_trimmed_paths;
|
|||
use rustc_middle::ty::{self, AssocItem, Ty, TypeFoldable, TypeVisitableExt};
|
||||
use rustc_span::symbol::sym;
|
||||
use rustc_span::{Span, DUMMY_SP};
|
||||
use rustc_trait_selection::infer::InferCtxtExt;
|
||||
use rustc_trait_selection::traits::ObligationCause;
|
||||
|
||||
use super::method::probe;
|
||||
|
|
|
@ -40,6 +40,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::infer::InferCtxtExt;
|
||||
use rustc_trait_selection::traits::{self, ObligationCauseCode, SelectionContext};
|
||||
|
||||
use std::iter;
|
||||
|
|
|
@ -2582,7 +2582,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
(hir::ExprKind::AddrOf(hir::BorrowKind::Ref, _, expr), _, &ty::Ref(_, checked, _))
|
||||
if self.can_sub(self.param_env, checked, expected) =>
|
||||
if self.can_eq(self.param_env, checked, expected) =>
|
||||
{
|
||||
let make_sugg = |start: Span, end: BytePos| {
|
||||
// skip `(` for tuples such as `(c) = (&123)`.
|
||||
|
|
|
@ -33,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::infer::InferCtxtExt as _;
|
||||
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::{
|
||||
|
@ -857,7 +858,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
|
|||
let args = self.fresh_args_for_item(self.span, method.def_id);
|
||||
let fty = self.tcx.fn_sig(method.def_id).instantiate(self.tcx, args);
|
||||
let fty = self.instantiate_binder_with_fresh_vars(self.span, infer::FnCall, fty);
|
||||
self.can_sub(self.param_env, fty.output(), expected)
|
||||
self.can_eq(self.param_env, fty.output(), expected)
|
||||
}),
|
||||
_ => false,
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@ use rustc_span::source_map::Spanned;
|
|||
use rustc_span::symbol::{kw, sym, Ident};
|
||||
use rustc_span::{BytePos, Span, DUMMY_SP};
|
||||
use rustc_target::abi::FieldIdx;
|
||||
use rustc_trait_selection::infer::InferCtxtExt;
|
||||
use rustc_trait_selection::traits::{ObligationCause, ObligationCauseCode};
|
||||
use ty::VariantDef;
|
||||
|
||||
|
|
|
@ -820,7 +820,7 @@ fn foo(&self) -> Self::T { String::new() }
|
|||
tcx.defaultness(item.id.owner_id)
|
||||
{
|
||||
let assoc_ty = tcx.type_of(item.id.owner_id).instantiate_identity();
|
||||
if self.infcx.can_eq(param_env, assoc_ty, found) {
|
||||
if self.infcx.can_eq_shallow(param_env, assoc_ty, found) {
|
||||
diag.span_label(
|
||||
item.span,
|
||||
"associated type defaults can't be assumed inside the \
|
||||
|
@ -843,7 +843,7 @@ fn foo(&self) -> Self::T { String::new() }
|
|||
let assoc_ty = tcx.type_of(item.id.owner_id).instantiate_identity();
|
||||
if let hir::Defaultness::Default { has_value: true } =
|
||||
tcx.defaultness(item.id.owner_id)
|
||||
&& self.infcx.can_eq(param_env, assoc_ty, found)
|
||||
&& self.infcx.can_eq_shallow(param_env, assoc_ty, found)
|
||||
{
|
||||
diag.span_label(
|
||||
item.span,
|
||||
|
|
|
@ -769,21 +769,7 @@ impl<'tcx> InferCtxt<'tcx> {
|
|||
|
||||
// FIXME(-Znext-solver): Get rid of this method, it's never correct. Either that,
|
||||
// or we need to process the obligations.
|
||||
pub fn can_sub<T>(&self, param_env: ty::ParamEnv<'tcx>, expected: T, actual: T) -> bool
|
||||
where
|
||||
T: at::ToTrace<'tcx>,
|
||||
{
|
||||
let origin = &ObligationCause::dummy();
|
||||
self.probe(|_| {
|
||||
// We're only answering whether there could be a subtyping relation, and with
|
||||
// opaque types, "there could be one", via registering a hidden type.
|
||||
self.at(origin, param_env).sub(DefineOpaqueTypes::Yes, expected, actual).is_ok()
|
||||
})
|
||||
}
|
||||
|
||||
// FIXME(-Znext-solver): Get rid of this method, it's never correct. Either that,
|
||||
// or we need to process the obligations.
|
||||
pub fn can_eq<T>(&self, param_env: ty::ParamEnv<'tcx>, a: T, b: T) -> bool
|
||||
pub fn can_eq_shallow<T>(&self, param_env: ty::ParamEnv<'tcx>, a: T, b: T) -> bool
|
||||
where
|
||||
T: at::ToTrace<'tcx>,
|
||||
{
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
use crate::infer::at::ToTrace;
|
||||
use crate::traits::query::evaluate_obligation::InferCtxtExt as _;
|
||||
use crate::traits::{self, Obligation, ObligationCause, ObligationCtxt, SelectionContext};
|
||||
|
||||
|
@ -17,6 +18,16 @@ pub use rustc_infer::infer::*;
|
|||
|
||||
#[extension(pub trait InferCtxtExt<'tcx>)]
|
||||
impl<'tcx> InferCtxt<'tcx> {
|
||||
fn can_eq<T: ToTrace<'tcx>>(&self, param_env: ty::ParamEnv<'tcx>, a: T, b: T) -> bool {
|
||||
self.probe(|_| {
|
||||
let ocx = ObligationCtxt::new(self);
|
||||
let Ok(()) = ocx.eq(&ObligationCause::dummy(), param_env, a, b) else {
|
||||
return false;
|
||||
};
|
||||
ocx.select_where_possible().is_empty()
|
||||
})
|
||||
}
|
||||
|
||||
fn type_is_copy_modulo_regions(&self, param_env: ty::ParamEnv<'tcx>, ty: Ty<'tcx>) -> bool {
|
||||
let ty = self.resolve_vars_if_possible(ty);
|
||||
|
||||
|
|
|
@ -1,5 +1,10 @@
|
|||
use super::{ObligationCauseCode, PredicateObligation};
|
||||
use crate::errors::{
|
||||
EmptyOnClauseInOnUnimplemented, InvalidOnClauseInOnUnimplemented, NoValueInOnUnimplemented,
|
||||
};
|
||||
use crate::infer::error_reporting::TypeErrCtxt;
|
||||
use crate::infer::InferCtxtExt;
|
||||
use crate::traits::error_reporting::type_err_ctxt_ext::InferCtxtPrivExt;
|
||||
use rustc_ast::AttrArgs;
|
||||
use rustc_ast::AttrArgsEq;
|
||||
use rustc_ast::AttrKind;
|
||||
|
@ -21,12 +26,6 @@ use rustc_span::Span;
|
|||
use std::iter;
|
||||
use std::path::PathBuf;
|
||||
|
||||
use crate::errors::{
|
||||
EmptyOnClauseInOnUnimplemented, InvalidOnClauseInOnUnimplemented, NoValueInOnUnimplemented,
|
||||
};
|
||||
|
||||
use crate::traits::error_reporting::type_err_ctxt_ext::InferCtxtPrivExt;
|
||||
|
||||
/// The symbols which are always allowed in a format string
|
||||
static ALLOWED_FORMAT_SYMBOLS: &[Symbol] = &[
|
||||
kw::SelfUpper,
|
||||
|
|
|
@ -1073,7 +1073,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
|||
// mismatched, then we have a totally different error to report.
|
||||
if self.enter_forall(found_args, |found_args| {
|
||||
self.enter_forall(expected_args, |expected_args| {
|
||||
!self.can_sub(obligation.param_env, expected_args, found_args)
|
||||
!self.can_eq(obligation.param_env, expected_args, found_args)
|
||||
})
|
||||
}) {
|
||||
return None;
|
||||
|
|
|
@ -18,7 +18,7 @@ use super::{
|
|||
TraitQueryMode,
|
||||
};
|
||||
|
||||
use crate::infer::{InferCtxt, InferOk, TypeFreshener};
|
||||
use crate::infer::{InferCtxt, InferCtxtExt, InferOk, TypeFreshener};
|
||||
use crate::solve::InferCtxtSelectExt as _;
|
||||
use crate::traits::error_reporting::TypeErrCtxtExt;
|
||||
use crate::traits::normalize::normalize_with_depth;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
error[E0277]: the trait bound `i32: Baz<Self>` is not satisfied
|
||||
error[E0277]: the trait bound `<Self as Foo>::Bar<()>: Eq<i32>` is not satisfied
|
||||
--> $DIR/assume-gat-normalization-for-nested-goals.rs:9:30
|
||||
|
|
||||
LL | type Bar<T>: Baz<Self> = i32;
|
||||
|
|
|
@ -5,7 +5,7 @@ fn fine(x: impl Into<u32>) -> impl Into<u32> { x }
|
|||
|
||||
fn bad_in_ret_position(x: impl Into<u32>) -> impl Into<impl Debug> { x }
|
||||
//~^ ERROR nested `impl Trait` is not allowed
|
||||
//~| ERROR the trait bound `impl Into<u32>: Into<impl Debug>` is not satisfied
|
||||
//~| ERROR the trait bound `impl Debug: From<impl Into<u32>>` is not satisfied
|
||||
|
||||
fn bad_in_fn_syntax(x: fn() -> impl Into<impl Debug>) {}
|
||||
//~^ ERROR nested `impl Trait` is not allowed
|
||||
|
@ -18,7 +18,7 @@ struct X;
|
|||
impl X {
|
||||
fn bad(x: impl Into<u32>) -> impl Into<impl Debug> { x }
|
||||
//~^ ERROR nested `impl Trait` is not allowed
|
||||
//~| ERROR the trait bound `impl Into<u32>: Into<impl Debug>` is not satisfied
|
||||
//~| ERROR the trait bound `impl Debug: From<impl Into<u32>>` is not satisfied
|
||||
}
|
||||
|
||||
fn allowed_in_assoc_type() -> impl Iterator<Item=impl Fn()> {
|
||||
|
|
|
@ -42,7 +42,7 @@ LL | fn bad_in_fn_syntax(x: fn() -> impl Into<impl Debug>) {}
|
|||
|
|
||||
= note: `impl Trait` is only allowed in arguments and return types of functions and methods
|
||||
|
||||
error[E0277]: the trait bound `impl Into<u32>: Into<impl Debug>` is not satisfied
|
||||
error[E0277]: the trait bound `impl Debug: From<impl Into<u32>>` is not satisfied
|
||||
--> $DIR/nested_impl_trait.rs:6:46
|
||||
|
|
||||
LL | fn bad_in_ret_position(x: impl Into<u32>) -> impl Into<impl Debug> { x }
|
||||
|
@ -51,7 +51,7 @@ LL | fn bad_in_ret_position(x: impl Into<u32>) -> impl Into<impl Debug> { x }
|
|||
= help: the trait `Into<U>` is implemented for `T`
|
||||
= note: required for `impl Into<u32>` to implement `Into<impl Debug>`
|
||||
|
||||
error[E0277]: the trait bound `impl Into<u32>: Into<impl Debug>` is not satisfied
|
||||
error[E0277]: the trait bound `impl Debug: From<impl Into<u32>>` is not satisfied
|
||||
--> $DIR/nested_impl_trait.rs:19:34
|
||||
|
|
||||
LL | fn bad(x: impl Into<u32>) -> impl Into<impl Debug> { x }
|
||||
|
|
|
@ -17,10 +17,6 @@ note: required by a bound in `is_send`
|
|||
|
|
||||
LL | fn is_send(_: impl Send) {}
|
||||
| ^^^^ required by this bound in `is_send`
|
||||
help: consider dereferencing here
|
||||
|
|
||||
LL | is_send(*foo());
|
||||
| +
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ LL | fn bar(self: Bar<u32>) {
|
|||
= help: consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)
|
||||
|
||||
error[E0307]: invalid `self` parameter type: `&Bar<u32>`
|
||||
--> $DIR/method_resolution3.rs:21:18
|
||||
--> $DIR/method_resolution3.rs:20:18
|
||||
|
|
||||
LL | fn baz(self: &Bar<u32>) {
|
||||
| ^^^^^^^^^
|
||||
|
|
|
@ -1,15 +1,21 @@
|
|||
error[E0271]: type mismatch resolving `Foo == u32`
|
||||
error[E0307]: invalid `self` parameter type: `Bar<u32>`
|
||||
--> $DIR/method_resolution3.rs:16:18
|
||||
|
|
||||
LL | fn bar(self: Bar<u32>) {
|
||||
| ^^^^^^^^ types differ
|
||||
| ^^^^^^^^
|
||||
|
|
||||
= note: type of `self` must be `Self` or a type that dereferences to it
|
||||
= help: consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)
|
||||
|
||||
error[E0271]: type mismatch resolving `Foo == u32`
|
||||
--> $DIR/method_resolution3.rs:21:18
|
||||
error[E0307]: invalid `self` parameter type: `&Bar<u32>`
|
||||
--> $DIR/method_resolution3.rs:20:18
|
||||
|
|
||||
LL | fn baz(self: &Bar<u32>) {
|
||||
| ^^^^^^^^^ types differ
|
||||
| ^^^^^^^^^
|
||||
|
|
||||
= note: type of `self` must be `Self` or a type that dereferences to it
|
||||
= help: consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0271`.
|
||||
For more information about this error, try `rustc --explain E0307`.
|
||||
|
|
|
@ -14,13 +14,11 @@ struct Bar<T>(T);
|
|||
|
||||
impl Bar<Foo> {
|
||||
fn bar(self: Bar<u32>) {
|
||||
//[current]~^ ERROR: invalid `self` parameter
|
||||
//[next]~^^ ERROR: type mismatch resolving `Foo == u32`
|
||||
//~^ ERROR: invalid `self` parameter
|
||||
self.foo()
|
||||
}
|
||||
fn baz(self: &Bar<u32>) {
|
||||
//[current]~^ ERROR: invalid `self` parameter
|
||||
//[next]~^^ ERROR: type mismatch resolving `Foo == u32`
|
||||
//~^ ERROR: invalid `self` parameter
|
||||
self.foo()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@ LL | fn foo(self: Bar<Foo>) {
|
|||
= help: consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)
|
||||
|
||||
error[E0307]: invalid `self` parameter type: `&Bar<Foo>`
|
||||
--> $DIR/method_resolution4.rs:32:20
|
||||
--> $DIR/method_resolution4.rs:31:20
|
||||
|
|
||||
LL | fn foomp(self: &Bar<Foo>) {
|
||||
| ^^^^^^^^^
|
||||
|
|
|
@ -1,15 +1,21 @@
|
|||
error[E0271]: type mismatch resolving `u32 == Foo`
|
||||
error[E0307]: invalid `self` parameter type: `Bar<Foo>`
|
||||
--> $DIR/method_resolution4.rs:27:18
|
||||
|
|
||||
LL | fn foo(self: Bar<Foo>) {
|
||||
| ^^^^^^^^ types differ
|
||||
| ^^^^^^^^
|
||||
|
|
||||
= note: type of `self` must be `Self` or a type that dereferences to it
|
||||
= help: consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)
|
||||
|
||||
error[E0271]: type mismatch resolving `u32 == Foo`
|
||||
--> $DIR/method_resolution4.rs:32:20
|
||||
error[E0307]: invalid `self` parameter type: `&Bar<Foo>`
|
||||
--> $DIR/method_resolution4.rs:31:20
|
||||
|
|
||||
LL | fn foomp(self: &Bar<Foo>) {
|
||||
| ^^^^^^^^^ types differ
|
||||
| ^^^^^^^^^
|
||||
|
|
||||
= note: type of `self` must be `Self` or a type that dereferences to it
|
||||
= help: consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0271`.
|
||||
For more information about this error, try `rustc --explain E0307`.
|
||||
|
|
|
@ -25,13 +25,11 @@ impl Bar<Foo> {
|
|||
|
||||
impl Bar<u32> {
|
||||
fn foo(self: Bar<Foo>) {
|
||||
//[current]~^ ERROR: invalid `self` parameter
|
||||
//[next]~^^ ERROR: type mismatch resolving `u32 == Foo`
|
||||
//~^ ERROR: invalid `self` parameter
|
||||
self.bar()
|
||||
}
|
||||
fn foomp(self: &Bar<Foo>) {
|
||||
//[current]~^ ERROR: invalid `self` parameter
|
||||
//[next]~^^ ERROR: type mismatch resolving `u32 == Foo`
|
||||
//~^ ERROR: invalid `self` parameter
|
||||
self.bar()
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue