diff --git a/compiler/rustc_typeck/src/check/wfcheck.rs b/compiler/rustc_typeck/src/check/wfcheck.rs index 5c6c8aca17346..ba8e4470feca2 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`, \ 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 0000000000000..2c71583b31236 --- /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 {} + +trait Uwu { + fn nya() -> impl Wf>; + //~^ 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 0000000000000..92e36841b70c2 --- /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>; + | ^^^^^^^^^^^^^ 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 { + | ^ 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 {} + | ^ required by this bound in `Wf` +help: consider relaxing the implicit `Sized` restriction + | +LL | trait Wf {} + | ++++++++ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0277`.