Skip to content

builtin Fn impl, require return type wf #106807

New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Closed
wants to merge 1 commit into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions compiler/rustc_trait_selection/src/traits/select/confirmation.rs
Original file line number Diff line number Diff line change
@@ -619,8 +619,26 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
.map_bound(|(trait_ref, _)| trait_ref);

let mut nested = self.confirm_poly_trait_refs(obligation, trait_ref)?;

let cause = obligation.derived_cause(BuiltinDerivedObligation);

// Require the output to be well formed as it is otherwise possible to have an
// impl with an associated type which isn't well formed, which is unsound.
//
// FIXME: using `no_bound_vars` as we cannot deal with implied bounds for late-bound
// lifetimes right now.
//
// FIXME: move this to the wf requirements of function definitions themselves instead.
if let Some(return_ty) = sig.output().no_bound_vars() {
nested.push(Obligation::new(
tcx,
cause.clone(),
obligation.param_env,
ty::Binder::dummy(ty::PredicateKind::WellFormed(return_ty.into())),
));
}


if obligation.is_const() && !is_const {
// function is a trait method
if let ty::FnDef(def_id, substs) = self_ty.kind() && let Some(trait_id) = tcx.trait_of_item(*def_id) {
1 change: 1 addition & 0 deletions tests/ui/lifetimes/lifetime-errors/issue_74400.rs
Original file line number Diff line number Diff line change
@@ -11,6 +11,7 @@ fn f<T, S>(data: &[T], key: impl Fn(&T) -> S) {
fn g<T>(data: &[T]) {
f(data, identity)
//~^ ERROR the parameter type
//~| ERROR the parameter type
//~| ERROR mismatched types
//~| ERROR implementation of `FnOnce` is not general
}
13 changes: 12 additions & 1 deletion tests/ui/lifetimes/lifetime-errors/issue_74400.stderr
Original file line number Diff line number Diff line change
@@ -9,6 +9,17 @@ help: consider adding an explicit lifetime bound...
LL | fn g<T: 'static>(data: &[T]) {
| +++++++++

error[E0310]: the parameter type `T` may not live long enough
--> $DIR/issue_74400.rs:12:5
|
LL | f(data, identity)
| ^^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds
|
help: consider adding an explicit lifetime bound...
|
LL | fn g<T: 'static>(data: &[T]) {
| +++++++++

error[E0308]: mismatched types
--> $DIR/issue_74400.rs:12:5
|
@@ -32,7 +43,7 @@ LL | f(data, identity)
= note: `fn(&'2 T) -> &'2 T {identity::<&'2 T>}` must implement `FnOnce<(&'1 T,)>`, for any lifetime `'1`...
= note: ...but it actually implements `FnOnce<(&'2 T,)>`, for some specific lifetime `'2`

error: aborting due to 3 previous errors
error: aborting due to 4 previous errors

Some errors have detailed explanations: E0308, E0310.
For more information about an error, try `rustc --explain E0308`.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
error[E0275]: overflow evaluating the requirement `Foo: Sized`
error[E0275]: overflow evaluating the requirement `Foo well-formed`
--> $DIR/issue-53398-cyclic-types.rs:5:13
|
LL | fn foo() -> Foo {