mirror of https://github.com/rust-lang/rust.git
Auto merge of #127172 - compiler-errors:full-can_eq-everywhere, r=lcnr
Make `can_eq` process obligations (almost) everywhere Move `can_eq` to an extension trait on `InferCtxt` in `rustc_trait_selection`, and change it so that it processes obligations. This should strengthen it to be more accurate in some cases, but is most important for the new trait solver which delays relating aliases to `AliasRelate` goals. Without this, we always basically just return true when passing aliases to `can_eq`, which can lead to weird errors, for example #127149. I'm not actually certain if we should *have* `can_eq` be called on the good path. In cases where we need `can_eq`, we probably should just be using a regular probe. Fixes #127149 r? lcnr
This commit is contained in:
commit
89aefb9c53
|
@ -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 _;
|
||||
|
|
|
@ -39,6 +39,7 @@ use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt as _
|
|||
use rustc_trait_selection::traits::{
|
||||
self, FulfillmentError, ObligationCause, ObligationCauseCode, ObligationCtxt, WellFormedLoc,
|
||||
};
|
||||
use rustc_type_ir::solve::NoSolution;
|
||||
use rustc_type_ir::TypeFlags;
|
||||
|
||||
use std::cell::LazyCell;
|
||||
|
@ -1712,13 +1713,12 @@ fn receiver_is_valid<'tcx>(
|
|||
let cause =
|
||||
ObligationCause::new(span, wfcx.body_def_id, traits::ObligationCauseCode::MethodReceiver);
|
||||
|
||||
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) {
|
||||
if let Err(err) = wfcx.eq(&cause, wfcx.param_env, self_ty, receiver_ty) {
|
||||
infcx.err_ctxt().report_mismatched_types(&cause, self_ty, receiver_ty, err).emit();
|
||||
}
|
||||
// Special case `receiver == self_ty`, which doesn't necessarily require the `Receiver` lang item.
|
||||
if let Ok(()) = wfcx.infcx.commit_if_ok(|_| {
|
||||
let ocx = ObligationCtxt::new(wfcx.infcx);
|
||||
ocx.eq(&cause, wfcx.param_env, self_ty, receiver_ty)?;
|
||||
if ocx.select_all_or_error().is_empty() { Ok(()) } else { Err(NoSolution) }
|
||||
}) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1729,58 +1729,51 @@ fn receiver_is_valid<'tcx>(
|
|||
autoderef = autoderef.include_raw_pointers();
|
||||
}
|
||||
|
||||
// The first type is `receiver_ty`, which we know its not equal to `self_ty`; skip it.
|
||||
autoderef.next();
|
||||
|
||||
let receiver_trait_def_id = tcx.require_lang_item(LangItem::Receiver, Some(span));
|
||||
|
||||
// Keep dereferencing `receiver_ty` until we get to `self_ty`.
|
||||
loop {
|
||||
if let Some((potential_self_ty, _)) = autoderef.next() {
|
||||
debug!(
|
||||
"receiver_is_valid: potential self type `{:?}` to match `{:?}`",
|
||||
potential_self_ty, self_ty
|
||||
);
|
||||
while let Some((potential_self_ty, _)) = autoderef.next() {
|
||||
debug!(
|
||||
"receiver_is_valid: potential self type `{:?}` to match `{:?}`",
|
||||
potential_self_ty, self_ty
|
||||
);
|
||||
|
||||
if can_eq_self(potential_self_ty) {
|
||||
wfcx.register_obligations(autoderef.into_obligations());
|
||||
|
||||
if let Err(err) = wfcx.eq(&cause, wfcx.param_env, self_ty, potential_self_ty) {
|
||||
infcx
|
||||
.err_ctxt()
|
||||
.report_mismatched_types(&cause, self_ty, potential_self_ty, err)
|
||||
.emit();
|
||||
}
|
||||
// Check if the self type unifies. If it does, then commit the result
|
||||
// since it may have region side-effects.
|
||||
if let Ok(()) = wfcx.infcx.commit_if_ok(|_| {
|
||||
let ocx = ObligationCtxt::new(wfcx.infcx);
|
||||
ocx.eq(&cause, wfcx.param_env, self_ty, potential_self_ty)?;
|
||||
if ocx.select_all_or_error().is_empty() { Ok(()) } else { Err(NoSolution) }
|
||||
}) {
|
||||
wfcx.register_obligations(autoderef.into_obligations());
|
||||
return true;
|
||||
}
|
||||
|
||||
// Without `feature(arbitrary_self_types)`, we require that each step in the
|
||||
// deref chain implement `receiver`.
|
||||
if !arbitrary_self_types_enabled {
|
||||
if !receiver_is_implemented(
|
||||
wfcx,
|
||||
receiver_trait_def_id,
|
||||
cause.clone(),
|
||||
potential_self_ty,
|
||||
) {
|
||||
// We cannot proceed.
|
||||
break;
|
||||
} else {
|
||||
// Without `feature(arbitrary_self_types)`, we require that each step in the
|
||||
// deref chain implement `receiver`
|
||||
if !arbitrary_self_types_enabled
|
||||
&& !receiver_is_implemented(
|
||||
wfcx,
|
||||
receiver_trait_def_id,
|
||||
cause.clone(),
|
||||
potential_self_ty,
|
||||
)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
debug!("receiver_is_valid: type `{:?}` does not deref to `{:?}`", receiver_ty, self_ty);
|
||||
return false;
|
||||
|
||||
// Register the bound, in case it has any region side-effects.
|
||||
wfcx.register_bound(
|
||||
cause.clone(),
|
||||
wfcx.param_env,
|
||||
potential_self_ty,
|
||||
receiver_trait_def_id,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Without `feature(arbitrary_self_types)`, we require that `receiver_ty` implements `Receiver`.
|
||||
if !arbitrary_self_types_enabled
|
||||
&& !receiver_is_implemented(wfcx, receiver_trait_def_id, cause.clone(), receiver_ty)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
true
|
||||
debug!("receiver_is_valid: type `{:?}` does not deref to `{:?}`", receiver_ty, self_ty);
|
||||
false
|
||||
}
|
||||
|
||||
fn receiver_is_implemented<'tcx>(
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -768,19 +768,9 @@ impl<'tcx> InferCtxt<'tcx> {
|
|||
.collect()
|
||||
}
|
||||
|
||||
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()
|
||||
})
|
||||
}
|
||||
|
||||
pub fn can_eq<T>(&self, param_env: ty::ParamEnv<'tcx>, a: T, b: T) -> bool
|
||||
// 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_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 }
|
||||
|
|
|
@ -1,12 +0,0 @@
|
|||
error[E0271]: type mismatch resolving `<() as Index>::Output == &mut <() as Index>::Output`
|
||||
--> $DIR/issue-100222.rs:34:12
|
||||
|
|
||||
LL | fn foo(&mut self, x: <Self as Index>::Output) -> <Self as Index>::Output
|
||||
| ^^^^^^^^^ expected `()`, found `&mut <() as Index>::Output`
|
||||
|
|
||||
= note: expected unit type `()`
|
||||
found mutable reference `&mut <() as Index>::Output`
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0271`.
|
|
@ -1,12 +0,0 @@
|
|||
error[E0271]: type mismatch resolving `<() as Index>::Output == &mut <() as Index>::Output`
|
||||
--> $DIR/issue-100222.rs:25:12
|
||||
|
|
||||
LL | fn foo(&mut self, x: <Self as Index>::Output) -> <Self as Index>::Output
|
||||
| ^^^^^^^^^ expected `()`, found `&mut <() as Index>::Output`
|
||||
|
|
||||
= note: expected unit type `()`
|
||||
found mutable reference `&mut <() as Index>::Output`
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0271`.
|
|
@ -1,6 +1,7 @@
|
|||
//@ revisions: nn ny yn yy
|
||||
//@ known-bug: #110395
|
||||
//@ compile-flags: -Znext-solver
|
||||
//@ check-pass
|
||||
|
||||
#![allow(incomplete_features)]
|
||||
#![feature(const_trait_impl, effects, associated_type_defaults, const_mut_refs)]
|
||||
|
||||
|
|
|
@ -1,12 +0,0 @@
|
|||
error[E0271]: type mismatch resolving `<() as Index>::Output == &mut <() as Index>::Output`
|
||||
--> $DIR/issue-100222.rs:34:12
|
||||
|
|
||||
LL | fn foo(&mut self, x: <Self as Index>::Output) -> <Self as Index>::Output
|
||||
| ^^^^^^^^^ expected `()`, found `&mut <() as Index>::Output`
|
||||
|
|
||||
= note: expected unit type `()`
|
||||
found mutable reference `&mut <() as Index>::Output`
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0271`.
|
|
@ -1,12 +0,0 @@
|
|||
error[E0271]: type mismatch resolving `<() as Index>::Output == &mut <() as Index>::Output`
|
||||
--> $DIR/issue-100222.rs:25:12
|
||||
|
|
||||
LL | fn foo(&mut self, x: <Self as Index>::Output) -> <Self as Index>::Output
|
||||
| ^^^^^^^^^ expected `()`, found `&mut <() as Index>::Output`
|
||||
|
|
||||
= note: expected unit type `()`
|
||||
found mutable reference `&mut <() as Index>::Output`
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0271`.
|
|
@ -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
|
||||
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
//@ compile-flags: -Znext-solver
|
||||
//@ check-pass
|
||||
|
||||
// Fixes a regression in `receiver_is_valid` in wfcheck where we were using
|
||||
// `InferCtxt::can_eq` instead of processing alias-relate goals, leading to false
|
||||
// positives, not deref'ing enough steps to check the receiver is valid.
|
||||
|
||||
trait Mirror {
|
||||
type Mirror: ?Sized;
|
||||
}
|
||||
impl<T: ?Sized> Mirror for T {
|
||||
type Mirror = T;
|
||||
}
|
||||
|
||||
trait Foo {
|
||||
fn foo(&self) {}
|
||||
}
|
||||
|
||||
impl Foo for <() as Mirror>::Mirror {
|
||||
fn foo(&self) {}
|
||||
}
|
||||
|
||||
fn main() {}
|
|
@ -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