mirror of
https://github.com/rust-lang/rust.git
synced 2025-04-28 11:07:42 +00:00
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
This commit is contained in:
commit
c763eceae3
@ -310,7 +310,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
.iter()
|
.iter()
|
||||||
.filter(|field| {
|
.filter(|field| {
|
||||||
let field_ty = field.ty(self.tcx, identity_substs);
|
let field_ty = field.ty(self.tcx, identity_substs);
|
||||||
Self::find_param_in_ty(field_ty.into(), param_to_point_at)
|
find_param_in_ty(field_ty.into(), param_to_point_at)
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
@ -356,7 +356,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
.inputs()
|
.inputs()
|
||||||
.iter()
|
.iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.filter(|(_, ty)| Self::find_param_in_ty((**ty).into(), param_to_point_at))
|
.filter(|(_, ty)| find_param_in_ty((**ty).into(), param_to_point_at))
|
||||||
.collect();
|
.collect();
|
||||||
// If there's one field that references the given generic, great!
|
// If there's one field that references the given generic, great!
|
||||||
if let [(idx, _)] = args_referencing_param.as_slice()
|
if let [(idx, _)] = args_referencing_param.as_slice()
|
||||||
@ -579,8 +579,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
// Find out which of `in_ty_elements` refer to `param`.
|
// Find out which of `in_ty_elements` refer to `param`.
|
||||||
// FIXME: It may be better to take the first if there are multiple,
|
// FIXME: It may be better to take the first if there are multiple,
|
||||||
// just so that the error points to a smaller expression.
|
// just so that the error points to a smaller expression.
|
||||||
let Some((drill_expr, drill_ty)) = Self::is_iterator_singleton(expr_elements.iter().zip( in_ty_elements.iter()).filter(|(_expr_elem, in_ty_elem)| {
|
let Some((drill_expr, drill_ty)) = is_iterator_singleton(expr_elements.iter().zip( in_ty_elements.iter()).filter(|(_expr_elem, in_ty_elem)| {
|
||||||
Self::find_param_in_ty((*in_ty_elem).into(), param)
|
find_param_in_ty((*in_ty_elem).into(), param)
|
||||||
})) else {
|
})) else {
|
||||||
// The param is not mentioned, or it is mentioned in multiple indexes.
|
// The param is not mentioned, or it is mentioned in multiple indexes.
|
||||||
return Err(expr);
|
return Err(expr);
|
||||||
@ -628,10 +628,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
// We need to know which of the generic parameters mentions our target param.
|
// We need to know which of the generic parameters mentions our target param.
|
||||||
// We expect that at least one of them does, since it is expected to be mentioned.
|
// We expect that at least one of them does, since it is expected to be mentioned.
|
||||||
let Some((drill_generic_index, generic_argument_type)) =
|
let Some((drill_generic_index, generic_argument_type)) =
|
||||||
Self::is_iterator_singleton(
|
is_iterator_singleton(
|
||||||
in_ty_adt_generic_args.iter().enumerate().filter(
|
in_ty_adt_generic_args.iter().enumerate().filter(
|
||||||
|(_index, in_ty_generic)| {
|
|(_index, in_ty_generic)| {
|
||||||
Self::find_param_in_ty(*in_ty_generic, param)
|
find_param_in_ty(*in_ty_generic, param)
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
) else {
|
) else {
|
||||||
@ -751,10 +751,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
// We need to know which of the generic parameters mentions our target param.
|
// We need to know which of the generic parameters mentions our target param.
|
||||||
// We expect that at least one of them does, since it is expected to be mentioned.
|
// We expect that at least one of them does, since it is expected to be mentioned.
|
||||||
let Some((drill_generic_index, generic_argument_type)) =
|
let Some((drill_generic_index, generic_argument_type)) =
|
||||||
Self::is_iterator_singleton(
|
is_iterator_singleton(
|
||||||
in_ty_adt_generic_args.iter().enumerate().filter(
|
in_ty_adt_generic_args.iter().enumerate().filter(
|
||||||
|(_index, in_ty_generic)| {
|
|(_index, in_ty_generic)| {
|
||||||
Self::find_param_in_ty(*in_ty_generic, param)
|
find_param_in_ty(*in_ty_generic, param)
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
) else {
|
) else {
|
||||||
@ -793,14 +793,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
// outer contextual information.
|
// outer contextual information.
|
||||||
|
|
||||||
// (1) Find the (unique) field index which mentions the type in our constraint:
|
// (1) Find the (unique) field index which mentions the type in our constraint:
|
||||||
let Some((field_index, field_type)) = Self::is_iterator_singleton(
|
let Some((field_index, field_type)) = is_iterator_singleton(
|
||||||
in_ty_adt
|
in_ty_adt
|
||||||
.variant_with_id(variant_def_id)
|
.variant_with_id(variant_def_id)
|
||||||
.fields
|
.fields
|
||||||
.iter()
|
.iter()
|
||||||
.map(|field| field.ty(self.tcx, *in_ty_adt_generic_args))
|
.map(|field| field.ty(self.tcx, *in_ty_adt_generic_args))
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.filter(|(_index, field_type)| Self::find_param_in_ty((*field_type).into(), param))
|
.filter(|(_index, field_type)| find_param_in_ty((*field_type).into(), param))
|
||||||
) else {
|
) else {
|
||||||
return Err(expr);
|
return Err(expr);
|
||||||
};
|
};
|
||||||
@ -833,20 +833,20 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
|
|
||||||
Err(expr)
|
Err(expr)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// FIXME: This can be made into a private, non-impl function later.
|
/// Traverses the given ty (either a `ty::Ty` or a `ty::GenericArg`) and searches for references
|
||||||
/// Traverses the given ty (either a `ty::Ty` or a `ty::GenericArg`) and searches for references
|
/// to the given `param_to_point_at`. Returns `true` if it finds any use of the param.
|
||||||
/// to the given `param_to_point_at`. Returns `true` if it finds any use of the param.
|
fn find_param_in_ty<'tcx>(
|
||||||
pub fn find_param_in_ty(
|
ty: ty::GenericArg<'tcx>,
|
||||||
ty: ty::GenericArg<'tcx>,
|
param_to_point_at: ty::GenericArg<'tcx>,
|
||||||
param_to_point_at: ty::GenericArg<'tcx>,
|
) -> bool {
|
||||||
) -> bool {
|
let mut walk = ty.walk();
|
||||||
let mut walk = ty.walk();
|
while let Some(arg) = walk.next() {
|
||||||
while let Some(arg) = walk.next() {
|
if arg == param_to_point_at {
|
||||||
if arg == param_to_point_at {
|
return true;
|
||||||
return true;
|
}
|
||||||
}
|
if let ty::GenericArgKind::Type(ty) = arg.unpack()
|
||||||
if let ty::GenericArgKind::Type(ty) = arg.unpack()
|
|
||||||
&& let ty::Alias(ty::Projection, ..) = ty.kind()
|
&& let ty::Alias(ty::Projection, ..) = ty.kind()
|
||||||
{
|
{
|
||||||
// This logic may seem a bit strange, but typically when
|
// This logic may seem a bit strange, but typically when
|
||||||
@ -857,16 +857,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
// in some UI tests.
|
// in some UI tests.
|
||||||
walk.skip_current_subtree();
|
walk.skip_current_subtree();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
false
|
|
||||||
}
|
}
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
// FIXME: This can be made into a private, non-impl function later.
|
/// Returns `Some(iterator.next())` if it has exactly one item, and `None` otherwise.
|
||||||
/// Returns `Some(iterator.next())` if it has exactly one item, and `None` otherwise.
|
fn is_iterator_singleton<T>(mut iterator: impl Iterator<Item = T>) -> Option<T> {
|
||||||
pub fn is_iterator_singleton<T>(mut iterator: impl Iterator<Item = T>) -> Option<T> {
|
match (iterator.next(), iterator.next()) {
|
||||||
match (iterator.next(), iterator.next()) {
|
(_, Some(_)) => None,
|
||||||
(_, Some(_)) => None,
|
(first, _) => first,
|
||||||
(first, _) => first,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -712,10 +712,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unreachable!(
|
self.tcx.sess.delay_span_bug(
|
||||||
"we captured two identical projections: capture1 = {:?}, capture2 = {:?}",
|
closure_span,
|
||||||
capture1, capture2
|
&format!(
|
||||||
|
"two identical projections: ({:?}, {:?})",
|
||||||
|
capture1.place.projections, capture2.place.projections
|
||||||
|
),
|
||||||
);
|
);
|
||||||
|
std::cmp::Ordering::Equal
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -333,6 +333,7 @@ fn main() {
|
|||||||
} else if target.contains("darwin")
|
} else if target.contains("darwin")
|
||||||
|| target.contains("freebsd")
|
|| target.contains("freebsd")
|
||||||
|| target.contains("windows-gnullvm")
|
|| target.contains("windows-gnullvm")
|
||||||
|
|| target.contains("aix")
|
||||||
{
|
{
|
||||||
"c++"
|
"c++"
|
||||||
} else if target.contains("netbsd") && llvm_static_stdcpp.is_some() {
|
} else if target.contains("netbsd") && llvm_static_stdcpp.is_some() {
|
||||||
|
@ -212,6 +212,11 @@ pub(super) trait GoalKind<'tcx>: TypeFoldable<TyCtxt<'tcx>> + Copy + Eq {
|
|||||||
ecx: &mut EvalCtxt<'_, 'tcx>,
|
ecx: &mut EvalCtxt<'_, 'tcx>,
|
||||||
goal: Goal<'tcx, Self>,
|
goal: Goal<'tcx, Self>,
|
||||||
) -> QueryResult<'tcx>;
|
) -> QueryResult<'tcx>;
|
||||||
|
|
||||||
|
fn consider_builtin_destruct_candidate(
|
||||||
|
ecx: &mut EvalCtxt<'_, 'tcx>,
|
||||||
|
goal: Goal<'tcx, Self>,
|
||||||
|
) -> QueryResult<'tcx>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> EvalCtxt<'_, 'tcx> {
|
impl<'tcx> EvalCtxt<'_, 'tcx> {
|
||||||
@ -340,6 +345,8 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
|
|||||||
G::consider_builtin_unsize_candidate(self, goal)
|
G::consider_builtin_unsize_candidate(self, goal)
|
||||||
} else if lang_items.discriminant_kind_trait() == Some(trait_def_id) {
|
} else if lang_items.discriminant_kind_trait() == Some(trait_def_id) {
|
||||||
G::consider_builtin_discriminant_kind_candidate(self, goal)
|
G::consider_builtin_discriminant_kind_candidate(self, goal)
|
||||||
|
} else if lang_items.destruct_trait() == Some(trait_def_id) {
|
||||||
|
G::consider_builtin_destruct_candidate(self, goal)
|
||||||
} else {
|
} else {
|
||||||
Err(NoSolution)
|
Err(NoSolution)
|
||||||
};
|
};
|
||||||
|
@ -487,6 +487,13 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> {
|
|||||||
ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
|
ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn consider_builtin_destruct_candidate(
|
||||||
|
_ecx: &mut EvalCtxt<'_, 'tcx>,
|
||||||
|
goal: Goal<'tcx, Self>,
|
||||||
|
) -> QueryResult<'tcx> {
|
||||||
|
bug!("`Destruct` does not have an associated type: {:?}", goal);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This behavior is also implemented in `rustc_ty_utils` and in the old `project` code.
|
/// This behavior is also implemented in `rustc_ty_utils` and in the old `project` code.
|
||||||
|
@ -534,6 +534,20 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
|
|||||||
// `DiscriminantKind` is automatically implemented for every type.
|
// `DiscriminantKind` is automatically implemented for every type.
|
||||||
ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
|
ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn consider_builtin_destruct_candidate(
|
||||||
|
ecx: &mut EvalCtxt<'_, 'tcx>,
|
||||||
|
goal: Goal<'tcx, Self>,
|
||||||
|
) -> QueryResult<'tcx> {
|
||||||
|
if !goal.param_env.is_const() {
|
||||||
|
// `Destruct` is automatically implemented for every type in
|
||||||
|
// non-const environments.
|
||||||
|
ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
|
||||||
|
} else {
|
||||||
|
// FIXME(-Ztrait-solver=next): Implement this when we get const working in the new solver
|
||||||
|
Err(NoSolution)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> EvalCtxt<'_, 'tcx> {
|
impl<'tcx> EvalCtxt<'_, 'tcx> {
|
||||||
|
@ -13,7 +13,6 @@ pub mod set;
|
|||||||
mod set_val;
|
mod set_val;
|
||||||
mod split;
|
mod split;
|
||||||
|
|
||||||
#[doc(hidden)]
|
|
||||||
trait Recover<Q: ?Sized> {
|
trait Recover<Q: ?Sized> {
|
||||||
type Key;
|
type Key;
|
||||||
|
|
||||||
|
@ -1,6 +1,3 @@
|
|||||||
// This is pretty much entirely stolen from TreeSet, since BTreeMap has an identical interface
|
|
||||||
// to TreeMap
|
|
||||||
|
|
||||||
use crate::vec::Vec;
|
use crate::vec::Vec;
|
||||||
use core::borrow::Borrow;
|
use core::borrow::Borrow;
|
||||||
use core::cmp::Ordering::{self, Equal, Greater, Less};
|
use core::cmp::Ordering::{self, Equal, Greater, Less};
|
||||||
@ -18,8 +15,6 @@ use super::Recover;
|
|||||||
|
|
||||||
use crate::alloc::{Allocator, Global};
|
use crate::alloc::{Allocator, Global};
|
||||||
|
|
||||||
// FIXME(conventions): implement bounded iterators
|
|
||||||
|
|
||||||
/// An ordered set based on a B-Tree.
|
/// An ordered set based on a B-Tree.
|
||||||
///
|
///
|
||||||
/// See [`BTreeMap`]'s documentation for a detailed discussion of this collection's performance
|
/// See [`BTreeMap`]'s documentation for a detailed discussion of this collection's performance
|
||||||
|
@ -12,13 +12,6 @@ use crate::ops::{BitAnd, BitOr, BitXor, Sub};
|
|||||||
|
|
||||||
use super::map::{map_try_reserve_error, RandomState};
|
use super::map::{map_try_reserve_error, RandomState};
|
||||||
|
|
||||||
// Future Optimization (FIXME!)
|
|
||||||
// ============================
|
|
||||||
//
|
|
||||||
// Iteration over zero sized values is a noop. There is no need
|
|
||||||
// for `bucket.val` in the case of HashSet. I suppose we would need HKT
|
|
||||||
// to get rid of it properly.
|
|
||||||
|
|
||||||
/// A [hash set] implemented as a `HashMap` where the value is `()`.
|
/// A [hash set] implemented as a `HashMap` where the value is `()`.
|
||||||
///
|
///
|
||||||
/// As with the [`HashMap`] type, a `HashSet` requires that the elements
|
/// As with the [`HashMap`] type, a `HashSet` requires that the elements
|
||||||
|
22
tests/ui/closures/issue-109188.rs
Normal file
22
tests/ui/closures/issue-109188.rs
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
enum Either {
|
||||||
|
One(X),
|
||||||
|
Two(X),
|
||||||
|
}
|
||||||
|
|
||||||
|
struct X(Y);
|
||||||
|
|
||||||
|
struct Y;
|
||||||
|
|
||||||
|
fn consume_fnmut(f: &dyn FnMut()) {
|
||||||
|
f();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn move_into_fnmut() {
|
||||||
|
let x = move_into_fnmut();
|
||||||
|
consume_fnmut(&|| {
|
||||||
|
let Either::One(_t) = x; //~ ERROR mismatched types
|
||||||
|
let Either::Two(_t) = x; //~ ERROR mismatched types
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() { }
|
19
tests/ui/closures/issue-109188.stderr
Normal file
19
tests/ui/closures/issue-109188.stderr
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/issue-109188.rs:17:13
|
||||||
|
|
|
||||||
|
LL | let Either::One(_t) = x;
|
||||||
|
| ^^^^^^^^^^^^^^^ - this expression has type `()`
|
||||||
|
| |
|
||||||
|
| expected `()`, found `Either`
|
||||||
|
|
||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/issue-109188.rs:18:13
|
||||||
|
|
|
||||||
|
LL | let Either::Two(_t) = x;
|
||||||
|
| ^^^^^^^^^^^^^^^ - this expression has type `()`
|
||||||
|
| |
|
||||||
|
| expected `()`, found `Either`
|
||||||
|
|
||||||
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0308`.
|
@ -1,3 +1,4 @@
|
|||||||
|
// compile-flags: -Ztrait-solver=next
|
||||||
// check-pass
|
// check-pass
|
||||||
|
|
||||||
trait Mirror {
|
trait Mirror {
|
||||||
|
13
tests/ui/traits/new-solver/destruct.rs
Normal file
13
tests/ui/traits/new-solver/destruct.rs
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
// compile-flags: -Ztrait-solver=next
|
||||||
|
// check-pass
|
||||||
|
|
||||||
|
#![feature(const_trait_impl)]
|
||||||
|
|
||||||
|
fn foo(_: impl std::marker::Destruct) {}
|
||||||
|
|
||||||
|
struct MyAdt;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
foo(1);
|
||||||
|
foo(MyAdt);
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user