Skip to content

Commit 507afda

Browse files
Don't consider sized type variables in coerce_unsized
1 parent d137783 commit 507afda

File tree

3 files changed

+114
-51
lines changed

3 files changed

+114
-51
lines changed

compiler/rustc_hir_typeck/src/coercion.rs

Lines changed: 1 addition & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -639,35 +639,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
639639
};
640640
match selcx.select(&obligation.with(selcx.tcx(), trait_pred)) {
641641
// Uncertain or unimplemented.
642-
Ok(None) => {
643-
if trait_pred.def_id() == unsize_did {
644-
let trait_pred = self.resolve_vars_if_possible(trait_pred);
645-
let self_ty = trait_pred.skip_binder().self_ty();
646-
let unsize_ty = trait_pred.skip_binder().trait_ref.substs[1].expect_ty();
647-
debug!("coerce_unsized: ambiguous unsize case for {:?}", trait_pred);
648-
match (&self_ty.kind(), &unsize_ty.kind()) {
649-
(ty::Infer(ty::TyVar(v)), ty::Dynamic(..))
650-
if self.type_var_is_sized(*v) =>
651-
{
652-
debug!("coerce_unsized: have sized infer {:?}", v);
653-
coercion.obligations.push(obligation);
654-
// `$0: Unsize<dyn Trait>` where we know that `$0: Sized`, try going
655-
// for unsizing.
656-
}
657-
_ => {
658-
// Some other case for `$0: Unsize<Something>`. Note that we
659-
// hit this case even if `Something` is a sized type, so just
660-
// don't do the coercion.
661-
debug!("coerce_unsized: ambiguous unsize");
662-
return Err(TypeError::Mismatch);
663-
}
664-
}
665-
} else {
666-
debug!("coerce_unsized: early return - ambiguous");
667-
return Err(TypeError::Mismatch);
668-
}
669-
}
670-
Err(traits::Unimplemented) => {
642+
Ok(None) | Err(traits::Unimplemented) => {
671643
debug!("coerce_unsized: early return - can't prove obligation");
672644
return Err(TypeError::Mismatch);
673645
}

compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -669,18 +669,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
669669
)
670670
}
671671

