about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMichael Goulet <michael@errs.io>2022-09-11 06:58:11 +0000
committerMichael Goulet <michael@errs.io>2022-09-11 06:58:11 +0000
commitfd2766e7fde443d46eb051bb5ef27bbb29ee101d (patch)
tree11c89faf2afce3ba1484620f91561abb891d9d1d
parent98f3001eecbe4cbd091c10ffab45b4c164bb507b (diff)
downloadrust-fd2766e7fde443d46eb051bb5ef27bbb29ee101d.tar.gz
rust-fd2766e7fde443d46eb051bb5ef27bbb29ee101d.zip
Check that the types in RPITITs are WF
-rw-r--r--compiler/rustc_typeck/src/check/wfcheck.rs44
-rw-r--r--src/test/ui/impl-trait/in-trait/wf-bounds.rs16
-rw-r--r--src/test/ui/impl-trait/in-trait/wf-bounds.stderr33
3 files changed, 93 insertions, 0 deletions
diff --git a/compiler/rustc_typeck/src/check/wfcheck.rs b/compiler/rustc_typeck/src/check/wfcheck.rs
index 5c6c8aca173..ba8e4470fec 100644
--- a/compiler/rustc_typeck/src/check/wfcheck.rs
+++ b/compiler/rustc_typeck/src/check/wfcheck.rs
@@ -1,4 +1,5 @@
 use crate::constrained_generic_params::{identify_constrained_generic_params, Parameter};
+use hir::def::DefKind;
 use rustc_ast as ast;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticBuilder, ErrorGuaranteed};
@@ -1530,6 +1531,49 @@ fn check_fn_or_method<'tcx>(
     );
 
     check_where_clauses(wfcx, span, def_id);
+
+    check_return_position_impl_trait_in_trait_bounds(
+        tcx,
+        wfcx,
+        def_id,
+        sig.output(),
+        hir_decl.output.span(),
+    );
+}
+
+/// Basically `check_associated_type_bounds`, but separated for now and should be
+/// deduplicated when RPITITs get lowered into real associated items.
+fn check_return_position_impl_trait_in_trait_bounds<'tcx>(
+    tcx: TyCtxt<'tcx>,
+    wfcx: &WfCheckingCtxt<'_, 'tcx>,
+    fn_def_id: LocalDefId,
+    fn_output: Ty<'tcx>,
+    span: Span,
+) {
+    if let Some(assoc_item) = tcx.opt_associated_item(fn_def_id.to_def_id())
+        && assoc_item.container == ty::AssocItemContainer::TraitContainer
+    {
+        for arg in fn_output.walk() {
+            if let ty::GenericArgKind::Type(ty) = arg.unpack()
+                && let ty::Projection(proj) = ty.kind()
+                && tcx.def_kind(proj.item_def_id) == DefKind::ImplTraitPlaceholder
+                && tcx.impl_trait_in_trait_parent(proj.item_def_id) == fn_def_id.to_def_id()
+            {
+                let bounds = wfcx.tcx().explicit_item_bounds(proj.item_def_id);
+                let wf_obligations = bounds.iter().flat_map(|&(bound, bound_span)| {
+                    let normalized_bound = wfcx.normalize(span, None, bound);
+                    traits::wf::predicate_obligations(
+                        wfcx.infcx,
+                        wfcx.param_env,
+                        wfcx.body_id,
+                        normalized_bound,
+                        bound_span,
+                    )
+                });
+                wfcx.register_obligations(wf_obligations);
+            }
+        }
+    }
 }
 
 const HELP_FOR_SELF_TYPE: &str = "consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, \
diff --git a/src/test/ui/impl-trait/in-trait/wf-bounds.rs b/src/test/ui/impl-trait/in-trait/wf-bounds.rs
new file mode 100644
index 00000000000..2c71583b312
--- /dev/null
+++ b/src/test/ui/impl-trait/in-trait/wf-bounds.rs
@@ -0,0 +1,16 @@
+// issue #101663
+
+#![feature(return_position_impl_trait_in_trait)]
+#![allow(incomplete_features)]
+
+trait Wf<T> {}
+
+trait Uwu {
+    fn nya() -> impl Wf<Vec<[u8]>>;
+    //~^ ERROR the size for values of type `[u8]` cannot be known at compilation time
+
+    fn nya2() -> impl Wf<[u8]>;
+    //~^ ERROR the size for values of type `[u8]` cannot be known at compilation time
+}
+
+fn main() {}
diff --git a/src/test/ui/impl-trait/in-trait/wf-bounds.stderr b/src/test/ui/impl-trait/in-trait/wf-bounds.stderr
new file mode 100644
index 00000000000..92e36841b70
--- /dev/null
+++ b/src/test/ui/impl-trait/in-trait/wf-bounds.stderr
@@ -0,0 +1,33 @@
+error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
+  --> $DIR/wf-bounds.rs:9:22
+   |
+LL |     fn nya() -> impl Wf<Vec<[u8]>>;
+   |                      ^^^^^^^^^^^^^ doesn't have a size known at compile-time
+   |
+   = help: the trait `Sized` is not implemented for `[u8]`
+note: required by a bound in `Vec`
+  --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
+   |
+LL | pub struct Vec<T, #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global> {
+   |                ^ required by this bound in `Vec`
+
+error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
+  --> $DIR/wf-bounds.rs:12:23
+   |
+LL |     fn nya2() -> impl Wf<[u8]>;
+   |                       ^^^^^^^^ doesn't have a size known at compile-time
+   |
+   = help: the trait `Sized` is not implemented for `[u8]`
+note: required by a bound in `Wf`
+  --> $DIR/wf-bounds.rs:6:10
+   |
+LL | trait Wf<T> {}
+   |          ^ required by this bound in `Wf`
+help: consider relaxing the implicit `Sized` restriction
+   |
+LL | trait Wf<T: ?Sized> {}
+   |           ++++++++
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0277`.