Skip to content

Commit c763ece

Browse files
committed
Auto merge of #109552 - matthiaskrgr:rollup-03xwois, r=matthiaskrgr
Rollup of 5 pull requests Successful merges: - #109406 (Remove outdated comments) - #109433 (Return equal for two identical projections) - #109495 (Implement non-const `Destruct` trait in new solver) - #109519 (Link against libc++ on AIX) - #109550 (Make helper functions private in fn_ctxt/adjust_fulfillment_errors) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
2 parents 4c0f500 + 2cfcca6 commit c763ece

File tree

13 files changed

+121
-48
lines changed

13 files changed

+121
-48
lines changed

compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs

+30-32
Original file line numberDiff line numberDiff line change
@@ -310,7 +310,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
310310
.iter()
311311
.filter(|field| {
312312
let field_ty = field.ty(self.tcx, identity_substs);
313-
Self::find_param_in_ty(field_ty.into(), param_to_point_at)
313+
find_param_in_ty(field_ty.into(), param_to_point_at)
314314
})
315315
.collect();
316316

@@ -356,7 +356,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
356356
.inputs()
357357
.iter()
358358
.enumerate()
359-
.filter(|(_, ty)| Self::find_param_in_ty((**ty).into(), param_to_point_at))
359+
.filter(|(_, ty)| find_param_in_ty((**ty).into(), param_to_point_at))
360360
.collect();
361361
// If there's one field that references the given generic, great!
362362
if let [(idx, _)] = args_referencing_param.as_slice()
@@ -579,8 +579,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
579579
// Find out which of `in_ty_elements` refer to `param`.
580580
// FIXME: It may be better to take the first if there are multiple,
581581
// just so that the error points to a smaller expression.
582-
let Some((drill_expr, drill_ty)) = Self::is_iterator_singleton(expr_elements.iter().zip( in_ty_elements.iter()).filter(|(_expr_elem, in_ty_elem)| {
583-
Self::find_param_in_ty((*in_ty_elem).into(), param)
582+
let Some((drill_expr, drill_ty)) = is_iterator_singleton(expr_elements.iter().zip( in_ty_elements.iter()).filter(|(_expr_elem, in_ty_elem)| {
583+
find_param_in_ty((*in_ty_elem).into(), param)
584584
})) else {
585585
// The param is not mentioned, or it is mentioned in multiple indexes.
586586
return Err(expr);
@@ -628,10 +628,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
628628
// We need to know which of the generic parameters mentions our target param.
629629
// We expect that at least one of them does, since it is expected to be mentioned.
630630
let Some((drill_generic_index, generic_argument_type)) =
631-
Self::is_iterator_singleton(
631+
is_iterator_singleton(
632632
in_ty_adt_generic_args.iter().enumerate().filter(
633633
|(_index, in_ty_generic)| {
634-
Self::find_param_in_ty(*in_ty_generic, param)
634+
find_param_in_ty(*in_ty_generic, param)
635635
},
636636
),
637637
) else {
@@ -751,10 +751,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
751751
// We need to know which of the generic parameters mentions our target param.
752752
// We expect that at least one of them does, since it is expected to be mentioned.
753753
let Some((drill_generic_index, generic_argument_type)) =
754-
Self::is_iterator_singleton(
754+
is_iterator_singleton(
755755
in_ty_adt_generic_args.iter().enumerate().filter(
756756
|(_index, in_ty_generic)| {
757-
Self::find_param_in_ty(*in_ty_generic, param)
757+
find_param_in_ty(*in_ty_generic, param)
758758
},
759759
),
760760
) else {
@@ -793,14 +793,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
793793
// outer contextual information.
794794

795795
// (1) Find the (unique) field index which mentions the type in our constraint:
796-
let Some((field_index, field_type)) = Self::is_iterator_singleton(
796+
let Some((field_index, field_type)) = is_iterator_singleton(
797797
in_ty_adt
798798
.variant_with_id(variant_def_id)
799799
.fields
800800
.iter()
801801
.map(|field| field.ty(self.tcx, *in_ty_adt_generic_args))
802802
.enumerate()
803-
.filter(|(_index, field_type)| Self::find_param_in_ty((*field_type).into(), param))
803+
.filter(|(_index, field_type)| find_param_in_ty((*field_type).into(), param))
804804
) else {
805805
return Err(expr);
806806
};
@@ -833,20 +833,20 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
833833

834834
Err(expr)
835835
}
836+
}
836837

837-
// FIXME: This can be made into a private, non-impl function later.
838-
/// Traverses the given ty (either a `ty::Ty` or a `ty::GenericArg`) and searches for references
839-
/// to the given `param_to_point_at`. Returns `true` if it finds any use of the param.
840-
pub fn find_param_in_ty(
841-
ty: ty::GenericArg<'tcx>,
842-
param_to_point_at: ty::GenericArg<'tcx>,
843-
) -> bool {
844-
let mut walk = ty.walk();
845-
while let Some(arg) = walk.next() {
846-
if arg == param_to_point_at {
847-
return true;
848-
}
849-
if let ty::GenericArgKind::Type(ty) = arg.unpack()
838+
/// Traverses the given ty (either a `ty::Ty` or a `ty::GenericArg`) and searches for references
839+
/// to the given `param_to_point_at`. Returns `true` if it finds any use of the param.
840+
fn find_param_in_ty<'tcx>(
841+
ty: ty::GenericArg<'tcx>,
842+
param_to_point_at: ty::GenericArg<'tcx>,
843+
) -> bool {
844+
let mut walk = ty.walk();
845+
while let Some(arg) = walk.next() {
846+
if arg == param_to_point_at {
847+
return true;
848+
}
849+
if let ty::GenericArgKind::Type(ty) = arg.unpack()
850850
&& let ty::Alias(ty::Projection, ..) = ty.kind()
851851
{
852852
// This logic may seem a bit strange, but typically when
@@ -857,16 +857,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
857857
// in some UI tests.
858858
walk.skip_current_subtree();
859859
}
860-
}
861-
false
862860
}
861+
false
862+
}
863863

864-
// FIXME: This can be made into a private, non-impl function later.
865-
/// Returns `Some(iterator.next())` if it has exactly one item, and `None` otherwise.
866-
pub fn is_iterator_singleton<T>(mut iterator: impl Iterator<Item = T>) -> Option<T> {
867-
match (iterator.next(), iterator.next()) {
868-
(_, Some(_)) => None,
869-
(first, _) => first,
870-
}
864+
/// Returns `Some(iterator.next())` if it has exactly one item, and `None` otherwise.
865+
fn is_iterator_singleton<T>(mut iterator: impl Iterator<Item = T>) -> Option<T> {
866+
match (iterator.next(), iterator.next()) {
867+
(_, Some(_)) => None,
868+
(first, _) => first,
871869
}
872870
}

compiler/rustc_hir_typeck/src/upvar.rs

+7-3
Original file line numberDiff line numberDiff line change
@@ -712,10 +712,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
712712
}
713713
}
714714

715-
unreachable!(
716-
"we captured two identical projections: capture1 = {:?}, capture2 = {:?}",
717-
capture1, capture2
715+
self.tcx.sess.delay_span_bug(
716+
closure_span,
717+
&format!(
718+
"two identical projections: ({:?}, {:?})",
719+
capture1.place.projections, capture2.place.projections
720+
),
718721
);
722+
std::cmp::Ordering::Equal
719723
});
720724
}
721725

compiler/rustc_llvm/build.rs

+1
Original file line numberDiff line numberDiff line change
@@ -333,6 +333,7 @@ fn main() {
333333
} else if target.contains("darwin")
334334
|| target.contains("freebsd")
335335
|| target.contains("windows-gnullvm")
336+
|| target.contains("aix")
336337
{
337338
"c++"
338339
} else if target.contains("netbsd") && llvm_static_stdcpp.is_some() {

compiler/rustc_trait_selection/src/solve/assembly.rs

+7
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,11 @@ pub(super) trait GoalKind<'tcx>: TypeFoldable<TyCtxt<'tcx>> + Copy + Eq {
212212
ecx: &mut EvalCtxt<'_, 'tcx>,
213213
goal: Goal<'tcx, Self>,
214214
) -> QueryResult<'tcx>;
215+
216+
fn consider_builtin_destruct_candidate(
217+
ecx: &mut EvalCtxt<'_, 'tcx>,
218+
goal: Goal<'tcx, Self>,
219+
) -> QueryResult<'tcx>;
215220
}
216221

217222
impl<'tcx> EvalCtxt<'_, 'tcx> {
@@ -340,6 +345,8 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
340345
G::consider_builtin_unsize_candidate(self, goal)
341346
} else if lang_items.discriminant_kind_trait() == Some(trait_def_id) {
342347
G::consider_builtin_discriminant_kind_candidate(self, goal)
348+
} else if lang_items.destruct_trait() == Some(trait_def_id) {
349+
G::consider_builtin_destruct_candidate(self, goal)
343350
} else {
344351
Err(NoSolution)
345352
};

compiler/rustc_trait_selection/src/solve/project_goals.rs

+7
Original file line numberDiff line numberDiff line change
@@ -487,6 +487,13 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> {
487487
ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
488488
})
489489
}
490+
491+
fn consider_builtin_destruct_candidate(
492+
_ecx: &mut EvalCtxt<'_, 'tcx>,
493+
goal: Goal<'tcx, Self>,
494+
) -> QueryResult<'tcx> {
495+
bug!("`Destruct` does not have an associated type: {:?}", goal);
496+
}
490497
}
491498

