Skip to content

Commit a8ecb79

Browse files
authored
Rollup merge of #136274 - compiler-errors:sized-wf, r=lcnr
Check Sizedness of return type in WF Still need to clean this up a bit. This should fix rust-lang/trait-system-refactor-initiative#150. r? lcnr
2 parents 40c4e05 + 3683975 commit a8ecb79

File tree

61 files changed

+508
-428
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

61 files changed

+508
-428
lines changed

compiler/rustc_hir_analysis/src/check/wfcheck.rs

+28-2
Original file line numberDiff line numberDiff line change
@@ -1065,6 +1065,7 @@ fn check_associated_item(
10651065
let ty = tcx.type_of(item.def_id).instantiate_identity();
10661066
let ty = wfcx.normalize(span, Some(WellFormedLoc::Ty(item_id)), ty);
10671067
wfcx.register_wf_obligation(span, loc, ty.into());
1068+
check_sized_if_body(wfcx, item.def_id.expect_local(), ty, Some(span));
10681069
Ok(())
10691070
}
10701071
ty::AssocKind::Fn => {
@@ -1189,7 +1190,7 @@ fn check_type_defn<'tcx>(
11891190
),
11901191
wfcx.param_env,
11911192
ty,
1192-
tcx.require_lang_item(LangItem::Sized, None),
1193+
tcx.require_lang_item(LangItem::Sized, Some(hir_ty.span)),
11931194
);
11941195
}
11951196

@@ -1314,7 +1315,7 @@ fn check_item_type(
13141315
),
13151316
wfcx.param_env,
13161317
item_ty,
1317-
tcx.require_lang_item(LangItem::Sized, None),
1318+
tcx.require_lang_item(LangItem::Sized, Some(ty_span)),
13181319
);
13191320
}
13201321

@@ -1644,6 +1645,31 @@ fn check_fn_or_method<'tcx>(
16441645
);
16451646
}
16461647
}
1648+
1649+
// If the function has a body, additionally require that the return type is sized.
1650+
check_sized_if_body(wfcx, def_id, sig.output(), match hir_decl.output {
1651+
hir::FnRetTy::Return(ty) => Some(ty.span),
1652+
hir::FnRetTy::DefaultReturn(_) => None,
1653+
});
1654+
}
1655+
1656+
fn check_sized_if_body<'tcx>(
1657+
wfcx: &WfCheckingCtxt<'_, 'tcx>,
1658+
def_id: LocalDefId,
1659+
ty: Ty<'tcx>,
1660+
maybe_span: Option<Span>,
1661+
) {
1662+
let tcx = wfcx.tcx();
1663+
if let Some(body) = tcx.hir().maybe_body_owned_by(def_id) {
1664+
let span = maybe_span.unwrap_or(body.value.span);
1665+
1666+
wfcx.register_bound(
1667+
ObligationCause::new(span, def_id, traits::ObligationCauseCode::SizedReturnType),
1668+
wfcx.param_env,
1669+
ty,
1670+
tcx.require_lang_item(LangItem::Sized, Some(span)),
1671+
);
1672+
}
16471673
}
16481674

16491675
/// The `arbitrary_self_types_pointers` feature implies `arbitrary_self_types`.

compiler/rustc_hir_typeck/src/check.rs

