Fix obligation param and bless tests
This commit is contained in:
@@ -28,7 +28,7 @@ use crate::traits::{
|
|||||||
BuiltinDerivedObligation, ImplDerivedObligation, ImplDerivedObligationCause, ImplSource,
|
BuiltinDerivedObligation, ImplDerivedObligation, ImplDerivedObligationCause, ImplSource,
|
||||||
ImplSourceUserDefinedData, Normalized, Obligation, ObligationCause, PolyTraitObligation,
|
ImplSourceUserDefinedData, Normalized, Obligation, ObligationCause, PolyTraitObligation,
|
||||||
PredicateObligation, Selection, SelectionError, SignatureMismatch, TraitNotObjectSafe,
|
PredicateObligation, Selection, SelectionError, SignatureMismatch, TraitNotObjectSafe,
|
||||||
Unimplemented,
|
TraitObligation, Unimplemented,
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::BuiltinImplConditions;
|
use super::BuiltinImplConditions;
|
||||||
@@ -693,12 +693,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||||||
)
|
)
|
||||||
.map_bound(|(trait_ref, _)| trait_ref);
|
.map_bound(|(trait_ref, _)| trait_ref);
|
||||||
|
|
||||||
let mut nested = self.equate_trait_refs(
|
let mut nested =
|
||||||
&obligation.cause,
|
self.equate_trait_refs(obligation.with(tcx, placeholder_predicate), trait_ref)?;
|
||||||
obligation.param_env,
|
|
||||||
placeholder_predicate.trait_ref,
|
|
||||||
trait_ref,
|
|
||||||
)?;
|
|
||||||
let cause = obligation.derived_cause(BuiltinDerivedObligation);
|
let cause = obligation.derived_cause(BuiltinDerivedObligation);
|
||||||
|
|
||||||
// Confirm the `type Output: Sized;` bound that is present on `FnOnce`
|
// Confirm the `type Output: Sized;` bound that is present on `FnOnce`
|
||||||
@@ -764,9 +760,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||||||
);
|
);
|
||||||
|
|
||||||
let nested = self.equate_trait_refs(
|
let nested = self.equate_trait_refs(
|
||||||
&obligation.cause,
|
obligation.with(self.tcx(), placeholder_predicate),
|
||||||
obligation.param_env,
|
|
||||||
placeholder_predicate.trait_ref,
|
|
||||||
ty::Binder::dummy(trait_ref),
|
ty::Binder::dummy(trait_ref),
|
||||||
)?;
|
)?;
|
||||||
debug!(?trait_ref, ?nested, "coroutine candidate obligations");
|
debug!(?trait_ref, ?nested, "coroutine candidate obligations");
|
||||||
@@ -796,9 +790,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||||||
);
|
);
|
||||||
|
|
||||||
let nested = self.equate_trait_refs(
|
let nested = self.equate_trait_refs(
|
||||||
&obligation.cause,
|
obligation.with(self.tcx(), placeholder_predicate),
|
||||||
obligation.param_env,
|
|
||||||
placeholder_predicate.trait_ref,
|
|
||||||
ty::Binder::dummy(trait_ref),
|
ty::Binder::dummy(trait_ref),
|
||||||
)?;
|
)?;
|
||||||
debug!(?trait_ref, ?nested, "future candidate obligations");
|
debug!(?trait_ref, ?nested, "future candidate obligations");
|
||||||
@@ -828,9 +820,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||||||
);
|
);
|
||||||
|
|
||||||
let nested = self.equate_trait_refs(
|
let nested = self.equate_trait_refs(
|
||||||
&obligation.cause,
|
obligation.with(self.tcx(), placeholder_predicate),
|
||||||
obligation.param_env,
|
|
||||||
placeholder_predicate.trait_ref,
|
|
||||||
ty::Binder::dummy(trait_ref),
|
ty::Binder::dummy(trait_ref),
|
||||||
)?;
|
)?;
|
||||||
debug!(?trait_ref, ?nested, "iterator candidate obligations");
|
debug!(?trait_ref, ?nested, "iterator candidate obligations");
|
||||||
@@ -860,9 +850,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||||||
);
|
);
|
||||||
|
|
||||||
let nested = self.equate_trait_refs(
|
let nested = self.equate_trait_refs(
|
||||||
&obligation.cause,
|
obligation.with(self.tcx(), placeholder_predicate),
|
||||||
obligation.param_env,
|
|
||||||
placeholder_predicate.trait_ref,
|
|
||||||
ty::Binder::dummy(trait_ref),
|
ty::Binder::dummy(trait_ref),
|
||||||
)?;
|
)?;
|
||||||
debug!(?trait_ref, ?nested, "iterator candidate obligations");
|
debug!(?trait_ref, ?nested, "iterator candidate obligations");
|
||||||
@@ -898,12 +886,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
self.equate_trait_refs(
|
self.equate_trait_refs(obligation.with(self.tcx(), placeholder_predicate), trait_ref)
|
||||||
&obligation.cause,
|
|
||||||
obligation.param_env,
|
|
||||||
placeholder_predicate.trait_ref,
|
|
||||||
trait_ref,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[instrument(skip(self), level = "debug")]
|
#[instrument(skip(self), level = "debug")]
|
||||||
@@ -981,12 +964,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||||||
_ => bug!("expected callable type for AsyncFn candidate"),
|
_ => bug!("expected callable type for AsyncFn candidate"),
|
||||||
};
|
};
|
||||||
|
|
||||||
nested.extend(self.equate_trait_refs(
|
nested.extend(
|
||||||
&obligation.cause,
|
self.equate_trait_refs(obligation.with(tcx, placeholder_predicate), trait_ref)?,
|
||||||
obligation.param_env,
|
);
|
||||||
placeholder_predicate.trait_ref,
|
|
||||||
trait_ref,
|
|
||||||
)?);
|
|
||||||
|
|
||||||
let goal_kind =
|
let goal_kind =
|
||||||
self.tcx().async_fn_trait_kind_from_def_id(obligation.predicate.def_id()).unwrap();
|
self.tcx().async_fn_trait_kind_from_def_id(obligation.predicate.def_id()).unwrap();
|
||||||
@@ -1041,13 +1021,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||||||
#[instrument(skip(self), level = "trace")]
|
#[instrument(skip(self), level = "trace")]
|
||||||
fn equate_trait_refs(
|
fn equate_trait_refs(
|
||||||
&mut self,
|
&mut self,
|
||||||
cause: &ObligationCause<'tcx>,
|
obligation: TraitObligation<'tcx>,
|
||||||
param_env: ty::ParamEnv<'tcx>,
|
|
||||||
obligation_trait_ref: ty::TraitRef<'tcx>,
|
|
||||||
found_trait_ref: ty::PolyTraitRef<'tcx>,
|
found_trait_ref: ty::PolyTraitRef<'tcx>,
|
||||||
) -> Result<Vec<PredicateObligation<'tcx>>, SelectionError<'tcx>> {
|
) -> Result<Vec<PredicateObligation<'tcx>>, SelectionError<'tcx>> {
|
||||||
let found_trait_ref = self.infcx.instantiate_binder_with_fresh_vars(
|
let found_trait_ref = self.infcx.instantiate_binder_with_fresh_vars(
|
||||||
cause.span,
|
obligation.cause.span,
|
||||||
HigherRankedType,
|
HigherRankedType,
|
||||||
found_trait_ref,
|
found_trait_ref,
|
||||||
);
|
);
|
||||||
@@ -1056,16 +1034,16 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||||||
ensure_sufficient_stack(|| {
|
ensure_sufficient_stack(|| {
|
||||||
normalize_with_depth(
|
normalize_with_depth(
|
||||||
self,
|
self,
|
||||||
param_env,
|
obligation.param_env,
|
||||||
cause.clone(),
|
obligation.cause.clone(),
|
||||||
0,
|
obligation.recursion_depth + 1,
|
||||||
(obligation_trait_ref, found_trait_ref),
|
(obligation.predicate.trait_ref, found_trait_ref),
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
|
|
||||||
// needed to define opaque types for tests/ui/type-alias-impl-trait/assoc-projection-ice.rs
|
// needed to define opaque types for tests/ui/type-alias-impl-trait/assoc-projection-ice.rs
|
||||||
self.infcx
|
self.infcx
|
||||||
.at(&cause, param_env)
|
.at(&obligation.cause, obligation.param_env)
|
||||||
.eq(DefineOpaqueTypes::Yes, obligation_trait_ref, found_trait_ref)
|
.eq(DefineOpaqueTypes::Yes, obligation_trait_ref, found_trait_ref)
|
||||||
.map(|InferOk { mut obligations, .. }| {
|
.map(|InferOk { mut obligations, .. }| {
|
||||||
obligations.extend(nested);
|
obligations.extend(nested);
|
||||||
|
|||||||
@@ -2,6 +2,13 @@
|
|||||||
//@ compile-flags: -Zunstable-options
|
//@ compile-flags: -Zunstable-options
|
||||||
//@ revisions: current next
|
//@ revisions: current next
|
||||||
//@[next] compile-flags: -Znext-solver
|
//@[next] compile-flags: -Znext-solver
|
||||||
|
//@ check-pass
|
||||||
|
|
||||||
|
// Makes sure that we support closure/coroutine goals where the signature of
|
||||||
|
// the item references higher-ranked lifetimes from the *predicate* binder,
|
||||||
|
// not its own internal signature binder.
|
||||||
|
//
|
||||||
|
// This was fixed in <https://github.com/rust-lang/rust/pull/122267>.
|
||||||
|
|
||||||
#![feature(unboxed_closures, gen_blocks)]
|
#![feature(unboxed_closures, gen_blocks)]
|
||||||
|
|
||||||
@@ -48,4 +55,4 @@ fn main() {
|
|||||||
|
|
||||||
fn uwu<'a>(x: &'a ()) -> impl Fn(&'a ()) { |_| {} }
|
fn uwu<'a>(x: &'a ()) -> impl Fn(&'a ()) { |_| {} }
|
||||||
Closure(uwu).dispatch();
|
Closure(uwu).dispatch();
|
||||||
}
|
}
|
||||||
|
|||||||
33
tests/ui/higher-ranked/closure-bound-codegen-ice.rs
Normal file
33
tests/ui/higher-ranked/closure-bound-codegen-ice.rs
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
//@ revisions: current next
|
||||||
|
//@[next] compile-flags: -Znext-solver
|
||||||
|
//@ build-pass
|
||||||
|
|
||||||
|
// Regression test for incomplete handling of Fn-trait goals,
|
||||||
|
// fixed in #122267.
|
||||||
|
|
||||||
|
trait Trait {
|
||||||
|
type Assoc<'a>: FnOnce(&'a ());
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Trait for () {
|
||||||
|
type Assoc<'a> = fn(&'a ());
|
||||||
|
}
|
||||||
|
|
||||||
|
trait Indir {
|
||||||
|
fn break_me() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<F: Trait> Indir for F
|
||||||
|
where
|
||||||
|
for<'a> F::Assoc<'a>: FnOnce(&'a ()),
|
||||||
|
{
|
||||||
|
fn break_me() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn foo<F: Trait>() {
|
||||||
|
F::break_me()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
foo::<()>();
|
||||||
|
}
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
error[E0277]: expected a `Fn(&'w ())` closure, found `fn(&'w ())`
|
|
||||||
--> $DIR/fn-ptr.rs:12:5
|
|
||||||
|
|
|
||||||
LL | ice();
|
|
||||||
| ^^^^^ expected an `Fn(&'w ())` closure, found `fn(&'w ())`
|
|
||||||
|
|
|
||||||
= help: the trait `for<'w> Fn<(&'w (),)>` is not implemented for `fn(&'w ())`
|
|
||||||
note: required by a bound in `ice`
|
|
||||||
--> $DIR/fn-ptr.rs:7:25
|
|
||||||
|
|
|
||||||
LL | fn ice()
|
|
||||||
| --- required by a bound in this function
|
|
||||||
LL | where
|
|
||||||
LL | for<'w> fn(&'w ()): Fn(&'w ()),
|
|
||||||
| ^^^^^^^^^^ required by this bound in `ice`
|
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0277`.
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
error[E0277]: expected a `Fn(&'w ())` closure, found `fn(&'w ())`
|
|
||||||
--> $DIR/fn-ptr.rs:13:5
|
|
||||||
|
|
|
||||||
LL | ice();
|
|
||||||
| ^^^^^ expected an `Fn(&'w ())` closure, found `fn(&'w ())`
|
|
||||||
|
|
|
||||||
= help: the trait `for<'w> Fn<(&'w (),)>` is not implemented for `fn(&'w ())`
|
|
||||||
note: required by a bound in `ice`
|
|
||||||
--> $DIR/fn-ptr.rs:8:25
|
|
||||||
|
|
|
||||||
LL | fn ice()
|
|
||||||
| --- required by a bound in this function
|
|
||||||
LL | where
|
|
||||||
LL | for<'w> fn(&'w ()): Fn(&'w ()),
|
|
||||||
| ^^^^^^^^^^ required by this bound in `ice`
|
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0277`.
|
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
//@ revisions: current next
|
//@ revisions: current next
|
||||||
//@ ignore-compare-mode-next-solver (explicit revisions)
|
//@ ignore-compare-mode-next-solver (explicit revisions)
|
||||||
//@[next] compile-flags: -Znext-solver
|
//@[next] compile-flags: -Znext-solver
|
||||||
//@[next] check-pass
|
//@ check-pass
|
||||||
|
|
||||||
fn ice()
|
fn ice()
|
||||||
where
|
where
|
||||||
@@ -11,5 +11,4 @@ where
|
|||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
ice();
|
ice();
|
||||||
//[current]~^ ERROR expected a `Fn(&'w ())` closure, found `fn(&'w ())`
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +0,0 @@
|
|||||||
error: the compiler unexpectedly panicked. this is a bug.
|
|
||||||
|
|
||||||
query stack during panic:
|
|
||||||
#0 [evaluate_obligation] evaluating trait selection obligation `for<'a> {async fn body@$DIR/future.rs:32:35: 34:2}: core::future::future::Future`
|
|
||||||
#1 [codegen_select_candidate] computing candidate for `<strlen as Trait>`
|
|
||||||
end of query stack
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
error: the compiler unexpectedly panicked. this is a bug.
|
|
||||||
|
|
||||||
query stack during panic:
|
|
||||||
#0 [evaluate_obligation] evaluating trait selection obligation `for<'a> {async fn body of strlen()}: core::future::future::Future`
|
|
||||||
#1 [codegen_select_candidate] computing candidate for `<strlen as Trait>`
|
|
||||||
end of query stack
|
|
||||||
@@ -3,14 +3,7 @@
|
|||||||
//@ revisions: current next
|
//@ revisions: current next
|
||||||
//@ ignore-compare-mode-next-solver (explicit revisions)
|
//@ ignore-compare-mode-next-solver (explicit revisions)
|
||||||
//@[next] compile-flags: -Znext-solver
|
//@[next] compile-flags: -Znext-solver
|
||||||
//@[next] check-pass
|
//@ check-pass
|
||||||
//@[current] known-bug: #112347
|
|
||||||
//@[current] build-fail
|
|
||||||
//@[current] failure-status: 101
|
|
||||||
//@[current] normalize-stderr-test "note: .*\n\n" -> ""
|
|
||||||
//@[current] normalize-stderr-test "thread 'rustc' panicked.*\n.*\n" -> ""
|
|
||||||
//@[current] normalize-stderr-test "(error: internal compiler error: [^:]+):\d+:\d+: " -> "$1:LL:CC: "
|
|
||||||
//@[current] rustc-env:RUST_BACKTRACE=0
|
|
||||||
|
|
||||||
#![feature(unboxed_closures)]
|
#![feature(unboxed_closures)]
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ fn main() {
|
|||||||
let f = | _ , y: &u32 , z | ();
|
let f = | _ , y: &u32 , z | ();
|
||||||
thing(f);
|
thing(f);
|
||||||
//~^ ERROR implementation of `FnOnce` is not general enough
|
//~^ ERROR implementation of `FnOnce` is not general enough
|
||||||
//~^^ ERROR implementation of `FnOnce` is not general enough
|
//~| ERROR implementation of `FnOnce` is not general enough
|
||||||
let f = | x, y: _ , z: u32 | ();
|
let f = | x, y: _ , z: u32 | ();
|
||||||
thing(f);
|
thing(f);
|
||||||
//~^ ERROR implementation of `FnOnce` is not general enough
|
//~^ ERROR implementation of `FnOnce` is not general enough
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
//! Regression test for #74400: Type mismatch in function arguments E0631, E0271 are falsely
|
//! Regression test for #74400: Type mismatch in function arguments E0631, E0271 are falsely
|
||||||
//! recognized as E0308 mismatched types.
|
//! recognized as "implementation of `FnOnce` is not general enough".
|
||||||
|
|
||||||
use std::convert::identity;
|
use std::convert::identity;
|
||||||
|
|
||||||
@@ -13,6 +13,6 @@ fn g<T>(data: &[T]) {
|
|||||||
//~^ ERROR the parameter type
|
//~^ ERROR the parameter type
|
||||||
//~| ERROR the parameter type
|
//~| ERROR the parameter type
|
||||||
//~| ERROR the parameter type
|
//~| ERROR the parameter type
|
||||||
//~| ERROR implementation of `FnOnce` is not general
|
//~| ERROR implementation of `FnOnce` is not general enough
|
||||||
//~| ERROR implementation of `Fn` is not general enough
|
//~| ERROR implementation of `Fn` is not general enough
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user