492499
/// This behavior is also implemented in `rustc_ty_utils` and in the old `project` code.

compiler/rustc_trait_selection/src/solve/trait_goals.rs

+14
Original file line numberDiff line numberDiff line change
@@ -534,6 +534,20 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
534534
// `DiscriminantKind` is automatically implemented for every type.
535535
ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
536536
}
537+
538+
fn consider_builtin_destruct_candidate(
539+
ecx: &mut EvalCtxt<'_, 'tcx>,
540+
goal: Goal<'tcx, Self>,
541+
) -> QueryResult<'tcx> {
542+
if !goal.param_env.is_const() {
543+
// `Destruct` is automatically implemented for every type in
544+
// non-const environments.
545+
ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
546+
} else {
547+
// FIXME(-Ztrait-solver=next): Implement this when we get const working in the new solver
548+
Err(NoSolution)
549+
}
550+
}
537551
}
538552

539553
impl<'tcx> EvalCtxt<'_, 'tcx> {

library/alloc/src/collections/btree/mod.rs

-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ pub mod set;
1313
mod set_val;
1414
mod split;
1515

16-
#[doc(hidden)]
1716
trait Recover<Q: ?Sized> {
1817
type Key;
1918

library/alloc/src/collections/btree/set.rs

-5
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
// This is pretty much entirely stolen from TreeSet, since BTreeMap has an identical interface
2-
// to TreeMap
3-
41
use crate::vec::Vec;
52
use core::borrow::Borrow;
63
use core::cmp::Ordering::{self, Equal, Greater, Less};
@@ -18,8 +15,6 @@ use super::Recover;
1815

1916
use crate::alloc::{Allocator, Global};
2017

21-
// FIXME(conventions): implement bounded iterators
22-
2318
/// An ordered set based on a B-Tree.
2419
///
2520
/// See [`BTreeMap`]'s documentation for a detailed discussion of this collection's performance

library/std/src/collections/hash/set.rs

-7
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,6 @@ use crate::ops::{BitAnd, BitOr, BitXor, Sub};
1212

1313
use super::map::{map_try_reserve_error, RandomState};
1414

15-
// Future Optimization (FIXME!)
16-
// ============================
17-
//
18-
// Iteration over zero sized values is a noop. There is no need
19-
// for `bucket.val` in the case of HashSet. I suppose we would need HKT
20-
// to get rid of it properly.
21-
2215
/// A [hash set] implemented as a `HashMap` where the value is `()`.
2316
///
2417
/// As with the [`HashMap`] type, a `HashSet` requires that the elements

tests/ui/closures/issue-109188.rs

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
enum Either {
2+
One(X),
3+
Two(X),
4+
}
5+
6+
struct X(Y);
7+
8+
struct Y;
9+
10+
fn consume_fnmut(f: &dyn FnMut()) {
11+
f();
12+
}
13+
14+
fn move_into_fnmut() {
15+
let x = move_into_fnmut();
16+
consume_fnmut(&|| {
17+
let Either::One(_t) = x; //~ ERROR mismatched types
18+
let Either::Two(_t) = x; //~ ERROR mismatched types
19+
});
20+
}
21+
22+
fn main() { }

tests/ui/closures/issue-109188.stderr

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
error[E0308]: mismatched types
2+
--> $DIR/issue-109188.rs:17:13
3+
|
4+
LL | let Either::One(_t) = x;
5+
| ^^^^^^^^^^^^^^^ - this expression has type `()`
6+
| |
7+
| expected `()`, found `Either`
8+
9+
error[E0308]: mismatched types
10+
--> $DIR/issue-109188.rs:18:13
11+
|
12+
LL | let Either::Two(_t) = x;
13+
| ^^^^^^^^^^^^^^^ - this expression has type `()`
14+
| |
15+
| expected `()`, found `Either`
16+
17+
error: aborting due to 2 previous errors
18+
19+
For more information about this error, try `rustc --explain E0308`.

tests/ui/traits/new-solver/canonical-int-var-eq-in-response.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
// compile-flags: -Ztrait-solver=next
12
// check-pass
23

34
trait Mirror {
+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// compile-flags: -Ztrait-solver=next
2+
// check-pass
3+
4+
#![feature(const_trait_impl)]
5+
6+
fn foo(_: impl std::marker::Destruct) {}
7+
8+
struct MyAdt;
9+
10+
fn main() {
11+
foo(1);
12+
foo(MyAdt);
13+
}

0 commit comments

Comments
 (0)