Skip to content

Commit

Permalink
Auto merge of #113429 - compiler-errors:rollup-wkv4w9a, r=compiler-er…
Browse files Browse the repository at this point in the history
…rors

Rollup of 8 pull requests

Successful merges:

 - #111917 (Simplify duplicate checks for mir validator)
 - #112008 (Fix incorrect documented default bufsize in bufreader/writer)
 - #112825 (Don't call `type_of` on TAIT in defining scope in new solver)
 - #113164 (Add a regression test for #109054)
 - #113318 (Revert "alloc: Allow comparing Boxs over different allocators", add regression test)
 - #113397 (Prefer object candidates in new selection)
 - #113419 (Avoid calling item_name for RPITIT)
 - #113421 (Do not assert >1 RPITITs on collect_return_position_impl_trait_in_trait_tys)

r? `@ghost`
`@rustbot` modify labels: rollup
  • Loading branch information
bors committed Jul 7, 2023
2 parents bb548f9 + 45cb1ba commit 7cc3da0
Show file tree
Hide file tree
Showing 23 changed files with 307 additions and 151 deletions.
23 changes: 9 additions & 14 deletions compiler/rustc_const_eval/src/transform/validate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,8 @@ impl<'tcx> MirPass<'tcx> for Validator {
unwind_edge_count: 0,
reachable_blocks: traversal::reachable_as_bitset(body),
storage_liveness,
place_cache: Vec::new(),
value_cache: Vec::new(),
place_cache: FxHashSet::default(),
value_cache: FxHashSet::default(),
};
checker.visit_body(body);
checker.check_cleanup_control_flow();
Expand All @@ -95,8 +95,8 @@ struct TypeChecker<'a, 'tcx> {
unwind_edge_count: usize,
reachable_blocks: BitSet<BasicBlock>,
storage_liveness: ResultsCursor<'a, 'tcx, MaybeStorageLive<'static>>,
place_cache: Vec<PlaceRef<'tcx>>,
value_cache: Vec<u128>,
place_cache: FxHashSet<PlaceRef<'tcx>>,
value_cache: FxHashSet<u128>,
}

impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
Expand Down Expand Up @@ -951,10 +951,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {

self.value_cache.clear();
self.value_cache.extend(targets.iter().map(|(value, _)| value));
let all_len = self.value_cache.len();
self.value_cache.sort_unstable();
self.value_cache.dedup();
let has_duplicates = all_len != self.value_cache.len();
let has_duplicates = targets.iter().len() != self.value_cache.len();
if has_duplicates {
self.fail(
location,
Expand Down Expand Up @@ -987,16 +984,14 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
// passed by a reference to the callee. Consequently they must be non-overlapping.
// Currently this simply checks for duplicate places.
self.place_cache.clear();
self.place_cache.push(destination.as_ref());
self.place_cache.insert(destination.as_ref());
let mut has_duplicates = false;
for arg in args {
if let Operand::Move(place) = arg {
self.place_cache.push(place.as_ref());
has_duplicates |= !self.place_cache.insert(place.as_ref());
}
}
let all_len = self.place_cache.len();
let mut dedup = FxHashSet::default();
self.place_cache.retain(|p| dedup.insert(*p));
let has_duplicates = all_len != self.place_cache.len();

if has_duplicates {
self.fail(
location,
Expand Down
12 changes: 7 additions & 5 deletions compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -669,11 +669,13 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
)
.fold_with(&mut collector);

debug_assert_ne!(
collector.types.len(),
0,
"expect >1 RPITITs in call to `collect_return_position_impl_trait_in_trait_tys`"
);
if !unnormalized_trait_sig.output().references_error() {
debug_assert_ne!(
collector.types.len(),
0,
"expect >1 RPITITs in call to `collect_return_position_impl_trait_in_trait_tys`"
);
}

let trait_sig = ocx.normalize(&norm_cause, param_env, unnormalized_trait_sig);
trait_sig.error_reported()?;
Expand Down
8 changes: 5 additions & 3 deletions compiler/rustc_infer/src/traits/error_reporting/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,11 @@ impl<'tcx> InferCtxt<'tcx> {
"impl has stricter requirements than trait"
);

if let Some(span) = self.tcx.hir().span_if_local(trait_item_def_id) {
let item_name = self.tcx.item_name(impl_item_def_id.to_def_id());
err.span_label(span, format!("definition of `{}` from trait", item_name));
if !self.tcx.is_impl_trait_in_trait(trait_item_def_id) {
if let Some(span) = self.tcx.hir().span_if_local(trait_item_def_id) {
let item_name = self.tcx.item_name(impl_item_def_id.to_def_id());
err.span_label(span, format!("definition of `{}` from trait", item_name));
}
}

err.span_label(error_span, format!("impl has extra requirement {}", requirement));
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_trait_selection/src/solve/eval_ctxt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -837,7 +837,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
}
}

pub(super) fn can_define_opaque_ty(&mut self, def_id: LocalDefId) -> bool {
pub(super) fn can_define_opaque_ty(&self, def_id: LocalDefId) -> bool {
self.infcx.opaque_type_origin(def_id).is_some()
}

Expand Down
8 changes: 8 additions & 0 deletions compiler/rustc_trait_selection/src/solve/eval_ctxt/select.rs
Original file line number Diff line number Diff line change
Expand Up @@ -173,10 +173,18 @@ fn candidate_should_be_dropped_in_favor_of<'tcx>(
victim_idx >= other_idx
}
(_, CandidateSource::ParamEnv(_)) => true,

(
CandidateSource::BuiltinImpl(BuiltinImplSource::Object),
CandidateSource::BuiltinImpl(BuiltinImplSource::Object),
) => false,
(_, CandidateSource::BuiltinImpl(BuiltinImplSource::Object)) => true,

(CandidateSource::Impl(victim_def_id), CandidateSource::Impl(other_def_id)) => {
tcx.specializes((other_def_id, victim_def_id))
&& other.result.value.certainty == Certainty::Yes
}

_ => false,
}
}
Expand Down
27 changes: 27 additions & 0 deletions compiler/rustc_trait_selection/src/solve/trait_goals.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use rustc_hir::{LangItem, Movability};
use rustc_infer::traits::query::NoSolution;
use rustc_infer::traits::util::supertraits;
use rustc_middle::traits::solve::{CanonicalResponse, Certainty, Goal, QueryResult};
use rustc_middle::traits::Reveal;
use rustc_middle::ty::fast_reject::{DeepRejectCtxt, TreatParams, TreatProjections};
use rustc_middle::ty::{self, ToPredicate, Ty, TyCtxt};
use rustc_middle::ty::{TraitPredicate, TypeVisitableExt};
Expand Down Expand Up @@ -118,6 +119,32 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
return result;
}

// Don't call `type_of` on a local TAIT that's in the defining scope,
// since that may require calling `typeck` on the same item we're
// currently type checking, which will result in a fatal cycle that
// ideally we want to avoid, since we can make progress on this goal
// via an alias bound or a locally-inferred hidden type instead.
//
// Also, don't call `type_of` on a TAIT in `Reveal::All` mode, since
// we already normalize the self type in
// `assemble_candidates_after_normalizing_self_ty`, and we'd
// just be registering an identical candidate here.
//
// Returning `Err(NoSolution)` here is ok in `SolverMode::Coherence`
// since we'll always be registering an ambiguous candidate in
// `assemble_candidates_after_normalizing_self_ty` due to normalizing
// the TAIT.
if let ty::Alias(ty::Opaque, opaque_ty) = goal.predicate.self_ty().kind() {
if matches!(goal.param_env.reveal(), Reveal::All)
|| opaque_ty
.def_id
.as_local()
.is_some_and(|def_id| ecx.can_define_opaque_ty(def_id))
{
return Err(NoSolution);
}
}

