Auto merge of #118661 - fee1-dead-contrib:restore-const-partialEq, r=compiler-errors
Restore `const PartialEq` And thus fixes a number of tests. There is a bug that still needs to be fixed, so WIP for now. r? `@compiler-errors`
This commit is contained in:
commit
6f40082313
38 changed files with 154 additions and 199 deletions
|
@ -120,7 +120,6 @@ impl<'tcx> Printer<'tcx> for AbsolutePathPrinter<'tcx> {
|
|||
&mut self,
|
||||
print_prefix: impl FnOnce(&mut Self) -> Result<(), PrintError>,
|
||||
args: &[GenericArg<'tcx>],
|
||||
_params: &[ty::GenericParamDef],
|
||||
) -> Result<(), PrintError> {
|
||||
print_prefix(self)?;
|
||||
let args =
|
||||
|
|
|
@ -641,7 +641,6 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
|||
&mut self,
|
||||
print_prefix: impl FnOnce(&mut Self) -> Result<(), PrintError>,
|
||||
_args: &[GenericArg<'tcx>],
|
||||
_params: &[ty::GenericParamDef],
|
||||
) -> Result<(), PrintError> {
|
||||
print_prefix(self)
|
||||
}
|
||||
|
@ -1237,9 +1236,9 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
|||
(&ty::Adt(def1, sub1), &ty::Adt(def2, sub2)) => {
|
||||
let did1 = def1.did();
|
||||
let did2 = def2.did();
|
||||
let (sub_no_defaults_1, _) =
|
||||
let sub_no_defaults_1 =
|
||||
self.tcx.generics_of(did1).own_args_no_defaults(self.tcx, sub1);
|
||||
let (sub_no_defaults_2, _) =
|
||||
let sub_no_defaults_2 =
|
||||
self.tcx.generics_of(did2).own_args_no_defaults(self.tcx, sub2);
|
||||
let mut values = (DiagnosticStyledString::new(), DiagnosticStyledString::new());
|
||||
let path1 = self.tcx.def_path_str(did1);
|
||||
|
|
|
@ -757,7 +757,6 @@ impl<'a, 'tcx> FindInferSourceVisitor<'a, 'tcx> {
|
|||
.tcx
|
||||
.generics_of(def.did())
|
||||
.own_args_no_defaults(self.tcx, args)
|
||||
.0
|
||||
.iter()
|
||||
.map(|&arg| self.arg_cost(arg))
|
||||
.sum::<usize>()
|
||||
|
@ -1186,7 +1185,7 @@ impl<'a, 'tcx> Visitor<'tcx> for FindInferSourceVisitor<'a, 'tcx> {
|
|||
}
|
||||
let args = self.infcx.resolve_vars_if_possible(args);
|
||||
let generic_args =
|
||||
&generics.own_args_no_defaults(tcx, args).0[generics.own_counts().lifetimes..];
|
||||
&generics.own_args_no_defaults(tcx, args)[generics.own_counts().lifetimes..];
|
||||
let span = match expr.kind {
|
||||
ExprKind::MethodCall(path, ..) => path.ident.span,
|
||||
_ => expr.span,
|
||||
|
|
|
@ -116,7 +116,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
|||
// FIXME: extract this logic for use in other diagnostics.
|
||||
let (trait_ref, assoc_args) = proj.trait_ref_and_own_args(tcx);
|
||||
let item_name = tcx.item_name(proj.def_id);
|
||||
let item_args = self.format_generic_args(proj.def_id, assoc_args);
|
||||
let item_args = self.format_generic_args(assoc_args);
|
||||
|
||||
// Here, we try to see if there's an existing
|
||||
// trait implementation that matches the one that
|
||||
|
@ -775,7 +775,7 @@ fn foo(&self) -> Self::T { String::new() }
|
|||
let span = Span::new(pos, pos, span.ctxt(), span.parent());
|
||||
(span, format!(", {} = {}", assoc.ident(tcx), ty))
|
||||
} else {
|
||||
let item_args = self.format_generic_args(assoc.def_id, assoc_args);
|
||||
let item_args = self.format_generic_args(assoc_args);
|
||||
(span.shrink_to_hi(), format!("<{}{} = {}>", assoc.ident(tcx), item_args, ty))
|
||||
};
|
||||
diag.span_suggestion_verbose(span, msg(), sugg, MaybeIncorrect);
|
||||
|
@ -784,13 +784,9 @@ fn foo(&self) -> Self::T { String::new() }
|
|||
false
|
||||
}
|
||||
|
||||
pub fn format_generic_args(
|
||||
&self,
|
||||
assoc_def_id: DefId,
|
||||
args: &[ty::GenericArg<'tcx>],
|
||||
) -> String {
|
||||
pub fn format_generic_args(&self, args: &[ty::GenericArg<'tcx>]) -> String {
|
||||
FmtPrinter::print_string(self.tcx, hir::def::Namespace::TypeNS, |cx| {
|
||||
cx.path_generic_args(|_| Ok(()), args, &self.infcx.tcx.generics_of(assoc_def_id).params)
|
||||
cx.path_generic_args(|_| Ok(()), args)
|
||||
})
|
||||
.expect("could not write to `String`.")
|
||||
}
|
||||
|
|
|
@ -1285,7 +1285,6 @@ impl<'tcx> LateContext<'tcx> {
|
|||
&mut self,
|
||||
print_prefix: impl FnOnce(&mut Self) -> Result<(), PrintError>,
|
||||
_args: &[GenericArg<'tcx>],
|
||||
_params: &[ty::GenericParamDef],
|
||||
) -> Result<(), PrintError> {
|
||||
print_prefix(self)
|
||||
}
|
||||
|
|
|
@ -336,7 +336,8 @@ impl<'hir> Map<'hir> {
|
|||
/// Returns the `BodyOwnerKind` of this `LocalDefId`.
|
||||
///
|
||||
/// Panics if `LocalDefId` does not have an associated body.
|
||||
pub fn body_owner_kind(self, def_id: LocalDefId) -> BodyOwnerKind {
|
||||
pub fn body_owner_kind(self, def_id: impl Into<DefId>) -> BodyOwnerKind {
|
||||
let def_id = def_id.into();
|
||||
match self.tcx.def_kind(def_id) {
|
||||
DefKind::Const | DefKind::AssocConst | DefKind::AnonConst => {
|
||||
BodyOwnerKind::Const { inline: false }
|
||||
|
@ -356,20 +357,17 @@ impl<'hir> Map<'hir> {
|
|||
/// This should only be used for determining the context of a body, a return
|
||||
/// value of `Some` does not always suggest that the owner of the body is `const`,
|
||||
/// just that it has to be checked as if it were.
|
||||
pub fn body_const_context(self, def_id: LocalDefId) -> Option<ConstContext> {
|
||||
pub fn body_const_context(self, def_id: impl Into<DefId>) -> Option<ConstContext> {
|
||||
let def_id = def_id.into();
|
||||
let ccx = match self.body_owner_kind(def_id) {
|
||||
BodyOwnerKind::Const { inline } => ConstContext::Const { inline },
|
||||
BodyOwnerKind::Static(mt) => ConstContext::Static(mt),
|
||||
|
||||
BodyOwnerKind::Fn if self.tcx.is_constructor(def_id.to_def_id()) => return None,
|
||||
BodyOwnerKind::Fn | BodyOwnerKind::Closure
|
||||
if self.tcx.is_const_fn_raw(def_id.to_def_id()) =>
|
||||
{
|
||||
ConstContext::ConstFn
|
||||
}
|
||||
BodyOwnerKind::Fn if self.tcx.is_const_default_method(def_id.to_def_id()) => {
|
||||
BodyOwnerKind::Fn if self.tcx.is_constructor(def_id) => return None,
|
||||
BodyOwnerKind::Fn | BodyOwnerKind::Closure if self.tcx.is_const_fn_raw(def_id) => {
|
||||
ConstContext::ConstFn
|
||||
}
|
||||
BodyOwnerKind::Fn if self.tcx.is_const_default_method(def_id) => ConstContext::ConstFn,
|
||||
BodyOwnerKind::Fn | BodyOwnerKind::Closure => return None,
|
||||
};
|
||||
|
||||
|
|
|
@ -320,21 +320,21 @@ impl<'tcx> Generics {
|
|||
&'tcx self,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
args: &'tcx [ty::GenericArg<'tcx>],
|
||||
) -> (&'tcx [ty::GenericArg<'tcx>], &'tcx [ty::GenericParamDef]) {
|
||||
let mut own_args = self.parent_count..self.count();
|
||||
let mut own_params = 0..self.params.len();
|
||||
) -> &'tcx [ty::GenericArg<'tcx>] {
|
||||
let mut own_params = self.parent_count..self.count();
|
||||
if self.has_self && self.parent.is_none() {
|
||||
own_args.start = 1;
|
||||
own_params.start = 1;
|
||||
}
|
||||
|
||||
let verbose = tcx.sess.verbose();
|
||||
|
||||
// Filter the default arguments.
|
||||
//
|
||||
// This currently uses structural equality instead
|
||||
// of semantic equivalence. While not ideal, that's
|
||||
// good enough for now as this should only be used
|
||||
// for diagnostics anyways.
|
||||
let num_default_params = self
|
||||
own_params.end -= self
|
||||
.params
|
||||
.iter()
|
||||
.rev()
|
||||
|
@ -342,12 +342,12 @@ impl<'tcx> Generics {
|
|||
param.default_value(tcx).is_some_and(|default| {
|
||||
default.instantiate(tcx, args) == args[param.index as usize]
|
||||
})
|
||||
// filter out trailing effect params, if we're not in `-Zverbose`.
|
||||
|| (!verbose && matches!(param.kind, GenericParamDefKind::Const { is_host_effect: true, .. }))
|
||||
})
|
||||
.count();
|
||||
own_params.end -= num_default_params;
|
||||
own_args.end -= num_default_params;
|
||||
|
||||
(&args[own_args], &self.params[own_params])
|
||||
&args[own_params]
|
||||
}
|
||||
|
||||
/// Returns the args corresponding to the generic parameters of this item, excluding `Self`.
|
||||
|
|
|
@ -83,7 +83,6 @@ pub trait Printer<'tcx>: Sized {
|
|||
&mut self,
|
||||
print_prefix: impl FnOnce(&mut Self) -> Result<(), PrintError>,
|
||||
args: &[GenericArg<'tcx>],
|
||||
params: &[ty::GenericParamDef],
|
||||
) -> Result<(), PrintError>;
|
||||
|
||||
// Defaults (should not be overridden):
|
||||
|
@ -142,12 +141,10 @@ pub trait Printer<'tcx>: Sized {
|
|||
// on top of the same path, but without its own generics.
|
||||
_ => {
|
||||
if !generics.params.is_empty() && args.len() >= generics.count() {
|
||||
let (args, params) =
|
||||
generics.own_args_no_defaults(self.tcx(), args);
|
||||
let args = generics.own_args_no_defaults(self.tcx(), args);
|
||||
return self.path_generic_args(
|
||||
|cx| cx.print_def_path(def_id, parent_args),
|
||||
args,
|
||||
params,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -965,7 +965,7 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
|
|||
define_scoped_cx!(cx);
|
||||
// Get the (single) generic ty (the args) of this FnOnce trait ref.
|
||||
let generics = tcx.generics_of(trait_ref.def_id);
|
||||
let (own_args, _) = generics.own_args_no_defaults(tcx, trait_ref.args);
|
||||
let own_args = generics.own_args_no_defaults(tcx, trait_ref.args);
|
||||
|
||||
match (entry.return_ty, own_args[0].expect_ty()) {
|
||||
// We can only print `impl Fn() -> ()` if we have a tuple of args and we recorded
|
||||
|
@ -1031,7 +1031,7 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
|
|||
p!(print(trait_ref.print_only_trait_name()));
|
||||
|
||||
let generics = tcx.generics_of(trait_ref.def_id);
|
||||
let (own_args, _) = generics.own_args_no_defaults(tcx, trait_ref.args);
|
||||
let own_args = generics.own_args_no_defaults(tcx, trait_ref.args);
|
||||
|
||||
if !own_args.is_empty() || !assoc_items.is_empty() {
|
||||
let mut first = true;
|
||||
|
@ -1183,7 +1183,6 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
|
|||
)
|
||||
},
|
||||
&alias_ty.args[1..],
|
||||
&self.tcx().generics_of(alias_ty.def_id).params,
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -1232,7 +1231,7 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
|
|||
let dummy_cx = Ty::new_fresh(cx.tcx(), 0);
|
||||
let principal = principal.with_self_ty(cx.tcx(), dummy_cx);
|
||||
|
||||
let (args, _) = cx
|
||||
let args = cx
|
||||
.tcx()
|
||||
.generics_of(principal.def_id)
|
||||
.own_args_no_defaults(cx.tcx(), principal.args);
|
||||
|
@ -2030,26 +2029,14 @@ impl<'tcx> Printer<'tcx> for FmtPrinter<'_, 'tcx> {
|
|||
&mut self,
|
||||
print_prefix: impl FnOnce(&mut Self) -> Result<(), PrintError>,
|
||||
args: &[GenericArg<'tcx>],
|
||||
params: &[ty::GenericParamDef],
|
||||
) -> Result<(), PrintError> {
|
||||
print_prefix(self)?;
|
||||
|
||||
let tcx = self.tcx;
|
||||
let verbose = tcx.sess.verbose();
|
||||
let mut args = args
|
||||
.iter()
|
||||
.copied()
|
||||
.zip(params)
|
||||
// If -Zverbose is passed, we should print the host parameter instead
|
||||
// of eating it.
|
||||
.filter(|(_, param)| verbose || !param.is_host_effect())
|
||||
.peekable();
|
||||
|
||||
if args.peek().is_some() {
|
||||
if !args.is_empty() {
|
||||
if self.in_value {
|
||||
write!(self, "::")?;
|
||||
}
|
||||
self.generic_delimiters(|cx| cx.comma_sep(args.map(|(arg, _)| arg)))
|
||||
self.generic_delimiters(|cx| cx.comma_sep(args.iter().copied()))
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
|
@ -2881,7 +2868,8 @@ define_print_and_forward_display! {
|
|||
TraitPredPrintModifiersAndPath<'tcx> {
|
||||
if let Some(idx) = cx.tcx().generics_of(self.0.trait_ref.def_id).host_effect_index
|
||||
{
|
||||
if self.0.trait_ref.args.const_at(idx) != cx.tcx().consts.true_ {
|
||||
let arg = self.0.trait_ref.args.const_at(idx);
|
||||
if arg != cx.tcx().consts.true_ && !arg.has_infer() {
|
||||
p!("~const ");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -782,7 +782,8 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||
|| self.extern_crate(key.as_def_id()).is_some_and(|e| e.is_direct())
|
||||
}
|
||||
|
||||
pub fn expected_host_effect_param_for_body(self, def_id: LocalDefId) -> ty::Const<'tcx> {
|
||||
pub fn expected_host_effect_param_for_body(self, def_id: impl Into<DefId>) -> ty::Const<'tcx> {
|
||||
let def_id = def_id.into();
|
||||
// FIXME(effects): This is suspicious and should probably not be done,
|
||||
// especially now that we enforce host effects and then properly handle
|
||||
// effect vars during fallback.
|
||||
|
|
|
@ -342,7 +342,6 @@ impl<'tcx> Printer<'tcx> for SymbolPrinter<'tcx> {
|
|||
&mut self,
|
||||
print_prefix: impl FnOnce(&mut Self) -> Result<(), PrintError>,
|
||||
args: &[GenericArg<'tcx>],
|
||||
_params: &[ty::GenericParamDef],
|
||||
) -> Result<(), PrintError> {
|
||||
print_prefix(self)?;
|
||||
|
||||
|
|
|
@ -298,7 +298,6 @@ impl<'tcx> Printer<'tcx> for SymbolMangler<'tcx> {
|
|||
)
|
||||
},
|
||||
args,
|
||||
&self.tcx.generics_of(impl_def_id).params,
|
||||
)?;
|
||||
} else {
|
||||
self.push_disambiguator(key.disambiguated_data.disambiguator as u64);
|
||||
|
@ -801,7 +800,6 @@ impl<'tcx> Printer<'tcx> for SymbolMangler<'tcx> {
|
|||
&mut self,
|
||||
print_prefix: impl FnOnce(&mut Self) -> Result<(), PrintError>,
|
||||
args: &[GenericArg<'tcx>],
|
||||
_params: &[ty::GenericParamDef],
|
||||
) -> Result<(), PrintError> {
|
||||
// Don't print any regions if they're all erased.
|
||||
let print_regions = args.iter().any(|arg| match arg.unpack() {
|
||||
|
|
|
@ -3628,17 +3628,19 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
|||
is_derivable_trait &&
|
||||
// Ensure all fields impl the trait.
|
||||
adt.all_fields().all(|field| {
|
||||
let field_ty = field.ty(self.tcx, args);
|
||||
let field_ty = ty::GenericArg::from(field.ty(self.tcx, args));
|
||||
let trait_args = match diagnostic_name {
|
||||
sym::PartialEq | sym::PartialOrd => {
|
||||
Some(field_ty)
|
||||
}
|
||||
_ => None,
|
||||
};
|
||||
// Also add host param, if present
|
||||
let host = self.tcx.generics_of(trait_pred.def_id()).host_effect_index.map(|idx| trait_pred.skip_binder().trait_ref.args[idx]);
|
||||
let trait_pred = trait_pred.map_bound_ref(|tr| ty::TraitPredicate {
|
||||
trait_ref: ty::TraitRef::new(self.tcx,
|
||||
trait_pred.def_id(),
|
||||
[field_ty].into_iter().chain(trait_args),
|
||||
[field_ty].into_iter().chain(trait_args).chain(host),
|
||||
),
|
||||
..*tr
|
||||
});
|
||||
|
@ -3659,6 +3661,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
|||
trait_pred.skip_binder().self_ty(),
|
||||
diagnostic_name,
|
||||
),
|
||||
// FIXME(effects, const_trait_impl) derive_const as suggestion?
|
||||
format!("#[derive({diagnostic_name})]\n"),
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
|
|
|
@ -224,6 +224,7 @@ use self::Ordering::*;
|
|||
append_const_msg
|
||||
)]
|
||||
#[rustc_diagnostic_item = "PartialEq"]
|
||||
#[cfg_attr(not(bootstrap), const_trait)]
|
||||
pub trait PartialEq<Rhs: ?Sized = Self> {
|
||||
/// This method tests for `self` and `other` values to be equal, and is used
|
||||
/// by `==`.
|
||||
|
@ -1414,12 +1415,23 @@ mod impls {
|
|||
macro_rules! partial_eq_impl {
|
||||
($($t:ty)*) => ($(
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[cfg(bootstrap)]
|
||||
impl PartialEq for $t {
|
||||
#[inline]
|
||||
fn eq(&self, other: &$t) -> bool { (*self) == (*other) }
|
||||
#[inline]
|
||||
fn ne(&self, other: &$t) -> bool { (*self) != (*other) }
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[rustc_const_unstable(feature = "const_cmp", issue = "92391")]
|
||||
#[cfg(not(bootstrap))]
|
||||
impl const PartialEq for $t {
|
||||
#[inline]
|
||||
fn eq(&self, other: &$t) -> bool { (*self) == (*other) }
|
||||
#[inline]
|
||||
fn ne(&self, other: &$t) -> bool { (*self) != (*other) }
|
||||
}
|
||||
)*)
|
||||
}
|
||||
|
||||
|
|
|
@ -450,12 +450,12 @@ fn check_partial_eq_without_eq<'tcx>(cx: &LateContext<'tcx>, span: Span, trait_r
|
|||
&& let Some(def_id) = trait_ref.trait_def_id()
|
||||
&& cx.tcx.is_diagnostic_item(sym::PartialEq, def_id)
|
||||
&& let param_env = param_env_for_derived_eq(cx.tcx, adt.did(), eq_trait_def_id)
|
||||
&& !implements_trait_with_env(cx.tcx, param_env, ty, eq_trait_def_id, &[])
|
||||
&& !implements_trait_with_env(cx.tcx, param_env, ty, eq_trait_def_id, adt.did(),&[])
|
||||
// If all of our fields implement `Eq`, we can implement `Eq` too
|
||||
&& adt
|
||||
.all_fields()
|
||||
.map(|f| f.ty(cx.tcx, args))
|
||||
.all(|ty| implements_trait_with_env(cx.tcx, param_env, ty, eq_trait_def_id, &[]))
|
||||
.all(|ty| implements_trait_with_env(cx.tcx, param_env, ty, eq_trait_def_id, adt.did(), &[]))
|
||||
{
|
||||
span_lint_and_sugg(
|
||||
cx,
|
||||
|
|
|
@ -194,6 +194,10 @@ fn is_same_generics<'tcx>(
|
|||
.enumerate()
|
||||
.skip(1) // skip `Self` implicit arg
|
||||
.all(|(arg_index, arg)| {
|
||||
if [implied_by_generics.host_effect_index, implied_generics.host_effect_index].contains(&Some(arg_index)) {
|
||||
// skip host effect params in determining whether generics are same
|
||||
return true;
|
||||
}
|
||||
if let Some(ty) = arg.as_type() {
|
||||
if let &ty::Param(ty::ParamTy { index, .. }) = ty.kind()
|
||||
// `index == 0` means that it's referring to `Self`,
|
||||
|
|
|
@ -118,7 +118,7 @@ fn is_ref_iterable<'tcx>(
|
|||
.liberate_late_bound_regions(fn_id, cx.tcx.fn_sig(fn_id).skip_binder())
|
||||
&& let &[req_self_ty, req_res_ty] = &**sig.inputs_and_output
|
||||
&& let param_env = cx.tcx.param_env(fn_id)
|
||||
&& implements_trait_with_env(cx.tcx, param_env, req_self_ty, trait_id, &[])
|
||||
&& implements_trait_with_env(cx.tcx, param_env, req_self_ty, trait_id, fn_id, &[])
|
||||
&& let Some(into_iter_ty) =
|
||||
make_normalized_projection_with_regions(cx.tcx, param_env, trait_id, sym!(IntoIter), [req_self_ty])
|
||||
&& let req_res_ty = normalize_with_regions(cx.tcx, param_env, req_res_ty)
|
||||
|
|
|
@ -186,6 +186,7 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByValue {
|
|||
cx.param_env,
|
||||
ty,
|
||||
t,
|
||||
None,
|
||||
[Option::<ty::GenericArg<'tcx>>::None],
|
||||
)
|
||||
})
|
||||
|
|
|
@ -214,7 +214,8 @@ pub fn implements_trait<'tcx>(
|
|||
trait_id: DefId,
|
||||
args: &[GenericArg<'tcx>],
|
||||
) -> bool {
|
||||
implements_trait_with_env_from_iter(cx.tcx, cx.param_env, ty, trait_id, args.iter().map(|&x| Some(x)))
|
||||
let callee_id = cx.enclosing_body.map(|body| cx.tcx.hir().body_owner(body).owner.to_def_id());
|
||||
implements_trait_with_env_from_iter(cx.tcx, cx.param_env, ty, trait_id, callee_id, args.iter().map(|&x| Some(x)))
|
||||
}
|
||||
|
||||
/// Same as `implements_trait` but allows using a `ParamEnv` different from the lint context.
|
||||
|
@ -223,9 +224,10 @@ pub fn implements_trait_with_env<'tcx>(
|
|||
param_env: ParamEnv<'tcx>,
|
||||
ty: Ty<'tcx>,
|
||||
trait_id: DefId,
|
||||
callee_id: DefId,
|
||||
args: &[GenericArg<'tcx>],
|
||||
) -> bool {
|
||||
implements_trait_with_env_from_iter(tcx, param_env, ty, trait_id, args.iter().map(|&x| Some(x)))
|
||||
implements_trait_with_env_from_iter(tcx, param_env, ty, trait_id, Some(callee_id), args.iter().map(|&x| Some(x)))
|
||||
}
|
||||
|
||||
/// Same as `implements_trait_from_env` but takes the arguments as an iterator.
|
||||
|
@ -234,6 +236,7 @@ pub fn implements_trait_with_env_from_iter<'tcx>(
|
|||
param_env: ParamEnv<'tcx>,
|
||||
ty: Ty<'tcx>,
|
||||
trait_id: DefId,
|
||||
callee_id: Option<DefId>,
|
||||
args: impl IntoIterator<Item = impl Into<Option<GenericArg<'tcx>>>>,
|
||||
) -> bool {
|
||||
// Clippy shouldn't have infer types
|
||||
|
@ -245,20 +248,29 @@ pub fn implements_trait_with_env_from_iter<'tcx>(
|
|||
}
|
||||
|
||||
let infcx = tcx.infer_ctxt().build();
|
||||
let args = args.into_iter().map(|arg| {
|
||||
arg.into().unwrap_or_else(|| {
|
||||
let orig = TypeVariableOrigin {
|
||||
kind: TypeVariableOriginKind::MiscVariable,
|
||||
span: DUMMY_SP,
|
||||
};
|
||||
infcx.next_ty_var(orig).into()
|
||||
})
|
||||
}).collect::<Vec<_>>();
|
||||
|
||||
// If an effect arg was not specified, we need to specify it.
|
||||
let effect_arg = if tcx.generics_of(trait_id).host_effect_index.is_some_and(|x| args.get(x - 1).is_none()) {
|
||||
Some(GenericArg::from(callee_id.map(|def_id| tcx.expected_host_effect_param_for_body(def_id)).unwrap_or(tcx.consts.true_)))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
let trait_ref = TraitRef::new(
|
||||
tcx,
|
||||
trait_id,
|
||||
Some(GenericArg::from(ty))
|
||||
.into_iter()
|
||||
.chain(args.into_iter().map(|arg| {
|
||||
arg.into().unwrap_or_else(|| {
|
||||
let orig = TypeVariableOrigin {
|
||||
kind: TypeVariableOriginKind::MiscVariable,
|
||||
span: DUMMY_SP,
|
||||
};
|
||||
infcx.next_ty_var(orig).into()
|
||||
})
|
||||
})),
|
||||
.chain(args).chain(effect_arg),
|
||||
);
|
||||
|
||||
debug_assert_matches!(
|
||||
|
|
|
@ -4,12 +4,6 @@ error[E0635]: unknown feature `const_fn_trait_ref_impls`
|
|||
LL | #![feature(const_fn_trait_ref_impls)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error[E0635]: unknown feature `const_cmp`
|
||||
--> $DIR/fn_trait_refs.rs:8:12
|
||||
|
|
||||
LL | #![feature(const_cmp)]
|
||||
| ^^^^^^^^^
|
||||
|
||||
error: ~const can only be applied to `#[const_trait]` traits
|
||||
--> $DIR/fn_trait_refs.rs:15:15
|
||||
|
|
||||
|
@ -80,6 +74,6 @@ LL | T: ~const FnMut<()> + ~const Destruct,
|
|||
|
|
||||
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||
|
||||
error: aborting due to 12 previous errors
|
||||
error: aborting due to 11 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0635`.
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// known-bug: #110395
|
||||
// check-pass
|
||||
#![feature(const_trait_impl)]
|
||||
|
||||
#[const_trait]
|
||||
|
|
|
@ -1,8 +0,0 @@
|
|||
error: ~const can only be applied to `#[const_trait]` traits
|
||||
--> $DIR/call-generic-in-impl.rs:9:16
|
||||
|
|
||||
LL | impl<T: ~const PartialEq> const MyPartialEq for T {
|
||||
| ^^^^^^^^^
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
//! Basic test for calling methods on generic type parameters in `const fn`.
|
||||
|
||||
// known-bug: #110395
|
||||
// check-pass
|
||||
|
||||
#![feature(const_trait_impl)]
|
||||
#![feature(const_trait_impl, effects)]
|
||||
|
||||
struct S;
|
||||
|
||||
|
|
|
@ -1,14 +0,0 @@
|
|||
error: ~const can only be applied to `#[const_trait]` traits
|
||||
--> $DIR/call-generic-method-chain.rs:18:32
|
||||
|
|
||||
LL | const fn equals_self<T: ~const PartialEq>(t: &T) -> bool {
|
||||
| ^^^^^^^^^
|
||||
|
||||
error: ~const can only be applied to `#[const_trait]` traits
|
||||
--> $DIR/call-generic-method-chain.rs:22:40
|
||||
|
|
||||
LL | const fn equals_self_wrapper<T: ~const PartialEq>(t: &T) -> bool {
|
||||
| ^^^^^^^^^
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
// known-bug: #110395
|
||||
// check-pass
|
||||
|
||||
#![feature(const_trait_impl)]
|
||||
#![feature(const_trait_impl, effects)]
|
||||
|
||||
struct S;
|
||||
|
||||
|
|
|
@ -1,14 +0,0 @@
|
|||
error: ~const can only be applied to `#[const_trait]` traits
|
||||
--> $DIR/call-generic-method-dup-bound.rs:18:44
|
||||
|
|
||||
LL | const fn equals_self<T: PartialEq + ~const PartialEq>(t: &T) -> bool {
|
||||
| ^^^^^^^^^
|
||||
|
||||
error: ~const can only be applied to `#[const_trait]` traits
|
||||
--> $DIR/call-generic-method-dup-bound.rs:25:37
|
||||
|
|
||||
LL | const fn equals_self2<T: A + ~const PartialEq>(t: &T) -> bool {
|
||||
| ^^^^^^^^^
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
|
@ -1,10 +1,9 @@
|
|||
// FIXME(effects)
|
||||
// check-pass
|
||||
#![feature(const_trait_impl, effects)]
|
||||
|
||||
pub const fn equals_self<T: PartialEq>(t: &T) -> bool {
|
||||
*t == *t
|
||||
// (remove this) ~^ ERROR can't compare
|
||||
//~^ ERROR mismatched types
|
||||
// FIXME(effects): diagnostic
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
error[E0308]: mismatched types
|
||||
--> $DIR/call-generic-method-fail.rs:4:5
|
||||
|
|
||||
LL | *t == *t
|
||||
| ^^^^^^^^ expected `host`, found `true`
|
||||
|
|
||||
= note: expected constant `host`
|
||||
found constant `true`
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0308`.
|
|
@ -21,7 +21,6 @@ const fn equals_self<T: ~const Foo>(t: &T) -> bool {
|
|||
// it not using the impl.
|
||||
|
||||
pub const EQ: bool = equals_self(&S);
|
||||
//~^ ERROR
|
||||
// FIXME(effects) the diagnostics here isn't ideal, we shouldn't get `<false>`
|
||||
//~^ ERROR: the trait bound `S: ~const Foo` is not satisfied
|
||||
|
||||
fn main() {}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
//! Basic test for calling methods on generic type parameters in `const fn`.
|
||||
|
||||
// known-bug: #110395
|
||||
// check-pass
|
||||
|
||||
#![feature(const_trait_impl)]
|
||||
#![feature(const_trait_impl, effects)]
|
||||
|
||||
struct S;
|
||||
|
||||
|
|
|
@ -1,8 +0,0 @@
|
|||
error: ~const can only be applied to `#[const_trait]` traits
|
||||
--> $DIR/call-generic-method-pass.rs:18:32
|
||||
|
|
||||
LL | const fn equals_self<T: ~const PartialEq>(t: &T) -> bool {
|
||||
| ^^^^^^^^^
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
|
@ -3,6 +3,7 @@
|
|||
#![feature(
|
||||
associated_type_bounds,
|
||||
const_trait_impl,
|
||||
effects,
|
||||
const_cmp,
|
||||
)]
|
||||
|
||||
|
|
|
@ -1,39 +1,28 @@
|
|||
error[E0635]: unknown feature `const_cmp`
|
||||
--> $DIR/const-impl-trait.rs:6:5
|
||||
|
|
||||
LL | const_cmp,
|
||||
| ^^^^^^^^^
|
||||
|
||||
error: ~const can only be applied to `#[const_trait]` traits
|
||||
--> $DIR/const-impl-trait.rs:11:30
|
||||
|
|
||||
LL | const fn cmp(a: &impl ~const PartialEq) -> bool {
|
||||
| ^^^^^^^^^
|
||||
|
||||
error: ~const can only be applied to `#[const_trait]` traits
|
||||
--> $DIR/const-impl-trait.rs:15:30
|
||||
|
|
||||
LL | const fn wrap(x: impl ~const PartialEq + ~const Destruct)
|
||||
| ^^^^^^^^^
|
||||
|
||||
error: ~const can only be applied to `#[const_trait]` traits
|
||||
--> $DIR/const-impl-trait.rs:16:20
|
||||
|
|
||||
LL | -> impl ~const PartialEq + ~const Destruct
|
||||
| ^^^^^^^^^
|
||||
|
||||
error: ~const can only be applied to `#[const_trait]` traits
|
||||
--> $DIR/const-impl-trait.rs:23:29
|
||||
|
|
||||
LL | fn huh() -> impl ~const PartialEq + ~const Destruct + Copy;
|
||||
| ^^^^^^^^^
|
||||
|
||||
error: ~const can only be applied to `#[const_trait]` traits
|
||||
--> $DIR/const-impl-trait.rs:27:29
|
||||
error[E0277]: can't compare `impl PartialEq + Destruct + Copy` with `impl PartialEq + Destruct + Copy`
|
||||
--> $DIR/const-impl-trait.rs:28:17
|
||||
|
|
||||
LL | fn huh() -> impl ~const PartialEq + ~const Destruct + Copy {
|
||||
| ^^^^^^^^^
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no implementation for `impl PartialEq + Destruct + Copy == impl PartialEq + Destruct + Copy`
|
||||
|
|
||||
= help: the trait `~const PartialEq` is not implemented for `impl PartialEq + Destruct + Copy`
|
||||
note: required by a bound in `Foo::{opaque#0}`
|
||||
--> $DIR/const-impl-trait.rs:24:22
|
||||
|
|
||||
LL | fn huh() -> impl ~const PartialEq + ~const Destruct + Copy;
|
||||
| ^^^^^^^^^^^^^^^^ required by this bound in `Foo::{opaque#0}`
|
||||
|
||||
error: aborting due to 6 previous errors
|
||||
error[E0277]: can't drop `impl PartialEq + Destruct + Copy`
|
||||
--> $DIR/const-impl-trait.rs:28:17
|
||||
|
|
||||
LL | fn huh() -> impl ~const PartialEq + ~const Destruct + Copy {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `~const Destruct` is not implemented for `impl PartialEq + Destruct + Copy`
|
||||
|
|
||||
note: required by a bound in `Foo::{opaque#0}`
|
||||
--> $DIR/const-impl-trait.rs:24:41
|
||||
|
|
||||
LL | fn huh() -> impl ~const PartialEq + ~const Destruct + Copy;
|
||||
| ^^^^^^^^^^^^^^^ required by this bound in `Foo::{opaque#0}`
|
||||
|
||||
For more information about this error, try `rustc --explain E0635`.
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0277`.
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
// known-bug: #110395
|
||||
#![feature(const_trait_impl, const_cmp, const_default_impls, derive_const)]
|
||||
|
||||
#![feature(const_trait_impl, const_cmp, const_default_impls, derive_const, effects)]
|
||||
|
||||
pub struct A;
|
||||
|
||||
|
|
|
@ -1,15 +1,28 @@
|
|||
error[E0635]: unknown feature `const_cmp`
|
||||
--> $DIR/derive-const-use.rs:2:30
|
||||
|
|
||||
LL | #![feature(const_trait_impl, const_cmp, const_default_impls, derive_const)]
|
||||
| ^^^^^^^^^
|
||||
|
||||
error[E0635]: unknown feature `const_default_impls`
|
||||
--> $DIR/derive-const-use.rs:2:41
|
||||
--> $DIR/derive-const-use.rs:3:41
|
||||
|
|
||||
LL | #![feature(const_trait_impl, const_cmp, const_default_impls, derive_const)]
|
||||
LL | #![feature(const_trait_impl, const_cmp, const_default_impls, derive_const, effects)]
|
||||
| ^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
error: const `impl` for trait `Default` which is not marked with `#[const_trait]`
|
||||
--> $DIR/derive-const-use.rs:7:12
|
||||
|
|
||||
LL | impl const Default for A {
|
||||
| ^^^^^^^
|
||||
|
|
||||
= note: marking a trait with `#[const_trait]` ensures all default method bodies are `const`
|
||||
= note: adding a non-const method body in the future would be a breaking change
|
||||
|
||||
error: const `impl` for trait `Default` which is not marked with `#[const_trait]`
|
||||
--> $DIR/derive-const-use.rs:15:16
|
||||
|
|
||||
LL | #[derive_const(Default, PartialEq)]
|
||||
| ^^^^^^^
|
||||
|
|
||||
= note: marking a trait with `#[const_trait]` ensures all default method bodies are `const`
|
||||
= note: adding a non-const method body in the future would be a breaking change
|
||||
= note: this error originates in the derive macro `Default` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0635`.
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// known-bug: #110395
|
||||
// check-pass
|
||||
|
||||
#![feature(derive_const)]
|
||||
#![feature(const_trait_impl)]
|
||||
#![feature(const_trait_impl, effects)]
|
||||
|
||||
#[derive_const(PartialEq)]
|
||||
pub struct Reverse<T>(T);
|
||||
|
|
|
@ -1,10 +0,0 @@
|
|||
error: ~const can only be applied to `#[const_trait]` traits
|
||||
--> $DIR/derive-const-with-params.rs:6:16
|
||||
|
|
||||
LL | #[derive_const(PartialEq)]
|
||||
| ^^^^^^^^^
|
||||
|
|
||||
= note: this error originates in the derive macro `PartialEq` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
|
@ -16,10 +16,6 @@ help: consider annotating `S<T>` with `#[derive(PartialEq)]`
|
|||
LL + #[derive(PartialEq)]
|
||||
LL | struct S<T>(T);
|
||||
|
|
||||
help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement
|
||||
|
|
||||
LL | pub fn foo<T>(s: S<T>, t: S<T>) where S<T>: PartialEq {
|
||||
| +++++++++++++++++++++
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue