Skip to content

Commit 047c4fa

Browse files
Delay all sized checks
1 parent 8fd06e4 commit 047c4fa

32 files changed

+160
-294
lines changed

compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1398,7 +1398,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
13981398
(_, ty)| {
13991399
let ty = self.resolve_vars_if_possible(ty);
14001400
same &=
1401-
!matches!(ty.kind(), ty::Error(_))
1401+
!ty.references_error()
14021402
&& last_ty.map_or(true, |last_ty| {
14031403
// FIXME: ideally we would use `can_coerce` here instead, but `typeck` comes
14041404
// *after* in the dependency graph.

compiler/rustc_typeck/src/check/expr.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -582,7 +582,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
582582
infer::LateBoundRegionConversionTime::FnCall,
583583
fn_sig.output(),
584584
);
585-
self.require_type_is_sized_deferred(output, expr.span, traits::SizedReturnType);
585+
self.require_type_is_sized(output, expr.span, traits::SizedReturnType);
586586
}
587587

588588
// We always require that the type provided as the value for

compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs

+11-5
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ use rustc_errors::{Applicability, Diagnostic, ErrorGuaranteed, MultiSpan};
1313
use rustc_hir as hir;
1414
use rustc_hir::def::{CtorOf, DefKind, Res};
1515
use rustc_hir::def_id::DefId;
16-
use rustc_hir::lang_items::LangItem;
1716
use rustc_hir::{ExprKind, GenericArg, Node, QPath};
1817
use rustc_infer::infer::canonical::{Canonical, OriginalQueryValues, QueryResponse};
1918
use rustc_infer::infer::error_reporting::TypeAnnotationNeeded::E0282;
@@ -437,19 +436,26 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
437436
code: traits::ObligationCauseCode<'tcx>,
438437
) {
439438
if !ty.references_error() {
440-
let lang_item = self.tcx.require_lang_item(LangItem::Sized, None);
441-
self.require_type_meets(ty, span, code, lang_item);
439+
if let Some(deferred_sized_obligations) =
440+
&mut *self.deferred_sized_obligations.borrow_mut()
441+
{
442+
deferred_sized_obligations.push((ty, span, code));
443+
} else {
444+
self.require_type_is_sized_eager(ty, span, code);
445+
}
442446
}
443447
}
444448

