Skip to content

Commit 6069317

Browse files
committed
builtin Fn impl, require return type wf
1 parent 4a04f25 commit 6069317

File tree

4 files changed

+32
-2
lines changed

4 files changed

+32
-2
lines changed

compiler/rustc_trait_selection/src/traits/select/confirmation.rs

+18
Original file line numberDiff line numberDiff line change
@@ -619,8 +619,26 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
619619
.map_bound(|(trait_ref, _)| trait_ref);
620620

621621
let mut nested = self.confirm_poly_trait_refs(obligation, trait_ref)?;
622+
622623
let cause = obligation.derived_cause(BuiltinDerivedObligation);
623624

625+
// Require the output to be well formed as it is otherwise possible to have an
626+
// impl with an associated type which isn't well formed, which is unsound.
627+
//
628+
// FIXME: using `no_bound_vars` as we cannot deal with implied bounds for late-bound
629+
// lifetimes right now.
630+
//
631+
// FIXME: move this to the wf requirements of function definitions themselves instead.
632+
if let Some(return_ty) = sig.output().no_bound_vars() {
633+
nested.push(Obligation::new(
634+
tcx,
635+
cause.clone(),
636+
obligation.param_env,
637+
ty::Binder::dummy(ty::PredicateKind::WellFormed(return_ty.into())),
638+
));
639+
}
640+
641+
624642
if obligation.is_const() && !is_const {
625643
// function is a trait method
626644
if let ty::FnDef(def_id, substs) = self_ty.kind() && let Some(trait_id) = tcx.trait_of_item(*def_id) {

tests/ui/lifetimes/lifetime-errors/issue_74400.rs

+1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ fn f<T, S>(data: &[T], key: impl Fn(&T) -> S) {
1111
fn g<T>(data: &[T]) {
1212
f(data, identity)
1313
//~^ ERROR the parameter type
14+
//~| ERROR the parameter type
1415
//~| ERROR mismatched types
1516
//~| ERROR implementation of `FnOnce` is not general
1617
}

tests/ui/lifetimes/lifetime-errors/issue_74400.stderr

+12-1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,17 @@ help: consider adding an explicit lifetime bound...
99
LL | fn g<T: 'static>(data: &[T]) {
1010
| +++++++++
1111

12+
error[E0310]: the parameter type `T` may not live long enough
13+
--> $DIR/issue_74400.rs:12:5
14+
|
15+
LL | f(data, identity)
16+
| ^^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds
17+
|
18+
help: consider adding an explicit lifetime bound...
19+
|
20+
LL | fn g<T: 'static>(data: &[T]) {
21+
| +++++++++
22+
1223
error[E0308]: mismatched types
1324
--> $DIR/issue_74400.rs:12:5
1425
|
@@ -32,7 +43,7 @@ LL | f(data, identity)
3243
= note: `fn(&'2 T) -> &'2 T {identity::<&'2 T>}` must implement `FnOnce<(&'1 T,)>`, for any lifetime `'1`...
3344
= note: ...but it actually implements `FnOnce<(&'2 T,)>`, for some specific lifetime `'2`
3445

35-
error: aborting due to 3 previous errors
46+
error: aborting due to 4 previous errors
3647

3748
Some errors have detailed explanations: E0308, E0310.
3849
For more information about an error, try `rustc --explain E0308`.

tests/ui/type-alias-impl-trait/issue-53398-cyclic-types.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
error[E0275]: overflow evaluating the requirement `Foo: Sized`
1+
error[E0275]: overflow evaluating the requirement `Foo well-formed`
22
--> $DIR/issue-53398-cyclic-types.rs:5:13
33
|
44
LL | fn foo() -> Foo {

0 commit comments

Comments
 (0)