Skip to content

wf-check hidden types at definition site #114933

New issue

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

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

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
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
8 changes: 8 additions & 0 deletions compiler/rustc_infer/src/infer/nll_relate/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,10 @@ where
.handle_opaque_type(a, b, true, &cause, self.delegate.param_env())?
.obligations;
self.delegate.register_obligations(obligations);
self.register_predicates([
ty::ClauseKind::WellFormed(a.into()),
ty::ClauseKind::WellFormed(b.into()),
]);
trace!(a = ?a.kind(), b = ?b.kind(), "opaque type instantiated");
Ok(a)
}
Expand Down Expand Up @@ -687,6 +691,10 @@ where
}

fn register_type_relate_obligation(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) {
self.register_predicates([
ty::ClauseKind::WellFormed(a.into()),
ty::ClauseKind::WellFormed(b.into()),
]);
self.register_predicates([ty::Binder::dummy(match self.ambient_variance {
ty::Variance::Covariant => ty::PredicateKind::AliasRelate(
a.into(),
Expand Down
5 changes: 5 additions & 0 deletions compiler/rustc_trait_selection/src/solve/alias_relate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,11 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
Invert::Yes => (other, fresh),
};
self.sub(param_env, sub, sup)?;
self.add_goal(Goal::new(
self.tcx(),
param_env,
ty::ClauseKind::WellFormed(fresh.into()),
));
fresh
}
};
Expand Down
1 change: 1 addition & 0 deletions tests/ui/borrowck/erase-error-in-mir-drop-tracking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ where
{
async move { c.connect().await }
//~^ ERROR `C` does not live long enough
//~| ERROR `C` may not live long enough
}

fn main() {}
16 changes: 14 additions & 2 deletions tests/ui/borrowck/erase-error-in-mir-drop-tracking.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,18 @@ error: `C` does not live long enough
LL | async move { c.connect().await }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error: aborting due to 2 previous errors
error[E0310]: the parameter type `C` may not live long enough
--> $DIR/erase-error-in-mir-drop-tracking.rs:19:5
|
LL | async move { c.connect().await }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ...so that the type `C` will meet its required lifetime bounds
|
help: consider adding an explicit lifetime bound...
|
LL | C: Client + Send + Sync + 'static,
| +++++++++

error: aborting due to 3 previous errors

For more information about this error, try `rustc --explain E0261`.
Some errors have detailed explanations: E0261, E0310.
For more information about an error, try `rustc --explain E0261`.
21 changes: 21 additions & 0 deletions tests/ui/impl-trait/wf-check-hidden-type.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
//! Regression test for #114728.

trait Extend<'a, 'b> {
fn extend(self, _: &'a str) -> &'b str;
}

impl<'a, 'b> Extend<'a, 'b> for Option<&'b &'a ()> {
fn extend(self, s: &'a str) -> &'b str {
s
}
}

fn boom<'a, 'b>() -> impl Extend<'a, 'b> {
None::<&'_ &'_ ()>
//~^ ERROR lifetime may not live long enough
}

fn main() {
let y = boom().extend(&String::from("temporary"));
println!("{}", y);
}
14 changes: 14 additions & 0 deletions tests/ui/impl-trait/wf-check-hidden-type.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
error: lifetime may not live long enough
--> $DIR/wf-check-hidden-type.rs:14:5
|
LL | fn boom<'a, 'b>() -> impl Extend<'a, 'b> {
| -- -- lifetime `'b` defined here
| |
| lifetime `'a` defined here
LL | None::<&'_ &'_ ()>
| ^^^^^^^^^^^^^^^^^^ function was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a`
|
= help: consider adding the following bound: `'a: 'b`

error: aborting due to previous error

Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
error[E0277]: `impl Future<Output = ()>` cannot be sent between threads safely
--> $DIR/auto-with-drop_tracking_mir.rs:25:13
--> $DIR/auto-with-drop_tracking_mir.rs:28:13
|
LL | is_send(foo());
| ------- ^^^^^ `impl Future<Output = ()>` cannot be sent between threads safely
Expand All @@ -8,7 +8,7 @@ LL | is_send(foo());
|
= help: the trait `Send` is not implemented for `impl Future<Output = ()>`
note: required by a bound in `is_send`
--> $DIR/auto-with-drop_tracking_mir.rs:24:24
--> $DIR/auto-with-drop_tracking_mir.rs:27:24
|
LL | fn is_send(_: impl Send) {}
| ^^^^ required by this bound in `is_send`
Expand Down
5 changes: 4 additions & 1 deletion tests/ui/traits/new-solver/auto-with-drop_tracking_mir.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
// compile-flags: -Ztrait-solver=next -Zdrop-tracking-mir
// edition: 2021
// revisions: pass fail
//[pass] check-pass
//[pass] check-fail
// WARN new-solver BUG.

#![feature(negative_impls)]

struct NotSync;
impl !Sync for NotSync {}

async fn foo() {
//[pass]~^ ERROR type mismatch
#[cfg(pass)]
let x = &();
#[cfg(fail)]
Expand All @@ -19,6 +21,7 @@ async fn foo() {
}

async fn bar() {}
//[pass]~^ ERROR type mismatch

fn main() {
fn is_send(_: impl Send) {}
Expand Down
31 changes: 31 additions & 0 deletions tests/ui/type-alias-impl-trait/wf-check-definition-site.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
//! Regression test for #114572.
//! We were inferring an ill-formed type:
//! `Opaque<'a> = Static<&'a str>`, vs
//! `Opaque<'a> = Static<&'static str>`.
// check-pass

#![feature(type_alias_impl_trait)]

struct Static<T: 'static>(T);

type OpaqueRet<'a> = impl Sized + 'a;
fn test_return<'a>(msg: Static<&'static u8>) -> OpaqueRet<'a> {
msg
}

type OpaqueAssign<'a> = impl Sized + 'a;
fn test_assign<'a>(msg: Static<&'static u8>) -> Option<OpaqueAssign<'a>> {
let _: OpaqueAssign<'a> = msg;
None
}

// `OpaqueRef<'a, T> = Ref<'a, T>`, vs
// `OpaqueRef<'a, T> = Ref<'static, T>`.
trait RefAt<'a>: 'a {}
struct Ref<'a, T: RefAt<'a>>(&'a T);
type OpaqueRef<'a, T: RefAt<'static>> = impl Sized + 'a;
fn test_trait<'a, T: RefAt<'static>>(msg: Ref<'static, T>) -> OpaqueRef<'a, T> {
msg
}

fn main() {}
2 changes: 1 addition & 1 deletion tests/ui/type-alias-impl-trait/wf-nested.fail.stderr
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
error[E0310]: the parameter type `T` may not live long enough
--> $DIR/wf-nested.rs:55:27
--> $DIR/wf-nested.rs:57:27
|
LL | type InnerOpaque<T> = impl Sized;
| ^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds...
Expand Down
2 changes: 1 addition & 1 deletion tests/ui/type-alias-impl-trait/wf-nested.pass_sound.stderr
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
error[E0310]: the parameter type `T` may not live long enough
--> $DIR/wf-nested.rs:46:17
--> $DIR/wf-nested.rs:48:17
|
LL | let _ = outer.get();
| ^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds
Expand Down
2 changes: 2 additions & 0 deletions tests/ui/type-alias-impl-trait/wf-nested.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ mod pass {
use super::*;
type OuterOpaque<T> = impl Trait<&'static T, Out = impl Sized>;
fn define<T>() -> OuterOpaque<T> {}

fn define_rpit<T>() -> impl Trait<&'static T, Out = impl Sized> {}
}

// Test the soundness of `pass` - We should require `T: 'static` at the use site.
Expand Down