672-
pub(in super::super) fn type_var_is_sized(&self, self_ty: ty::TyVid) -> bool {
673-
let sized_did = self.tcx.lang_items().sized_trait();
674-
self.obligations_for_self_ty(self_ty).any(|obligation| {
675-
match obligation.predicate.kind().skip_binder() {
676-
ty::PredicateKind::Clause(ty::Clause::Trait(data)) => {
677-
Some(data.def_id()) == sized_did
678-
}
679-
_ => false,
680-
}
681-
})
682-
}
683-
684672
pub(in super::super) fn err_args(&self, len: usize) -> Vec<Ty<'tcx>> {
685673
vec![self.tcx.ty_error(); len]
686674
}
Lines changed: 113 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,122 @@
1-
error[E0277]: the trait bound `(): std::error::Error` is not satisfied
2-
--> $DIR/coerce-issue-49593-box-never.rs:18:53
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:18:75
33
|
44
LL | /* *mut $0 is coerced to Box<dyn Error> here */ 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 `()` to the object type `dyn std::error::Error`
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+
LL | impl<T> Box<T> {
14+
| ^ required by this bound in `Box::<T>::new`
815

9-
error[E0277]: the trait bound `(): std::error::Error` is not satisfied
10-
--> $DIR/coerce-issue-49593-box-never.rs:23:49
16+
error[E0277]: the size for values of type `(dyn std::error::Error + 'static)` cannot be known at compilation time
17+
--> $DIR/coerce-issue-49593-box-never.rs:23:74
1118
|
1219
LL | /* *mut $0 is coerced to *mut Error here */ raw_ptr_box::<_ /* ! */>(x)
13-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::error::Error` is not implemented for `()`
20+
| ------------------------ ^ doesn't have a size known at compile-time
21+
| |
22+
| required by a bound introduced by this call
23+
|
24+
= help: the trait `Sized` is not implemented for `(dyn std::error::Error + 'static)`
25+
note: required by a bound in `raw_ptr_box`
26+
--> $DIR/coerce-issue-49593-box-never.rs:13:16
27+
|
28+
LL | fn raw_ptr_box<T>(t: T) -> *mut T {
29+
| ^ required by this bound in `raw_ptr_box`
30+
help: consider relaxing the implicit `Sized` restriction
31+
|
32+
LL | fn raw_ptr_box<T: ?Sized>(t: T) -> *mut T {
33+
| ++++++++
34+
35+
error[E0277]: the size for values of type `dyn Xyz` cannot be known at compilation time
36+
--> $DIR/coerce-issue-49593-box-never.rs:45:70
37+
|
38+
LL | = /* Box<$0> is coerced to Box<Xyz> here */ Box::new(x.unwrap());
39+
| -------- ^^^^^^^^^^ doesn't have a size known at compile-time
40+
| |
41+
| required by a bound introduced by this call
42+
|
43+
= help: the trait `Sized` is not implemented for `dyn Xyz`
44+
note: required by a bound in `Box::<T>::new`
45+
--> $SRC_DIR/alloc/src/boxed.rs:LL:COL
46+
|
47+
LL | impl<T> Box<T> {
48+
| ^ required by this bound in `Box::<T>::new`
49+
50+
error[E0277]: the size for values of type `dyn Xyz` cannot be known at compilation time
51+
--> $DIR/coerce-issue-49593-box-never.rs:45:70
52+
|
53+
LL | = /* Box<$0> is coerced to Box<Xyz> here */ Box::new(x.unwrap());
54+
| ^ ------ required by a bound introduced by this call
55+
| |
56+
| doesn't have a size known at compile-time
57+
|
58+
= help: the trait `Sized` is not implemented for `dyn Xyz`
59+
note: required by a bound in `Option::<T>::unwrap`
60+
--> $SRC_DIR/core/src/option.rs:LL:COL
61+
|
62+
LL | impl<T> Option<T> {
63+
| ^ required by this bound in `Option::<T>::unwrap`
64+
65+
error[E0277]: the size for values of type `dyn Xyz` cannot be known at compilation time
66+
--> $DIR/coerce-issue-49593-box-never.rs:40:35
67+
|
68+
LL | let mut x /* : Option<S> */ = None;
69+
| ^^^^ doesn't have a size known at compile-time
70+
|
71+
= help: the trait `Sized` is not implemented for `dyn Xyz`
72+
note: required by a bound in `None`
73+
--> $SRC_DIR/core/src/option.rs:LL:COL
74+
|
75+
LL | pub enum Option<T> {
76+
| ^ required by this bound in `None`
77+
78+
error[E0308]: mismatched types
79+
--> $DIR/coerce-issue-49593-box-never.rs:48:13
80+
|
81+
LL | let mut x /* : Option<S> */ = None;
82+
| ---- expected due to this value
83+
...
84+
LL | x = Some(S);
85+
| ^^^^^^^ expected trait object `dyn Xyz`, found struct `S`
86+
|
87+
= note: expected enum `Option<dyn Xyz>`
88+
found enum `Option<S>`
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:54: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 a bound in `Option`
98+
--> $SRC_DIR/core/src/option.rs:LL:COL
99+
|
100+
LL | pub enum Option<T> {
101+
| ^ required by this bound in `Option`
102+
103+
error[E0308]: mismatched types
104+
--> $DIR/coerce-issue-49593-box-never.rs:54:23
105+
|
106+
LL | mem::swap(&mut x, &mut y);
107+
| --------- ^^^^^^ expected trait object `dyn Xyz`, found struct `S`
108+
| |
109+
| arguments to this function are incorrect
110+
|
111+
= note: expected mutable reference `&mut Option<dyn Xyz>`
112+
found mutable reference `&mut Option<S>`
113+
note: function defined here
114+
--> $SRC_DIR/core/src/mem/mod.rs:LL:COL
14115
|
15-
= note: required for the cast from `()` to the object type `(dyn std::error::Error + 'static)`
116+
LL | pub const fn swap<T>(x: &mut T, y: &mut T) {
117+
| ^^^^
16118

17-
error: aborting due to 2 previous errors
119+
error: aborting due to 8 previous errors
18120

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

0 commit comments

Comments
 (0)