Auto merge of #111895 - matthiaskrgr:rollup-9a6szng, r=matthiaskrgr
Rollup of 5 pull requests Successful merges: - #111861 (Don't ICE on return-type notation when promoting trait preds to associated type bounds) - #111864 (Always require closure parameters to be `Sized`) - #111870 (Rename `traits_in_crate` query to `traits`) - #111880 (Don't ICE when computing PointerLike trait when region vars are in param-env) - #111887 (Add regression tests for pretty-printing inherent projections) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
82faf5ed60
@ -427,6 +427,8 @@ pub(super) fn explicit_predicates_of<'tcx>(
|
|||||||
// supertrait).
|
// supertrait).
|
||||||
if let ty::Alias(ty::Projection, projection) = ty.kind() {
|
if let ty::Alias(ty::Projection, projection) = ty.kind() {
|
||||||
projection.substs == trait_identity_substs
|
projection.substs == trait_identity_substs
|
||||||
|
// FIXME(return_type_notation): This check should be more robust
|
||||||
|
&& !tcx.is_impl_trait_in_trait(projection.def_id)
|
||||||
&& tcx.associated_item(projection.def_id).container_id(tcx)
|
&& tcx.associated_item(projection.def_id).container_id(tcx)
|
||||||
== def_id.to_def_id()
|
== def_id.to_def_id()
|
||||||
} else {
|
} else {
|
||||||
|
@ -32,6 +32,7 @@ pub(super) fn check_fn<'a, 'tcx>(
|
|||||||
fn_def_id: LocalDefId,
|
fn_def_id: LocalDefId,
|
||||||
body: &'tcx hir::Body<'tcx>,
|
body: &'tcx hir::Body<'tcx>,
|
||||||
can_be_generator: Option<hir::Movability>,
|
can_be_generator: Option<hir::Movability>,
|
||||||
|
params_can_be_unsized: bool,
|
||||||
) -> Option<GeneratorTypes<'tcx>> {
|
) -> Option<GeneratorTypes<'tcx>> {
|
||||||
let fn_id = fcx.tcx.hir().local_def_id_to_hir_id(fn_def_id);
|
let fn_id = fcx.tcx.hir().local_def_id_to_hir_id(fn_def_id);
|
||||||
|
|
||||||
@ -94,7 +95,7 @@ pub(super) fn check_fn<'a, 'tcx>(
|
|||||||
// The check for a non-trivial pattern is a hack to avoid duplicate warnings
|
// The check for a non-trivial pattern is a hack to avoid duplicate warnings
|
||||||
// for simple cases like `fn foo(x: Trait)`,
|
// for simple cases like `fn foo(x: Trait)`,
|
||||||
// where we would error once on the parameter as a whole, and once on the binding `x`.
|
// where we would error once on the parameter as a whole, and once on the binding `x`.
|
||||||
if param.pat.simple_ident().is_none() && !tcx.features().unsized_fn_params {
|
if param.pat.simple_ident().is_none() && !params_can_be_unsized {
|
||||||
fcx.require_type_is_sized(param_ty, param.pat.span, traits::SizedArgumentType(ty_span));
|
fcx.require_type_is_sized(param_ty, param.pat.span, traits::SizedArgumentType(ty_span));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -89,6 +89,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
expr_def_id,
|
expr_def_id,
|
||||||
body,
|
body,
|
||||||
closure.movability,
|
closure.movability,
|
||||||
|
// Closure "rust-call" ABI doesn't support unsized params
|
||||||
|
false,
|
||||||
);
|
);
|
||||||
|
|
||||||
let parent_substs = InternalSubsts::identity_for_item(
|
let parent_substs = InternalSubsts::identity_for_item(
|
||||||
|
@ -212,7 +212,7 @@ fn typeck_with_fallback<'tcx>(
|
|||||||
let fn_sig = tcx.liberate_late_bound_regions(def_id.to_def_id(), fn_sig);
|
let fn_sig = tcx.liberate_late_bound_regions(def_id.to_def_id(), fn_sig);
|
||||||
let fn_sig = fcx.normalize(body.value.span, fn_sig);
|
let fn_sig = fcx.normalize(body.value.span, fn_sig);
|
||||||
|
|
||||||
check_fn(&mut fcx, fn_sig, decl, def_id, body, None);
|
check_fn(&mut fcx, fn_sig, decl, def_id, body, None, tcx.features().unsized_fn_params);
|
||||||
} else {
|
} else {
|
||||||
let expected_type = if let Some(&hir::Ty { kind: hir::TyKind::Infer, span, .. }) = body_ty {
|
let expected_type = if let Some(&hir::Ty { kind: hir::TyKind::Infer, span, .. }) = body_ty {
|
||||||
Some(fcx.next_ty_var(TypeVariableOrigin {
|
Some(fcx.next_ty_var(TypeVariableOrigin {
|
||||||
|
@ -323,7 +323,7 @@ provide! { tcx, def_id, other, cdata,
|
|||||||
|
|
||||||
extra_filename => { cdata.root.extra_filename.clone() }
|
extra_filename => { cdata.root.extra_filename.clone() }
|
||||||
|
|
||||||
traits_in_crate => { tcx.arena.alloc_from_iter(cdata.get_traits()) }
|
traits => { tcx.arena.alloc_from_iter(cdata.get_traits()) }
|
||||||
trait_impls_in_crate => { tcx.arena.alloc_from_iter(cdata.get_trait_impls()) }
|
trait_impls_in_crate => { tcx.arena.alloc_from_iter(cdata.get_trait_impls()) }
|
||||||
implementations_of_trait => { cdata.get_implementations_of_trait(tcx, other) }
|
implementations_of_trait => { cdata.get_implementations_of_trait(tcx, other) }
|
||||||
crate_incoherent_impls => { cdata.get_incoherent_impls(tcx, other) }
|
crate_incoherent_impls => { cdata.get_incoherent_impls(tcx, other) }
|
||||||
|
@ -1938,7 +1938,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
|
|||||||
|
|
||||||
fn encode_traits(&mut self) -> LazyArray<DefIndex> {
|
fn encode_traits(&mut self) -> LazyArray<DefIndex> {
|
||||||
empty_proc_macro!(self);
|
empty_proc_macro!(self);
|
||||||
self.lazy_array(self.tcx.traits_in_crate(LOCAL_CRATE).iter().map(|def_id| def_id.index))
|
self.lazy_array(self.tcx.traits(LOCAL_CRATE).iter().map(|def_id| def_id.index))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Encodes an index, mapping each trait to its (local) implementations.
|
/// Encodes an index, mapping each trait to its (local) implementations.
|
||||||
@ -2329,7 +2329,7 @@ pub fn provide(providers: &mut Providers) {
|
|||||||
.get(&def_id)
|
.get(&def_id)
|
||||||
.expect("no traits in scope for a doc link")
|
.expect("no traits in scope for a doc link")
|
||||||
},
|
},
|
||||||
traits_in_crate: |tcx, LocalCrate| {
|
traits: |tcx, LocalCrate| {
|
||||||
let mut traits = Vec::new();
|
let mut traits = Vec::new();
|
||||||
for id in tcx.hir().items() {
|
for id in tcx.hir().items() {
|
||||||
if matches!(tcx.def_kind(id.owner_id), DefKind::Trait | DefKind::TraitAlias) {
|
if matches!(tcx.def_kind(id.owner_id), DefKind::Trait | DefKind::TraitAlias) {
|
||||||
|
@ -38,7 +38,10 @@ use crate::traits::query::{
|
|||||||
OutlivesBound,
|
OutlivesBound,
|
||||||
};
|
};
|
||||||
use crate::traits::specialization_graph;
|
use crate::traits::specialization_graph;
|
||||||
use crate::traits::{self, ImplSource};
|
use crate::traits::{
|
||||||
|
CanonicalChalkEnvironmentAndGoal, CodegenObligationError, EvaluationResult, ImplSource,
|
||||||
|
ObjectSafetyViolation, ObligationCause, OverflowError, WellFormedLoc,
|
||||||
|
};
|
||||||
use crate::ty::fast_reject::SimplifiedType;
|
use crate::ty::fast_reject::SimplifiedType;
|
||||||
use crate::ty::layout::ValidityRequirement;
|
use crate::ty::layout::ValidityRequirement;
|
||||||
use crate::ty::subst::{GenericArg, SubstsRef};
|
use crate::ty::subst::{GenericArg, SubstsRef};
|
||||||
@ -1273,7 +1276,7 @@ rustc_queries! {
|
|||||||
|
|
||||||
query codegen_select_candidate(
|
query codegen_select_candidate(
|
||||||
key: (ty::ParamEnv<'tcx>, ty::PolyTraitRef<'tcx>)
|
key: (ty::ParamEnv<'tcx>, ty::PolyTraitRef<'tcx>)
|
||||||
) -> Result<&'tcx ImplSource<'tcx, ()>, traits::CodegenObligationError> {
|
) -> Result<&'tcx ImplSource<'tcx, ()>, CodegenObligationError> {
|
||||||
cache_on_disk_if { true }
|
cache_on_disk_if { true }
|
||||||
desc { |tcx| "computing candidate for `{}`", key.1 }
|
desc { |tcx| "computing candidate for `{}`", key.1 }
|
||||||
}
|
}
|
||||||
@ -1294,7 +1297,7 @@ rustc_queries! {
|
|||||||
desc { |tcx| "building specialization graph of trait `{}`", tcx.def_path_str(trait_id) }
|
desc { |tcx| "building specialization graph of trait `{}`", tcx.def_path_str(trait_id) }
|
||||||
cache_on_disk_if { true }
|
cache_on_disk_if { true }
|
||||||
}
|
}
|
||||||
query object_safety_violations(trait_id: DefId) -> &'tcx [traits::ObjectSafetyViolation] {
|
query object_safety_violations(trait_id: DefId) -> &'tcx [ObjectSafetyViolation] {
|
||||||
desc { |tcx| "determining object safety of trait `{}`", tcx.def_path_str(trait_id) }
|
desc { |tcx| "determining object safety of trait `{}`", tcx.def_path_str(trait_id) }
|
||||||
}
|
}
|
||||||
query check_is_object_safe(trait_id: DefId) -> bool {
|
query check_is_object_safe(trait_id: DefId) -> bool {
|
||||||
@ -1838,8 +1841,7 @@ rustc_queries! {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// A list of all traits in a crate, used by rustdoc and error reporting.
|
/// A list of all traits in a crate, used by rustdoc and error reporting.
|
||||||
/// NOTE: Not named just `traits` due to a naming conflict.
|
query traits(_: CrateNum) -> &'tcx [DefId] {
|
||||||
query traits_in_crate(_: CrateNum) -> &'tcx [DefId] {
|
|
||||||
desc { "fetching all traits in a crate" }
|
desc { "fetching all traits in a crate" }
|
||||||
separate_provide_extern
|
separate_provide_extern
|
||||||
}
|
}
|
||||||
@ -1953,12 +1955,12 @@ rustc_queries! {
|
|||||||
/// `infcx.predicate_must_hold()` instead.
|
/// `infcx.predicate_must_hold()` instead.
|
||||||
query evaluate_obligation(
|
query evaluate_obligation(
|
||||||
goal: CanonicalPredicateGoal<'tcx>
|
goal: CanonicalPredicateGoal<'tcx>
|
||||||
) -> Result<traits::EvaluationResult, traits::OverflowError> {
|
) -> Result<EvaluationResult, OverflowError> {
|
||||||
desc { "evaluating trait selection obligation `{}`", goal.value.value }
|
desc { "evaluating trait selection obligation `{}`", goal.value.value }
|
||||||
}
|
}
|
||||||
|
|
||||||
query evaluate_goal(
|
query evaluate_goal(
|
||||||
goal: traits::CanonicalChalkEnvironmentAndGoal<'tcx>
|
goal: CanonicalChalkEnvironmentAndGoal<'tcx>
|
||||||
) -> Result<
|
) -> Result<
|
||||||
&'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, ()>>,
|
&'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, ()>>,
|
||||||
NoSolution
|
NoSolution
|
||||||
@ -2128,8 +2130,8 @@ rustc_queries! {
|
|||||||
/// all of the cases that the normal `ty::Ty`-based wfcheck does. This is fine,
|
/// all of the cases that the normal `ty::Ty`-based wfcheck does. This is fine,
|
||||||
/// because the `ty::Ty`-based wfcheck is always run.
|
/// because the `ty::Ty`-based wfcheck is always run.
|
||||||
query diagnostic_hir_wf_check(
|
query diagnostic_hir_wf_check(
|
||||||
key: (ty::Predicate<'tcx>, traits::WellFormedLoc)
|
key: (ty::Predicate<'tcx>, WellFormedLoc)
|
||||||
) -> &'tcx Option<traits::ObligationCause<'tcx>> {
|
) -> &'tcx Option<ObligationCause<'tcx>> {
|
||||||
arena_cache
|
arena_cache
|
||||||
eval_always
|
eval_always
|
||||||
no_hash
|
no_hash
|
||||||
|
@ -1199,7 +1199,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||||||
pub fn all_traits(self) -> impl Iterator<Item = DefId> + 'tcx {
|
pub fn all_traits(self) -> impl Iterator<Item = DefId> + 'tcx {
|
||||||
iter::once(LOCAL_CRATE)
|
iter::once(LOCAL_CRATE)
|
||||||
.chain(self.crates(()).iter().copied())
|
.chain(self.crates(()).iter().copied())
|
||||||
.flat_map(move |cnum| self.traits_in_crate(cnum).iter().copied())
|
.flat_map(move |cnum| self.traits(cnum).iter().copied())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -177,14 +177,18 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
|
|||||||
return Err(NoSolution);
|
return Err(NoSolution);
|
||||||
}
|
}
|
||||||
|
|
||||||
if goal.predicate.self_ty().has_non_region_infer() {
|
// The regions of a type don't affect the size of the type
|
||||||
|
let tcx = ecx.tcx();
|
||||||
|
// We should erase regions from both the param-env and type, since both
|
||||||
|
// may have infer regions. Specifically, after canonicalizing and instantiating,
|
||||||
|
// early bound regions turn into region vars in both the new and old solver.
|
||||||
|
let key = tcx.erase_regions(goal.param_env.and(goal.predicate.self_ty()));
|
||||||
|
// But if there are inference variables, we have to wait until it's resolved.
|
||||||
|
if key.has_non_region_infer() {
|
||||||
return ecx.evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS);
|
return ecx.evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS);
|
||||||
}
|
}
|
||||||
|
|
||||||
let tcx = ecx.tcx();
|
if let Ok(layout) = tcx.layout_of(key)
|
||||||
let self_ty = tcx.erase_regions(goal.predicate.self_ty());
|
|
||||||
|
|
||||||
if let Ok(layout) = tcx.layout_of(goal.param_env.and(self_ty))
|
|
||||||
&& layout.layout.is_pointer_like(&tcx.data_layout)
|
&& layout.layout.is_pointer_like(&tcx.data_layout)
|
||||||
{
|
{
|
||||||
// FIXME: We could make this faster by making a no-constraints response
|
// FIXME: We could make this faster by making a no-constraints response
|
||||||
|
@ -967,16 +967,18 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||||||
) {
|
) {
|
||||||
// The regions of a type don't affect the size of the type
|
// The regions of a type don't affect the size of the type
|
||||||
let tcx = self.tcx();
|
let tcx = self.tcx();
|
||||||
let self_ty =
|
let self_ty = tcx.erase_late_bound_regions(obligation.predicate.self_ty());
|
||||||
tcx.erase_regions(tcx.erase_late_bound_regions(obligation.predicate.self_ty()));
|
// We should erase regions from both the param-env and type, since both
|
||||||
|
// may have infer regions. Specifically, after canonicalizing and instantiating,
|
||||||
|
// early bound regions turn into region vars in both the new and old solver.
|
||||||
|
let key = tcx.erase_regions(obligation.param_env.and(self_ty));
|
||||||
// But if there are inference variables, we have to wait until it's resolved.
|
// But if there are inference variables, we have to wait until it's resolved.
|
||||||
if self_ty.has_non_region_infer() {
|
if key.has_non_region_infer() {
|
||||||
candidates.ambiguous = true;
|
candidates.ambiguous = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Ok(layout) = tcx.layout_of(obligation.param_env.and(self_ty))
|
if let Ok(layout) = tcx.layout_of(key)
|
||||||
&& layout.layout.is_pointer_like(&tcx.data_layout)
|
&& layout.layout.is_pointer_like(&tcx.data_layout)
|
||||||
{
|
{
|
||||||
candidates.vec.push(BuiltinCandidate { has_nested: false });
|
candidates.vec.push(BuiltinCandidate { has_nested: false });
|
||||||
|
14
tests/ui/associated-inherent-types/issue-111879-0.rs
Normal file
14
tests/ui/associated-inherent-types/issue-111879-0.rs
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
#![feature(inherent_associated_types)]
|
||||||
|
#![allow(incomplete_features)]
|
||||||
|
|
||||||
|
// Check that we don't crash when printing inherent projections in diagnostics.
|
||||||
|
|
||||||
|
pub struct Carrier<'a>(&'a ());
|
||||||
|
|
||||||
|
pub type User = for<'b> fn(Carrier<'b>::Focus<i32>);
|
||||||
|
|
||||||
|
impl<'a> Carrier<'a> {
|
||||||
|
pub type Focus<T> = &'a mut User; //~ ERROR overflow evaluating associated type
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
8
tests/ui/associated-inherent-types/issue-111879-0.stderr
Normal file
8
tests/ui/associated-inherent-types/issue-111879-0.stderr
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
error: overflow evaluating associated type `Carrier<'b>::Focus<i32>`
|
||||||
|
--> $DIR/issue-111879-0.rs:11:25
|
||||||
|
|
|
||||||
|
LL | pub type Focus<T> = &'a mut User;
|
||||||
|
| ^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
12
tests/ui/associated-inherent-types/issue-111879-1.rs
Normal file
12
tests/ui/associated-inherent-types/issue-111879-1.rs
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
#![feature(inherent_associated_types)]
|
||||||
|
#![allow(incomplete_features)]
|
||||||
|
|
||||||
|
// Check that we don't crash when printing inherent projections in diagnostics.
|
||||||
|
|
||||||
|
struct Foo<T>(T);
|
||||||
|
|
||||||
|
impl<'a> Foo<fn(&'a ())> {
|
||||||
|
type Assoc = &'a ();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main(_: for<'a> fn(Foo<fn(&'a ())>::Assoc)) {} //~ ERROR `main` function has wrong type
|
12
tests/ui/associated-inherent-types/issue-111879-1.stderr
Normal file
12
tests/ui/associated-inherent-types/issue-111879-1.stderr
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
error[E0580]: `main` function has wrong type
|
||||||
|
--> $DIR/issue-111879-1.rs:12:1
|
||||||
|
|
|
||||||
|
LL | fn main(_: for<'a> fn(Foo<fn(&'a ())>::Assoc)) {}
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ incorrect number of function parameters
|
||||||
|
|
|
||||||
|
= note: expected fn pointer `fn()`
|
||||||
|
found fn pointer `fn(for<'a> fn(Foo<fn(&'a ())>::Assoc))`
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0580`.
|
@ -0,0 +1,11 @@
|
|||||||
|
// check-pass
|
||||||
|
|
||||||
|
#![feature(return_position_impl_trait_in_trait, return_type_notation)]
|
||||||
|
//~^ WARN the feature `return_type_notation` is incomplete and may not be safe to use
|
||||||
|
|
||||||
|
trait IntFactory {
|
||||||
|
fn stream(&self) -> impl Iterator<Item = i32>;
|
||||||
|
}
|
||||||
|
trait SendIntFactory: IntFactory<stream(): Send> + Send {}
|
||||||
|
|
||||||
|
fn main() {}
|
@ -0,0 +1,11 @@
|
|||||||
|
warning: the feature `return_type_notation` is incomplete and may not be safe to use and/or cause compiler crashes
|
||||||
|
--> $DIR/supertrait-bound.rs:3:49
|
||||||
|
|
|
||||||
|
LL | #![feature(return_position_impl_trait_in_trait, return_type_notation)]
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: see issue #109417 <https://github.com/rust-lang/rust/issues/109417> for more information
|
||||||
|
= note: `#[warn(incomplete_features)]` on by default
|
||||||
|
|
||||||
|
warning: 1 warning emitted
|
||||||
|
|
18
tests/ui/dyn-star/param-env-infer.current.stderr
Normal file
18
tests/ui/dyn-star/param-env-infer.current.stderr
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
warning: the feature `dyn_star` is incomplete and may not be safe to use and/or cause compiler crashes
|
||||||
|
--> $DIR/param-env-infer.rs:5:12
|
||||||
|
|
|
||||||
|
LL | #![feature(dyn_star, pointer_like_trait)]
|
||||||
|
| ^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: see issue #102425 <https://github.com/rust-lang/rust/issues/102425> for more information
|
||||||
|
= note: `#[warn(incomplete_features)]` on by default
|
||||||
|
|
||||||
|
error[E0282]: type annotations needed
|
||||||
|
--> $DIR/param-env-infer.rs:12:10
|
||||||
|
|
|
||||||
|
LL | t as _
|
||||||
|
| ^ cannot infer type
|
||||||
|
|
||||||
|
error: aborting due to previous error; 1 warning emitted
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0282`.
|
18
tests/ui/dyn-star/param-env-infer.next.stderr
Normal file
18
tests/ui/dyn-star/param-env-infer.next.stderr
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
warning: the feature `dyn_star` is incomplete and may not be safe to use and/or cause compiler crashes
|
||||||
|
--> $DIR/param-env-infer.rs:5:12
|
||||||
|
|
|
||||||
|
LL | #![feature(dyn_star, pointer_like_trait)]
|
||||||
|
| ^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: see issue #102425 <https://github.com/rust-lang/rust/issues/102425> for more information
|
||||||
|
= note: `#[warn(incomplete_features)]` on by default
|
||||||
|
|
||||||
|
error[E0282]: type annotations needed
|
||||||
|
--> $DIR/param-env-infer.rs:12:10
|
||||||
|
|
|
||||||
|
LL | t as _
|
||||||
|
| ^ cannot infer type
|
||||||
|
|
||||||
|
error: aborting due to previous error; 1 warning emitted
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0282`.
|
16
tests/ui/dyn-star/param-env-infer.rs
Normal file
16
tests/ui/dyn-star/param-env-infer.rs
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
// revisions: current next
|
||||||
|
//[next] compile-flags: -Ztrait-solver=next
|
||||||
|
// incremental
|
||||||
|
|
||||||
|
#![feature(dyn_star, pointer_like_trait)]
|
||||||
|
//~^ WARN the feature `dyn_star` is incomplete and may not be safe to use and/or cause compiler crashes
|
||||||
|
|
||||||
|
use std::fmt::Debug;
|
||||||
|
use std::marker::PointerLike;
|
||||||
|
|
||||||
|
fn make_dyn_star<'a, T: PointerLike + Debug + 'a>(t: T) -> impl PointerLike + Debug + 'a {
|
||||||
|
t as _
|
||||||
|
//~^ ERROR type annotations needed
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
9
tests/ui/unsized-locals/issue-67981.rs
Normal file
9
tests/ui/unsized-locals/issue-67981.rs
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
#![feature(unsized_fn_params)]
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let f: fn([u8]) = |_| {};
|
||||||
|
//~^ERROR the size for values of type `[u8]` cannot be known at compilation time
|
||||||
|
let slice: Box<[u8]> = Box::new([1; 8]);
|
||||||
|
|
||||||
|
f(*slice);
|
||||||
|
}
|
15
tests/ui/unsized-locals/issue-67981.stderr
Normal file
15
tests/ui/unsized-locals/issue-67981.stderr
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
|
||||||
|
--> $DIR/issue-67981.rs:4:24
|
||||||
|
|
|
||||||
|
LL | let f: fn([u8]) = |_| {};
|
||||||
|
| ^ doesn't have a size known at compile-time
|
||||||
|
|
|
||||||
|
= help: the trait `Sized` is not implemented for `[u8]`
|
||||||
|
help: function arguments must have a statically known size, borrowed types always have a known size
|
||||||
|
|
|
||||||
|
LL | let f: fn([u8]) = |&_| {};
|
||||||
|
| +
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0277`.
|
Loading…
x
Reference in New Issue
Block a user