ecx.probe_and_evaluate_goal_for_constituent_tys(
goal,
structural_traits::instantiate_constituent_tys_for_auto_trait,
Expand Down
35 changes: 9 additions & 26 deletions library/alloc/src/boxed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1319,56 +1319,39 @@ impl Clone for Box<str> {
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<T, A1, A2> PartialEq<Box<T, A2>> for Box<T, A1>
where
T: ?Sized + PartialEq,
A1: Allocator,
A2: Allocator,
{
impl<T: ?Sized + PartialEq, A: Allocator> PartialEq for Box<T, A> {
#[inline]
fn eq(&self, other: &Box<T, A2>) -> bool {
fn eq(&self, other: &Self) -> bool {
PartialEq::eq(&**self, &**other)
}

#[inline]
fn ne(&self, other: &Box<T, A2>) -> bool {
fn ne(&self, other: &Self) -> bool {
PartialEq::ne(&**self, &**other)
}
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<T, A1, A2> PartialOrd<Box<T, A2>> for Box<T, A1>
where
T: ?Sized + PartialOrd,
A1: Allocator,
A2: Allocator,
{
impl<T: ?Sized + PartialOrd, A: Allocator> PartialOrd for Box<T, A> {
#[inline]
fn partial_cmp(&self, other: &Box<T, A2>) -> Option<Ordering> {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
PartialOrd::partial_cmp(&**self, &**other)
}

#[inline]
fn lt(&self, other: &Box<T, A2>) -> bool {
fn lt(&self, other: &Self) -> bool {
PartialOrd::lt(&**self, &**other)
}

#[inline]
fn le(&self, other: &Box<T, A2>) -> bool {
fn le(&self, other: &Self) -> bool {
PartialOrd::le(&**self, &**other)
}

#[inline]
fn ge(&self, other: &Box<T, A2>) -> bool {
fn ge(&self, other: &Self) -> bool {
PartialOrd::ge(&**self, &**other)
}

#[inline]
fn gt(&self, other: &Box<T, A2>) -> bool {
fn gt(&self, other: &Self) -> bool {
PartialOrd::gt(&**self, &**other)
}
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<T: ?Sized + Ord, A: Allocator> Ord for Box<T, A> {
#[inline]
Expand Down
2 changes: 1 addition & 1 deletion library/std/src/io/buffered/bufreader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ pub struct BufReader<R: ?Sized> {
}

impl<R: Read> BufReader<R> {
/// Creates a new `BufReader<R>` with a default buffer capacity. The default is currently 8 KB,
/// Creates a new `BufReader<R>` with a default buffer capacity. The default is currently 8 KiB,
/// but may change in the future.
///
/// # Examples
Expand Down
2 changes: 1 addition & 1 deletion library/std/src/io/buffered/bufwriter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ pub struct BufWriter<W: ?Sized + Write> {
}

impl<W: Write> BufWriter<W> {
/// Creates a new `BufWriter<W>` with a default buffer capacity. The default is currently 8 KB,
/// Creates a new `BufWriter<W>` with a default buffer capacity. The default is currently 8 KiB,
/// but may change in the future.
///
/// # Examples
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
error[E0726]: implicit elided lifetime not allowed here
--> $DIR/return-not-existing-pair.rs:12:20
|
LL | impl<'a, 'b, T, U> MyTrait<T> for U {
| ^^^^^^^^^^ expected lifetime parameters
|
help: indicate the anonymous lifetimes
|
LL | impl<'a, 'b, T, U> MyTrait<'_, '_, T> for U {
| +++++++

error[E0412]: cannot find type `ConnImpl` in this scope
--> $DIR/return-not-existing-pair.rs:8:48
|
LL | async fn foo(&'a self, key: &'b T) -> (&'a ConnImpl, &'b T);
| ^^^^^^^^ not found in this scope

error[E0186]: method `foo` has a `&self` declaration in the trait, but not in the impl
--> $DIR/return-not-existing-pair.rs:14:5
|
LL | async fn foo(&'a self, key: &'b T) -> (&'a ConnImpl, &'b T);
| ------------------------------------------------------------ `&self` used in trait
...
LL | async fn foo(_: T) -> (&'a U, &'b T) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `&self` in impl

error[E0308]: mismatched types
--> $DIR/return-not-existing-pair.rs:14:42
|
LL | async fn foo(_: T) -> (&'a U, &'b T) {}
| ^^ expected `(&U, &T)`, found `()`
|
= note: expected tuple `(&'a U, &'b T)`
found unit type `()`

error: aborting due to 4 previous errors

Some errors have detailed explanations: E0186, E0308, E0412, E0726.
For more information about an error, try `rustc --explain E0186`.
39 changes: 39 additions & 0 deletions tests/ui/async-await/in-trait/return-not-existing-pair.next.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
error[E0726]: implicit elided lifetime not allowed here
--> $DIR/return-not-existing-pair.rs:12:20
|
LL | impl<'a, 'b, T, U> MyTrait<T> for U {
| ^^^^^^^^^^ expected lifetime parameters
|
help: indicate the anonymous lifetimes
|
LL | impl<'a, 'b, T, U> MyTrait<'_, '_, T> for U {
| +++++++

error[E0412]: cannot find type `ConnImpl` in this scope
--> $DIR/return-not-existing-pair.rs:8:48
|
LL | async fn foo(&'a self, key: &'b T) -> (&'a ConnImpl, &'b T);
| ^^^^^^^^ not found in this scope

error[E0186]: method `foo` has a `&self` declaration in the trait, but not in the impl
--> $DIR/return-not-existing-pair.rs:14:5
|
LL | async fn foo(&'a self, key: &'b T) -> (&'a ConnImpl, &'b T);
| ------------------------------------------------------------ `&self` used in trait
...
LL | async fn foo(_: T) -> (&'a U, &'b T) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `&self` in impl

error[E0308]: mismatched types
--> $DIR/return-not-existing-pair.rs:14:42
|
LL | async fn foo(_: T) -> (&'a U, &'b T) {}
| ^^ expected `(&U, &T)`, found `()`
|
= note: expected tuple `(&'a U, &'b T)`
found unit type `()`

error: aborting due to 4 previous errors

Some errors have detailed explanations: E0186, E0308, E0412, E0726.
For more information about an error, try `rustc --explain E0186`.
19 changes: 19 additions & 0 deletions tests/ui/async-await/in-trait/return-not-existing-pair.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// edition:2021
// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty
// revisions: current next

#![feature(async_fn_in_trait)]

trait MyTrait<'a, 'b, T> {
async fn foo(&'a self, key: &'b T) -> (&'a ConnImpl, &'b T);
//~^ ERROR: cannot find type `ConnImpl` in this scope [E0412]
}

impl<'a, 'b, T, U> MyTrait<T> for U {
//~^ ERROR: implicit elided lifetime not allowed here [E0726]
async fn foo(_: T) -> (&'a U, &'b T) {}
//~^ ERROR: method `foo` has a `&self` declaration in the trait, but not in the impl [E0186]
//~| ERROR: mismatched types [E0308]
}

fn main() {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
error[E0412]: cannot find type `Missing` in this scope
--> $DIR/return-not-existing-type-wrapping-rpitit.rs:10:25
|
LL | fn bar() -> Wrapper<Missing<impl Sized>>;
| ^^^^^^^ not found in this scope

error: aborting due to previous error

For more information about this error, try `rustc --explain E0412`.
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
error[E0412]: cannot find type `Missing` in this scope
--> $DIR/return-not-existing-type-wrapping-rpitit.rs:10:25
|
LL | fn bar() -> Wrapper<Missing<impl Sized>>;
| ^^^^^^^ not found in this scope

error: aborting due to previous error

For more information about this error, try `rustc --explain E0412`.
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// edition:2021
// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty
// revisions: current next

#![feature(return_position_impl_trait_in_trait)]

struct Wrapper<T>(T);

trait Foo {
fn bar() -> Wrapper<Missing<impl Sized>>;
//~^ ERROR: cannot find type `Missing` in this scope [E0412]
}

impl Foo for () {
fn bar() -> Wrapper<i32> {
Wrapper(0)
}
}

fn main() {}
2 changes: 1 addition & 1 deletion tests/ui/traits/new-solver/dont-remap-tait-substs.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// compile-flags: -Ztrait-solver=next
// known-bug: #112825
// check-pass

// Makes sure we don't prepopulate the MIR typeck of `define`
// with `Foo<T, U> = T`, but instead, `Foo<B, A> = B`, so that
Expand Down
Loading

0 comments on commit 7cc3da0

Please sign in to comment.