Skip to content

Commit 83930b0

Browse files
committed
wf-check hidden types at definition site
1 parent 6b29036 commit 83930b0

12 files changed

+104
-7
lines changed

compiler/rustc_infer/src/infer/nll_relate/mod.rs

+8
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,10 @@ where
254254
.handle_opaque_type(a, b, true, &cause, self.delegate.param_env())?
255255
.obligations;
256256
self.delegate.register_obligations(obligations);
257+
self.register_predicates([
258+
ty::ClauseKind::WellFormed(a.into()),
259+
ty::ClauseKind::WellFormed(b.into()),
260+
]);
257261
trace!(a = ?a.kind(), b = ?b.kind(), "opaque type instantiated");
258262
Ok(a)
259263
}
@@ -687,6 +691,10 @@ where
687691
}
688692

689693
fn register_type_relate_obligation(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) {
694+
self.register_predicates([
695+
ty::ClauseKind::WellFormed(a.into()),
696+
ty::ClauseKind::WellFormed(b.into()),
697+
]);
690698
self.register_predicates([ty::Binder::dummy(match self.ambient_variance {
691699
ty::Variance::Covariant => ty::PredicateKind::AliasRelate(
692700
a.into(),

compiler/rustc_trait_selection/src/solve/alias_relate.rs

+5
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,11 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
134134
Invert::Yes => (other, fresh),
135135
};
136136
self.sub(param_env, sub, sup)?;
137+
self.add_goal(Goal::new(
138+
self.tcx(),
139+
param_env,
140+
ty::ClauseKind::WellFormed(fresh.into()),
141+
));
137142
fresh
138143
}
139144
};

tests/ui/borrowck/erase-error-in-mir-drop-tracking.rs

+1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ where
1818
{
1919
async move { c.connect().await }
2020
//~^ ERROR `C` does not live long enough
21+
//~| ERROR `C` may not live long enough
2122
}
2223

2324
fn main() {}

tests/ui/borrowck/erase-error-in-mir-drop-tracking.stderr

+14-2
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,18 @@ error: `C` does not live long enough
1919
LL | async move { c.connect().await }
2020
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2121

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

24-
For more information about this error, try `rustc --explain E0261`.
35+
Some errors have detailed explanations: E0261, E0310.
36+
For more information about an error, try `rustc --explain E0261`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
//! Regression test for #114728.
2+
3+
trait Extend<'a, 'b> {
4+
fn extend(self, _: &'a str) -> &'b str;
5+
}
6+
7+
impl<'a, 'b> Extend<'a, 'b> for Option<&'b &'a ()> {
8+
fn extend(self, s: &'a str) -> &'b str {
9+
s
10+
}
11+
}
12+
13+
fn boom<'a, 'b>() -> impl Extend<'a, 'b> {
14+
None::<&'_ &'_ ()>
15+
//~^ ERROR lifetime may not live long enough
16+
}
17+
18+
fn main() {
19+
let y = boom().extend(&String::from("temporary"));
20+
println!("{}", y);
21+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
error: lifetime may not live long enough
2+
--> $DIR/wf-check-hidden-type.rs:14:5
3+
|
4+
LL | fn boom<'a, 'b>() -> impl Extend<'a, 'b> {
5+
| -- -- lifetime `'b` defined here
6+
| |
7+
| lifetime `'a` defined here
8+
LL | None::<&'_ &'_ ()>
9+
| ^^^^^^^^^^^^^^^^^^ function was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a`
10+
|
11+
= help: consider adding the following bound: `'a: 'b`
12+
13+
error: aborting due to previous error
14+

tests/ui/traits/new-solver/auto-with-drop_tracking_mir.fail.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error[E0277]: `impl Future<Output = ()>` cannot be sent between threads safely
2-
--> $DIR/auto-with-drop_tracking_mir.rs:25:13
2+
--> $DIR/auto-with-drop_tracking_mir.rs:28:13
33
|
44
LL | is_send(foo());
55
| ------- ^^^^^ `impl Future<Output = ()>` cannot be sent between threads safely
@@ -8,7 +8,7 @@ LL | is_send(foo());
88
|
99
= help: the trait `Send` is not implemented for `impl Future<Output = ()>`
1010
note: required by a bound in `is_send`
11-
--> $DIR/auto-with-drop_tracking_mir.rs:24:24
11+
--> $DIR/auto-with-drop_tracking_mir.rs:27:24
1212
|
1313
LL | fn is_send(_: impl Send) {}
1414
| ^^^^ required by this bound in `is_send`

tests/ui/traits/new-solver/auto-with-drop_tracking_mir.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,16 @@
11
// compile-flags: -Ztrait-solver=next -Zdrop-tracking-mir
22
// edition: 2021
33
// revisions: pass fail
4-
//[pass] check-pass
4+
//[pass] check-fail
5+
// WARN new-solver BUG.
56

67
#![feature(negative_impls)]
78

89
struct NotSync;
910
impl !Sync for NotSync {}
1011

1112
async fn foo() {
13+
//[pass]~^ ERROR type mismatch
1214
#[cfg(pass)]
1315
let x = &();
1416
#[cfg(fail)]
@@ -19,6 +21,7 @@ async fn foo() {
1921
}
2022

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

2326
fn main() {
2427
fn is_send(_: impl Send) {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
//! Regression test for #114572.
2+
//! We were inferring an ill-formed type:
3+
//! `Opaque<'a> = Static<&'a str>`, vs
4+
//! `Opaque<'a> = Static<&'static str>`.
5+
// check-pass
6+
7+
#![feature(type_alias_impl_trait)]
8+
9+
struct Static<T: 'static>(T);
10+
11+
type OpaqueRet<'a> = impl Sized + 'a;
12+
fn test_return<'a>(msg: Static<&'static u8>) -> OpaqueRet<'a> {
13+
msg
14+
}
15+
16+
type OpaqueAssign<'a> = impl Sized + 'a;
17+
fn test_assign<'a>(msg: Static<&'static u8>) -> Option<OpaqueAssign<'a>> {
18+
let _: OpaqueAssign<'a> = msg;
19+
None
20+
}
21+
22+
// `OpaqueRef<'a, T> = Ref<'a, T>`, vs
23+
// `OpaqueRef<'a, T> = Ref<'static, T>`.
24+
trait RefAt<'a>: 'a {}
25+
struct Ref<'a, T: RefAt<'a>>(&'a T);
26+
type OpaqueRef<'a, T: RefAt<'static>> = impl Sized + 'a;
27+
fn test_trait<'a, T: RefAt<'static>>(msg: Ref<'static, T>) -> OpaqueRef<'a, T> {
28+
msg
29+
}
30+
31+
fn main() {}

tests/ui/type-alias-impl-trait/wf-nested.fail.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error[E0310]: the parameter type `T` may not live long enough
2-
--> $DIR/wf-nested.rs:55:27
2+
--> $DIR/wf-nested.rs:57:27
33
|
44
LL | type InnerOpaque<T> = impl Sized;
55
| ^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds...

tests/ui/type-alias-impl-trait/wf-nested.pass_sound.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error[E0310]: the parameter type `T` may not live long enough
2-
--> $DIR/wf-nested.rs:46:17
2+
--> $DIR/wf-nested.rs:48:17
33
|
44
LL | let _ = outer.get();
55
| ^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds

tests/ui/type-alias-impl-trait/wf-nested.rs

+2
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ mod pass {
3232
use super::*;
3333
type OuterOpaque<T> = impl Trait<&'static T, Out = impl Sized>;
3434
fn define<T>() -> OuterOpaque<T> {}
35+
36+
fn define_rpit<T>() -> impl Trait<&'static T, Out = impl Sized> {}
3537
}
3638

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

0 commit comments

Comments
 (0)