445-
pub fn require_type_is_sized_deferred(
449+
pub fn require_type_is_sized_eager(
446450
&self,
447451
ty: Ty<'tcx>,
448452
span: Span,
449453
code: traits::ObligationCauseCode<'tcx>,
450454
) {
455+
let ty = self.normalize_associated_types_in(span, ty);
451456
if !ty.references_error() {
452-
self.deferred_sized_obligations.borrow_mut().push((ty, span, code));
457+
let lang_item = self.tcx.require_lang_item(hir::LangItem::Sized, None);
458+
self.require_type_meets(ty, span, code, lang_item);
453459
}
454460
}
455461

compiler/rustc_typeck/src/check/inherited.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ pub struct Inherited<'a, 'tcx> {
3838
// Some additional `Sized` obligations badly affect type inference.
3939
// These obligations are added in a later stage of typeck.
4040
pub(super) deferred_sized_obligations:
41-
RefCell<Vec<(Ty<'tcx>, Span, traits::ObligationCauseCode<'tcx>)>>,
41+
RefCell<Option<Vec<(Ty<'tcx>, Span, traits::ObligationCauseCode<'tcx>)>>>,
4242

4343
// When we process a call like `c()` where `c` is a closure type,
4444
// we may not have decided yet whether `c` is a `Fn`, `FnMut`, or
@@ -117,7 +117,7 @@ impl<'a, 'tcx> Inherited<'a, 'tcx> {
117117
infcx,
118118
fulfillment_cx: RefCell::new(<dyn TraitEngine<'_>>::new(tcx)),
119119
locals: RefCell::new(Default::default()),
120-
deferred_sized_obligations: RefCell::new(Vec::new()),
120+
deferred_sized_obligations: RefCell::new(Some(Vec::new())),
121121
deferred_call_resolutions: RefCell::new(Default::default()),
122122
deferred_cast_checks: RefCell::new(Vec::new()),
123123
deferred_transmute_checks: RefCell::new(Vec::new()),

compiler/rustc_typeck/src/check/mod.rs

+4-5
Original file line numberDiff line numberDiff line change
@@ -450,6 +450,10 @@ fn typeck_with_fallback<'tcx>(
450450
fcx
451451
};
452452

453+
for (ty, span, code) in fcx.deferred_sized_obligations.borrow_mut().take().unwrap() {
454+
fcx.require_type_is_sized_eager(ty, span, code);
455+
}
456+
453457
let fallback_has_occurred = fcx.type_inference_fallback();
454458

455459
// Even though coercion casts provide type hints, we check casts after fallback for
@@ -466,11 +470,6 @@ fn typeck_with_fallback<'tcx>(
466470
fcx.resolve_rvalue_scopes(def_id.to_def_id());
467471
fcx.resolve_generator_interiors(def_id.to_def_id());
468472

469-
for (ty, span, code) in fcx.deferred_sized_obligations.borrow_mut().drain(..) {
470-
let ty = fcx.normalize_ty(span, ty);
471-
fcx.require_type_is_sized(ty, span, code);
472-
}
473-
474473
fcx.select_all_obligations_or_error();
475474

476475
if !fcx.infcx.is_tainted_by_errors() {

src/test/ui/asm/type-check-1.rs

+2-4
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,9 @@ fn main() {
2424
//~^ ERROR the size for values of type `[u64]` cannot be known at compilation time
2525
//~| ERROR cannot use value of type `[u64]` for inline assembly
2626
asm!("{}", out(reg) v[..]);
27-
//~^ ERROR the size for values of type `[u64]` cannot be known at compilation time
28-
//~| ERROR cannot use value of type `[u64]` for inline assembly
27+
//~^ ERROR cannot use value of type `[u64]` for inline assembly
2928
asm!("{}", inout(reg) v[..]);
30-
//~^ ERROR the size for values of type `[u64]` cannot be known at compilation time
31-
//~| ERROR cannot use value of type `[u64]` for inline assembly
29+
//~^ ERROR cannot use value of type `[u64]` for inline assembly
3230

3331
// Constants must be... constant
3432

src/test/ui/asm/type-check-1.stderr

+11-29
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error[E0435]: attempt to use a non-constant value in a constant
2-
--> $DIR/type-check-1.rs:42:26
2+
--> $DIR/type-check-1.rs:40:26
33
|
44
LL | let x = 0;
55
| ----- help: consider using `const` instead of `let`: `const x`
@@ -8,7 +8,7 @@ LL | asm!("{}", const x);
88
| ^ non-constant value
99

1010
error[E0435]: attempt to use a non-constant value in a constant
11-
--> $DIR/type-check-1.rs:45:36
11+
--> $DIR/type-check-1.rs:43:36
1212
|
1313
LL | let x = 0;
1414
| ----- help: consider using `const` instead of `let`: `const x`
@@ -17,7 +17,7 @@ LL | asm!("{}", const const_foo(x));
1717
| ^ non-constant value
1818

1919
error[E0435]: attempt to use a non-constant value in a constant
20-
--> $DIR/type-check-1.rs:48:36
20+
--> $DIR/type-check-1.rs:46:36
2121
|
2222
LL | let x = 0;
2323
| ----- help: consider using `const` instead of `let`: `const x`
@@ -26,7 +26,7 @@ LL | asm!("{}", const const_bar(x));
2626
| ^ non-constant value
2727

2828
error: invalid `sym` operand
29-
--> $DIR/type-check-1.rs:50:24
29+
--> $DIR/type-check-1.rs:48:24
3030
|
3131
LL | asm!("{}", sym x);
3232
| ^ is a local variable
@@ -54,24 +54,6 @@ LL | asm!("{}", in(reg) v[..]);
5454
= help: the trait `Sized` is not implemented for `[u64]`
5555
= note: all inline asm arguments must have a statically known size
5656

57-
error[E0277]: the size for values of type `[u64]` cannot be known at compilation time
58-
--> $DIR/type-check-1.rs:26:29
59-
|
60-
LL | asm!("{}", out(reg) v[..]);
61-
| ^^^^^ doesn't have a size known at compile-time
62-
|
63-
= help: the trait `Sized` is not implemented for `[u64]`
64-
= note: all inline asm arguments must have a statically known size
65-
66-
error[E0277]: the size for values of type `[u64]` cannot be known at compilation time
67-
--> $DIR/type-check-1.rs:29:31
68-
|
69-
LL | asm!("{}", inout(reg) v[..]);
70-
| ^^^^^ doesn't have a size known at compile-time
71-
|
72-
= help: the trait `Sized` is not implemented for `[u64]`
73-
= note: all inline asm arguments must have a statically known size
74-
7557
error: cannot use value of type `[u64]` for inline assembly
7658
--> $DIR/type-check-1.rs:23:28
7759
|
@@ -89,21 +71,21 @@ LL | asm!("{}", out(reg) v[..]);
8971
= note: only integers, floats, SIMD vectors, pointers and function pointers can be used as arguments for inline assembly
9072

9173
error: cannot use value of type `[u64]` for inline assembly
92-
--> $DIR/type-check-1.rs:29:31
74+
--> $DIR/type-check-1.rs:28:31
9375
|
9476
LL | asm!("{}", inout(reg) v[..]);
9577
| ^^^^^
9678
|
9779
= note: only integers, floats, SIMD vectors, pointers and function pointers can be used as arguments for inline assembly
9880

9981
error[E0308]: mismatched types
100-
--> $DIR/type-check-1.rs:58:26
82+
--> $DIR/type-check-1.rs:56:26
10183
|
10284
LL | asm!("{}", const 0f32);
10385
| ^^^^ expected integer, found `f32`
10486

10587
error[E0308]: mismatched types
106-
--> $DIR/type-check-1.rs:60:26
88+
--> $DIR/type-check-1.rs:58:26
10789
|
10890
LL | asm!("{}", const 0 as *mut u8);
10991
| ^^^^^^^^^^^^ expected integer, found *-ptr
@@ -112,7 +94,7 @@ LL | asm!("{}", const 0 as *mut u8);
11294
found raw pointer `*mut u8`
11395

11496
error[E0308]: mismatched types
115-
--> $DIR/type-check-1.rs:62:26
97+
--> $DIR/type-check-1.rs:60:26
11698
|
11799
LL | asm!("{}", const &0);
118100
| ^^ expected integer, found `&{integer}`
@@ -124,21 +106,21 @@ LL + asm!("{}", const 0);
124106
|
125107

126108
error[E0308]: mismatched types
127-
--> $DIR/type-check-1.rs:76:25
109+
--> $DIR/type-check-1.rs:74:25
128110
|
129111
LL | global_asm!("{}", const 0f32);
130112
| ^^^^ expected integer, found `f32`
131113

132114
error[E0308]: mismatched types
133-
--> $DIR/type-check-1.rs:78:25
115+
--> $DIR/type-check-1.rs:76:25
134116
|
135117
LL | global_asm!("{}", const 0 as *mut u8);
136118
| ^^^^^^^^^^^^ expected integer, found *-ptr
137119
|
138120
= note: expected type `{integer}`
139121
found raw pointer `*mut u8`
140122

141-
error: aborting due to 17 previous errors
123+
error: aborting due to 15 previous errors
142124

143125
Some errors have detailed explanations: E0277, E0308, E0435.
144126
For more information about an error, try `rustc --explain E0277`.

src/test/ui/associated-types/associated-types-path-2.rs

+2
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,14 @@ pub fn f1_uint_uint() {
2929
f1(2u32, 4u32);
3030
//~^ ERROR `u32: Foo` is not satisfied
3131
//~| ERROR `u32: Foo` is not satisfied
32+
//~| ERROR `u32: Foo` is not satisfied
3233
}
3334

3435
pub fn f1_uint_int() {
3536
f1(2u32, 4i32);
3637
//~^ ERROR `u32: Foo` is not satisfied
3738
//~| ERROR `u32: Foo` is not satisfied
39+
//~| ERROR `u32: Foo` is not satisfied
3840
}
3941

4042
pub fn f2_int() {

src/test/ui/associated-types/associated-types-path-2.stderr

+20-14
Original file line numberDiff line numberDiff line change
@@ -31,21 +31,24 @@ note: required by a bound in `f1`
3131
LL | pub fn f1<T: Foo>(a: T, x: T::A) {}
3232
| ^^^ required by this bound in `f1`
3333

34+
error[E0277]: the trait bound `u32: Foo` is not satisfied
35+
--> $DIR/associated-types-path-2.rs:29:5
36+
|
37+
LL | f1(2u32, 4u32);
38+
| ^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `u32`
39+
|
40+
= help: the trait `Foo` is implemented for `i32`
41+
3442
error[E0277]: the trait bound `u32: Foo` is not satisfied
3543
--> $DIR/associated-types-path-2.rs:29:14
3644
|
3745
LL | f1(2u32, 4u32);
3846
| ^^^^ the trait `Foo` is not implemented for `u32`
3947
|
4048
= help: the trait `Foo` is implemented for `i32`
41-
= help: unsized fn params are gated as an unstable feature
42-
help: function arguments must have a statically known size, borrowed types always have a known size
43-
|
44-
LL | f1(2u32, &4u32);
45-
| +
4649

4750
error[E0277]: the trait bound `u32: Foo` is not satisfied
48-
--> $DIR/associated-types-path-2.rs:35:8
51+
--> $DIR/associated-types-path-2.rs:36:8
4952
|
5053
LL | f1(2u32, 4i32);
5154
| -- ^^^^ the trait `Foo` is not implemented for `u32`
@@ -60,20 +63,23 @@ LL | pub fn f1<T: Foo>(a: T, x: T::A) {}
6063
| ^^^ required by this bound in `f1`
6164

6265
error[E0277]: the trait bound `u32: Foo` is not satisfied
63-
--> $DIR/associated-types-path-2.rs:35:14
66+
--> $DIR/associated-types-path-2.rs:36:5
6467
|
6568
LL | f1(2u32, 4i32);
66-
| ^^^^ the trait `Foo` is not implemented for `u32`
69+
| ^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `u32`
6770
|
6871
= help: the trait `Foo` is implemented for `i32`
69-
= help: unsized fn params are gated as an unstable feature
70-
help: function arguments must have a statically known size, borrowed types always have a known size
72+
73+
error[E0277]: the trait bound `u32: Foo` is not satisfied
74+
--> $DIR/associated-types-path-2.rs:36:14
7175
|
72-
LL | f1(2u32, &4i32);
73-
| +
76+
LL | f1(2u32, 4i32);
77+
| ^^^^ the trait `Foo` is not implemented for `u32`
78+
|
79+
= help: the trait `Foo` is implemented for `i32`
7480

7581
error[E0308]: mismatched types
76-
--> $DIR/associated-types-path-2.rs:41:18
82+
--> $DIR/associated-types-path-2.rs:43:18
7783
|
7884
LL | let _: i32 = f2(2i32);
7985
| --- ^^^^^^^^ expected `i32`, found `u32`
@@ -85,7 +91,7 @@ help: you can convert a `u32` to an `i32` and panic if the converted value doesn
8591
LL | let _: i32 = f2(2i32).try_into().unwrap();
8692
| ++++++++++++++++++++
8793

88-
error: aborting due to 6 previous errors
94+
error: aborting due to 8 previous errors
8995

9096
Some errors have detailed explanations: E0277, E0308.
9197
For more information about an error, try `rustc --explain E0277`.

src/test/ui/error-codes/E0282.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
fn main() {
2-
let x = "hello".chars().rev().collect(); //~ ERROR E0282
2+
let x = "hello".chars().rev().collect(); //~ ERROR E0283
33
}

src/test/ui/error-codes/E0282.stderr

+12-6
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,20 @@
1-
error[E0282]: type annotations needed
1+
error[E0283]: type annotations needed
22
--> $DIR/E0282.rs:2:9
33
|
44
LL | let x = "hello".chars().rev().collect();
5-
| ^
5+
| ^ ------- type must be known at this point
66
|
7-
help: consider giving `x` an explicit type
7+
= note: cannot satisfy `_: FromIterator<char>`
8+
note: required by a bound in `collect`
9+
--> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
810
|
9-
LL | let x: _ = "hello".chars().rev().collect();
10-
| +++
11+
LL | fn collect<B: FromIterator<Self::Item>>(self) -> B
12+
| ^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `collect`
13+
help: consider specifying the type argument in the function call
14+
|
15+
LL | let x = "hello".chars().rev().collect::<B>();
16+
| +++++
1117

1218
error: aborting due to previous error
1319

14-
For more information about this error, try `rustc --explain E0282`.
20+
For more information about this error, try `rustc --explain E0283`.
+13-13
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,3 @@
1-
error[E0277]: the size for values of type `str` cannot be known at compilation time
2-
--> $DIR/sized-yield.rs:8:26
3-
|
4-
LL | let mut gen = move || {
5-
| __________________________^
6-
LL | |
7-
LL | | yield s[..];
8-
LL | | };
9-
| |____^ doesn't have a size known at compile-time
10-
|
11-
= help: the trait `Sized` is not implemented for `str`
12-
= note: the yield type of a generator must have a statically known size
13-
141
error[E0277]: the size for values of type `str` cannot be known at compilation time
152
--> $DIR/sized-yield.rs:12:23
163
|
@@ -24,6 +11,19 @@ note: required by a bound in `GeneratorState`
2411
LL | pub enum GeneratorState<Y, R> {
2512
| ^ required by this bound in `GeneratorState`
2613

14+
error[E0277]: the size for values of type `str` cannot be known at compilation time
15+
--> $DIR/sized-yield.rs:8:26
16+
|
17+
LL | let mut gen = move || {
18+
| __________________________^
19+
LL | |
20+
LL | | yield s[..];
21+
LL | | };
22+
| |____^ doesn't have a size known at compile-time
23+
|
24+
= help: the trait `Sized` is not implemented for `str`
25+
= note: the yield type of a generator must have a statically known size
26+
2727
error: aborting due to 2 previous errors
2828

2929
For more information about this error, try `rustc --explain E0277`.

src/test/ui/impl-trait/rpit-not-sized.stderr

+3
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@ error[E0277]: the size for values of type `impl ?Sized` cannot be known at compi
33
|
44
LL | fn foo() -> impl ?Sized {
55
| ^^^^^^^^^^^ doesn't have a size known at compile-time
6+
LL |
7+
LL | ()
8+
| -- this returned value is of type `()`
69
|
710
= help: the trait `Sized` is not implemented for `impl ?Sized`
811
= note: the return type of a function must have a statically known size

0 commit comments

Comments
 (0)