Skip to content

Commit

Permalink
Check that the types in RPITITs are WF
Browse files Browse the repository at this point in the history
  • Loading branch information
compiler-errors committed Sep 11, 2022
1 parent 98f3001 commit fd2766e
Show file tree
Hide file tree
Showing 3 changed files with 93 additions and 0 deletions.
44 changes: 44 additions & 0 deletions compiler/rustc_typeck/src/check/wfcheck.rs
Original file line number Diff line number Diff line change
@@ -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};
Expand Down Expand Up @@ -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>`, \
Expand Down
16 changes: 16 additions & 0 deletions src/test/ui/impl-trait/in-trait/wf-bounds.rs
Original file line number Diff line number Diff line change
@@ -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() {}
33 changes: 33 additions & 0 deletions src/test/ui/impl-trait/in-trait/wf-bounds.stderr
Original file line number Diff line number Diff line change
@@ -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`.

0 comments on commit fd2766e

Please sign in to comment.