+7-12
Original file line numberDiff line numberDiff line change
@@ -117,22 +117,17 @@ pub(super) fn check_fn<'a, 'tcx>(
117117

118118
fcx.typeck_results.borrow_mut().liberated_fn_sigs_mut().insert(fn_id, fn_sig);
119119

120-
let return_or_body_span = match decl.output {
121-
hir::FnRetTy::DefaultReturn(_) => body.value.span,
122-
hir::FnRetTy::Return(ty) => ty.span,
123-
};
124-
125-
fcx.require_type_is_sized(
126-
declared_ret_ty,
127-
return_or_body_span,
128-
ObligationCauseCode::SizedReturnType,
129-
);
130-
// We checked the root's signature during wfcheck, but not the child.
120+
// We checked the root's ret ty during wfcheck, but not the child.
131121
if fcx.tcx.is_typeck_child(fn_def_id.to_def_id()) {
122+
let return_or_body_span = match decl.output {
123+
hir::FnRetTy::DefaultReturn(_) => body.value.span,
124+
hir::FnRetTy::Return(ty) => ty.span,
125+
};
126+
132127
fcx.require_type_is_sized(
133128
declared_ret_ty,
134129
return_or_body_span,
135-
ObligationCauseCode::WellFormed(None),
130+
ObligationCauseCode::SizedReturnType,
136131
);
137132
}
138133

compiler/rustc_hir_typeck/src/lib.rs

-2
Original file line numberDiff line numberDiff line change
@@ -186,8 +186,6 @@ fn typeck_with_inspect<'tcx>(
186186
let wf_code = ObligationCauseCode::WellFormed(Some(WellFormedLoc::Ty(def_id)));
187187
fcx.register_wf_obligation(expected_type.into(), body.value.span, wf_code);
188188

189-
fcx.require_type_is_sized(expected_type, body.value.span, ObligationCauseCode::ConstSized);
190-
191189
// Gather locals in statics (because of block expressions).
192190
GatherLocalsVisitor::new(&fcx).visit_body(body);
193191

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

-5
Original file line numberDiff line numberDiff line change
@@ -703,7 +703,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
703703
};
704704

705705
self.note_obligation_cause(&mut err, &obligation);
706-
self.point_at_returns_when_relevant(&mut err, &obligation);
707706
err.emit()
708707
}
709708
}
@@ -806,7 +805,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
806805
"Async",
807806
);
808807
self.note_obligation_cause(&mut err, &obligation);
809-
self.point_at_returns_when_relevant(&mut err, &obligation);
810808
return Some(err.emit());
811809
}
812810
}
@@ -852,7 +850,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
852850
"",
853851
);
854852
self.note_obligation_cause(&mut err, &obligation);
855-
self.point_at_returns_when_relevant(&mut err, &obligation);
856853
return Some(err.emit());
857854
}
858855

@@ -868,7 +865,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
868865
kind: expected_kind.as_str(),
869866
});
870867
self.note_obligation_cause(&mut err, &obligation);
871-
self.point_at_returns_when_relevant(&mut err, &obligation);
872868
return Some(err.emit());
873869
}
874870
}
@@ -2826,7 +2822,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
28262822
err.span_note(self.tcx.def_span(def_id), "opaque type is declared here");
28272823

28282824
self.note_obligation_cause(&mut err, &obligation);
2829-
self.point_at_returns_when_relevant(&mut err, &obligation);
28302825
self.dcx().try_steal_replace_and_emit_err(self.tcx.def_span(def_id), StashKey::Cycle, err)
28312826
}
28322827

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

-1
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
185185
suggest_increasing_limit,
186186
);
187187
self.note_obligation_cause(&mut err, &obligation);
188-
self.point_at_returns_when_relevant(&mut err, &obligation);
189188
err.emit()
190189
}
191190
}

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

+9-56
Original file line numberDiff line numberDiff line change
@@ -1765,7 +1765,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
17651765
};
17661766

17671767
err.code(E0746);
1768-
err.primary_message("return type cannot have an unboxed trait object");
1768+
err.primary_message("return type cannot be a trait object without pointer indirection");
17691769
err.children.clear();
17701770

17711771
let span = obligation.cause.span;
@@ -1781,25 +1781,13 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
17811781
} else {
17821782
("dyn ", span.shrink_to_lo())
17831783
};
1784-
let alternatively = if visitor
1785-
.returns
1786-
.iter()
1787-
.map(|expr| self.typeck_results.as_ref().unwrap().expr_ty_adjusted_opt(expr))
1788-
.collect::<FxHashSet<_>>()
1789-
.len()
1790-
<= 1
1791-
{
1792-
err.span_suggestion_verbose(
1793-
impl_span,
1794-
"consider returning an `impl Trait` instead of a `dyn Trait`",
1795-
"impl ",
1796-
Applicability::MaybeIncorrect,
1797-
);
1798-
"alternatively, "
1799-
} else {
1800-
err.help("if there were a single returned type, you could use `impl Trait` instead");
1801-
""
1802-
};
1784+
1785+
err.span_suggestion_verbose(
1786+
impl_span,
1787+
"consider returning an `impl Trait` instead of a `dyn Trait`",
1788+
"impl ",
1789+
Applicability::MaybeIncorrect,
1790+
);
18031791

