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).
|
||||
if let ty::Alias(ty::Projection, projection) = ty.kind() {
|
||||
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)
|
||||
== def_id.to_def_id()
|
||||
} else {
|
||||
|
@ -32,6 +32,7 @@ pub(super) fn check_fn<'a, 'tcx>(
|
||||
fn_def_id: LocalDefId,
|
||||
body: &'tcx hir::Body<'tcx>,
|
||||
can_be_generator: Option<hir::Movability>,
|
||||
params_can_be_unsized: bool,
|
||||
) -> Option<GeneratorTypes<'tcx>> {
|
||||
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
|
||||
// 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`.
|
||||
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));
|
||||
}
|
||||
|
||||
|
@ -89,6 +89,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
expr_def_id,
|
||||
body,
|
||||
closure.movability,
|
||||
// Closure "rust-call" ABI doesn't support unsized params
|
||||
false,
|
||||
);
|
||||
|
||||
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 = 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 {
|
||||
let expected_type = if let Some(&hir::Ty { kind: hir::TyKind::Infer, span, .. }) = body_ty {
|
||||
Some(fcx.next_ty_var(TypeVariableOrigin {
|
||||
|
@ -323,7 +323,7 @@ provide! { tcx, def_id, other, cdata,
|
||||
|
||||
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()) }
|
||||
implementations_of_trait => { cdata.get_implementations_of_trait(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> {
|
||||
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.
|
||||
@ -2329,7 +2329,7 @@ pub fn provide(providers: &mut Providers) {
|
||||
.get(&def_id)
|
||||
.expect("no traits in scope for a doc link")
|
||||
},
|
||||
traits_in_crate: |tcx, LocalCrate| {
|
||||
traits: |tcx, LocalCrate| {
|
||||
let mut traits = Vec::new();
|
||||
for id in tcx.hir().items() {
|
||||
if matches!(tcx.def_kind(id.owner_id), DefKind::Trait | DefKind::TraitAlias) {
|
||||
|
@ -38,7 +38,10 @@ use crate::traits::query::{
|
||||
OutlivesBound,
|
||||
};
|
||||
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::layout::ValidityRequirement;
|
||||
use crate::ty::subst::{GenericArg, SubstsRef};
|
||||
@ -1273,7 +1276,7 @@ rustc_queries! {
|
||||
|
||||
query codegen_select_candidate(
|
||||
key: (ty::ParamEnv<'tcx>, ty::PolyTraitRef<'tcx>)
|
||||
) -> Result<&'tcx ImplSource<'tcx, ()>, traits::CodegenObligationError> {
|
||||
) -> Result<&'tcx ImplSource<'tcx, ()>, CodegenObligationError> {
|
||||
cache_on_disk_if { true }
|
||||
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) }
|
||||
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) }
|
||||
}
|
||||
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.
|
||||
/// NOTE: Not named just `traits` due to a naming conflict.
|
||||
query traits_in_crate(_: CrateNum) -> &'tcx [DefId] {
|
||||
query traits(_: CrateNum) -> &'tcx [DefId] {
|
||||
desc { "fetching all traits in a crate" }
|
||||
separate_provide_extern
|
||||
}
|
||||
@ -1953,12 +1955,12 @@ rustc_queries! {
|
||||
/// `infcx.predicate_must_hold()` instead.
|
||||
query evaluate_obligation(
|
||||
goal: CanonicalPredicateGoal<'tcx>
|
||||
) -> Result<traits::EvaluationResult, traits::OverflowError> {
|
||||
) -> Result<EvaluationResult, OverflowError> {
|
||||
desc { "evaluating trait selection obligation `{}`", goal.value.value }
|
||||
}
|
||||
|
||||
query evaluate_goal(
|
||||
goal: traits::CanonicalChalkEnvironmentAndGoal<'tcx>
|
||||
goal: CanonicalChalkEnvironmentAndGoal<'tcx>
|
||||
) -> Result<
|
||||
&'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, ()>>,
|
||||
NoSolution
|
||||
@ -2128,8 +2130,8 @@ rustc_queries! {
|
||||
/// all of the cases that the normal `ty::Ty`-based wfcheck does. This is fine,
|
||||
/// because the `ty::Ty`-based wfcheck is always run.
|
||||
query diagnostic_hir_wf_check(
|
||||
key: (ty::Predicate<'tcx>, traits::WellFormedLoc)
|
||||
) -> &'tcx Option<traits::ObligationCause<'tcx>> {
|
||||
key: (ty::Predicate<'tcx>, WellFormedLoc)
|
||||
) -> &'tcx Option<ObligationCause<'tcx>> {
|
||||
arena_cache
|
||||
eval_always
|
||||
no_hash
|
||||
|
@ -1199,7 +1199,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||
pub fn all_traits(self) -> impl Iterator<Item = DefId> + 'tcx {
|
||||
iter::once(LOCAL_CRATE)
|
||||
.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]
|
||||
|
@ -177,14 +177,18 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
|
||||
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);
|
||||
}
|
||||
|
||||
let tcx = ecx.tcx();
|
||||
let self_ty = tcx.erase_regions(goal.predicate.self_ty());
|
||||
|
||||
if let Ok(layout) = tcx.layout_of(goal.param_env.and(self_ty))
|
||||
if let Ok(layout) = tcx.layout_of(key)
|
||||
&& layout.layout.is_pointer_like(&tcx.data_layout)
|
||||
{
|
||||
// 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
|
||||
let tcx = self.tcx();
|
||||
let self_ty =
|
||||
tcx.erase_regions(tcx.erase_late_bound_regions(obligation.predicate.self_ty()));
|
||||
|
||||
let self_ty = 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.
|
||||
if self_ty.has_non_region_infer() {
|
||||
if key.has_non_region_infer() {
|
||||
candidates.ambiguous = true;
|
||||
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)
|
||||
{
|
||||
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