Skip to content

Rollup of 5 pull requests #111895

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 10 commits into from
May 24, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions compiler/rustc_hir_analysis/src/collect/predicates_of.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_hir_typeck/src/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);

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

Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_hir_typeck/src/closure.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_hir_typeck/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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) }
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_metadata/src/rmeta/encoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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) {
Expand Down
20 changes: 11 additions & 9 deletions compiler/rustc_middle/src/query/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down Expand Up @@ -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 }
}
Expand All @@ -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 {
Expand Down Expand Up @@ -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
}
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_middle/src/ty/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand Down
14 changes: 9 additions & 5 deletions compiler/rustc_trait_selection/src/solve/trait_goals.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 });
Expand Down
14 changes: 14 additions & 0 deletions tests/ui/associated-inherent-types/issue-111879-0.rs
Original file line number Diff line number Diff line change
@@ -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 changes: 8 additions & 0 deletions tests/ui/associated-inherent-types/issue-111879-0.stderr
Original file line number Diff line number Diff line change
@@ -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 changes: 12 additions & 0 deletions tests/ui/associated-inherent-types/issue-111879-1.rs
Original file line number Diff line number Diff line change
@@ -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 changes: 12 additions & 0 deletions tests/ui/associated-inherent-types/issue-111879-1.stderr
Original file line number Diff line number Diff line change
@@ -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`.
11 changes: 11 additions & 0 deletions tests/ui/async-await/return-type-notation/supertrait-bound.rs
Original file line number Diff line number Diff line change
@@ -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() {}
11 changes: 11 additions & 0 deletions tests/ui/async-await/return-type-notation/supertrait-bound.stderr
Original file line number Diff line number Diff line change
@@ -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 changes: 18 additions & 0 deletions tests/ui/dyn-star/param-env-infer.current.stderr
Original file line number Diff line number Diff line change
@@ -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 changes: 18 additions & 0 deletions tests/ui/dyn-star/param-env-infer.next.stderr
Original file line number Diff line number Diff line change
@@ -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 changes: 16 additions & 0 deletions tests/ui/dyn-star/param-env-infer.rs
Original file line number Diff line number Diff line change
@@ -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 changes: 9 additions & 0 deletions tests/ui/unsized-locals/issue-67981.rs
Original file line number Diff line number Diff line change
@@ -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 changes: 15 additions & 0 deletions tests/ui/unsized-locals/issue-67981.stderr
Original file line number Diff line number Diff line change
@@ -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`.