18041792
let mut sugg = vec![
18051793
(span.shrink_to_lo(), format!("Box<{pre}")),
@@ -1831,7 +1819,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
18311819

18321820
err.multipart_suggestion(
18331821
format!(
1834-
"{alternatively}box the return type, and wrap all of the returned values in \
1822+
"alternatively, box the return type, and wrap all of the returned values in \
18351823
`Box::new`",
18361824
),
18371825
sugg,
@@ -1841,41 +1829,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
18411829
true
18421830
}
18431831

1844-
pub(super) fn point_at_returns_when_relevant(
1845-
&self,
1846-
err: &mut Diag<'_>,
1847-
obligation: &PredicateObligation<'tcx>,
1848-
) {
1849-
match obligation.cause.code().peel_derives() {
1850-
ObligationCauseCode::SizedReturnType => {}
1851-
_ => return,
1852-
}
1853-
1854-
let hir = self.tcx.hir();
1855-
let node = self.tcx.hir_node_by_def_id(obligation.cause.body_id);
1856-
if let hir::Node::Item(hir::Item {
1857-
kind: hir::ItemKind::Fn { body: body_id, .. }, ..
1858-
}) = node
1859-
{
1860-
let body = hir.body(*body_id);
1861-
// Point at all the `return`s in the function as they have failed trait bounds.
1862-
let mut visitor = ReturnsVisitor::default();
1863-
visitor.visit_body(body);
1864-
let typeck_results = self.typeck_results.as_ref().unwrap();
1865-
for expr in &visitor.returns {
1866-
if let Some(returned_ty) = typeck_results.node_type_opt(expr.hir_id) {
1867-
let ty = self.resolve_vars_if_possible(returned_ty);
1868-
if ty.references_error() {
1869-
// don't print out the [type error] here
1870-
err.downgrade_to_delayed_bug();
1871-
} else {
1872-
err.span_label(expr.span, format!("this returned value is of type `{ty}`"));
1873-
}
1874-
}
1875-
}
1876-
}
1877-
}
1878-
18791832
pub(super) fn report_closure_arg_mismatch(
18801833
&self,
18811834
span: Span,

tests/crashes/134355.rs

-6
This file was deleted.

tests/rustdoc-json/primitives/primitive_impls.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
1-
#![feature(no_core)]
1+
#![feature(no_core, lang_items)]
22
#![feature(rustc_attrs)]
33
#![feature(rustdoc_internals)]
44
#![no_core]
55
#![rustc_coherence_is_core]
66

77
//@ set impl_i32 = "$.index[*][?(@.docs=='Only core can do this')].id"
88

9+
#[lang = "sized"]
10+
trait Sized {}
11+
912
/// Only core can do this
1013
impl i32 {
1114
//@ set identity = "$.index[*][?(@.docs=='Do Nothing')].id"

tests/rustdoc-ui/custom_code_classes_in_docs-warning3.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,12 @@
22
// feature.
33

44
#![deny(warnings)]
5-
#![feature(no_core)]
5+
#![feature(no_core, lang_items)]
66
#![no_core]
77

8+
#[lang = "sized"]
9+
trait Sized {}
10+
811
/// ```{class="}
912
/// main;
1013
/// ```

tests/rustdoc-ui/custom_code_classes_in_docs-warning3.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error: unclosed quote string `"`
2-
--> $DIR/custom_code_classes_in_docs-warning3.rs:8:1
2+
--> $DIR/custom_code_classes_in_docs-warning3.rs:11:1
33
|
44
LL | / /// ```{class="}
55
LL | | /// main;
@@ -17,7 +17,7 @@ LL | #![deny(warnings)]
1717
= note: `#[deny(rustdoc::invalid_codeblock_attributes)]` implied by `#[deny(warnings)]`
1818

1919
error: unclosed quote string `"`
20-
--> $DIR/custom_code_classes_in_docs-warning3.rs:8:1
20+
--> $DIR/custom_code_classes_in_docs-warning3.rs:11:1
2121
|
2222
LL | / /// ```{class="}
2323
LL | | /// main;

tests/rustdoc/cfg_doc_reexport.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
#![feature(doc_cfg)]
2-
#![feature(no_core)]
2+
#![feature(no_core, lang_items)]
33

44
#![crate_name = "foo"]
55
#![no_core]
66

7+
#[lang = "sized"]
8+
trait Sized {}
9+
710
//@ has 'foo/index.html'
811
//@ has - '//dt/*[@class="stab portability"]' 'foobar'
912
//@ has - '//dt/*[@class="stab portability"]' 'bar'

tests/rustdoc/cross-crate-primitive-doc.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,12 @@
22
//@ compile-flags: --extern-html-root-url=primitive_doc=../ -Z unstable-options
33
//@ only-linux
44

5-
#![feature(no_core)]
5+
#![feature(no_core, lang_items)]
66
#![no_core]
77

8+
#[lang = "sized"]
9+
trait Sized {}
10+
811
extern crate primitive_doc;
912

1013
//@ has 'cross_crate_primitive_doc/fn.foo.html' '//a[@href="../primitive_doc/primitive.usize.html"]' 'usize'

tests/rustdoc/intra-doc/no-doc-primitive.rs

+5
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,13 @@
66
#![rustc_coherence_is_core]
77
#![crate_type = "rlib"]
88

9+
910
//@ has no_doc_primitive/index.html
1011
//! A [`char`] and its [`char::len_utf8`].
12+
13+
#[lang = "sized"]
14+
trait Sized {}
15+
1116
impl char {
1217
pub fn len_utf8(self) -> usize {
1318
42

tests/rustdoc/reexport-trait-from-hidden-111064-2.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
// Regression test for <https://github.com/rust-lang/rust/issues/111064>.
2-
#![feature(no_core)]
2+
#![feature(no_core, lang_items)]
33
#![no_core]
44
#![crate_name = "foo"]
55

6+
#[lang = "sized"]
7+
trait Sized {}
8+
69
//@ files "foo" "['sidebar-items.js', 'all.html', 'hidden', 'index.html', 'struct.Bar.html', \
710
// 'visible']"
811
//@ files "foo/hidden" "['inner']"

tests/rustdoc/safe-intrinsic.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
#![feature(intrinsics)]
2-
#![feature(no_core)]
2+
#![feature(no_core, lang_items)]
33
#![feature(rustc_attrs)]
44

55
#![no_core]
66
#![crate_name = "foo"]
77

8+
#[lang = "sized"]
9+
trait Sized {}
10+
811
//@ has 'foo/fn.abort.html'
912
//@ has - '//pre[@class="rust item-decl"]' 'pub fn abort() -> !'
1013
#[rustc_intrinsic]

tests/ui/associated-consts/issue-58022.stderr

+9-9
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,3 @@
1-
error[E0790]: cannot refer to the associated constant on trait without specifying the corresponding `impl` type
2-
--> $DIR/issue-58022.rs:4:25
3-
|
4-
LL | const SIZE: usize;
5-
| ------------------ `Foo::SIZE` defined here
6-
LL |
7-
LL | fn new(slice: &[u8; Foo::SIZE]) -> Self;
8-
| ^^^^^^^^^ cannot refer to the associated constant of trait
9-
101
error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
112
--> $DIR/issue-58022.rs:13:41
123
|
@@ -21,6 +12,15 @@ LL | pub struct Bar<T: ?Sized>(T);
2112
| ^^^
2213
= note: the return type of a function must have a statically known size
2314

15+
error[E0790]: cannot refer to the associated constant on trait without specifying the corresponding `impl` type
16+
--> $DIR/issue-58022.rs:4:25
17+
|
18+
LL | const SIZE: usize;
19+
| ------------------ `Foo::SIZE` defined here
20+
LL |
21+
LL | fn new(slice: &[u8; Foo::SIZE]) -> Self;
22+
| ^^^^^^^^^ cannot refer to the associated constant of trait
23+
2424
error[E0423]: expected function, tuple struct or tuple variant, found trait `Foo`
2525
--> $DIR/issue-58022.rs:15:9
2626
|

tests/ui/consts/const-slice-array-deref.rs

-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
const ONE: [u16] = [1];
22
//~^ ERROR the size for values of type `[u16]` cannot be known at compilation time
3-
//~| ERROR the size for values of type `[u16]` cannot be known at compilation time
43
//~| ERROR mismatched types
54

65
const TWO: &'static u16 = &ONE[0];

0 commit comments

Comments
 (0)