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:
bors 2023-05-24 05:07:22 +00:00
commit 82faf5ed60
21 changed files with 182 additions and 25 deletions

View File

@ -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 {

View File

@ -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));
}

View File

@ -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(

View File

@ -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 {

View File

@ -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) }

View File

@ -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) {

View File

@ -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

View File

@ -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]

View File

@ -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

View File

@ -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 });

View 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() {}

View 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

View 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

View 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`.

View File

@ -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() {}

View File

@ -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

View 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`.

View 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`.

View 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() {}

View 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);
}

View 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`.