Method resolution constrains hidden types instead of rejecting method candidates
This commit is contained in:
parent
c75f7283bf
commit
9cf60ee9d3
@ -1418,7 +1418,7 @@ fn inferred_kind(
|
||||
let impl_ty = self.normalize(span, tcx.type_of(impl_def_id).instantiate(tcx, args));
|
||||
let self_ty = self.normalize(span, self_ty);
|
||||
match self.at(&self.misc(span), self.param_env).eq(
|
||||
DefineOpaqueTypes::No,
|
||||
DefineOpaqueTypes::Yes,
|
||||
impl_ty,
|
||||
self_ty,
|
||||
) {
|
||||
|
@ -497,7 +497,7 @@ fn unify_receivers(
|
||||
args,
|
||||
})),
|
||||
);
|
||||
match self.at(&cause, self.param_env).sup(DefineOpaqueTypes::No, method_self_ty, self_ty) {
|
||||
match self.at(&cause, self.param_env).sup(DefineOpaqueTypes::Yes, method_self_ty, self_ty) {
|
||||
Ok(InferOk { obligations, value: () }) => {
|
||||
self.register_predicates(obligations);
|
||||
}
|
||||
|
@ -634,8 +634,8 @@ fn assemble_inherent_candidates(&mut self) {
|
||||
}
|
||||
}
|
||||
|
||||
#[instrument(level = "debug", skip(self))]
|
||||
fn assemble_probe(&mut self, self_ty: &Canonical<'tcx, QueryResponse<'tcx, Ty<'tcx>>>) {
|
||||
debug!("assemble_probe: self_ty={:?}", self_ty);
|
||||
let raw_self_ty = self_ty.value.value;
|
||||
match *raw_self_ty.kind() {
|
||||
ty::Dynamic(data, ..) if let Some(p) = data.principal() => {
|
||||
@ -713,13 +713,12 @@ fn assemble_inherent_impl_candidates_for_type(&mut self, def_id: DefId) {
|
||||
}
|
||||
}
|
||||
|
||||
#[instrument(level = "debug", skip(self))]
|
||||
fn assemble_inherent_impl_probe(&mut self, impl_def_id: DefId) {
|
||||
if !self.impl_dups.insert(impl_def_id) {
|
||||
return; // already visited
|
||||
}
|
||||
|
||||
debug!("assemble_inherent_impl_probe {:?}", impl_def_id);
|
||||
|
||||
for item in self.impl_or_trait_item(impl_def_id) {
|
||||
if !self.has_applicable_self(&item) {
|
||||
// No receiver declared. Not a candidate.
|
||||
@ -737,9 +736,8 @@ fn assemble_inherent_impl_probe(&mut self, impl_def_id: DefId) {
|
||||
}
|
||||
}
|
||||
|
||||
#[instrument(level = "debug", skip(self))]
|
||||
fn assemble_inherent_candidates_from_object(&mut self, self_ty: Ty<'tcx>) {
|
||||
debug!("assemble_inherent_candidates_from_object(self_ty={:?})", self_ty);
|
||||
|
||||
let principal = match self_ty.kind() {
|
||||
ty::Dynamic(ref data, ..) => Some(data),
|
||||
_ => None,
|
||||
@ -768,9 +766,9 @@ fn assemble_inherent_candidates_from_object(&mut self, self_ty: Ty<'tcx>) {
|
||||
});
|
||||
}
|
||||
|
||||
#[instrument(level = "debug", skip(self))]
|
||||
fn assemble_inherent_candidates_from_param(&mut self, param_ty: ty::ParamTy) {
|
||||
// FIXME: do we want to commit to this behavior for param bounds?
|
||||
debug!("assemble_inherent_candidates_from_param(param_ty={:?})", param_ty);
|
||||
|
||||
let bounds = self.param_env.caller_bounds().iter().filter_map(|predicate| {
|
||||
let bound_predicate = predicate.kind();
|
||||
@ -826,6 +824,7 @@ fn elaborate_bounds<F>(
|
||||
}
|
||||
}
|
||||
|
||||
#[instrument(level = "debug", skip(self))]
|
||||
fn assemble_extension_candidates_for_traits_in_scope(&mut self) {
|
||||
let mut duplicates = FxHashSet::default();
|
||||
let opt_applicable_traits = self.tcx.in_scope_traits(self.scope_expr_id);
|
||||
@ -842,6 +841,7 @@ fn assemble_extension_candidates_for_traits_in_scope(&mut self) {
|
||||
}
|
||||
}
|
||||
|
||||
#[instrument(level = "debug", skip(self))]
|
||||
fn assemble_extension_candidates_for_all_traits(&mut self) {
|
||||
let mut duplicates = FxHashSet::default();
|
||||
for trait_info in suggest::all_traits(self.tcx) {
|
||||
@ -863,12 +863,12 @@ fn matches_return_type(&self, method: ty::AssocItem, expected: Ty<'tcx>) -> bool
|
||||
}
|
||||
}
|
||||
|
||||
#[instrument(level = "debug", skip(self))]
|
||||
fn assemble_extension_candidates_for_trait(
|
||||
&mut self,
|
||||
import_ids: &SmallVec<[LocalDefId; 1]>,
|
||||
trait_def_id: DefId,
|
||||
) {
|
||||
debug!("assemble_extension_candidates_for_trait(trait_def_id={:?})", trait_def_id);
|
||||
let trait_args = self.fresh_args_for_item(self.span, trait_def_id);
|
||||
let trait_ref = ty::TraitRef::new(self.tcx, trait_def_id, trait_args);
|
||||
|
||||
@ -958,6 +958,7 @@ fn candidate_method_names(
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// THE ACTUAL SEARCH
|
||||
|
||||
#[instrument(level = "debug", skip(self))]
|
||||
fn pick(mut self) -> PickResult<'tcx> {
|
||||
assert!(self.method_name.is_some());
|
||||
|
||||
@ -1386,6 +1387,7 @@ fn candidate_source(&self, candidate: &Candidate<'tcx>, self_ty: Ty<'tcx>) -> Ca
|
||||
}
|
||||
}
|
||||
|
||||
#[instrument(level = "trace", skip(self, possibly_unsatisfied_predicates), ret)]
|
||||
fn consider_probe(
|
||||
&self,
|
||||
self_ty: Ty<'tcx>,
|
||||
@ -1415,15 +1417,8 @@ fn consider_probe(
|
||||
(xform_self_ty, xform_ret_ty) =
|
||||
self.xform_self_ty(probe.item, impl_ty, impl_args);
|
||||
xform_self_ty = ocx.normalize(cause, self.param_env, xform_self_ty);
|
||||
// FIXME: Make this `ocx.sup` once we define opaques more eagerly.
|
||||
match self.at(cause, self.param_env).sup(
|
||||
DefineOpaqueTypes::No,
|
||||
xform_self_ty,
|
||||
self_ty,
|
||||
) {
|
||||
Ok(infer_ok) => {
|
||||
ocx.register_infer_ok_obligations(infer_ok);
|
||||
}
|
||||
match ocx.sup(cause, self.param_env, xform_self_ty, self_ty) {
|
||||
Ok(()) => {}
|
||||
Err(err) => {
|
||||
debug!("--> cannot relate self-types {:?}", err);
|
||||
return ProbeResult::NoMatch;
|
||||
@ -1484,19 +1479,23 @@ fn consider_probe(
|
||||
(xform_self_ty, xform_ret_ty) =
|
||||
self.xform_self_ty(probe.item, trait_ref.self_ty(), trait_ref.args);
|
||||
xform_self_ty = ocx.normalize(cause, self.param_env, xform_self_ty);
|
||||
// FIXME: Make this `ocx.sup` once we define opaques more eagerly.
|
||||
match self.at(cause, self.param_env).sup(
|
||||
DefineOpaqueTypes::No,
|
||||
xform_self_ty,
|
||||
self_ty,
|
||||
) {
|
||||
Ok(infer_ok) => {
|
||||
ocx.register_infer_ok_obligations(infer_ok);
|
||||
}
|
||||
Err(err) => {
|
||||
debug!("--> cannot relate self-types {:?}", err);
|
||||
match self_ty.kind() {
|
||||
// HACK: opaque types will match anything for which their bounds hold.
|
||||
// Thus we need to prevent them from trying to match the `&_` autoref
|
||||
// candidates that get created for `&self` trait methods.
|
||||
ty::Alias(ty::Opaque, alias_ty)
|
||||
if self.infcx.can_define_opaque_ty(alias_ty.def_id)
|
||||
&& !xform_self_ty.is_ty_var() =>
|
||||
{
|
||||
return ProbeResult::NoMatch;
|
||||
}
|
||||
_ => match ocx.sup(cause, self.param_env, xform_self_ty, self_ty) {
|
||||
Ok(()) => {}
|
||||
Err(err) => {
|
||||
debug!("--> cannot relate self-types {:?}", err);
|
||||
return ProbeResult::NoMatch;
|
||||
}
|
||||
},
|
||||
}
|
||||
let obligation = traits::Obligation::new(
|
||||
self.tcx,
|
||||
@ -1536,15 +1535,8 @@ fn consider_probe(
|
||||
(xform_self_ty, xform_ret_ty) =
|
||||
self.xform_self_ty(probe.item, trait_ref.self_ty(), trait_ref.args);
|
||||
xform_self_ty = ocx.normalize(cause, self.param_env, xform_self_ty);
|
||||
// FIXME: Make this `ocx.sup` once we define opaques more eagerly.
|
||||
match self.at(cause, self.param_env).sup(
|
||||
DefineOpaqueTypes::No,
|
||||
xform_self_ty,
|
||||
self_ty,
|
||||
) {
|
||||
Ok(infer_ok) => {
|
||||
ocx.register_infer_ok_obligations(infer_ok);
|
||||
}
|
||||
match ocx.sup(cause, self.param_env, xform_self_ty, self_ty) {
|
||||
Ok(()) => {}
|
||||
Err(err) => {
|
||||
debug!("--> cannot relate self-types {:?}", err);
|
||||
return ProbeResult::NoMatch;
|
||||
@ -1665,6 +1657,7 @@ fn collapse_candidates_to_trait_pick(
|
||||
/// Similarly to `probe_for_return_type`, this method attempts to find the best matching
|
||||
/// candidate method where the method name may have been misspelled. Similarly to other
|
||||
/// edit distance based suggestions, we provide at most one such suggestion.
|
||||
#[instrument(level = "debug", skip(self))]
|
||||
pub(crate) fn probe_for_similar_candidate(
|
||||
&mut self,
|
||||
) -> Result<Option<ty::AssocItem>, MethodError<'tcx>> {
|
||||
|
@ -156,7 +156,7 @@ pub struct CandidateStep<'tcx> {
|
||||
|
||||
#[derive(Copy, Clone, Debug, HashStable)]
|
||||
pub struct MethodAutoderefStepsResult<'tcx> {
|
||||
/// The valid autoderef steps that could be find.
|
||||
/// The valid autoderef steps that could be found.
|
||||
pub steps: &'tcx [CandidateStep<'tcx>],
|
||||
/// If Some(T), a type autoderef reported an error on.
|
||||
pub opt_bad_ty: Option<&'tcx MethodAutoderefBadTy<'tcx>>,
|
||||
|
@ -1,36 +0,0 @@
|
||||
error[E0599]: no method named `bar` found for struct `Bar<impl Sized>` in the current scope
|
||||
--> $DIR/method-resolution.rs:23:11
|
||||
|
|
||||
LL | struct Bar<T>(T);
|
||||
| ------------- method `bar` not found for this struct
|
||||
...
|
||||
LL | x.bar();
|
||||
| ^^^ method not found in `Bar<impl Sized>`
|
||||
|
|
||||
= note: the method was found for
|
||||
- `Bar<u32>`
|
||||
|
||||
error[E0391]: cycle detected when computing type of opaque `foo::{opaque#0}`
|
||||
--> $DIR/method-resolution.rs:19:24
|
||||
|
|
||||
LL | fn foo(x: bool) -> Bar<impl Sized> {
|
||||
| ^^^^^^^^^^
|
||||
|
|
||||
note: ...which requires type-checking `foo`...
|
||||
--> $DIR/method-resolution.rs:23:9
|
||||
|
|
||||
LL | x.bar();
|
||||
| ^
|
||||
= note: ...which requires evaluating trait selection obligation `Bar<foo::{opaque#0}>: core::marker::Unpin`...
|
||||
= note: ...which again requires computing type of opaque `foo::{opaque#0}`, completing the cycle
|
||||
note: cycle used when computing type of `foo::{opaque#0}`
|
||||
--> $DIR/method-resolution.rs:19:24
|
||||
|
|
||||
LL | fn foo(x: bool) -> Bar<impl Sized> {
|
||||
| ^^^^^^^^^^
|
||||
= note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0391, E0599.
|
||||
For more information about an error, try `rustc --explain E0391`.
|
@ -1,10 +1,9 @@
|
||||
//! Check that we do not constrain hidden types during method resolution.
|
||||
//! Otherwise we'd pick up that calling `bar` can be satisfied iff `u32`
|
||||
//! is the hidden type of the RPIT.
|
||||
//! Since there is only one possible `bar` method, we invoke it and subsequently
|
||||
//! constrain `foo`'s RPIT to `u32`.
|
||||
|
||||
//@ revisions: current next
|
||||
//@[next] compile-flags: -Znext-solver
|
||||
//@[next] check-pass
|
||||
//@ check-pass
|
||||
|
||||
trait Trait {}
|
||||
|
||||
@ -17,11 +16,9 @@ fn bar(self) {}
|
||||
}
|
||||
|
||||
fn foo(x: bool) -> Bar<impl Sized> {
|
||||
//[current]~^ ERROR: cycle detected
|
||||
if x {
|
||||
let x = foo(false);
|
||||
x.bar();
|
||||
//[current]~^ ERROR: no method named `bar` found
|
||||
}
|
||||
todo!()
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
//! Check that the method call does not constrain the RPIT to `i32`, even though
|
||||
//! `i32` is the only trait that satisfies the RPIT's trait bounds.
|
||||
//! `i32` is the only type that satisfies the RPIT's trait bounds.
|
||||
|
||||
//@ revisions: current next
|
||||
//@[next] compile-flags: -Znext-solver
|
||||
|
@ -1,37 +1,20 @@
|
||||
error[E0599]: no method named `bar` found for struct `Bar<impl Sized>` in the current scope
|
||||
--> $DIR/method-resolution3.rs:22:11
|
||||
|
|
||||
LL | struct Bar<T>(T);
|
||||
| ------------- method `bar` not found for this struct
|
||||
...
|
||||
LL | x.bar();
|
||||
| ^^^ method not found in `Bar<impl Sized>`
|
||||
|
|
||||
= note: the method was found for
|
||||
- `Bar<i32>`
|
||||
- `Bar<u32>`
|
||||
|
||||
error[E0391]: cycle detected when computing type of opaque `foo::{opaque#0}`
|
||||
--> $DIR/method-resolution3.rs:18:24
|
||||
|
|
||||
LL | fn foo(x: bool) -> Bar<impl Sized> {
|
||||
| ^^^^^^^^^^
|
||||
|
|
||||
note: ...which requires type-checking `foo`...
|
||||
--> $DIR/method-resolution3.rs:22:9
|
||||
error[E0034]: multiple applicable items in scope
|
||||
--> $DIR/method-resolution3.rs:21:11
|
||||
|
|
||||
LL | x.bar();
|
||||
| ^
|
||||
= note: ...which requires evaluating trait selection obligation `Bar<foo::{opaque#0}>: core::marker::Unpin`...
|
||||
= note: ...which again requires computing type of opaque `foo::{opaque#0}`, completing the cycle
|
||||
note: cycle used when computing type of `foo::{opaque#0}`
|
||||
--> $DIR/method-resolution3.rs:18:24
|
||||
| ^^^ multiple `bar` found
|
||||
|
|
||||
LL | fn foo(x: bool) -> Bar<impl Sized> {
|
||||
| ^^^^^^^^^^
|
||||
= note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
|
||||
note: candidate #1 is defined in an impl for the type `Bar<i32>`
|
||||
--> $DIR/method-resolution3.rs:15:5
|
||||
|
|
||||
LL | fn bar(self) {}
|
||||
| ^^^^^^^^^^^^
|
||||
note: candidate #2 is defined in an impl for the type `Bar<u32>`
|
||||
--> $DIR/method-resolution3.rs:11:5
|
||||
|
|
||||
LL | fn bar(self) {}
|
||||
| ^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
Some errors have detailed explanations: E0391, E0599.
|
||||
For more information about an error, try `rustc --explain E0391`.
|
||||
For more information about this error, try `rustc --explain E0034`.
|
||||
|
@ -1,5 +1,5 @@
|
||||
error[E0034]: multiple applicable items in scope
|
||||
--> $DIR/method-resolution3.rs:22:11
|
||||
--> $DIR/method-resolution3.rs:21:11
|
||||
|
|
||||
LL | x.bar();
|
||||
| ^^^ multiple `bar` found
|
||||
|
@ -16,12 +16,10 @@ fn bar(self) {}
|
||||
}
|
||||
|
||||
fn foo(x: bool) -> Bar<impl Sized> {
|
||||
//[current]~^ ERROR: cycle
|
||||
if x {
|
||||
let x = foo(false);
|
||||
x.bar();
|
||||
//[current]~^ ERROR: no method named `bar`
|
||||
//[next]~^^ ERROR: multiple applicable items in scope
|
||||
//~^ ERROR: multiple applicable items in scope
|
||||
}
|
||||
todo!()
|
||||
}
|
||||
|
@ -4,9 +4,9 @@
|
||||
//! variable, but get a type mismatch when comparing `&mut _` with
|
||||
//! `std::iter::Empty`.
|
||||
|
||||
//@[current] check-pass
|
||||
//@ revisions: current next
|
||||
//@[next] compile-flags: -Znext-solver
|
||||
//@[current] check-pass
|
||||
|
||||
fn foo(b: bool) -> impl Iterator<Item = ()> {
|
||||
if b {
|
||||
|
@ -1,4 +1,7 @@
|
||||
#![feature(type_alias_impl_trait)]
|
||||
|
||||
//@ check-pass
|
||||
|
||||
struct Foo<T>(T);
|
||||
|
||||
impl Foo<u32> {
|
||||
@ -15,14 +18,11 @@ fn bar() -> Bar {
|
||||
impl Foo<Bar> {
|
||||
fn foo() -> Bar {
|
||||
Self::method();
|
||||
//~^ ERROR: no function or associated item named `method` found for struct `Foo<Bar>`
|
||||
Foo::<Bar>::method();
|
||||
//~^ ERROR: no function or associated item named `method` found for struct `Foo<Bar>`
|
||||
let x = Foo(bar());
|
||||
Foo::method2(x);
|
||||
let x = Self(bar());
|
||||
Self::method2(x);
|
||||
//~^ ERROR: no function or associated item named `method2` found for struct `Foo<Bar>`
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
@ -1,36 +0,0 @@
|
||||
error[E0599]: no function or associated item named `method` found for struct `Foo<Bar>` in the current scope
|
||||
--> $DIR/opaque_param_in_ufc.rs:17:15
|
||||
|
|
||||
LL | struct Foo<T>(T);
|
||||
| ------------- function or associated item `method` not found for this struct
|
||||
...
|
||||
LL | Self::method();
|
||||
| ^^^^^^ function or associated item not found in `Foo<Bar>`
|
||||
|
|
||||
= note: the function or associated item was found for
|
||||
- `Foo<u32>`
|
||||
|
||||
error[E0599]: no function or associated item named `method` found for struct `Foo<Bar>` in the current scope
|
||||
--> $DIR/opaque_param_in_ufc.rs:19:21
|
||||
|
|
||||
LL | struct Foo<T>(T);
|
||||
| ------------- function or associated item `method` not found for this struct
|
||||
...
|
||||
LL | Foo::<Bar>::method();
|
||||
| ^^^^^^ function or associated item not found in `Foo<Bar>`
|
||||
|
|
||||
= note: the function or associated item was found for
|
||||
- `Foo<u32>`
|
||||
|
||||
error[E0599]: no function or associated item named `method2` found for struct `Foo<Bar>` in the current scope
|
||||
--> $DIR/opaque_param_in_ufc.rs:24:15
|
||||
|
|
||||
LL | struct Foo<T>(T);
|
||||
| ------------- function or associated item `method2` not found for this struct
|
||||
...
|
||||
LL | Self::method2(x);
|
||||
| ^^^^^^^ function or associated item not found in `Foo<Bar>`
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0599`.
|
@ -1,36 +0,0 @@
|
||||
error[E0599]: no method named `foo` found for struct `Bar<Foo>` in the current scope
|
||||
--> $DIR/method_resolution2.rs:17:14
|
||||
|
|
||||
LL | struct Bar<T>(T);
|
||||
| ------------- method `foo` not found for this struct
|
||||
...
|
||||
LL | self.foo()
|
||||
| ^^^ method not found in `Bar<Foo>`
|
||||
|
|
||||
= note: the method was found for
|
||||
- `Bar<u32>`
|
||||
|
||||
error[E0391]: cycle detected when computing type of opaque `Foo::{opaque#0}`
|
||||
--> $DIR/method_resolution2.rs:10:12
|
||||
|
|
||||
LL | type Foo = impl Sized;
|
||||
| ^^^^^^^^^^
|
||||
|
|
||||
note: ...which requires type-checking `<impl at $DIR/method_resolution2.rs:15:1: 15:14>::bar`...
|
||||
--> $DIR/method_resolution2.rs:17:9
|
||||
|
|
||||
LL | self.foo()
|
||||
| ^^^^
|
||||
= note: ...which requires evaluating trait selection obligation `Bar<Foo>: core::marker::Unpin`...
|
||||
= note: ...which again requires computing type of opaque `Foo::{opaque#0}`, completing the cycle
|
||||
note: cycle used when computing type of `Foo::{opaque#0}`
|
||||
--> $DIR/method_resolution2.rs:10:12
|
||||
|
|
||||
LL | type Foo = impl Sized;
|
||||
| ^^^^^^^^^^
|
||||
= note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0391, E0599.
|
||||
For more information about an error, try `rustc --explain E0391`.
|
@ -1,21 +1,19 @@
|
||||
//! Check that we do not unify `Bar<Foo>` with `Bar<u32>`, even though the
|
||||
//! Check that we do unify `Bar<Foo>` with `Bar<u32>`, as the
|
||||
//! `foo` method call can be resolved unambiguously by doing so.
|
||||
|
||||
//@ revisions: current next
|
||||
//@[next] compile-flags: -Znext-solver
|
||||
//@[next] check-pass
|
||||
//@ check-pass
|
||||
|
||||
#![feature(type_alias_impl_trait)]
|
||||
|
||||
type Foo = impl Sized;
|
||||
//[current]~^ ERROR: cycle
|
||||
|
||||
struct Bar<T>(T);
|
||||
|
||||
impl Bar<Foo> {
|
||||
fn bar(self) {
|
||||
self.foo()
|
||||
//[current]~^ ERROR: no method named `foo`
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,15 +0,0 @@
|
||||
error[E0599]: no method named `bar` found for struct `Bar<u32>` in the current scope
|
||||
--> $DIR/method_resolution5.rs:25:14
|
||||
|
|
||||
LL | struct Bar<T>(T);
|
||||
| ------------- method `bar` not found for this struct
|
||||
...
|
||||
LL | self.bar()
|
||||
| ^^^ method not found in `Bar<u32>`
|
||||
|
|
||||
= note: the method was found for
|
||||
- `Bar<Foo>`
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0599`.
|
@ -3,7 +3,7 @@
|
||||
|
||||
//@ revisions: current next
|
||||
//@[next] compile-flags: -Znext-solver
|
||||
//@[next] check-pass
|
||||
//@ check-pass
|
||||
|
||||
#![feature(type_alias_impl_trait)]
|
||||
|
||||
@ -23,7 +23,6 @@ fn foo(self)
|
||||
Foo:,
|
||||
{
|
||||
self.bar()
|
||||
//[current]~^ ERROR: no method named `bar`
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user