Skip to content

Commit 628a858

Browse files
committed
Remove hacky inference hint in unsizing
1 parent f7b4354 commit 628a858

File tree

5 files changed

+246
-50
lines changed

5 files changed

+246
-50
lines changed

compiler/rustc_hir_typeck/src/coercion.rs

+2-25
Original file line numberDiff line numberDiff line change
@@ -694,31 +694,8 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
694694
match selcx.select(&obligation.with(selcx.tcx(), trait_pred)) {
695695
// Uncertain or unimplemented.
696696
Ok(None) => {
697-
if trait_pred.def_id() == unsize_did {
698-
let self_ty = trait_pred.self_ty();
699-
let unsize_ty = trait_pred.trait_ref.args[1].expect_ty();
700-
debug!("coerce_unsized: ambiguous unsize case for {:?}", trait_pred);
701-
match (self_ty.kind(), unsize_ty.kind()) {
702-
(&ty::Infer(ty::TyVar(v)), ty::Dynamic(..))
703-
if self.type_var_is_sized(v) =>
704-
{
705-
debug!("coerce_unsized: have sized infer {:?}", v);
706-
coercion.obligations.push(obligation);
707-
// `$0: Unsize<dyn Trait>` where we know that `$0: Sized`, try going
708-
// for unsizing.
709-
}
710-
_ => {
711-
// Some other case for `$0: Unsize<Something>`. Note that we
712-
// hit this case even if `Something` is a sized type, so just
713-
// don't do the coercion.
714-
debug!("coerce_unsized: ambiguous unsize");
715-
return Err(TypeError::Mismatch);
716-
}
717-
}
718-
} else {
719-
debug!("coerce_unsized: early return - ambiguous");
720-
return Err(TypeError::Mismatch);
721-
}
697+
debug!("coerce_unsized: early return - ambiguous");
698+
return Err(TypeError::Mismatch);
722699
}
723700
Err(traits::Unimplemented) => {
724701
debug!("coerce_unsized: early return - can't prove obligation");

compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs

-12
Original file line numberDiff line numberDiff line change
@@ -701,18 +701,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
701701
ret_ty.builtin_deref(true).unwrap()
702702
}
703703

704-
pub(crate) fn type_var_is_sized(&self, self_ty: ty::TyVid) -> bool {
705-
let sized_did = self.tcx.lang_items().sized_trait();
706-
self.obligations_for_self_ty(self_ty).into_iter().any(|obligation| {
707-
match obligation.predicate.kind().skip_binder() {
708-
ty::PredicateKind::Clause(ty::ClauseKind::Trait(data)) => {
709-
Some(data.def_id()) == sized_did
710-
}
711-
_ => false,
712-
}
713-
})
714-
}
715-
716704
pub(crate) fn err_args(&self, len: usize, guar: ErrorGuaranteed) -> Vec<Ty<'tcx>> {
717705
let ty_error = Ty::new_error(self.tcx, guar);
718706
vec![ty_error; len]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
error[E0277]: the size for values of type `dyn std::error::Error` cannot be known at compilation time
2+
--> $DIR/coerce-issue-49593-box-never.rs:26:27
3+
|
4+
LL | Box::<_ /* ! */>::new(x)
5+
| --------------------- ^ doesn't have a size known at compile-time
6+
| |
7+
| required by a bound introduced by this call
8+
|
9+
= help: the trait `Sized` is not implemented for `dyn std::error::Error`
10+
note: required by a bound in `Box::<T>::new`
11+
--> $SRC_DIR/alloc/src/boxed.rs:LL:COL
12+
13+
error[E0277]: the size for values of type `(dyn std::error::Error + 'static)` cannot be known at compilation time
14+
--> $DIR/coerce-issue-49593-box-never.rs:32:19
15+
|
16+
LL | raw_ptr_box::<_ /* ! */>(x)
17+
| ^ doesn't have a size known at compile-time
18+
|
19+
= help: the trait `Sized` is not implemented for `(dyn std::error::Error + 'static)`
20+
note: required by an implicit `Sized` bound in `raw_ptr_box`
21+
--> $DIR/coerce-issue-49593-box-never.rs:19:16
22+
|
23+
LL | fn raw_ptr_box<T>(t: T) -> *mut T {
24+
| ^ required by the implicit `Sized` requirement on this type parameter in `raw_ptr_box`
25+
help: consider relaxing the implicit `Sized` restriction
26+
|
27+
LL | fn raw_ptr_box<T: ?Sized>(t: T) -> *mut T {
28+
| ++++++++
29+
30+
error[E0277]: the size for values of type `(dyn std::error::Error + 'static)` cannot be known at compilation time
31+
--> $DIR/coerce-issue-49593-box-never.rs:32:30
32+
|
33+
LL | raw_ptr_box::<_ /* ! */>(x)
34+
| ^ doesn't have a size known at compile-time
35+
|
36+
= help: the trait `Sized` is not implemented for `(dyn std::error::Error + 'static)`
37+
= note: all function arguments must have a statically known size
38+
= help: unsized fn params are gated as an unstable feature
39+
40+
error[E0277]: the size for values of type `dyn Xyz` cannot be known at compilation time
41+
--> $DIR/coerce-issue-49593-box-never.rs:57:70
42+
|
43+
LL | = /* Box<$0> is coerced to Box<Xyz> here */ Box::new(x.unwrap());
44+
| -------- ^^^^^^^^^^ doesn't have a size known at compile-time
45+
| |
46+
| required by a bound introduced by this call
47+
|
48+
= help: the trait `Sized` is not implemented for `dyn Xyz`
49+
note: required by a bound in `Box::<T>::new`
50+
--> $SRC_DIR/alloc/src/boxed.rs:LL:COL
51+
help: consider removing this method call, as the receiver has type `Option<_>` and `Option<_>: Sized` trivially holds
52+
|
53+
LL - = /* Box<$0> is coerced to Box<Xyz> here */ Box::new(x.unwrap());
54+
LL + = /* Box<$0> is coerced to Box<Xyz> here */ Box::new(x);
55+
|
56+
57+
error[E0277]: the size for values of type `dyn Xyz` cannot be known at compilation time
58+
--> $DIR/coerce-issue-49593-box-never.rs:57:72
59+
|
60+
LL | = /* Box<$0> is coerced to Box<Xyz> here */ Box::new(x.unwrap());
61+
| ^^^^^^ doesn't have a size known at compile-time
62+
|
63+
= help: the trait `Sized` is not implemented for `dyn Xyz`
64+
note: required by a bound in `Option::<T>::unwrap`
65+
--> $SRC_DIR/core/src/option.rs:LL:COL
66+
67+
error[E0277]: the size for values of type `dyn Xyz` cannot be known at compilation time
68+
--> $DIR/coerce-issue-49593-box-never.rs:50:35
69+
|
70+
LL | let mut x /* : Option<S> */ = None;
71+
| ^^^^ doesn't have a size known at compile-time
72+
|
73+
= help: the trait `Sized` is not implemented for `dyn Xyz`
74+
note: required by a bound in `None`
75+
--> $SRC_DIR/core/src/option.rs:LL:COL
76+
77+
error[E0308]: mismatched types
78+
--> $DIR/coerce-issue-49593-box-never.rs:62:13
79+
|
80+
LL | let mut x /* : Option<S> */ = None;
81+
| ---- expected due to this value
82+
...
83+
LL | x = Some(S);
84+
| ^^^^^^^ expected `Option<dyn Xyz>`, found `Option<S>`
85+
|
86+
= note: expected enum `Option<dyn Xyz>`
87+
found enum `Option<S>`
88+
= help: `S` implements `Xyz` so you could box the found value and coerce it to the trait object `Box<dyn Xyz>`, you will have to change the expected type as well
89+
90+
error[E0277]: the size for values of type `dyn Xyz` cannot be known at compilation time
91+
--> $DIR/coerce-issue-49593-box-never.rs:69:5
92+
|
93+
LL | mem::swap(&mut x, &mut y);
94+
| ^^^^^^^^^ doesn't have a size known at compile-time
95+
|
96+
= help: the trait `Sized` is not implemented for `dyn Xyz`
97+
note: required by an implicit `Sized` bound in `Option`
98+
--> $SRC_DIR/core/src/option.rs:LL:COL
99+
100+
error[E0308]: mismatched types
101+
--> $DIR/coerce-issue-49593-box-never.rs:69:23
102+
|
103+
LL | mem::swap(&mut x, &mut y);
104+
| --------- ^^^^^^ expected `&mut Option<dyn Xyz>`, found `&mut Option<S>`
105+
| |
106+
| arguments to this function are incorrect
107+
|
108+
= note: expected mutable reference `&mut Option<dyn Xyz>`
109+
found mutable reference `&mut Option<S>`
110+
= help: `S` implements `Xyz` so you could box the found value and coerce it to the trait object `Box<dyn Xyz>`, you will have to change the expected type as well
111+
note: function defined here
112+
--> $SRC_DIR/core/src/mem/mod.rs:LL:COL
113+
114+
error: aborting due to 9 previous errors
115+
116+
Some errors have detailed explanations: E0277, E0308.
117+
For more information about an error, try `rustc --explain E0277`.
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,117 @@
1-
error[E0277]: the trait bound `(): std::error::Error` is not satisfied
2-
--> $DIR/coerce-issue-49593-box-never.rs:18:5
1+
error[E0277]: the size for values of type `dyn std::error::Error` cannot be known at compilation time
2+
--> $DIR/coerce-issue-49593-box-never.rs:26:27
33
|
44
LL | Box::<_ /* ! */>::new(x)
5-
| ^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::error::Error` is not implemented for `()`
5+
| --------------------- ^ doesn't have a size known at compile-time
6+
| |
7+
| required by a bound introduced by this call
68
|
7-
= note: required for the cast from `Box<()>` to `Box<(dyn std::error::Error + 'static)>`
9+
= help: the trait `Sized` is not implemented for `dyn std::error::Error`
10+
note: required by a bound in `Box::<T>::new`
11+
--> $SRC_DIR/alloc/src/boxed.rs:LL:COL
812

9-
error[E0277]: the trait bound `(): std::error::Error` is not satisfied
10-
--> $DIR/coerce-issue-49593-box-never.rs:24:5
13+
error[E0277]: the size for values of type `(dyn std::error::Error + 'static)` cannot be known at compilation time
14+
--> $DIR/coerce-issue-49593-box-never.rs:32:19
1115
|
1216
LL | raw_ptr_box::<_ /* ! */>(x)
13-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::error::Error` is not implemented for `()`
17+
| ^ doesn't have a size known at compile-time
1418
|
15-
= note: required for the cast from `*mut ()` to `*mut (dyn std::error::Error + 'static)`
19+
= help: the trait `Sized` is not implemented for `(dyn std::error::Error + 'static)`
20+
note: required by an implicit `Sized` bound in `raw_ptr_box`
21+
--> $DIR/coerce-issue-49593-box-never.rs:19:16
22+
|
23+
LL | fn raw_ptr_box<T>(t: T) -> *mut T {
24+
| ^ required by the implicit `Sized` requirement on this type parameter in `raw_ptr_box`
25+
help: consider relaxing the implicit `Sized` restriction
26+
|
27+
LL | fn raw_ptr_box<T: ?Sized>(t: T) -> *mut T {
28+
| ++++++++
29+
30+
error[E0277]: the size for values of type `(dyn std::error::Error + 'static)` cannot be known at compilation time
31+
--> $DIR/coerce-issue-49593-box-never.rs:32:30
32+
|
33+
LL | raw_ptr_box::<_ /* ! */>(x)
34+
| ^ doesn't have a size known at compile-time
35+
|
36+
= help: the trait `Sized` is not implemented for `(dyn std::error::Error + 'static)`
37+
= note: all function arguments must have a statically known size
38+
= help: unsized fn params are gated as an unstable feature
39+
40+
error[E0277]: the size for values of type `dyn Xyz` cannot be known at compilation time
41+
--> $DIR/coerce-issue-49593-box-never.rs:57:70
42+
|
43+
LL | = /* Box<$0> is coerced to Box<Xyz> here */ Box::new(x.unwrap());
44+
| -------- ^^^^^^^^^^ doesn't have a size known at compile-time
45+
| |
46+
| required by a bound introduced by this call
47+
|
48+
= help: the trait `Sized` is not implemented for `dyn Xyz`
49+
note: required by a bound in `Box::<T>::new`
50+
--> $SRC_DIR/alloc/src/boxed.rs:LL:COL
51+
help: consider removing this method call, as the receiver has type `Option<_>` and `Option<_>: Sized` trivially holds
52+
|
53+
LL - = /* Box<$0> is coerced to Box<Xyz> here */ Box::new(x.unwrap());
54+
LL + = /* Box<$0> is coerced to Box<Xyz> here */ Box::new(x);
55+
|
56+
57+
error[E0277]: the size for values of type `dyn Xyz` cannot be known at compilation time
58+
--> $DIR/coerce-issue-49593-box-never.rs:57:72
59+
|
60+
LL | = /* Box<$0> is coerced to Box<Xyz> here */ Box::new(x.unwrap());
61+
| ^^^^^^ doesn't have a size known at compile-time
62+
|
63+
= help: the trait `Sized` is not implemented for `dyn Xyz`
64+
note: required by a bound in `Option::<T>::unwrap`
65+
--> $SRC_DIR/core/src/option.rs:LL:COL
66+
67+
error[E0277]: the size for values of type `dyn Xyz` cannot be known at compilation time
68+
--> $DIR/coerce-issue-49593-box-never.rs:50:35
69+
|
70+
LL | let mut x /* : Option<S> */ = None;
71+
| ^^^^ doesn't have a size known at compile-time
72+
|
73+
= help: the trait `Sized` is not implemented for `dyn Xyz`
74+
note: required by a bound in `None`
75+
--> $SRC_DIR/core/src/option.rs:LL:COL
76+
77+
error[E0308]: mismatched types
78+
--> $DIR/coerce-issue-49593-box-never.rs:62:13
79+
|
80+
LL | let mut x /* : Option<S> */ = None;
81+
| ---- expected due to this value
82+
...
83+
LL | x = Some(S);
84+
| ^^^^^^^ expected `Option<dyn Xyz>`, found `Option<S>`
85+
|
86+
= note: expected enum `Option<dyn Xyz>`
87+
found enum `Option<S>`
88+
= help: `S` implements `Xyz` so you could box the found value and coerce it to the trait object `Box<dyn Xyz>`, you will have to change the expected type as well
89+
90+
error[E0277]: the size for values of type `dyn Xyz` cannot be known at compilation time
91+
--> $DIR/coerce-issue-49593-box-never.rs:69:5
92+
|
93+
LL | mem::swap(&mut x, &mut y);
94+
| ^^^^^^^^^ doesn't have a size known at compile-time
95+
|
96+
= help: the trait `Sized` is not implemented for `dyn Xyz`
97+
note: required by an implicit `Sized` bound in `Option`
98+
--> $SRC_DIR/core/src/option.rs:LL:COL
99+
100+
error[E0308]: mismatched types
101+
--> $DIR/coerce-issue-49593-box-never.rs:69:23
102+
|
103+
LL | mem::swap(&mut x, &mut y);
104+
| --------- ^^^^^^ expected `&mut Option<dyn Xyz>`, found `&mut Option<S>`
105+
| |
106+
| arguments to this function are incorrect
107+
|
108+
= note: expected mutable reference `&mut Option<dyn Xyz>`
109+
found mutable reference `&mut Option<S>`
110+
= help: `S` implements `Xyz` so you could box the found value and coerce it to the trait object `Box<dyn Xyz>`, you will have to change the expected type as well
111+
note: function defined here
112+
--> $SRC_DIR/core/src/mem/mod.rs:LL:COL
16113

17-
error: aborting due to 2 previous errors
114+
error: aborting due to 9 previous errors
18115

19-
For more information about this error, try `rustc --explain E0277`.
116+
Some errors have detailed explanations: E0277, E0308.
117+
For more information about an error, try `rustc --explain E0277`.

tests/ui/coercion/coerce-issue-49593-box-never.rs

+19-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,13 @@
1+
//! This test was supposed to test that unsizing an uninferred but
2+
//! `Sized` type works and will let inference happen later.
3+
//! The issue was that what instead happened was that the inference
4+
//! variable got equated to the unsized type, and subsequently failed
5+
//! the `Sized` check.
6+
//!
7+
//! This was a wart in our coercion code, so it was removed to be instead
8+
//! implemented in the trait system.
9+
110
//@ revisions: nofallback fallback
2-
//@[fallback] check-pass
311

412
#![feature(never_type)]
513
#![cfg_attr(fallback, feature(never_type_fallback))]
@@ -16,13 +24,14 @@ fn foo(x: !) -> Box<dyn Error> {
1624
// Method resolution will generate new inference vars and relate them.
1725
// Thus fallback will not fall back to `!`, but `()` instead.
1826
Box::<_ /* ! */>::new(x)
19-
//[nofallback]~^ ERROR trait bound `(): std::error::Error` is not satisfied
27+
//~^ ERROR cannot be known at compilation time
2028
}
2129

2230
fn foo_raw_ptr(x: !) -> *mut dyn Error {
2331
/* *mut $0 is coerced to *mut Error here */
2432
raw_ptr_box::<_ /* ! */>(x)
25-
//[nofallback]~^ ERROR trait bound `(): std::error::Error` is not satisfied
33+
//~^ ERROR cannot be known at compilation time
34+
//~| ERROR cannot be known at compilation time
2635
}
2736

2837
fn no_coercion(d: *mut dyn Error) -> *mut dyn Error {
@@ -39,20 +48,27 @@ impl Xyz for T {}
3948

4049
fn foo_no_never() {
4150
let mut x /* : Option<S> */ = None;
51+
//~^ ERROR cannot be known at compilation time
52+
4253
let mut first_iter = false;
4354
loop {
4455
if !first_iter {
4556
let y: Box<dyn Xyz>
4657
= /* Box<$0> is coerced to Box<Xyz> here */ Box::new(x.unwrap());
58+
//~^ ERROR cannot be known at compilation time
59+
//~| ERROR cannot be known at compilation time
4760
}
4861

4962
x = Some(S);
63+
//~^ ERROR mismatched types
5064
first_iter = true;
5165
}
5266

5367
let mut y: Option<S> = None;
5468
// assert types are equal
5569
mem::swap(&mut x, &mut y);
70+
//~^ ERROR cannot be known at compilation time
71+
//~| ERROR mismatched types
5672
}
5773

5874
fn main() {}

0 commit comments

Comments
 (0)