mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-23 07:14:28 +00:00
Rollup merge of #101676 - compiler-errors:rpitit-wf, r=lcnr
Check that the types in return position `impl Trait` in traits are well-formed This effectively duplicates `check_associated_type_bounds`, but that shouldn't be for long, since we're going to remove it once we refactor RPITITs into regular associated items. Fixes #101663 --- We don't check ```rust trait Foo { fn bar() -> impl ?Sized; } ``` currently, but that's for a different reason, which is that we don't currently check that a trait function's return type is sized (i.e. `fn bar() -> [u8]` also works in a trait).
This commit is contained in:
commit
5faf033f62
@ -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>`, \
|
||||
|
16
src/test/ui/impl-trait/in-trait/wf-bounds.rs
Normal file
16
src/test/ui/impl-trait/in-trait/wf-bounds.rs
Normal file
@ -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
src/test/ui/impl-trait/in-trait/wf-bounds.stderr
Normal file
33
src/test/ui/impl-trait/in-trait/wf-bounds.stderr
Normal file
@ -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`.
|
Loading…
Reference in New Issue
Block a user