From a16d491054a339c2ad9ee56d8295311eb31b1d42 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sun, 20 Oct 2024 20:22:11 +0000 Subject: [PATCH 1/5] Remove associated type based effects logic --- compiler/rustc_ast_lowering/src/item.rs | 205 ++---------------- compiler/rustc_ast_lowering/src/lib.rs | 20 +- compiler/rustc_feature/src/builtin_attrs.rs | 4 - compiler/rustc_hir/src/hir.rs | 1 - compiler/rustc_hir/src/intravisit.rs | 2 +- compiler/rustc_hir/src/lang_items.rs | 8 - compiler/rustc_hir_analysis/src/bounds.rs | 139 ------------ .../rustc_hir_analysis/src/check/intrinsic.rs | 8 +- .../rustc_hir_analysis/src/check/wfcheck.rs | 7 +- .../src/collect/generics_of.rs | 33 +-- .../src/collect/predicates_of.rs | 21 -- compiler/rustc_hir_analysis/src/delegation.rs | 5 - .../src/hir_ty_lowering/mod.rs | 10 +- compiler/rustc_hir_pretty/src/lib.rs | 2 +- compiler/rustc_hir_typeck/src/callee.rs | 35 +-- compiler/rustc_hir_typeck/src/fallback.rs | 29 +-- .../rustc_hir_typeck/src/fn_ctxt/_impl.rs | 26 +-- compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs | 6 - compiler/rustc_hir_typeck/src/method/mod.rs | 11 - .../src/infer/canonical/canonicalizer.rs | 14 +- .../rustc_infer/src/infer/canonical/mod.rs | 10 - compiler/rustc_infer/src/infer/context.rs | 21 -- compiler/rustc_infer/src/infer/freshen.rs | 9 - compiler/rustc_infer/src/infer/mod.rs | 74 +------ .../src/infer/relate/generalize.rs | 1 - compiler/rustc_infer/src/infer/resolve.rs | 3 - .../rustc_infer/src/infer/snapshot/fudge.rs | 27 +-- .../rustc_infer/src/infer/snapshot/mod.rs | 2 - .../src/infer/snapshot/undo_log.rs | 5 +- compiler/rustc_lint/src/nonstandard_style.rs | 6 +- .../src/rmeta/decoder/cstore_impl.rs | 1 - compiler/rustc_metadata/src/rmeta/encoder.rs | 3 - compiler/rustc_metadata/src/rmeta/mod.rs | 1 - compiler/rustc_middle/src/infer/unify_key.rs | 67 ------ compiler/rustc_middle/src/query/mod.rs | 6 - compiler/rustc_middle/src/ty/context.rs | 7 - compiler/rustc_middle/src/ty/diagnostics.rs | 3 - compiler/rustc_middle/src/ty/flags.rs | 4 +- compiler/rustc_middle/src/ty/generic_args.rs | 9 +- compiler/rustc_middle/src/ty/generics.rs | 19 +- compiler/rustc_middle/src/ty/instance.rs | 1 - compiler/rustc_middle/src/ty/util.rs | 46 +--- compiler/rustc_monomorphize/src/collector.rs | 1 - .../src/canonicalizer.rs | 1 - .../rustc_next_trait_solver/src/resolve.rs | 3 - .../src/solve/assembly/mod.rs | 8 - .../rustc_next_trait_solver/src/solve/mod.rs | 6 - .../src/solve/normalizes_to/mod.rs | 62 ------ .../src/solve/trait_goals.rs | 41 ---- .../rustc_smir/src/rustc_smir/convert/ty.rs | 3 +- compiler/rustc_span/src/symbol.rs | 9 - .../traits/fulfillment_errors.rs | 44 +--- .../src/traits/fulfill.rs | 1 - .../src/traits/select/candidate_assembly.rs | 2 +- .../src/traits/select/mod.rs | 3 +- compiler/rustc_ty_utils/src/assoc.rs | 139 +----------- compiler/rustc_type_ir/src/canonical.rs | 22 +- compiler/rustc_type_ir/src/const_kind.rs | 23 +- compiler/rustc_type_ir/src/effects.rs | 59 ----- compiler/rustc_type_ir/src/elaborate.rs | 65 ------ compiler/rustc_type_ir/src/infer_ctxt.rs | 10 - compiler/rustc_type_ir/src/lang_items.rs | 7 - compiler/rustc_type_ir/src/lib.rs | 2 - compiler/rustc_type_ir/src/relate/combine.rs | 28 +-- compiler/stable_mir/src/ty.rs | 1 - library/core/src/marker.rs | 44 ---- src/librustdoc/clean/auto_trait.rs | 2 +- src/librustdoc/clean/mod.rs | 6 +- src/librustdoc/clean/types.rs | 3 +- src/librustdoc/clean/utils.rs | 4 - .../clippy_utils/src/ty/type_certainty/mod.rs | 14 +- .../const-traits/const-fns-are-early-bound.rs | 48 ---- .../traits/const-traits/effects/minicore.rs | 32 --- 73 files changed, 85 insertions(+), 1519 deletions(-) delete mode 100644 compiler/rustc_type_ir/src/effects.rs diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index c43106c6e5f63..97fa90d340ea2 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -57,7 +57,7 @@ impl<'a, 'hir> ItemLowerer<'a, 'hir> { owner: NodeId, f: impl FnOnce(&mut LoweringContext<'_, 'hir>) -> hir::OwnerNode<'hir>, ) { - let mut lctx = LoweringContext::new(self.tcx, self.resolver, self.ast_index); + let mut lctx = LoweringContext::new(self.tcx, self.resolver); lctx.with_hir_id_owner(owner, |lctx| f(lctx)); for (def_id, info) in lctx.children { @@ -193,8 +193,6 @@ impl<'hir> LoweringContext<'_, 'hir> { ItemKind::Const(box ast::ConstItem { generics, ty, expr, .. }) => { let (generics, (ty, body_id)) = self.lower_generics( generics, - Const::No, - false, id, ImplTraitContext::Disallowed(ImplTraitPosition::Generic), |this| { @@ -225,16 +223,9 @@ impl<'hir> LoweringContext<'_, 'hir> { ); let itctx = ImplTraitContext::Universal; - let (generics, decl) = - this.lower_generics(generics, header.constness, false, id, itctx, |this| { - this.lower_fn_decl( - decl, - id, - *fn_sig_span, - FnDeclKind::Fn, - coroutine_kind, - ) - }); + let (generics, decl) = this.lower_generics(generics, id, itctx, |this| { + this.lower_fn_decl(decl, id, *fn_sig_span, FnDeclKind::Fn, coroutine_kind) + }); let sig = hir::FnSig { decl, header: this.lower_fn_header(*header, hir::Safety::Safe), @@ -269,8 +260,6 @@ impl<'hir> LoweringContext<'_, 'hir> { add_ty_alias_where_clause(&mut generics, *where_clauses, true); let (generics, ty) = self.lower_generics( &generics, - Const::No, - false, id, ImplTraitContext::Disallowed(ImplTraitPosition::Generic), |this| match ty { @@ -294,8 +283,6 @@ impl<'hir> LoweringContext<'_, 'hir> { ItemKind::Enum(enum_definition, generics) => { let (generics, variants) = self.lower_generics( generics, - Const::No, - false, id, ImplTraitContext::Disallowed(ImplTraitPosition::Generic), |this| { @@ -309,8 +296,6 @@ impl<'hir> LoweringContext<'_, 'hir> { ItemKind::Struct(struct_def, generics) => { let (generics, struct_def) = self.lower_generics( generics, - Const::No, - false, id, ImplTraitContext::Disallowed(ImplTraitPosition::Generic), |this| this.lower_variant_data(hir_id, struct_def), @@ -320,8 +305,6 @@ impl<'hir> LoweringContext<'_, 'hir> { ItemKind::Union(vdata, generics) => { let (generics, vdata) = self.lower_generics( generics, - Const::No, - false, id, ImplTraitContext::Disallowed(ImplTraitPosition::Generic), |this| this.lower_variant_data(hir_id, vdata), @@ -353,7 +336,7 @@ impl<'hir> LoweringContext<'_, 'hir> { // parent lifetime. let itctx = ImplTraitContext::Universal; let (generics, (trait_ref, lowered_ty)) = - self.lower_generics(ast_generics, Const::No, false, id, itctx, |this| { + self.lower_generics(ast_generics, id, itctx, |this| { let modifiers = TraitBoundModifiers { constness: BoundConstness::Never, asyncness: BoundAsyncness::Normal, @@ -405,8 +388,6 @@ impl<'hir> LoweringContext<'_, 'hir> { ItemKind::Trait(box Trait { is_auto, safety, generics, bounds, items }) => { let (generics, (safety, items, bounds)) = self.lower_generics( generics, - Const::No, - false, id, ImplTraitContext::Disallowed(ImplTraitPosition::Generic), |this| { @@ -426,8 +407,6 @@ impl<'hir> LoweringContext<'_, 'hir> { ItemKind::TraitAlias(generics, bounds) => { let (generics, bounds) = self.lower_generics( generics, - Const::No, - false, id, ImplTraitContext::Disallowed(ImplTraitPosition::Generic), |this| { @@ -604,50 +583,23 @@ impl<'hir> LoweringContext<'_, 'hir> { ctxt: AssocCtxt, parent_hir: &'hir hir::OwnerInfo<'hir>, ) -> hir::OwnerNode<'hir> { - // Evaluate with the lifetimes in `params` in-scope. - // This is used to track which lifetimes have already been defined, - // and which need to be replicated when lowering an async fn. - let parent_item = parent_hir.node().expect_item(); - let constness = match parent_item.kind { + match parent_item.kind { hir::ItemKind::Impl(impl_) => { self.is_in_trait_impl = impl_.of_trait.is_some(); - // N.B. the impl should always lower to methods that have `const host: bool` params if the trait - // is const. It doesn't matter whether the `impl` itself is const. Disallowing const fn from - // calling non-const impls are done through associated types. - if let Some(def_id) = impl_.of_trait.and_then(|tr| tr.trait_def_id()) { - if let Some(local_def) = def_id.as_local() { - match &self.ast_index[local_def] { - AstOwner::Item(ast::Item { attrs, .. }) => attrs - .iter() - .find(|attr| attr.has_name(sym::const_trait)) - .map_or(Const::No, |attr| Const::Yes(attr.span)), - _ => Const::No, - } - } else if self.tcx.is_const_trait(def_id) { - // FIXME(effects) span - Const::Yes(self.tcx.def_ident_span(def_id).unwrap()) - } else { - Const::No - } - } else { - Const::No - } } - hir::ItemKind::Trait(_, _, _, _, _) => parent_hir - .attrs - .get(parent_item.hir_id().local_id) - .iter() - .find(|attr| attr.has_name(sym::const_trait)) - .map_or(Const::No, |attr| Const::Yes(attr.span)), + hir::ItemKind::Trait(_, _, _, _, _) => {} kind => { span_bug!(item.span, "assoc item has unexpected kind of parent: {}", kind.descr()) } - }; + } + // Evaluate with the lifetimes in `params` in-scope. + // This is used to track which lifetimes have already been defined, + // and which need to be replicated when lowering an async fn. match ctxt { - AssocCtxt::Trait => hir::OwnerNode::TraitItem(self.lower_trait_item(item, constness)), - AssocCtxt::Impl => hir::OwnerNode::ImplItem(self.lower_impl_item(item, constness)), + AssocCtxt::Trait => hir::OwnerNode::TraitItem(self.lower_trait_item(item)), + AssocCtxt::Impl => hir::OwnerNode::ImplItem(self.lower_impl_item(item)), } } @@ -663,7 +615,7 @@ impl<'hir> LoweringContext<'_, 'hir> { let fdec = &sig.decl; let itctx = ImplTraitContext::Universal; let (generics, (decl, fn_args)) = - self.lower_generics(generics, Const::No, false, i.id, itctx, |this| { + self.lower_generics(generics, i.id, itctx, |this| { ( // Disallow `impl Trait` in foreign items. this.lower_fn_decl( @@ -775,11 +727,7 @@ impl<'hir> LoweringContext<'_, 'hir> { } } - fn lower_trait_item( - &mut self, - i: &AssocItem, - trait_constness: Const, - ) -> &'hir hir::TraitItem<'hir> { + fn lower_trait_item(&mut self, i: &AssocItem) -> &'hir hir::TraitItem<'hir> { let hir_id = self.lower_node_id(i.id); self.lower_attrs(hir_id, &i.attrs); let trait_item_def_id = hir_id.expect_owner(); @@ -788,8 +736,6 @@ impl<'hir> LoweringContext<'_, 'hir> { AssocItemKind::Const(box ConstItem { generics, ty, expr, .. }) => { let (generics, kind) = self.lower_generics( generics, - Const::No, - false, i.id, ImplTraitContext::Disallowed(ImplTraitPosition::Generic), |this| { @@ -810,7 +756,6 @@ impl<'hir> LoweringContext<'_, 'hir> { i.id, FnDeclKind::Trait, sig.header.coroutine_kind, - trait_constness, ); (generics, hir::TraitItemKind::Fn(sig, hir::TraitFn::Required(names)), false) } @@ -829,7 +774,6 @@ impl<'hir> LoweringContext<'_, 'hir> { i.id, FnDeclKind::Trait, sig.header.coroutine_kind, - trait_constness, ); (generics, hir::TraitItemKind::Fn(sig, hir::TraitFn::Provided(body_id)), true) } @@ -838,8 +782,6 @@ impl<'hir> LoweringContext<'_, 'hir> { add_ty_alias_where_clause(&mut generics, *where_clauses, false); let (generics, kind) = self.lower_generics( &generics, - Const::No, - false, i.id, ImplTraitContext::Disallowed(ImplTraitPosition::Generic), |this| { @@ -912,11 +854,7 @@ impl<'hir> LoweringContext<'_, 'hir> { self.expr(span, hir::ExprKind::Err(guar)) } - fn lower_impl_item( - &mut self, - i: &AssocItem, - constness_of_trait: Const, - ) -> &'hir hir::ImplItem<'hir> { + fn lower_impl_item(&mut self, i: &AssocItem) -> &'hir hir::ImplItem<'hir> { // Since `default impl` is not yet implemented, this is always true in impls. let has_value = true; let (defaultness, _) = self.lower_defaultness(i.kind.defaultness(), has_value); @@ -926,8 +864,6 @@ impl<'hir> LoweringContext<'_, 'hir> { let (generics, kind) = match &i.kind { AssocItemKind::Const(box ConstItem { generics, ty, expr, .. }) => self.lower_generics( generics, - Const::No, - false, i.id, ImplTraitContext::Disallowed(ImplTraitPosition::Generic), |this| { @@ -953,7 +889,6 @@ impl<'hir> LoweringContext<'_, 'hir> { i.id, if self.is_in_trait_impl { FnDeclKind::Impl } else { FnDeclKind::Inherent }, sig.header.coroutine_kind, - constness_of_trait, ); (generics, hir::ImplItemKind::Fn(sig, body_id)) @@ -963,8 +898,6 @@ impl<'hir> LoweringContext<'_, 'hir> { add_ty_alias_where_clause(&mut generics, *where_clauses, false); self.lower_generics( &generics, - Const::No, - false, i.id, ImplTraitContext::Disallowed(ImplTraitPosition::Generic), |this| match ty { @@ -1370,18 +1303,12 @@ impl<'hir> LoweringContext<'_, 'hir> { id: NodeId, kind: FnDeclKind, coroutine_kind: Option, - parent_constness: Const, ) -> (&'hir hir::Generics<'hir>, hir::FnSig<'hir>) { let header = self.lower_fn_header(sig.header, hir::Safety::Safe); - // Don't pass along the user-provided constness of trait associated functions; we don't want to - // synthesize a host effect param for them. We reject `const` on them during AST validation. - let constness = - if kind == FnDeclKind::Inherent { sig.header.constness } else { parent_constness }; let itctx = ImplTraitContext::Universal; - let (generics, decl) = - self.lower_generics(generics, constness, kind == FnDeclKind::Impl, id, itctx, |this| { - this.lower_fn_decl(&sig.decl, id, sig.span, kind, coroutine_kind) - }); + let (generics, decl) = self.lower_generics(generics, id, itctx, |this| { + this.lower_fn_decl(&sig.decl, id, sig.span, kind, coroutine_kind) + }); (generics, hir::FnSig { header, decl, span: self.lower_span(sig.span) }) } @@ -1460,8 +1387,6 @@ impl<'hir> LoweringContext<'_, 'hir> { fn lower_generics( &mut self, generics: &Generics, - constness: Const, - force_append_constness: bool, parent_node_id: NodeId, itctx: ImplTraitContext, f: impl FnOnce(&mut Self) -> T, @@ -1524,30 +1449,6 @@ impl<'hir> LoweringContext<'_, 'hir> { } } - // Desugar `~const` bound in generics into an additional `const host: bool` param - // if the effects feature is enabled. This needs to be done before we lower where - // clauses since where clauses need to bind to the DefId of the host param - let host_param_parts = if let Const::Yes(span) = constness - // if this comes from implementing a `const` trait, we must force constness to be appended - // to the impl item, no matter whether effects is enabled. - && (self.tcx.features().effects() || force_append_constness) - { - let span = self.lower_span(span); - let param_node_id = self.next_node_id(); - let hir_id = self.next_id(); - let def_id = self.create_def( - self.local_def_id(parent_node_id), - param_node_id, - sym::host, - DefKind::ConstParam, - span, - ); - self.host_param_id = Some(def_id); - Some((span, hir_id, def_id)) - } else { - None - }; - let mut predicates: SmallVec<[hir::WherePredicate<'hir>; 4]> = SmallVec::new(); predicates.extend(generics.params.iter().filter_map(|param| { self.lower_generic_bound_predicate( @@ -1595,74 +1496,6 @@ impl<'hir> LoweringContext<'_, 'hir> { let impl_trait_bounds = std::mem::take(&mut self.impl_trait_bounds); predicates.extend(impl_trait_bounds.into_iter()); - if let Some((span, hir_id, def_id)) = host_param_parts { - let const_node_id = self.next_node_id(); - let anon_const_did = - self.create_def(def_id, const_node_id, kw::Empty, DefKind::AnonConst, span); - - let const_id = self.next_id(); - let const_expr_id = self.next_id(); - let bool_id = self.next_id(); - - self.children.push((def_id, hir::MaybeOwner::NonOwner(hir_id))); - self.children.push((anon_const_did, hir::MaybeOwner::NonOwner(const_id))); - - let const_body = self.lower_body(|this| { - (&[], hir::Expr { - hir_id: const_expr_id, - kind: hir::ExprKind::Lit( - this.arena.alloc(hir::Lit { node: LitKind::Bool(true), span }), - ), - span, - }) - }); - - let default_ac = self.arena.alloc(hir::AnonConst { - def_id: anon_const_did, - hir_id: const_id, - body: const_body, - span, - }); - let default_ct = self.arena.alloc(hir::ConstArg { - hir_id: self.next_id(), - kind: hir::ConstArgKind::Anon(default_ac), - is_desugared_from_effects: false, - }); - let param = hir::GenericParam { - def_id, - hir_id, - name: hir::ParamName::Plain(Ident { name: sym::host, span }), - span, - kind: hir::GenericParamKind::Const { - ty: self.arena.alloc(self.ty( - span, - hir::TyKind::Path(hir::QPath::Resolved( - None, - self.arena.alloc(hir::Path { - res: Res::PrimTy(hir::PrimTy::Bool), - span, - segments: self.arena.alloc_from_iter([hir::PathSegment { - ident: Ident { name: sym::bool, span }, - hir_id: bool_id, - res: Res::PrimTy(hir::PrimTy::Bool), - args: None, - infer_args: false, - }]), - }), - )), - )), - default: Some(default_ct), - is_host_effect: true, - synthetic: true, - }, - colon_span: None, - pure_wrt_drop: false, - source: hir::GenericParamSource::Generics, - }; - - params.push(param); - } - let lowered_generics = self.arena.alloc(hir::Generics { params: self.arena.alloc_from_iter(params), predicates: self.arena.alloc_from_iter(predicates), diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 7cd0cd1ebcdc4..34b8137aea8ef 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -154,17 +154,10 @@ struct LoweringContext<'a, 'hir> { /// defined on the TAIT, so we have type Foo<'a1> = ... and we establish a mapping in this /// field from the original parameter 'a to the new parameter 'a1. generics_def_id_map: Vec>, - - host_param_id: Option, - ast_index: &'a IndexSlice>, } impl<'a, 'hir> LoweringContext<'a, 'hir> { - fn new( - tcx: TyCtxt<'hir>, - resolver: &'a mut ResolverAstLowering, - ast_index: &'a IndexSlice>, - ) -> Self { + fn new(tcx: TyCtxt<'hir>, resolver: &'a mut ResolverAstLowering) -> Self { Self { // Pseudo-globals. tcx, @@ -204,8 +197,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { // interact with `gen`/`async gen` blocks allow_async_iterator: [sym::gen_future, sym::async_iterator].into(), generics_def_id_map: Default::default(), - host_param_id: None, - ast_index, } } @@ -2054,11 +2045,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { param: &GenericParam, source: hir::GenericParamSource, ) -> hir::GenericParam<'hir> { - let (name, kind) = self.lower_generic_param_kind( - param, - source, - attr::contains_name(¶m.attrs, sym::rustc_runtime), - ); + let (name, kind) = self.lower_generic_param_kind(param, source); let hir_id = self.lower_node_id(param.id); self.lower_attrs(hir_id, ¶m.attrs); @@ -2078,7 +2065,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { &mut self, param: &GenericParam, source: hir::GenericParamSource, - is_host_effect: bool, ) -> (hir::ParamName, hir::GenericParamKind<'hir>) { match ¶m.kind { GenericParamKind::Lifetime => { @@ -2144,7 +2130,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { ( hir::ParamName::Plain(self.lower_ident(param.ident)), - hir::GenericParamKind::Const { ty, default, is_host_effect, synthetic: false }, + hir::GenericParamKind::Const { ty, default, synthetic: false }, ) } } diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs index 753195bf691c0..5921fbc0fd716 100644 --- a/compiler/rustc_feature/src/builtin_attrs.rs +++ b/compiler/rustc_feature/src/builtin_attrs.rs @@ -838,10 +838,6 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ rustc_const_panic_str, Normal, template!(Word), WarnFollowing, EncodeCrossCrate::Yes, INTERNAL_UNSTABLE ), - rustc_attr!( - rustc_runtime, Normal, template!(Word), WarnFollowing, - EncodeCrossCrate::No, INTERNAL_UNSTABLE - ), // ========================================================================== // Internal attributes, Layout related: diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 45be04c6db9ce..1c268c8bbe06b 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -580,7 +580,6 @@ pub enum GenericParamKind<'hir> { ty: &'hir Ty<'hir>, /// Optional default value for the const generic param default: Option<&'hir ConstArg<'hir>>, - is_host_effect: bool, synthetic: bool, }, } diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs index ffe519b0e7dd0..322f8e2a517c8 100644 --- a/compiler/rustc_hir/src/intravisit.rs +++ b/compiler/rustc_hir/src/intravisit.rs @@ -935,7 +935,7 @@ pub fn walk_generic_param<'v, V: Visitor<'v>>( match param.kind { GenericParamKind::Lifetime { .. } => {} GenericParamKind::Type { ref default, .. } => visit_opt!(visitor, visit_ty, default), - GenericParamKind::Const { ref ty, ref default, is_host_effect: _, synthetic: _ } => { + GenericParamKind::Const { ref ty, ref default, synthetic: _ } => { try_visit!(visitor.visit_ty(ty)); if let Some(ref default) = default { try_visit!(visitor.visit_const_param_default(param.hir_id, default)); diff --git a/compiler/rustc_hir/src/lang_items.rs b/compiler/rustc_hir/src/lang_items.rs index ae046c09ebea3..7d81f977c22ef 100644 --- a/compiler/rustc_hir/src/lang_items.rs +++ b/compiler/rustc_hir/src/lang_items.rs @@ -415,14 +415,6 @@ language_item_table! { String, sym::String, string, Target::Struct, GenericRequirement::None; CStr, sym::CStr, c_str, Target::Struct, GenericRequirement::None; - - EffectsRuntime, sym::EffectsRuntime, effects_runtime, Target::Struct, GenericRequirement::None; - EffectsNoRuntime, sym::EffectsNoRuntime, effects_no_runtime, Target::Struct, GenericRequirement::None; - EffectsMaybe, sym::EffectsMaybe, effects_maybe, Target::Struct, GenericRequirement::None; - EffectsIntersection, sym::EffectsIntersection, effects_intersection, Target::Trait, GenericRequirement::None; - EffectsIntersectionOutput, sym::EffectsIntersectionOutput, effects_intersection_output, Target::AssocTy, GenericRequirement::None; - EffectsCompat, sym::EffectsCompat, effects_compat, Target::Trait, GenericRequirement::Exact(1); - EffectsTyCompat, sym::EffectsTyCompat, effects_ty_compat, Target::Trait, GenericRequirement::Exact(1); } pub enum GenericRequirement { diff --git a/compiler/rustc_hir_analysis/src/bounds.rs b/compiler/rustc_hir_analysis/src/bounds.rs index 77df0cb7ef902..d0c45a7c04c73 100644 --- a/compiler/rustc_hir_analysis/src/bounds.rs +++ b/compiler/rustc_hir_analysis/src/bounds.rs @@ -3,13 +3,8 @@ use rustc_data_structures::fx::FxIndexMap; use rustc_hir::LangItem; -use rustc_hir::def::DefKind; -use rustc_middle::ty::fold::FnMutDelegate; use rustc_middle::ty::{self, Ty, TyCtxt, Upcast}; use rustc_span::Span; -use rustc_span::def_id::DefId; - -use crate::hir_ty_lowering::PredicateFilter; /// Collects together a list of type bounds. These lists of bounds occur in many places /// in Rust's syntax: @@ -47,12 +42,9 @@ impl<'tcx> Bounds<'tcx> { pub(crate) fn push_trait_bound( &mut self, tcx: TyCtxt<'tcx>, - defining_def_id: DefId, bound_trait_ref: ty::PolyTraitRef<'tcx>, span: Span, polarity: ty::PredicatePolarity, - constness: Option, - predicate_filter: PredicateFilter, ) { let clause = ( bound_trait_ref @@ -68,137 +60,6 @@ impl<'tcx> Bounds<'tcx> { } else { self.clauses.push(clause); } - - // FIXME(effects): Lift this out of `push_trait_bound`, and move it somewhere else. - // Perhaps moving this into `lower_poly_trait_ref`, just like we lower associated - // type bounds. - if !tcx.features().effects() { - return; - } - match predicate_filter { - PredicateFilter::SelfOnly | PredicateFilter::SelfThatDefines(_) => { - return; - } - PredicateFilter::All | PredicateFilter::SelfAndAssociatedTypeBounds => { - // Ok. - } - } - - // For `T: ~const Tr` or `T: const Tr`, we need to add an additional bound on the - // associated type of `` and make sure that the effect is compatible. - let compat_val = match (tcx.def_kind(defining_def_id), constness) { - // FIXME(effects): revisit the correctness of this - (_, Some(ty::BoundConstness::Const)) => tcx.consts.false_, - // body owners that can have trait bounds - ( - DefKind::Const | DefKind::Fn | DefKind::AssocFn, - Some(ty::BoundConstness::ConstIfConst), - ) => tcx.expected_host_effect_param_for_body(defining_def_id), - - (_, None) => { - if !tcx.is_const_trait(bound_trait_ref.def_id()) { - return; - } - tcx.consts.true_ - } - (DefKind::Trait, Some(ty::BoundConstness::ConstIfConst)) => { - // we are in a trait, where `bound_trait_ref` could be: - // (1) a super trait `trait Foo: ~const Bar`. - // - This generates `::Effects: TyCompat<::Effects>` - // - // (2) a where clause `where for<..> Something: ~const Bar`. - // - This generates `for<..> ::Effects: TyCompat<::Effects>` - let Some(own_fx) = tcx.associated_type_for_effects(defining_def_id) else { - tcx.dcx().span_delayed_bug(span, "should not have allowed `~const` on a trait that doesn't have `#[const_trait]`"); - return; - }; - let own_fx_ty = Ty::new_projection( - tcx, - own_fx, - ty::GenericArgs::identity_for_item(tcx, own_fx), - ); - let Some(their_fx) = tcx.associated_type_for_effects(bound_trait_ref.def_id()) - else { - tcx.dcx().span_delayed_bug(span, "`~const` on trait without Effects assoc"); - return; - }; - let their_fx_ty = - Ty::new_projection(tcx, their_fx, bound_trait_ref.skip_binder().args); - let compat = tcx.require_lang_item(LangItem::EffectsTyCompat, Some(span)); - let clause = bound_trait_ref - .map_bound(|_| { - let trait_ref = ty::TraitRef::new(tcx, compat, [own_fx_ty, their_fx_ty]); - ty::ClauseKind::Trait(ty::TraitPredicate { - trait_ref, - polarity: ty::PredicatePolarity::Positive, - }) - }) - .upcast(tcx); - - self.clauses.push((clause, span)); - return; - } - - (DefKind::Impl { of_trait: true }, Some(ty::BoundConstness::ConstIfConst)) => { - // this is a where clause on an impl header. - // push `::Effects` into the set for the `Min` bound. - let Some(assoc) = tcx.associated_type_for_effects(bound_trait_ref.def_id()) else { - tcx.dcx().span_delayed_bug(span, "`~const` on trait without Effects assoc"); - return; - }; - - let ty = bound_trait_ref - .map_bound(|trait_ref| Ty::new_projection(tcx, assoc, trait_ref.args)); - - // When the user has written `for<'a, T> X<'a, T>: ~const Foo`, replace the - // binders to dummy ones i.e. `X<'static, ()>` so they can be referenced in - // the `Min` associated type properly (which doesn't allow using `for<>`) - // This should work for any bound variables as long as they don't have any - // bounds e.g. `for`. - // FIXME(effects) reconsider this approach to allow compatibility with `for` - let ty = tcx.replace_bound_vars_uncached(ty, FnMutDelegate { - regions: &mut |_| tcx.lifetimes.re_static, - types: &mut |_| tcx.types.unit, - consts: &mut |_| unimplemented!("`~const` does not support const binders"), - }); - - self.effects_min_tys.insert(ty, span); - return; - } - // for - // ``` - // trait Foo { type Bar: ~const Trait } - // ``` - // ensure that `::Effects: TyCompat`. - // - // FIXME(effects) this is equality for now, which wouldn't be helpful for a non-const implementor - // that uses a `Bar` that implements `Trait` with `Maybe` effects. - (DefKind::AssocTy, Some(ty::BoundConstness::ConstIfConst)) => { - // FIXME(effects): implement this - return; - } - // probably illegal in this position. - (_, Some(ty::BoundConstness::ConstIfConst)) => { - tcx.dcx().span_delayed_bug(span, "invalid `~const` encountered"); - return; - } - }; - // create a new projection type `::Effects` - let Some(assoc) = tcx.associated_type_for_effects(bound_trait_ref.def_id()) else { - tcx.dcx().span_delayed_bug( - span, - "`~const` trait bound has no effect assoc yet no errors encountered?", - ); - return; - }; - let self_ty = Ty::new_projection(tcx, assoc, bound_trait_ref.skip_binder().args); - // make `::Effects: Compat` - let new_trait_ref = - ty::TraitRef::new(tcx, tcx.require_lang_item(LangItem::EffectsCompat, Some(span)), [ - ty::GenericArg::from(self_ty), - compat_val.into(), - ]); - self.clauses.push((bound_trait_ref.rebind(new_trait_ref).upcast(tcx), span)); } pub(crate) fn push_projection_bound( diff --git a/compiler/rustc_hir_analysis/src/check/intrinsic.rs b/compiler/rustc_hir_analysis/src/check/intrinsic.rs index 06317a3b3049c..c75bdcec38808 100644 --- a/compiler/rustc_hir_analysis/src/check/intrinsic.rs +++ b/compiler/rustc_hir_analysis/src/check/intrinsic.rs @@ -58,15 +58,9 @@ fn equate_intrinsic_type<'tcx>( // the host effect param should be invisible as it shouldn't matter // whether effects is enabled for the intrinsic provider crate. - let consts_count = if generics.host_effect_index.is_some() { - own_counts.consts - 1 - } else { - own_counts.consts - }; - if gen_count_ok(own_counts.lifetimes, n_lts, "lifetime") && gen_count_ok(own_counts.types, n_tps, "type") - && gen_count_ok(consts_count, n_cts, "const") + && gen_count_ok(own_counts.consts, n_cts, "const") { let _ = check_function_signature( tcx, diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index d70e8673c5203..79e579841746f 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -913,12 +913,7 @@ fn check_param_wf(tcx: TyCtxt<'_>, param: &hir::GenericParam<'_>) -> Result<(), hir::GenericParamKind::Lifetime { .. } | hir::GenericParamKind::Type { .. } => Ok(()), // Const parameters are well formed if their type is structural match. - hir::GenericParamKind::Const { - ty: hir_ty, - default: _, - is_host_effect: _, - synthetic: _, - } => { + hir::GenericParamKind::Const { ty: hir_ty, default: _, synthetic: _ } => { let ty = tcx.type_of(param.def_id).instantiate_identity(); if tcx.features().unsized_const_params() { diff --git a/compiler/rustc_hir_analysis/src/collect/generics_of.rs b/compiler/rustc_hir_analysis/src/collect/generics_of.rs index 348b2260d2606..3eec0e1266577 100644 --- a/compiler/rustc_hir_analysis/src/collect/generics_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/generics_of.rs @@ -53,7 +53,6 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics { param_def_id_to_index, has_self: opaque_ty_generics.has_self, has_late_bound_regions: opaque_ty_generics.has_late_bound_regions, - host_effect_index: parent_generics.host_effect_index, }; } @@ -161,7 +160,6 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics { param_def_id_to_index, has_self: generics.has_self, has_late_bound_regions: generics.has_late_bound_regions, - host_effect_index: None, }; } else { // HACK(eddyb) this provides the correct generics when @@ -292,12 +290,10 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics { let has_self = opt_self.is_some(); let mut parent_has_self = false; let mut own_start = has_self as u32; - let mut host_effect_index = None; let parent_count = parent_def_id.map_or(0, |def_id| { let generics = tcx.generics_of(def_id); assert!(!has_self); parent_has_self = generics.has_self; - host_effect_index = generics.host_effect_index; own_start = generics.count() as u32; generics.parent_count + generics.own_params.len() }); @@ -361,12 +357,8 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics { kind, }) } - GenericParamKind::Const { ty: _, default, is_host_effect, synthetic } => { - if !matches!(allow_defaults, Defaults::Allowed) - && default.is_some() - // `host` effect params are allowed to have defaults. - && !is_host_effect - { + GenericParamKind::Const { ty: _, default, synthetic } => { + if !matches!(allow_defaults, Defaults::Allowed) && default.is_some() { tcx.dcx().span_err( param.span, "defaults for const parameters are only allowed in \ @@ -376,27 +368,12 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics { let index = next_index(); - if is_host_effect { - if let Some(idx) = host_effect_index { - tcx.dcx().span_delayed_bug( - param.span, - format!("parent also has host effect param? index: {idx}, def: {def_id:?}"), - ); - } - - host_effect_index = Some(index as usize); - } - Some(ty::GenericParamDef { index, name: param.name.ident().name, def_id: param.def_id.to_def_id(), pure_wrt_drop: param.pure_wrt_drop, - kind: ty::GenericParamDefKind::Const { - has_default: default.is_some(), - is_host_effect, - synthetic, - }, + kind: ty::GenericParamDefKind::Const { has_default: default.is_some(), synthetic }, }) } })); @@ -459,7 +436,6 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics { param_def_id_to_index, has_self: has_self || parent_has_self, has_late_bound_regions: has_late_bound_regions(tcx, node), - host_effect_index, } } @@ -540,8 +516,7 @@ impl<'v> Visitor<'v> for AnonConstInParamTyDetector { type Result = ControlFlow<()>; fn visit_generic_param(&mut self, p: &'v hir::GenericParam<'v>) -> Self::Result { - if let GenericParamKind::Const { ty, default: _, is_host_effect: _, synthetic: _ } = p.kind - { + if let GenericParamKind::Const { ty, default: _, synthetic: _ } = p.kind { let prev = self.in_param_ty; self.in_param_ty = true; let res = self.visit_ty(ty); diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs index 097a1fbc39360..f9460ed5b4732 100644 --- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs @@ -78,7 +78,6 @@ pub(super) fn predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericPredic #[instrument(level = "trace", skip(tcx), ret)] fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::GenericPredicates<'_> { use rustc_hir::*; - use rustc_middle::ty::Ty; match tcx.opt_rpitit_info(def_id.to_def_id()) { Some(ImplTraitInTraitData::Trait { fn_def_id, .. }) => { @@ -345,26 +344,6 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen debug!(?predicates); } - // add `Self::Effects: Compat` to ensure non-const impls don't get called - // in const contexts. - if let Node::TraitItem(&TraitItem { kind: TraitItemKind::Fn(..), .. }) = node - && let Some(host_effect_index) = generics.host_effect_index - { - let parent = generics.parent.unwrap(); - let Some(assoc_def_id) = tcx.associated_type_for_effects(parent) else { - bug!("associated_type_for_effects returned None when there is host effect in generics"); - }; - let effects = - Ty::new_projection(tcx, assoc_def_id, ty::GenericArgs::identity_for_item(tcx, parent)); - let param = generics.param_at(host_effect_index, tcx); - let span = tcx.def_span(param.def_id); - let host = ty::Const::new_param(tcx, ty::ParamConst::for_def(param)); - let compat = tcx.require_lang_item(LangItem::EffectsCompat, Some(span)); - let trait_ref = - ty::TraitRef::new(tcx, compat, [ty::GenericArg::from(effects), host.into()]); - predicates.push((ty::Binder::dummy(trait_ref).upcast(tcx), span)); - } - ty::GenericPredicates { parent: generics.parent, predicates: tcx.arena.alloc_from_iter(predicates), diff --git a/compiler/rustc_hir_analysis/src/delegation.rs b/compiler/rustc_hir_analysis/src/delegation.rs index 1ccb7faaf3053..4d3595965c918 100644 --- a/compiler/rustc_hir_analysis/src/delegation.rs +++ b/compiler/rustc_hir_analysis/src/delegation.rs @@ -186,7 +186,6 @@ impl<'tcx> GenericsBuilder<'tcx> { param_def_id_to_index, has_self, has_late_bound_regions: sig_generics.has_late_bound_regions, - host_effect_index: sig_generics.host_effect_index, } } } @@ -472,10 +471,6 @@ fn check_constraints<'tcx>( })); }; - if tcx.has_host_param(sig_id) { - emit("delegation to a function with effect parameter is not supported yet"); - } - if let Some(local_sig_id) = sig_id.as_local() && tcx.hir().opt_delegation_sig_id(local_sig_id).is_some() { diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs index a73a2f925cd3e..d2636c1573e0d 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -694,15 +694,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { ); debug!(?poly_trait_ref); - bounds.push_trait_bound( - tcx, - self.item_def_id().to_def_id(), - poly_trait_ref, - span, - polarity, - constness, - predicate_filter, - ); + bounds.push_trait_bound(tcx, poly_trait_ref, span, polarity); let mut dup_constraints = FxIndexMap::default(); for constraint in trait_segment.args().constraints { diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs index 3ba9c76bcee3a..61214b9921533 100644 --- a/compiler/rustc_hir_pretty/src/lib.rs +++ b/compiler/rustc_hir_pretty/src/lib.rs @@ -2134,7 +2134,7 @@ impl<'a> State<'a> { self.print_type(default); } } - GenericParamKind::Const { ty, ref default, is_host_effect: _, synthetic: _ } => { + GenericParamKind::Const { ty, ref default, synthetic: _ } => { self.word_space(":"); self.print_type(ty); if let Some(default) = default { diff --git a/compiler/rustc_hir_typeck/src/callee.rs b/compiler/rustc_hir_typeck/src/callee.rs index 06e2a5e349340..b642ba03aee2e 100644 --- a/compiler/rustc_hir_typeck/src/callee.rs +++ b/compiler/rustc_hir_typeck/src/callee.rs @@ -20,7 +20,7 @@ use rustc_target::spec::abi; use rustc_trait_selection::error_reporting::traits::DefIdOrName; use rustc_trait_selection::infer::InferCtxtExt as _; use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt as _; -use tracing::{debug, instrument, trace}; +use tracing::{debug, instrument}; use super::method::MethodCallee; use super::method::probe::ProbeScope; @@ -836,37 +836,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { fn_sig.output() } - #[tracing::instrument(level = "debug", skip(self, span))] + #[tracing::instrument(level = "debug", skip(self, _span))] pub(super) fn enforce_context_effects( &self, - span: Span, - callee_did: DefId, - callee_args: GenericArgsRef<'tcx>, + _span: Span, + _callee_did: DefId, + _callee_args: GenericArgsRef<'tcx>, ) { - let tcx = self.tcx; - - // fast-reject if callee doesn't have the host effect param (non-const) - let generics = tcx.generics_of(callee_did); - let Some(host_effect_index) = generics.host_effect_index else { return }; - - let effect = tcx.expected_host_effect_param_for_body(self.body_id); - - trace!(?effect, ?generics, ?callee_args); - - let param = callee_args.const_at(host_effect_index); - let cause = self.misc(span); - // We know the type of `effect` to be `bool`, there will be no opaque type inference. - match self.at(&cause, self.param_env).eq(infer::DefineOpaqueTypes::Yes, effect, param) { - Ok(infer::InferOk { obligations, value: () }) => { - self.register_predicates(obligations); - } - Err(e) => { - // FIXME(effects): better diagnostic - self.err_ctxt() - .report_mismatched_consts(&cause, self.param_env, effect, param, e) - .emit(); - } - } + todo!() } fn confirm_overloaded_call( diff --git a/compiler/rustc_hir_typeck/src/fallback.rs b/compiler/rustc_hir_typeck/src/fallback.rs index 4fd508ab896e7..68776c525551a 100644 --- a/compiler/rustc_hir_typeck/src/fallback.rs +++ b/compiler/rustc_hir_typeck/src/fallback.rs @@ -7,8 +7,6 @@ use rustc_data_structures::unord::{UnordBag, UnordMap, UnordSet}; use rustc_hir as hir; use rustc_hir::HirId; use rustc_hir::intravisit::Visitor; -use rustc_infer::infer::{DefineOpaqueTypes, InferOk}; -use rustc_middle::bug; use rustc_middle::ty::{self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable}; use rustc_session::lint; use rustc_span::def_id::LocalDefId; @@ -48,7 +46,7 @@ impl<'tcx> FnCtxt<'_, 'tcx> { self.fulfillment_cx.borrow_mut().pending_obligations() ); - let fallback_occurred = self.fallback_types() | self.fallback_effects(); + let fallback_occurred = self.fallback_types(); if !fallback_occurred { return; @@ -103,31 +101,6 @@ impl<'tcx> FnCtxt<'_, 'tcx> { fallback_occurred } - fn fallback_effects(&self) -> bool { - let unsolved_effects = self.unsolved_effects(); - - if unsolved_effects.is_empty() { - return false; - } - - // not setting the `fallback_has_occurred` field here because - // that field is only used for type fallback diagnostics. - for effect in unsolved_effects { - let expected = self.tcx.consts.true_; - let cause = self.misc(DUMMY_SP); - match self.at(&cause, self.param_env).eq(DefineOpaqueTypes::Yes, expected, effect) { - Ok(InferOk { obligations, value: () }) => { - self.register_predicates(obligations); - } - Err(e) => { - bug!("cannot eq unsolved effect: {e:?}") - } - } - } - - true - } - // Tries to apply a fallback to `ty` if it is an unsolved variable. // // - Unconstrained ints are replaced with `i32`. diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index d2d311ef5654f..0fc566c58f72f 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -1262,15 +1262,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { (GenericParamDefKind::Type { .. }, GenericArg::Infer(inf)) => { self.fcx.ty_infer(Some(param), inf.span).into() } - ( - &GenericParamDefKind::Const { has_default, is_host_effect, .. }, - GenericArg::Infer(inf), - ) => { - if has_default && is_host_effect { - self.fcx.var_for_effect(param) - } else { - self.fcx.ct_infer(Some(param), inf.span).into() - } + (&GenericParamDefKind::Const { .. }, GenericArg::Infer(inf)) => { + self.fcx.ct_infer(Some(param), inf.span).into() } _ => unreachable!(), } @@ -1305,20 +1298,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.fcx.var_for_def(self.span, param) } } - GenericParamDefKind::Const { has_default, is_host_effect, .. } => { + GenericParamDefKind::Const { has_default, .. } => { if has_default { - // N.B. this is a bit of a hack. `infer_args` is passed depending on - // whether the user has provided generic args. E.g. for `Vec::new` - // we would have to infer the generic types. However, for `Vec::::new` - // where the allocator param `A` has a default we will *not* infer. But - // for effect params this is a different story: if the user has not written - // anything explicit for the effect param, we always need to try to infer - // it before falling back to default, such that a `const fn` such as - // `needs_drop::<()>` can still be called in const contexts. (if we defaulted - // instead of inferred, typeck would error) - if is_host_effect { - return self.fcx.var_for_effect(param); - } else if !infer_args { + if !infer_args { return tcx .const_param_default(param.def_id) .instantiate(tcx, preceding_args) diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs index 4123feebb407f..3940d138deb0a 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs @@ -247,12 +247,6 @@ impl<'tcx> HirTyLowerer<'tcx> for FnCtxt<'_, 'tcx> { fn ct_infer(&self, param: Option<&ty::GenericParamDef>, span: Span) -> Const<'tcx> { // FIXME ideally this shouldn't use unwrap match param { - Some( - param @ ty::GenericParamDef { - kind: ty::GenericParamDefKind::Const { is_host_effect: true, .. }, - .. - }, - ) => self.var_for_effect(param).as_const().unwrap(), Some(param) => self.var_for_def(span, param).as_const().unwrap(), None => self.next_const_var(span), } diff --git a/compiler/rustc_hir_typeck/src/method/mod.rs b/compiler/rustc_hir_typeck/src/method/mod.rs index 69b9be0027682..e20a0cb67c357 100644 --- a/compiler/rustc_hir_typeck/src/method/mod.rs +++ b/compiler/rustc_hir_typeck/src/method/mod.rs @@ -369,17 +369,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ) -> Option>> { let (obligation, args) = self.obligation_for_method(cause, trait_def_id, self_ty, opt_input_types); - // FIXME(effects) find a better way to do this - // Operators don't have generic methods, but making them `#[const_trait]` gives them - // `const host: bool`. - let args = if self.tcx.is_const_trait(trait_def_id) { - self.tcx.mk_args_from_iter( - args.iter() - .chain([self.tcx.expected_host_effect_param_for_body(self.body_id).into()]), - ) - } else { - args - }; self.construct_obligation_for_trait(m_name, trait_def_id, obligation, args) } diff --git a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs index e3519dfb02852..90d07964fdac0 100644 --- a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs +++ b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs @@ -489,17 +489,6 @@ impl<'cx, 'tcx> TypeFolder> for Canonicalizer<'cx, 'tcx> { } } } - ty::ConstKind::Infer(InferConst::EffectVar(vid)) => { - match self.infcx.unwrap().probe_effect_var(vid) { - Some(value) => return self.fold_const(value), - None => { - return self.canonicalize_const_var( - CanonicalVarInfo { kind: CanonicalVarKind::Effect }, - ct, - ); - } - } - } ty::ConstKind::Infer(InferConst::Fresh(_)) => { bug!("encountered a fresh const during canonicalization") } @@ -700,8 +689,7 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> { .iter() .map(|v| CanonicalVarInfo { kind: match v.kind { - CanonicalVarKind::Ty(CanonicalTyVarKind::Int | CanonicalTyVarKind::Float) - | CanonicalVarKind::Effect => { + CanonicalVarKind::Ty(CanonicalTyVarKind::Int | CanonicalTyVarKind::Float) => { return *v; } CanonicalVarKind::Ty(CanonicalTyVarKind::General(u)) => { diff --git a/compiler/rustc_infer/src/infer/canonical/mod.rs b/compiler/rustc_infer/src/infer/canonical/mod.rs index 8caedcd4053bb..fb5fc3a53fe61 100644 --- a/compiler/rustc_infer/src/infer/canonical/mod.rs +++ b/compiler/rustc_infer/src/infer/canonical/mod.rs @@ -24,7 +24,6 @@ pub use instantiate::CanonicalExt; use rustc_index::IndexVec; pub use rustc_middle::infer::canonical::*; -use rustc_middle::infer::unify_key::EffectVarValue; use rustc_middle::ty::fold::TypeFoldable; use rustc_middle::ty::{self, GenericArg, List, Ty, TyCtxt}; use rustc_span::Span; @@ -145,15 +144,6 @@ impl<'tcx> InferCtxt<'tcx> { CanonicalVarKind::Const(ui) => { self.next_const_var_in_universe(span, universe_map(ui)).into() } - CanonicalVarKind::Effect => { - let vid = self - .inner - .borrow_mut() - .effect_unification_table() - .new_key(EffectVarValue::Unknown) - .vid; - ty::Const::new_infer(self.tcx, ty::InferConst::EffectVar(vid)).into() - } CanonicalVarKind::PlaceholderConst(ty::PlaceholderConst { universe, bound }) => { let universe_mapped = universe_map(universe); let placeholder_mapped = ty::PlaceholderConst { universe: universe_mapped, bound }; diff --git a/compiler/rustc_infer/src/infer/context.rs b/compiler/rustc_infer/src/infer/context.rs index 57007752cade3..0c151a11ad4e3 100644 --- a/compiler/rustc_infer/src/infer/context.rs +++ b/compiler/rustc_infer/src/infer/context.rs @@ -1,6 +1,5 @@ ///! Definition of `InferCtxtLike` from the librarified type layer. use rustc_hir::def_id::{DefId, LocalDefId}; -use rustc_middle::infer::unify_key::EffectVarValue; use rustc_middle::traits::ObligationCause; use rustc_middle::traits::solve::SolverMode; use rustc_middle::ty::fold::TypeFoldable; @@ -88,15 +87,6 @@ impl<'tcx> rustc_type_ir::InferCtxtLike for InferCtxt<'tcx> { } } - fn opportunistic_resolve_effect_var(&self, vid: ty::EffectVid) -> ty::Const<'tcx> { - match self.probe_effect_var(vid) { - Some(ct) => ct, - None => { - ty::Const::new_infer(self.tcx, ty::InferConst::EffectVar(self.root_effect_var(vid))) - } - } - } - fn opportunistic_resolve_lt_var(&self, vid: ty::RegionVid) -> ty::Region<'tcx> { self.inner.borrow_mut().unwrap_region_constraints().opportunistic_resolve_var(self.tcx, vid) } @@ -152,10 +142,6 @@ impl<'tcx> rustc_type_ir::InferCtxtLike for InferCtxt<'tcx> { self.inner.borrow_mut().const_unification_table().union(a, b); } - fn equate_effect_vids_raw(&self, a: rustc_type_ir::EffectVid, b: rustc_type_ir::EffectVid) { - self.inner.borrow_mut().effect_unification_table().union(a, b); - } - fn instantiate_ty_var_raw>( &self, relation: &mut R, @@ -189,13 +175,6 @@ impl<'tcx> rustc_type_ir::InferCtxtLike for InferCtxt<'tcx> { self.inner.borrow_mut().float_unification_table().union_value(vid, value); } - fn instantiate_effect_var_raw(&self, vid: rustc_type_ir::EffectVid, value: ty::Const<'tcx>) { - self.inner - .borrow_mut() - .effect_unification_table() - .union_value(vid, EffectVarValue::Known(value)); - } - fn instantiate_const_var_raw>( &self, relation: &mut R, diff --git a/compiler/rustc_infer/src/infer/freshen.rs b/compiler/rustc_infer/src/infer/freshen.rs index c4294111ebe85..28eac5b7496dd 100644 --- a/compiler/rustc_infer/src/infer/freshen.rs +++ b/compiler/rustc_infer/src/infer/freshen.rs @@ -153,15 +153,6 @@ impl<'a, 'tcx> TypeFolder> for TypeFreshener<'a, 'tcx> { drop(inner); self.freshen_const(input, ty::InferConst::Fresh) } - ty::ConstKind::Infer(ty::InferConst::EffectVar(v)) => { - let mut inner = self.infcx.inner.borrow_mut(); - let input = - inner.effect_unification_table().probe_value(v).known().ok_or_else(|| { - ty::InferConst::EffectVar(inner.effect_unification_table().find(v).vid) - }); - drop(inner); - self.freshen_const(input, ty::InferConst::Fresh) - } ty::ConstKind::Infer(ty::InferConst::Fresh(i)) => { if i >= self.const_freshen_count { bug!( diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index 5afdf3c245402..be43cba97f08f 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -26,9 +26,7 @@ use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_macros::extension; pub use rustc_macros::{TypeFoldable, TypeVisitable}; use rustc_middle::infer::canonical::{CanonicalQueryInput, CanonicalVarValues}; -use rustc_middle::infer::unify_key::{ - ConstVariableOrigin, ConstVariableValue, ConstVidKey, EffectVarValue, EffectVidKey, -}; +use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableValue, ConstVidKey}; use rustc_middle::mir::ConstraintCategory; use rustc_middle::mir::interpret::{ErrorHandled, EvalToValTreeResult}; use rustc_middle::traits::select; @@ -39,7 +37,7 @@ use rustc_middle::ty::fold::{ }; use rustc_middle::ty::visit::TypeVisitableExt; use rustc_middle::ty::{ - self, ConstVid, EffectVid, FloatVid, GenericArg, GenericArgKind, GenericArgs, GenericArgsRef, + self, ConstVid, FloatVid, GenericArg, GenericArgKind, GenericArgs, GenericArgsRef, GenericParamDefKind, InferConst, IntVid, Ty, TyCtxt, TyVid, }; use rustc_middle::{bug, span_bug}; @@ -117,9 +115,6 @@ pub struct InferCtxtInner<'tcx> { /// Map from floating variable to the kind of float it represents. float_unification_storage: ut::UnificationTableStorage, - /// Map from effect variable to the effect param it represents. - effect_unification_storage: ut::UnificationTableStorage>, - /// Tracks the set of region variables and the constraints between them. /// /// This is initially `Some(_)` but when @@ -176,7 +171,6 @@ impl<'tcx> InferCtxtInner<'tcx> { const_unification_storage: Default::default(), int_unification_storage: Default::default(), float_unification_storage: Default::default(), - effect_unification_storage: Default::default(), region_constraint_storage: Some(Default::default()), region_obligations: vec![], opaque_type_storage: Default::default(), @@ -228,10 +222,6 @@ impl<'tcx> InferCtxtInner<'tcx> { self.const_unification_storage.with_log(&mut self.undo_log) } - fn effect_unification_table(&mut self) -> UnificationTable<'_, 'tcx, EffectVidKey<'tcx>> { - self.effect_unification_storage.with_log(&mut self.undo_log) - } - #[inline] pub fn unwrap_region_constraints(&mut self) -> RegionConstraintCollector<'_, 'tcx> { self.region_constraint_storage @@ -524,7 +514,6 @@ impl fmt::Display for FixupError { ), Ty(_) => write!(f, "unconstrained type"), Const(_) => write!(f, "unconstrained const value"), - Effect(_) => write!(f, "unconstrained effect value"), } } } @@ -726,17 +715,6 @@ impl<'tcx> InferCtxt<'tcx> { vars } - pub fn unsolved_effects(&self) -> Vec> { - let mut inner = self.inner.borrow_mut(); - let mut table = inner.effect_unification_table(); - - (0..table.len()) - .map(|i| ty::EffectVid::from_usize(i)) - .filter(|&vid| table.probe_value(vid).is_unknown()) - .map(|v| ty::Const::new_infer(self.tcx, ty::InferConst::EffectVar(v))) - .collect() - } - #[instrument(skip(self), level = "debug")] pub fn sub_regions( &self, @@ -899,13 +877,6 @@ impl<'tcx> InferCtxt<'tcx> { ty::Const::new_var(self.tcx, vid) } - fn next_effect_var(&self) -> ty::Const<'tcx> { - let effect_vid = - self.inner.borrow_mut().effect_unification_table().new_key(EffectVarValue::Unknown).vid; - - ty::Const::new_infer(self.tcx, ty::InferConst::EffectVar(effect_vid)) - } - pub fn next_int_var(&self) -> Ty<'tcx> { let next_int_var_id = self.inner.borrow_mut().int_unification_table().new_key(ty::IntVarValue::Unknown); @@ -991,10 +962,7 @@ impl<'tcx> InferCtxt<'tcx> { Ty::new_var(self.tcx, ty_var_id).into() } - GenericParamDefKind::Const { is_host_effect, .. } => { - if is_host_effect { - return self.var_for_effect(param); - } + GenericParamDefKind::Const { .. } => { let origin = ConstVariableOrigin { param_def_id: Some(param.def_id), span }; let const_var_id = self .inner @@ -1007,16 +975,6 @@ impl<'tcx> InferCtxt<'tcx> { } } - pub fn var_for_effect(&self, param: &ty::GenericParamDef) -> GenericArg<'tcx> { - let ty = self - .tcx - .type_of(param.def_id) - .no_bound_vars() - .expect("const parameter types cannot be generic"); - debug_assert_eq!(self.tcx.types.bool, ty); - self.next_effect_var().into() - } - /// Given a set of generics defined on a type or impl, returns the generic parameters mapping /// each type/region parameter to a fresh inference variable. pub fn fresh_args_for_item(&self, span: Span, def_id: DefId) -> GenericArgsRef<'tcx> { @@ -1142,13 +1100,6 @@ impl<'tcx> InferCtxt<'tcx> { .probe_value(vid) .known() .unwrap_or(ct), - InferConst::EffectVar(vid) => self - .inner - .borrow_mut() - .effect_unification_table() - .probe_value(vid) - .known() - .unwrap_or(ct), InferConst::Fresh(_) => ct, }, ty::ConstKind::Param(_) @@ -1169,10 +1120,6 @@ impl<'tcx> InferCtxt<'tcx> { self.inner.borrow_mut().const_unification_table().find(var).vid } - pub fn root_effect_var(&self, var: ty::EffectVid) -> ty::EffectVid { - self.inner.borrow_mut().effect_unification_table().find(var).vid - } - /// Resolves an int var to a rigid int type, if it was constrained to one, /// or else the root int var in the unification table. pub fn opportunistic_resolve_int_var(&self, vid: ty::IntVid) -> Ty<'tcx> { @@ -1238,10 +1185,6 @@ impl<'tcx> InferCtxt<'tcx> { } } - pub fn probe_effect_var(&self, vid: EffectVid) -> Option> { - self.inner.borrow_mut().effect_unification_table().probe_value(vid).known() - } - /// Attempts to resolve all type/region/const variables in /// `value`. Region inference must have been run already (e.g., /// by calling `resolve_regions_and_report_errors`). If some @@ -1511,14 +1454,6 @@ impl<'tcx> InferCtxt<'tcx> { ConstVariableValue::Known { .. } => true, } } - - TyOrConstInferVar::Effect(v) => { - // If `probe_value` returns `Some`, it never equals - // `ty::ConstKind::Infer(ty::InferConst::Effect(v))`. - // - // Not `inlined_probe_value(v)` because this call site is colder. - self.probe_effect_var(v).is_some() - } } } @@ -1545,8 +1480,6 @@ pub enum TyOrConstInferVar { /// Equivalent to `ty::ConstKind::Infer(ty::InferConst::Var(_))`. Const(ConstVid), - /// Equivalent to `ty::ConstKind::Infer(ty::InferConst::EffectVar(_))`. - Effect(EffectVid), } impl<'tcx> TyOrConstInferVar { @@ -1577,7 +1510,6 @@ impl<'tcx> TyOrConstInferVar { fn maybe_from_const(ct: ty::Const<'tcx>) -> Option { match ct.kind() { ty::ConstKind::Infer(InferConst::Var(v)) => Some(TyOrConstInferVar::Const(v)), - ty::ConstKind::Infer(InferConst::EffectVar(v)) => Some(TyOrConstInferVar::Effect(v)), _ => None, } } diff --git a/compiler/rustc_infer/src/infer/relate/generalize.rs b/compiler/rustc_infer/src/infer/relate/generalize.rs index 7049444db9b5f..32817dbcb2140 100644 --- a/compiler/rustc_infer/src/infer/relate/generalize.rs +++ b/compiler/rustc_infer/src/infer/relate/generalize.rs @@ -660,7 +660,6 @@ impl<'tcx> TypeRelation> for Generalizer<'_, 'tcx> { } } } - ty::ConstKind::Infer(InferConst::EffectVar(_)) => Ok(c), // FIXME: Unevaluated constants are also not rigid, so the current // approach of always relating them structurally is incomplete. // diff --git a/compiler/rustc_infer/src/infer/resolve.rs b/compiler/rustc_infer/src/infer/resolve.rs index 64cc76f827eb8..6ec2e0152f0dc 100644 --- a/compiler/rustc_infer/src/infer/resolve.rs +++ b/compiler/rustc_infer/src/infer/resolve.rs @@ -176,9 +176,6 @@ impl<'a, 'tcx> FallibleTypeFolder> for FullTypeResolver<'a, 'tcx> { ty::ConstKind::Infer(InferConst::Fresh(_)) => { bug!("Unexpected const in full const resolver: {:?}", c); } - ty::ConstKind::Infer(InferConst::EffectVar(evid)) => { - return Err(FixupError { unresolved: super::TyOrConstInferVar::Effect(evid) }); - } _ => {} } c.try_super_fold_with(self) diff --git a/compiler/rustc_infer/src/infer/snapshot/fudge.rs b/compiler/rustc_infer/src/infer/snapshot/fudge.rs index 613cebc266dd9..394e07a81e7da 100644 --- a/compiler/rustc_infer/src/infer/snapshot/fudge.rs +++ b/compiler/rustc_infer/src/infer/snapshot/fudge.rs @@ -4,7 +4,6 @@ use rustc_data_structures::{snapshot_vec as sv, unify as ut}; use rustc_middle::infer::unify_key::{ConstVariableValue, ConstVidKey}; use rustc_middle::ty::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable}; use rustc_middle::ty::{self, ConstVid, FloatVid, IntVid, RegionVid, Ty, TyCtxt, TyVid}; -use rustc_type_ir::EffectVid; use rustc_type_ir::visit::TypeVisitableExt; use tracing::instrument; use ut::UnifyKey; @@ -129,7 +128,6 @@ struct SnapshotVarData { int_vars: Range, float_vars: Range, const_vars: (Range, Vec), - effect_vars: Range, } impl SnapshotVarData { @@ -148,30 +146,16 @@ impl SnapshotVarData { &mut inner.const_unification_table(), vars_pre_snapshot.const_var_len, ); - let effect_vars = vars_since_snapshot( - &inner.effect_unification_table(), - vars_pre_snapshot.effect_var_len, - ); - let effect_vars = effect_vars.start.vid..effect_vars.end.vid; - - SnapshotVarData { region_vars, type_vars, int_vars, float_vars, const_vars, effect_vars } + SnapshotVarData { region_vars, type_vars, int_vars, float_vars, const_vars } } fn is_empty(&self) -> bool { - let SnapshotVarData { - region_vars, - type_vars, - int_vars, - float_vars, - const_vars, - effect_vars, - } = self; + let SnapshotVarData { region_vars, type_vars, int_vars, float_vars, const_vars } = self; region_vars.0.is_empty() && type_vars.0.is_empty() && int_vars.is_empty() && float_vars.is_empty() && const_vars.0.is_empty() - && effect_vars.is_empty() } } @@ -258,13 +242,6 @@ impl<'a, 'tcx> TypeFolder> for InferenceFudger<'a, 'tcx> { ct } } - ty::InferConst::EffectVar(vid) => { - if self.snapshot_vars.effect_vars.contains(&vid) { - self.infcx.next_effect_var() - } else { - ct - } - } ty::InferConst::Fresh(_) => { unreachable!("unexpected fresh infcx var") } diff --git a/compiler/rustc_infer/src/infer/snapshot/mod.rs b/compiler/rustc_infer/src/infer/snapshot/mod.rs index fa813500c544e..b16c80cf20143 100644 --- a/compiler/rustc_infer/src/infer/snapshot/mod.rs +++ b/compiler/rustc_infer/src/infer/snapshot/mod.rs @@ -23,7 +23,6 @@ struct VariableLengths { int_var_len: usize, float_var_len: usize, const_var_len: usize, - effect_var_len: usize, } impl<'tcx> InferCtxt<'tcx> { @@ -35,7 +34,6 @@ impl<'tcx> InferCtxt<'tcx> { int_var_len: inner.int_unification_table().len(), float_var_len: inner.float_unification_table().len(), const_var_len: inner.const_unification_table().len(), - effect_var_len: inner.effect_unification_table().len(), } } diff --git a/compiler/rustc_infer/src/infer/snapshot/undo_log.rs b/compiler/rustc_infer/src/infer/snapshot/undo_log.rs index 79ea0915c9c05..713389f461836 100644 --- a/compiler/rustc_infer/src/infer/snapshot/undo_log.rs +++ b/compiler/rustc_infer/src/infer/snapshot/undo_log.rs @@ -2,7 +2,7 @@ use std::marker::PhantomData; use rustc_data_structures::undo_log::{Rollback, UndoLogs}; use rustc_data_structures::{snapshot_vec as sv, unify as ut}; -use rustc_middle::infer::unify_key::{ConstVidKey, EffectVidKey, RegionVidKey}; +use rustc_middle::infer::unify_key::{ConstVidKey, RegionVidKey}; use rustc_middle::ty::{self, OpaqueHiddenType, OpaqueTypeKey}; use tracing::debug; @@ -22,7 +22,6 @@ pub(crate) enum UndoLog<'tcx> { ConstUnificationTable(sv::UndoLog>>), IntUnificationTable(sv::UndoLog>), FloatUnificationTable(sv::UndoLog>), - EffectUnificationTable(sv::UndoLog>>), RegionConstraintCollector(region_constraints::UndoLog<'tcx>), RegionUnificationTable(sv::UndoLog>>), ProjectionCache(traits::UndoLog<'tcx>), @@ -50,7 +49,6 @@ impl_from! { FloatUnificationTable(sv::UndoLog>), ConstUnificationTable(sv::UndoLog>>), - EffectUnificationTable(sv::UndoLog>>), RegionUnificationTable(sv::UndoLog>>), ProjectionCache(traits::UndoLog<'tcx>), @@ -65,7 +63,6 @@ impl<'tcx> Rollback> for InferCtxtInner<'tcx> { UndoLog::ConstUnificationTable(undo) => self.const_unification_storage.reverse(undo), UndoLog::IntUnificationTable(undo) => self.int_unification_storage.reverse(undo), UndoLog::FloatUnificationTable(undo) => self.float_unification_storage.reverse(undo), - UndoLog::EffectUnificationTable(undo) => self.effect_unification_storage.reverse(undo), UndoLog::RegionConstraintCollector(undo) => { self.region_constraint_storage.as_mut().unwrap().reverse(undo) } diff --git a/compiler/rustc_lint/src/nonstandard_style.rs b/compiler/rustc_lint/src/nonstandard_style.rs index 83a8ca4307e03..1c27e1daa9066 100644 --- a/compiler/rustc_lint/src/nonstandard_style.rs +++ b/compiler/rustc_lint/src/nonstandard_style.rs @@ -542,11 +542,7 @@ impl<'tcx> LateLintPass<'tcx> for NonUpperCaseGlobals { } fn check_generic_param(&mut self, cx: &LateContext<'_>, param: &hir::GenericParam<'_>) { - if let GenericParamKind::Const { is_host_effect, .. } = param.kind { - // `host` params are explicitly allowed to be lowercase. - if is_host_effect { - return; - } + if let GenericParamKind::Const { .. } = param.kind { NonUpperCaseGlobals::check_upper_case(cx, "const parameter", ¶m.name.ident()); } } diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs index 7bb40996d58f2..d4cbf6e13afbc 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs @@ -330,7 +330,6 @@ provide! { tcx, def_id, other, cdata, .process_decoded(tcx, || panic!("{def_id:?} does not have trait_impl_trait_tys"))) } - associated_type_for_effects => { table } associated_types_for_impl_traits_in_associated_fn => { table_defaulted_array } visibility => { cdata.get_visibility(def_id.index) } diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index ec678c7515b0d..80b979fe088f5 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -1479,9 +1479,6 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { for &def_id in associated_item_def_ids { self.encode_info_for_assoc_item(def_id); } - if let Some(assoc_def_id) = self.tcx.associated_type_for_effects(def_id) { - record!(self.tables.associated_type_for_effects[def_id] <- assoc_def_id); - } } if let DefKind::Closure | DefKind::SyntheticCoroutineBody = def_kind && let Some(coroutine_kind) = self.tcx.coroutine_kind(def_id) diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs index 79bd1c13b1216..8da1be8054460 100644 --- a/compiler/rustc_metadata/src/rmeta/mod.rs +++ b/compiler/rustc_metadata/src/rmeta/mod.rs @@ -394,7 +394,6 @@ define_tables! { explicit_implied_predicates_of: Table, Span)>>, inherent_impls: Table>, associated_types_for_impl_traits_in_associated_fn: Table>, - associated_type_for_effects: Table>>, opt_rpitit_info: Table>>, is_effects_desugaring: Table, unused_generic_params: Table, diff --git a/compiler/rustc_middle/src/infer/unify_key.rs b/compiler/rustc_middle/src/infer/unify_key.rs index cf692b145b8dc..7f9211043d690 100644 --- a/compiler/rustc_middle/src/infer/unify_key.rs +++ b/compiler/rustc_middle/src/infer/unify_key.rs @@ -172,70 +172,3 @@ impl<'tcx> UnifyValue for ConstVariableValue<'tcx> { } } } - -/// values for the effect inference variable -#[derive(Clone, Copy, Debug)] -pub enum EffectVarValue<'tcx> { - Unknown, - Known(ty::Const<'tcx>), -} - -impl<'tcx> EffectVarValue<'tcx> { - pub fn known(self) -> Option> { - match self { - EffectVarValue::Unknown => None, - EffectVarValue::Known(value) => Some(value), - } - } - - pub fn is_unknown(self) -> bool { - match self { - EffectVarValue::Unknown => true, - EffectVarValue::Known(_) => false, - } - } -} - -impl<'tcx> UnifyValue for EffectVarValue<'tcx> { - type Error = NoError; - - fn unify_values(value1: &Self, value2: &Self) -> Result { - match (*value1, *value2) { - (EffectVarValue::Unknown, EffectVarValue::Unknown) => Ok(EffectVarValue::Unknown), - (EffectVarValue::Unknown, EffectVarValue::Known(val)) - | (EffectVarValue::Known(val), EffectVarValue::Unknown) => { - Ok(EffectVarValue::Known(val)) - } - (EffectVarValue::Known(_), EffectVarValue::Known(_)) => { - bug!("equating known inference variables: {value1:?} {value2:?}") - } - } - } -} - -#[derive(PartialEq, Copy, Clone, Debug)] -pub struct EffectVidKey<'tcx> { - pub vid: ty::EffectVid, - pub phantom: PhantomData>, -} - -impl<'tcx> From for EffectVidKey<'tcx> { - fn from(vid: ty::EffectVid) -> Self { - EffectVidKey { vid, phantom: PhantomData } - } -} - -impl<'tcx> UnifyKey for EffectVidKey<'tcx> { - type Value = EffectVarValue<'tcx>; - #[inline] - fn index(&self) -> u32 { - self.vid.as_u32() - } - #[inline] - fn from_index(i: u32) -> Self { - EffectVidKey::from(ty::EffectVid::from_u32(i)) - } - fn tag() -> &'static str { - "EffectVidKey" - } -} diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index f8ba606e087c8..0b751779501d9 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -854,12 +854,6 @@ rustc_queries! { separate_provide_extern } - query associated_type_for_effects(def_id: DefId) -> Option { - desc { |tcx| "creating associated items for effects in `{}`", tcx.def_path_str(def_id) } - cache_on_disk_if { def_id.is_local() } - separate_provide_extern - } - /// Given an impl trait in trait `opaque_ty_def_id`, create and return the corresponding /// associated item. query associated_type_for_impl_trait_in_trait(opaque_ty_def_id: LocalDefId) -> LocalDefId { diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index b682524ae39f4..281899647efb5 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -646,13 +646,6 @@ bidirectional_lang_item_map! { Destruct, DiscriminantKind, DynMetadata, - EffectsCompat, - EffectsIntersection, - EffectsIntersectionOutput, - EffectsMaybe, - EffectsNoRuntime, - EffectsRuntime, - EffectsTyCompat, Fn, FnMut, FnOnce, diff --git a/compiler/rustc_middle/src/ty/diagnostics.rs b/compiler/rustc_middle/src/ty/diagnostics.rs index 8bd2ae9128f7c..64405d18c7d24 100644 --- a/compiler/rustc_middle/src/ty/diagnostics.rs +++ b/compiler/rustc_middle/src/ty/diagnostics.rs @@ -592,9 +592,6 @@ impl<'tcx> TypeVisitor> for IsSuggestableVisitor<'tcx> { match c.kind() { ConstKind::Infer(InferConst::Var(_)) if self.infer_suggestable => {} - // effect variables are always suggestable, because they are not visible - ConstKind::Infer(InferConst::EffectVar(_)) => {} - ConstKind::Infer(..) | ConstKind::Bound(..) | ConstKind::Placeholder(..) diff --git a/compiler/rustc_middle/src/ty/flags.rs b/compiler/rustc_middle/src/ty/flags.rs index 92a975c028e55..39899f1d32be6 100644 --- a/compiler/rustc_middle/src/ty/flags.rs +++ b/compiler/rustc_middle/src/ty/flags.rs @@ -354,9 +354,7 @@ impl FlagComputation { self.add_flags(TypeFlags::STILL_FURTHER_SPECIALIZABLE); match infer { InferConst::Fresh(_) => self.add_flags(TypeFlags::HAS_CT_FRESH), - InferConst::Var(_) | InferConst::EffectVar(_) => { - self.add_flags(TypeFlags::HAS_CT_INFER) - } + InferConst::Var(_) => self.add_flags(TypeFlags::HAS_CT_INFER), } } ty::ConstKind::Bound(debruijn, _) => { diff --git a/compiler/rustc_middle/src/ty/generic_args.rs b/compiler/rustc_middle/src/ty/generic_args.rs index daf1362e25c1f..56111ee063eb1 100644 --- a/compiler/rustc_middle/src/ty/generic_args.rs +++ b/compiler/rustc_middle/src/ty/generic_args.rs @@ -501,12 +501,11 @@ impl<'tcx> GenericArgs<'tcx> { #[inline] pub fn non_erasable_generics( &'tcx self, - tcx: TyCtxt<'tcx>, - def_id: DefId, + // FIXME(effects): Remove these + _tcx: TyCtxt<'tcx>, + _def_id: DefId, ) -> impl DoubleEndedIterator> + 'tcx { - let generics = tcx.generics_of(def_id); - self.iter().enumerate().filter_map(|(i, k)| match k.unpack() { - _ if Some(i) == generics.host_effect_index => None, + self.iter().filter_map(|k| match k.unpack() { ty::GenericArgKind::Lifetime(_) => None, generic => Some(generic), }) diff --git a/compiler/rustc_middle/src/ty/generics.rs b/compiler/rustc_middle/src/ty/generics.rs index 63534a3d01745..e24a3f281fc50 100644 --- a/compiler/rustc_middle/src/ty/generics.rs +++ b/compiler/rustc_middle/src/ty/generics.rs @@ -14,7 +14,7 @@ use crate::ty::{EarlyBinder, GenericArgsRef}; pub enum GenericParamDefKind { Lifetime, Type { has_default: bool, synthetic: bool }, - Const { has_default: bool, is_host_effect: bool, synthetic: bool }, + Const { has_default: bool, synthetic: bool }, } impl GenericParamDefKind { @@ -81,10 +81,6 @@ impl GenericParamDef { } } - pub fn is_host_effect(&self) -> bool { - matches!(self.kind, GenericParamDefKind::Const { is_host_effect: true, .. }) - } - pub fn default_value<'tcx>( &self, tcx: TyCtxt<'tcx>, @@ -133,9 +129,6 @@ pub struct Generics { pub has_self: bool, pub has_late_bound_regions: Option, - - // The index of the host effect when instantiated. (i.e. might be index to parent args) - pub host_effect_index: Option, } impl<'tcx> rustc_type_ir::inherent::GenericsOf> for &'tcx Generics { @@ -216,12 +209,10 @@ impl<'tcx> Generics { pub fn own_requires_monomorphization(&self) -> bool { for param in &self.own_params { match param.kind { - GenericParamDefKind::Type { .. } - | GenericParamDefKind::Const { is_host_effect: false, .. } => { + GenericParamDefKind::Type { .. } | GenericParamDefKind::Const { .. } => { return true; } - GenericParamDefKind::Lifetime - | GenericParamDefKind::Const { is_host_effect: true, .. } => {} + GenericParamDefKind::Lifetime => {} } } false @@ -300,8 +291,6 @@ impl<'tcx> Generics { own_params.start = 1; } - let verbose = tcx.sess.verbose_internals(); - // Filter the default arguments. // // This currently uses structural equality instead @@ -316,8 +305,6 @@ 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-internals`. - || (!verbose && matches!(param.kind, GenericParamDefKind::Const { is_host_effect: true, .. })) }) .count(); diff --git a/compiler/rustc_middle/src/ty/instance.rs b/compiler/rustc_middle/src/ty/instance.rs index b1c5ff50fdc86..61cb43225015c 100644 --- a/compiler/rustc_middle/src/ty/instance.rs +++ b/compiler/rustc_middle/src/ty/instance.rs @@ -476,7 +476,6 @@ impl<'tcx> Instance<'tcx> { pub fn mono(tcx: TyCtxt<'tcx>, def_id: DefId) -> Instance<'tcx> { let args = GenericArgs::for_item(tcx, def_id, |param, _| match param.kind { ty::GenericParamDefKind::Lifetime => tcx.lifetimes.re_erased.into(), - ty::GenericParamDefKind::Const { is_host_effect: true, .. } => tcx.consts.true_.into(), ty::GenericParamDefKind::Type { .. } => { bug!("Instance::mono: {:?} has type parameters", def_id) } diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index 06cbb6c9f1d86..7fd7e463acf89 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -17,10 +17,10 @@ use rustc_span::sym; use rustc_target::abi::{Float, Integer, IntegerType, Size}; use rustc_target::spec::abi::Abi; use smallvec::{SmallVec, smallvec}; -use tracing::{debug, instrument, trace}; +use tracing::{debug, instrument}; use crate::middle::codegen_fn_attrs::CodegenFnAttrFlags; -use crate::query::{IntoQueryParam, Providers}; +use crate::query::Providers; use crate::ty::layout::{FloatExt, IntegerExt}; use crate::ty::{ self, Asyncness, FallibleTypeFolder, GenericArgKind, GenericArgsRef, Ty, TyCtxt, TypeFoldable, @@ -865,48 +865,6 @@ impl<'tcx> TyCtxt<'tcx> { || self.extern_crate(key).is_some_and(|e| e.is_direct()) } - /// Whether the item has a host effect param. This is different from `TyCtxt::is_const`, - /// because the item must also be "maybe const", and the crate where the item is - /// defined must also have the effects feature enabled. - pub fn has_host_param(self, def_id: impl IntoQueryParam) -> bool { - self.generics_of(def_id).host_effect_index.is_some() - } - - pub fn expected_host_effect_param_for_body(self, def_id: impl Into) -> 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. - let mut host_always_on = !self.features().effects() - || self.sess.opts.unstable_opts.unleash_the_miri_inside_of_you; - - // Compute the constness required by the context. - let const_context = self.hir().body_const_context(def_id); - - let kind = self.def_kind(def_id); - debug_assert_ne!(kind, DefKind::ConstParam); - - if self.has_attr(def_id, sym::rustc_do_not_const_check) { - trace!("do not const check this context"); - host_always_on = true; - } - - match const_context { - _ if host_always_on => self.consts.true_, - Some(hir::ConstContext::Static(_) | hir::ConstContext::Const { .. }) => { - self.consts.false_ - } - Some(hir::ConstContext::ConstFn) => { - let host_idx = self - .generics_of(def_id) - .host_effect_index - .expect("ConstContext::Maybe must have host effect param"); - ty::GenericArgs::identity_for_item(self, def_id).const_at(host_idx) - } - None => self.consts.true_, - } - } - /// Expand any [weak alias types][weak] contained within the given `value`. /// /// This should be used over other normalization routines in situations where diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs index b4d084d4dffc4..e5c59d6082210 100644 --- a/compiler/rustc_monomorphize/src/collector.rs +++ b/compiler/rustc_monomorphize/src/collector.rs @@ -1522,7 +1522,6 @@ fn create_mono_items_for_default_impls<'tcx>( // it, to validate whether or not the impl is legal to instantiate at all. let only_region_params = |param: &ty::GenericParamDef, _: &_| match param.kind { GenericParamDefKind::Lifetime => tcx.lifetimes.re_erased.into(), - GenericParamDefKind::Const { is_host_effect: true, .. } => tcx.consts.true_.into(), GenericParamDefKind::Type { .. } | GenericParamDefKind::Const { .. } => { unreachable!( "`own_requires_monomorphization` check means that \ diff --git a/compiler/rustc_next_trait_solver/src/canonicalizer.rs b/compiler/rustc_next_trait_solver/src/canonicalizer.rs index 23634d35c07fe..63608f9e85615 100644 --- a/compiler/rustc_next_trait_solver/src/canonicalizer.rs +++ b/compiler/rustc_next_trait_solver/src/canonicalizer.rs @@ -431,7 +431,6 @@ impl, I: Interner> TypeFolder for Canonicaliz ); CanonicalVarKind::Const(self.delegate.universe_of_ct(vid).unwrap()) } - ty::InferConst::EffectVar(_) => CanonicalVarKind::Effect, ty::InferConst::Fresh(_) => todo!(), }, ty::ConstKind::Placeholder(placeholder) => match self.canonicalize_mode { diff --git a/compiler/rustc_next_trait_solver/src/resolve.rs b/compiler/rustc_next_trait_solver/src/resolve.rs index f2654f7534e1d..71c87714745ee 100644 --- a/compiler/rustc_next_trait_solver/src/resolve.rs +++ b/compiler/rustc_next_trait_solver/src/resolve.rs @@ -76,9 +76,6 @@ impl, I: Interner> TypeFolder for EagerResolv resolved } } - ty::ConstKind::Infer(ty::InferConst::EffectVar(vid)) => { - self.delegate.opportunistic_resolve_effect_var(vid) - } _ => { if c.has_infer() { c.super_fold_with(self) diff --git a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs index c9c0d6391fc81..5e604a5d74f58 100644 --- a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs @@ -270,11 +270,6 @@ where ecx: &mut EvalCtxt<'_, D>, goal: Goal, ) -> Vec>; - - fn consider_builtin_effects_intersection_candidate( - ecx: &mut EvalCtxt<'_, D>, - goal: Goal, - ) -> Result, NoSolution>; } impl EvalCtxt<'_, D> @@ -481,9 +476,6 @@ where Some(TraitSolverLangItem::TransmuteTrait) => { G::consider_builtin_transmute_candidate(self, goal) } - Some(TraitSolverLangItem::EffectsIntersection) => { - G::consider_builtin_effects_intersection_candidate(self, goal) - } _ => Err(NoSolution), } }; diff --git a/compiler/rustc_next_trait_solver/src/solve/mod.rs b/compiler/rustc_next_trait_solver/src/solve/mod.rs index a475a58e483b0..b7fdc339be5cd 100644 --- a/compiler/rustc_next_trait_solver/src/solve/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/mod.rs @@ -182,12 +182,6 @@ where let (ct, ty) = goal.predicate; let ct_ty = match ct.kind() { - // FIXME: Ignore effect vars because canonicalization doesn't handle them correctly - // and if we stall on the var then we wind up creating ambiguity errors in a probe - // for this goal which contains an effect var. Which then ends up ICEing. - ty::ConstKind::Infer(ty::InferConst::EffectVar(_)) => { - return self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes); - } ty::ConstKind::Infer(_) => { return self.evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS); } diff --git a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs index 4d8b193ee4911..c98fd85355142 100644 --- a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs @@ -911,68 +911,6 @@ where ) -> Result, NoSolution> { panic!("`TransmuteFrom` does not have an associated type: {:?}", goal) } - - fn consider_builtin_effects_intersection_candidate( - ecx: &mut EvalCtxt<'_, D>, - goal: Goal, - ) -> Result, NoSolution> { - let ty::Tuple(types) = goal.predicate.self_ty().kind() else { - return Err(NoSolution); - }; - - let cx = ecx.cx(); - - let mut first_non_maybe = None; - let mut non_maybe_count = 0; - for ty in types.iter() { - if !matches!(ty::EffectKind::try_from_ty(cx, ty), Some(ty::EffectKind::Maybe)) { - first_non_maybe.get_or_insert(ty); - non_maybe_count += 1; - } - } - - match non_maybe_count { - 0 => { - let ty = ty::EffectKind::Maybe.to_ty(cx); - ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc).enter(|ecx| { - ecx.instantiate_normalizes_to_term(goal, ty.into()); - ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) - }) - } - 1 => { - let ty = first_non_maybe.unwrap(); - ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc).enter(|ecx| { - ecx.instantiate_normalizes_to_term(goal, ty.into()); - ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) - }) - } - _ => { - let mut min = ty::EffectKind::Maybe; - - for ty in types.iter() { - // We can't find the intersection if the types used are generic. - // - // FIXME(effects): do we want to look at where clauses to get some - // clue for the case where generic types are being used? - let Some(kind) = ty::EffectKind::try_from_ty(cx, ty) else { - return Err(NoSolution); - }; - - let Some(result) = ty::EffectKind::intersection(min, kind) else { - return Err(NoSolution); - }; - - min = result; - } - - let ty = min.to_ty(cx); - ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc).enter(|ecx| { - ecx.instantiate_normalizes_to_term(goal, ty.into()); - ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) - }) - } - } - } } impl EvalCtxt<'_, D> diff --git a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs index a8d6536baadde..6b26f960286f6 100644 --- a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs +++ b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs @@ -719,47 +719,6 @@ where } }) } - - fn consider_builtin_effects_intersection_candidate( - ecx: &mut EvalCtxt<'_, D>, - goal: Goal, - ) -> Result, NoSolution> { - if goal.predicate.polarity != ty::PredicatePolarity::Positive { - return Err(NoSolution); - } - - let ty::Tuple(types) = goal.predicate.self_ty().kind() else { - return Err(NoSolution); - }; - - let cx = ecx.cx(); - let maybe_count = types - .iter() - .filter_map(|ty| ty::EffectKind::try_from_ty(cx, ty)) - .filter(|&ty| ty == ty::EffectKind::Maybe) - .count(); - - // Don't do concrete type check unless there are more than one type that will influence the result. - // This would allow `(Maybe, T): Min` pass even if we know nothing about `T`. - if types.len() - maybe_count > 1 { - let mut min = ty::EffectKind::Maybe; - - for ty in types.iter() { - let Some(kind) = ty::EffectKind::try_from_ty(ecx.cx(), ty) else { - return Err(NoSolution); - }; - - let Some(result) = ty::EffectKind::intersection(min, kind) else { - return Err(NoSolution); - }; - - min = result; - } - } - - ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc) - .enter(|ecx| ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)) - } } impl EvalCtxt<'_, D> diff --git a/compiler/rustc_smir/src/rustc_smir/convert/ty.rs b/compiler/rustc_smir/src/rustc_smir/convert/ty.rs index ef2ee9a166aff..0abc89ddb81a8 100644 --- a/compiler/rustc_smir/src/rustc_smir/convert/ty.rs +++ b/compiler/rustc_smir/src/rustc_smir/convert/ty.rs @@ -588,7 +588,6 @@ impl<'tcx> Stable<'tcx> for ty::Generics { .has_late_bound_regions .as_ref() .map(|late_bound_regions| late_bound_regions.stable(tables)), - host_effect_index: self.host_effect_index, } } } @@ -603,7 +602,7 @@ impl<'tcx> Stable<'tcx> for rustc_middle::ty::GenericParamDefKind { ty::GenericParamDefKind::Type { has_default, synthetic } => { GenericParamDefKind::Type { has_default: *has_default, synthetic: *synthetic } } - ty::GenericParamDefKind::Const { has_default, is_host_effect: _, synthetic: _ } => { + ty::GenericParamDefKind::Const { has_default, synthetic: _ } => { GenericParamDefKind::Const { has_default: *has_default } } } diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index aa05b88ea0c40..bf5f948fe9199 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -195,14 +195,6 @@ symbols! { Display, DoubleEndedIterator, Duration, - EffectsCompat, - EffectsIntersection, - EffectsIntersectionOutput, - EffectsMaybe, - EffectsNoRuntime, - EffectsRuntime, - EffectsTyCompat, - Effects__, Encodable, Encoder, Enumerate, @@ -1737,7 +1729,6 @@ symbols! { rustc_reallocator, rustc_regions, rustc_reservation_impl, - rustc_runtime, rustc_safe_intrinsic, rustc_serialize, rustc_skip_during_method_dispatch, diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs index 6ef64c3ed80a8..b0175fff8a7f2 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs @@ -2374,50 +2374,14 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { }) } - /// For effects predicates such as `::Effects: Compat`, pretend that the - /// predicate that failed was `u32: Add`. Return the constness of such predicate to later - /// print as `u32: ~const Add`. + // FIXME(effects): Remove this. fn get_effects_trait_pred_override( &self, p: ty::PolyTraitPredicate<'tcx>, leaf: ty::PolyTraitPredicate<'tcx>, - span: Span, - ) -> (ty::PolyTraitPredicate<'tcx>, ty::PolyTraitPredicate<'tcx>, Option) - { - let trait_ref = p.to_poly_trait_ref(); - if !self.tcx.is_lang_item(trait_ref.def_id(), LangItem::EffectsCompat) { - return (p, leaf, None); - } - - let Some(ty::Alias(ty::AliasTyKind::Projection, projection)) = - trait_ref.self_ty().no_bound_vars().map(Ty::kind) - else { - return (p, leaf, None); - }; - - let constness = trait_ref.skip_binder().args.const_at(1); - - let constness = if constness == self.tcx.consts.true_ || constness.is_ct_infer() { - None - } else if constness == self.tcx.consts.false_ { - Some(ty::BoundConstness::Const) - } else if matches!(constness.kind(), ty::ConstKind::Param(_)) { - Some(ty::BoundConstness::ConstIfConst) - } else { - self.dcx().span_bug(span, format!("Unknown constness argument: {constness:?}")); - }; - - let new_pred = p.map_bound(|mut trait_pred| { - trait_pred.trait_ref = projection.trait_ref(self.tcx); - trait_pred - }); - - let new_leaf = leaf.map_bound(|mut trait_pred| { - trait_pred.trait_ref = projection.trait_ref(self.tcx); - trait_pred - }); - - (new_pred, new_leaf, constness) + _span: Span, + ) -> (ty::PolyTraitPredicate<'tcx>, ty::PolyTraitPredicate<'tcx>, ty::BoundConstness) { + (p, leaf, ty::BoundConstness::NotConst) } fn add_tuple_trait_message( diff --git a/compiler/rustc_trait_selection/src/traits/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs index 2bdeb00bdacba..ca9e6cd662d9a 100644 --- a/compiler/rustc_trait_selection/src/traits/fulfill.rs +++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs @@ -450,7 +450,6 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> { ty::ConstKind::Infer(var) => { let var = match var { ty::InferConst::Var(vid) => TyOrConstInferVar::Const(vid), - ty::InferConst::EffectVar(vid) => TyOrConstInferVar::Effect(vid), ty::InferConst::Fresh(_) => { bug!("encountered fresh const in fulfill") } diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs index eea3867190d3e..dac007663162e 100644 --- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs +++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs @@ -547,7 +547,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { } } // Provide an impl for suitable functions, rejecting `#[target_feature]` functions (RFC 2396). - ty::FnDef(def_id, _args) => { + ty::FnDef(def_id, _) => { let tcx = self.tcx(); if tcx.fn_sig(def_id).skip_binder().is_fn_trait_compatible() && tcx.codegen_fn_attrs(def_id).target_features.is_empty() diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index d5b1c5a97daa6..4d7e2769af5f4 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -1821,8 +1821,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> { |cand: ty::PolyTraitPredicate<'tcx>| cand.is_global() && !cand.has_bound_vars(); // (*) Prefer `BuiltinCandidate { has_nested: false }`, `PointeeCandidate`, - // `DiscriminantKindCandidate`, `ConstDestructCandidate` - // to anything else. + // or `DiscriminantKindCandidate` to anything else. // // This is a fix for #53123 and prevents winnowing from accidentally extending the // lifetime of a variable. diff --git a/compiler/rustc_ty_utils/src/assoc.rs b/compiler/rustc_ty_utils/src/assoc.rs index a3210dd80d77b..16fd28201c222 100644 --- a/compiler/rustc_ty_utils/src/assoc.rs +++ b/compiler/rustc_ty_utils/src/assoc.rs @@ -4,9 +4,8 @@ use rustc_hir::def::DefKind; use rustc_hir::def_id::{DefId, DefIdMap, LocalDefId}; use rustc_hir::intravisit::{self, Visitor}; use rustc_middle::query::Providers; -use rustc_middle::ty::{self, ImplTraitInTraitData, Ty, TyCtxt}; +use rustc_middle::ty::{self, ImplTraitInTraitData, TyCtxt}; use rustc_middle::{bug, span_bug}; -use rustc_span::sym; use rustc_span::symbol::kw; pub(crate) fn provide(providers: &mut Providers) { @@ -15,7 +14,6 @@ pub(crate) fn provide(providers: &mut Providers) { associated_item_def_ids, associated_items, associated_types_for_impl_traits_in_associated_fn, - associated_type_for_effects, associated_type_for_impl_trait_in_trait, impl_item_implementor_ids, ..*providers @@ -46,8 +44,7 @@ fn associated_item_def_ids(tcx: TyCtxt<'_>, def_id: LocalDefId) -> &[DefId] { ) }) .copied(), - ) - .chain(tcx.associated_type_for_effects(def_id)), + ), ) } hir::ItemKind::Impl(impl_) => { @@ -73,8 +70,7 @@ fn associated_item_def_ids(tcx: TyCtxt<'_>, def_id: LocalDefId) -> &[DefId] { ) }) .copied() - })) - .chain(tcx.associated_type_for_effects(def_id)), + })), ) } _ => span_bug!(item.span, "associated_item_def_ids: not impl or trait"), @@ -171,134 +167,6 @@ fn associated_item_from_impl_item_ref(impl_item_ref: &hir::ImplItemRef) -> ty::A } } -/// Given an `def_id` of a trait or a trait impl: -/// -/// If `def_id` is a trait that has `#[const_trait]`, then it synthesizes -/// a new def id corresponding to a new associated type for the effects. -/// -/// If `def_id` is an impl, then synthesize the associated type according -/// to the constness of the impl. -fn associated_type_for_effects(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option { - // don't synthesize the associated type even if the user has written `const_trait` - // if the effects feature is disabled. - if !tcx.features().effects() { - return None; - } - let (feed, parent_did) = match tcx.def_kind(def_id) { - DefKind::Trait => { - let trait_def_id = def_id; - let attr = tcx.get_attr(def_id, sym::const_trait)?; - - let span = attr.span; - let trait_assoc_ty = tcx.at(span).create_def(trait_def_id, kw::Empty, DefKind::AssocTy); - - let local_def_id = trait_assoc_ty.def_id(); - let def_id = local_def_id.to_def_id(); - - // Copy span of the attribute. - trait_assoc_ty.def_ident_span(Some(span)); - - trait_assoc_ty.associated_item(ty::AssocItem { - name: kw::Empty, - kind: ty::AssocKind::Type, - def_id, - trait_item_def_id: None, - container: ty::TraitContainer, - fn_has_self_parameter: false, - opt_rpitit_info: None, - is_effects_desugaring: true, - }); - - // No default type - trait_assoc_ty.defaultness(hir::Defaultness::Default { has_value: false }); - - trait_assoc_ty.is_type_alias_impl_trait(false); - - (trait_assoc_ty, trait_def_id) - } - DefKind::Impl { .. } => { - let impl_def_id = def_id; - let trait_id = tcx.trait_id_of_impl(def_id.to_def_id())?; - - // first get the DefId of the assoc type on the trait, if there is not, - // then we don't need to generate it on the impl. - let trait_assoc_id = tcx.associated_type_for_effects(trait_id)?; - - // FIXME(effects): span - let span = tcx.def_ident_span(def_id).unwrap(); - - let impl_assoc_ty = tcx.at(span).create_def(def_id, kw::Empty, DefKind::AssocTy); - - let local_def_id = impl_assoc_ty.def_id(); - let def_id = local_def_id.to_def_id(); - - impl_assoc_ty.def_ident_span(Some(span)); - - impl_assoc_ty.associated_item(ty::AssocItem { - name: kw::Empty, - kind: ty::AssocKind::Type, - def_id, - trait_item_def_id: Some(trait_assoc_id), - container: ty::ImplContainer, - fn_has_self_parameter: false, - opt_rpitit_info: None, - is_effects_desugaring: true, - }); - - // no default value. - impl_assoc_ty.defaultness(hir::Defaultness::Final); - - // set the type of the associated type! If this is a const impl, - // we set to Maybe, otherwise we set to `Runtime`. - let type_def_id = if tcx.is_const_trait_impl_raw(impl_def_id.to_def_id()) { - tcx.require_lang_item(hir::LangItem::EffectsMaybe, Some(span)) - } else { - tcx.require_lang_item(hir::LangItem::EffectsRuntime, Some(span)) - }; - // FIXME(effects): make impls use `Min` for their effect types - impl_assoc_ty.type_of(ty::EarlyBinder::bind(Ty::new_adt( - tcx, - tcx.adt_def(type_def_id), - ty::GenericArgs::empty(), - ))); - - (impl_assoc_ty, impl_def_id) - } - def_kind => bug!( - "associated_type_for_effects: {:?} should be Trait or Impl but is {:?}", - def_id, - def_kind - ), - }; - - feed.feed_hir(); - - // visibility is public. - feed.visibility(ty::Visibility::Public); - - // Copy generics_of of the trait/impl, making the trait/impl as parent. - feed.generics_of({ - let parent_generics = tcx.generics_of(parent_did); - let parent_count = parent_generics.parent_count + parent_generics.own_params.len(); - - ty::Generics { - parent: Some(parent_did.to_def_id()), - parent_count, - own_params: vec![], - param_def_id_to_index: parent_generics.param_def_id_to_index.clone(), - has_self: false, - has_late_bound_regions: None, - host_effect_index: parent_generics.host_effect_index, - } - }); - feed.explicit_item_super_predicates(ty::EarlyBinder::bind(&[])); - - // There are no inferred outlives for the synthesized associated type. - feed.inferred_outlives_of(&[]); - - Some(feed.def_id().to_def_id()) -} - /// Given an `fn_def_id` of a trait or a trait implementation: /// /// if `fn_def_id` is a function defined inside a trait, then it synthesizes @@ -494,7 +362,6 @@ fn associated_type_for_impl_trait_in_impl( param_def_id_to_index, has_self: false, has_late_bound_regions: trait_assoc_generics.has_late_bound_regions, - host_effect_index: parent_generics.host_effect_index, } }); diff --git a/compiler/rustc_type_ir/src/canonical.rs b/compiler/rustc_type_ir/src/canonical.rs index 07cb8b037ecf7..3fb7d87bcc4bc 100644 --- a/compiler/rustc_type_ir/src/canonical.rs +++ b/compiler/rustc_type_ir/src/canonical.rs @@ -108,7 +108,6 @@ impl CanonicalVarInfo { CanonicalVarKind::PlaceholderRegion(..) => false, CanonicalVarKind::Const(_) => true, CanonicalVarKind::PlaceholderConst(_) => false, - CanonicalVarKind::Effect => true, } } @@ -118,17 +117,15 @@ impl CanonicalVarInfo { CanonicalVarKind::Ty(_) | CanonicalVarKind::PlaceholderTy(_) | CanonicalVarKind::Const(_) - | CanonicalVarKind::PlaceholderConst(_) - | CanonicalVarKind::Effect => false, + | CanonicalVarKind::PlaceholderConst(_) => false, } } pub fn expect_placeholder_index(self) -> usize { match self.kind { - CanonicalVarKind::Ty(_) - | CanonicalVarKind::Region(_) - | CanonicalVarKind::Const(_) - | CanonicalVarKind::Effect => panic!("expected placeholder: {self:?}"), + CanonicalVarKind::Ty(_) | CanonicalVarKind::Region(_) | CanonicalVarKind::Const(_) => { + panic!("expected placeholder: {self:?}") + } CanonicalVarKind::PlaceholderRegion(placeholder) => placeholder.var().as_usize(), CanonicalVarKind::PlaceholderTy(placeholder) => placeholder.var().as_usize(), @@ -161,9 +158,6 @@ pub enum CanonicalVarKind { /// Some kind of const inference variable. Const(UniverseIndex), - /// Effect variable `'?E`. - Effect, - /// A "placeholder" that represents "any const". PlaceholderConst(I::PlaceholderConst), } @@ -180,7 +174,6 @@ impl CanonicalVarKind { CanonicalVarKind::Ty(CanonicalTyVarKind::Float | CanonicalTyVarKind::Int) => { UniverseIndex::ROOT } - CanonicalVarKind::Effect => UniverseIndex::ROOT, } } @@ -205,8 +198,7 @@ impl CanonicalVarKind { CanonicalVarKind::PlaceholderConst(placeholder) => { CanonicalVarKind::PlaceholderConst(placeholder.with_updated_universe(ui)) } - CanonicalVarKind::Ty(CanonicalTyVarKind::Int | CanonicalTyVarKind::Float) - | CanonicalVarKind::Effect => { + CanonicalVarKind::Ty(CanonicalTyVarKind::Int | CanonicalTyVarKind::Float) => { assert_eq!(ui, UniverseIndex::ROOT); self } @@ -311,10 +303,6 @@ impl CanonicalVarValues { Region::new_anon_bound(cx, ty::INNERMOST, ty::BoundVar::from_usize(i)) .into() } - CanonicalVarKind::Effect => { - Const::new_anon_bound(cx, ty::INNERMOST, ty::BoundVar::from_usize(i)) - .into() - } CanonicalVarKind::Const(_) | CanonicalVarKind::PlaceholderConst(_) => { Const::new_anon_bound(cx, ty::INNERMOST, ty::BoundVar::from_usize(i)) .into() diff --git a/compiler/rustc_type_ir/src/const_kind.rs b/compiler/rustc_type_ir/src/const_kind.rs index 7a8c612057fa2..03dfe547cedd4 100644 --- a/compiler/rustc_type_ir/src/const_kind.rs +++ b/compiler/rustc_type_ir/src/const_kind.rs @@ -84,32 +84,12 @@ rustc_index::newtype_index! { pub struct ConstVid {} } -rustc_index::newtype_index! { - /// An **effect** **v**ariable **ID**. - /// - /// Handling effect infer variables happens separately from const infer variables - /// because we do not want to reuse any of the const infer machinery. If we try to - /// relate an effect variable with a normal one, we would ICE, which can catch bugs - /// where we are not correctly using the effect var for an effect param. Fallback - /// is also implemented on top of having separate effect and normal const variables. - #[encodable] - #[orderable] - #[debug_format = "?{}e"] - #[gate_rustc_only] - pub struct EffectVid {} -} - /// An inference variable for a const, for use in const generics. #[derive(Copy, Clone, Eq, PartialEq, PartialOrd, Ord, Hash)] #[cfg_attr(feature = "nightly", derive(TyEncodable, TyDecodable))] pub enum InferConst { /// Infer the value of the const. Var(ConstVid), - /// Infer the value of the effect. - /// - /// For why this is separate from the `Var` variant above, see the - /// documentation on `EffectVid`. - EffectVar(EffectVid), /// A fresh const variable. See `infer::freshen` for more details. Fresh(u32), } @@ -118,7 +98,6 @@ impl fmt::Debug for InferConst { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { InferConst::Var(var) => write!(f, "{var:?}"), - InferConst::EffectVar(var) => write!(f, "{var:?}"), InferConst::Fresh(var) => write!(f, "Fresh({var:?})"), } } @@ -128,7 +107,7 @@ impl fmt::Debug for InferConst { impl HashStable for InferConst { fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) { match self { - InferConst::Var(_) | InferConst::EffectVar(_) => { + InferConst::Var(_) => { panic!("const variables should not be hashed: {self:?}") } InferConst::Fresh(i) => i.hash_stable(hcx, hasher), diff --git a/compiler/rustc_type_ir/src/effects.rs b/compiler/rustc_type_ir/src/effects.rs deleted file mode 100644 index ab43533dd8692..0000000000000 --- a/compiler/rustc_type_ir/src/effects.rs +++ /dev/null @@ -1,59 +0,0 @@ -use crate::Interner; -use crate::inherent::*; -use crate::lang_items::TraitSolverLangItem::{EffectsMaybe, EffectsNoRuntime, EffectsRuntime}; - -#[derive(Clone, Copy, PartialEq, Eq)] -pub enum EffectKind { - Maybe, - Runtime, - NoRuntime, -} - -impl EffectKind { - pub fn try_from_def_id(cx: I, def_id: I::DefId) -> Option { - if cx.is_lang_item(def_id, EffectsMaybe) { - Some(EffectKind::Maybe) - } else if cx.is_lang_item(def_id, EffectsRuntime) { - Some(EffectKind::Runtime) - } else if cx.is_lang_item(def_id, EffectsNoRuntime) { - Some(EffectKind::NoRuntime) - } else { - None - } - } - - pub fn to_def_id(self, cx: I) -> I::DefId { - let lang_item = match self { - EffectKind::Maybe => EffectsMaybe, - EffectKind::NoRuntime => EffectsNoRuntime, - EffectKind::Runtime => EffectsRuntime, - }; - - cx.require_lang_item(lang_item) - } - - pub fn try_from_ty(cx: I, ty: I::Ty) -> Option { - if let crate::Adt(def, _) = ty.kind() { - Self::try_from_def_id(cx, def.def_id()) - } else { - None - } - } - - pub fn to_ty(self, cx: I) -> I::Ty { - I::Ty::new_adt(cx, cx.adt_def(self.to_def_id(cx)), Default::default()) - } - - /// Returns an intersection between two effect kinds. If one effect kind - /// is more permissive than the other (e.g. `Maybe` vs `Runtime`), this - /// returns the less permissive effect kind (`Runtime`). - pub fn intersection(a: Self, b: Self) -> Option { - use EffectKind::*; - match (a, b) { - (Maybe, x) | (x, Maybe) => Some(x), - (Runtime, Runtime) => Some(Runtime), - (NoRuntime, NoRuntime) => Some(NoRuntime), - (Runtime, NoRuntime) | (NoRuntime, Runtime) => None, - } - } -} diff --git a/compiler/rustc_type_ir/src/elaborate.rs b/compiler/rustc_type_ir/src/elaborate.rs index dac45ff2aba3f..56a72f943ab4e 100644 --- a/compiler/rustc_type_ir/src/elaborate.rs +++ b/compiler/rustc_type_ir/src/elaborate.rs @@ -4,7 +4,6 @@ use smallvec::smallvec; use crate::data_structures::HashSet; use crate::inherent::*; -use crate::lang_items::TraitSolverLangItem; use crate::outlives::{Component, push_outlives_components}; use crate::{self as ty, Interner, Upcast as _}; @@ -130,70 +129,6 @@ impl> Elaborator { return; } - // HACK(effects): The following code is required to get implied bounds for effects associated - // types to work with super traits. - // - // Suppose `data` is a trait predicate with the form `::Fx: EffectsCompat` - // and we know that `trait Tr: ~const SuperTr`, we need to elaborate this predicate into - // `::Fx: EffectsCompat`. - // - // Since the semantics for elaborating bounds about effects is equivalent to elaborating - // bounds about super traits (elaborate `T: Tr` into `T: SuperTr`), we place effects elaboration - // next to super trait elaboration. - if cx.is_lang_item(data.def_id(), TraitSolverLangItem::EffectsCompat) - && matches!(self.mode, Filter::All) - { - // first, ensure that the predicate we've got looks like a `::Fx: EffectsCompat`. - if let ty::Alias(ty::AliasTyKind::Projection, alias_ty) = data.self_ty().kind() - { - // look for effects-level bounds that look like `::Fx: TyCompat<::Fx>` - // on the trait, which is proof to us that `Tr: ~const SuperTr`. We're looking for bounds on the - // associated trait, so we use `explicit_implied_predicates_of` since it gives us more than just - // `Self: SuperTr` bounds. - let bounds = cx.explicit_implied_predicates_of(cx.parent(alias_ty.def_id)); - - // instantiate the implied bounds, so we get `::Fx` and not `::Fx`. - let elaborated = bounds.iter_instantiated(cx, alias_ty.args).filter_map( - |(clause, _)| { - let ty::ClauseKind::Trait(tycompat_bound) = - clause.kind().skip_binder() - else { - return None; - }; - if !cx.is_lang_item( - tycompat_bound.def_id(), - TraitSolverLangItem::EffectsTyCompat, - ) { - return None; - } - - // extract `::Fx` from the `TyCompat` bound. - let supertrait_effects_ty = - tycompat_bound.trait_ref.args.type_at(1); - let ty::Alias(ty::AliasTyKind::Projection, supertrait_alias_ty) = - supertrait_effects_ty.kind() - else { - return None; - }; - - // The self types (`T`) must be equal for `::Fx` and `::Fx`. - if supertrait_alias_ty.self_ty() != alias_ty.self_ty() { - return None; - }; - - // replace the self type in the original bound `::Fx: EffectsCompat` - // to the effects type of the super trait. (`::Fx`) - let elaborated_bound = data.with_self_ty(cx, supertrait_effects_ty); - Some( - elaboratable - .child(bound_clause.rebind(elaborated_bound).upcast(cx)), - ) - }, - ); - self.extend_deduped(elaborated); - } - } - let map_to_child_clause = |(index, (clause, span)): (usize, (I::Clause, I::Span))| { elaboratable.child_with_derived_cause( diff --git a/compiler/rustc_type_ir/src/infer_ctxt.rs b/compiler/rustc_type_ir/src/infer_ctxt.rs index b9f5cde653eaa..7c6a3c65ebfb4 100644 --- a/compiler/rustc_type_ir/src/infer_ctxt.rs +++ b/compiler/rustc_type_ir/src/infer_ctxt.rs @@ -38,10 +38,6 @@ pub trait InferCtxtLike: Sized { &self, vid: ty::ConstVid, ) -> ::Const; - fn opportunistic_resolve_effect_var( - &self, - vid: ty::EffectVid, - ) -> ::Const; fn opportunistic_resolve_lt_var( &self, vid: ty::RegionVid, @@ -71,7 +67,6 @@ pub trait InferCtxtLike: Sized { fn equate_int_vids_raw(&self, a: ty::IntVid, b: ty::IntVid); fn equate_float_vids_raw(&self, a: ty::FloatVid, b: ty::FloatVid); fn equate_const_vids_raw(&self, a: ty::ConstVid, b: ty::ConstVid); - fn equate_effect_vids_raw(&self, a: ty::EffectVid, b: ty::EffectVid); fn instantiate_ty_var_raw>( &self, @@ -83,11 +78,6 @@ pub trait InferCtxtLike: Sized { ) -> RelateResult; fn instantiate_int_var_raw(&self, vid: ty::IntVid, value: ty::IntVarValue); fn instantiate_float_var_raw(&self, vid: ty::FloatVid, value: ty::FloatVarValue); - fn instantiate_effect_var_raw( - &self, - vid: ty::EffectVid, - value: ::Const, - ); fn instantiate_const_var_raw>( &self, relation: &mut R, diff --git a/compiler/rustc_type_ir/src/lang_items.rs b/compiler/rustc_type_ir/src/lang_items.rs index c680c8447460d..d6ca22a90a4db 100644 --- a/compiler/rustc_type_ir/src/lang_items.rs +++ b/compiler/rustc_type_ir/src/lang_items.rs @@ -20,13 +20,6 @@ pub enum TraitSolverLangItem { Destruct, DiscriminantKind, DynMetadata, - EffectsCompat, - EffectsIntersection, - EffectsIntersectionOutput, - EffectsMaybe, - EffectsNoRuntime, - EffectsRuntime, - EffectsTyCompat, Fn, FnMut, FnOnce, diff --git a/compiler/rustc_type_ir/src/lib.rs b/compiler/rustc_type_ir/src/lib.rs index 9e6d1f424ba49..e7ca24178cbf7 100644 --- a/compiler/rustc_type_ir/src/lib.rs +++ b/compiler/rustc_type_ir/src/lib.rs @@ -43,7 +43,6 @@ mod macros; mod binder; mod canonical; mod const_kind; -mod effects; mod flags; mod generic_arg; mod infer_ctxt; @@ -67,7 +66,6 @@ pub use canonical::*; #[cfg(feature = "nightly")] pub use codec::*; pub use const_kind::*; -pub use effects::*; pub use flags::*; pub use generic_arg::*; pub use infer_ctxt::*; diff --git a/compiler/rustc_type_ir/src/relate/combine.rs b/compiler/rustc_type_ir/src/relate/combine.rs index 60a953801a479..17a3912730f57 100644 --- a/compiler/rustc_type_ir/src/relate/combine.rs +++ b/compiler/rustc_type_ir/src/relate/combine.rs @@ -179,23 +179,9 @@ where Ok(a) } - ( - ty::ConstKind::Infer(ty::InferConst::EffectVar(a_vid)), - ty::ConstKind::Infer(ty::InferConst::EffectVar(b_vid)), - ) => { - infcx.equate_effect_vids_raw(a_vid, b_vid); - Ok(a) - } - // All other cases of inference with other variables are errors. - ( - ty::ConstKind::Infer(ty::InferConst::Var(_) | ty::InferConst::EffectVar(_)), - ty::ConstKind::Infer(_), - ) - | ( - ty::ConstKind::Infer(_), - ty::ConstKind::Infer(ty::InferConst::Var(_) | ty::InferConst::EffectVar(_)), - ) => { + (ty::ConstKind::Infer(ty::InferConst::Var(_)), ty::ConstKind::Infer(_)) + | (ty::ConstKind::Infer(_), ty::ConstKind::Infer(ty::InferConst::Var(_))) => { panic!( "tried to combine ConstKind::Infer/ConstKind::Infer(InferConst::Var): {a:?} and {b:?}" ) @@ -211,16 +197,6 @@ where Ok(a) } - (ty::ConstKind::Infer(ty::InferConst::EffectVar(vid)), _) => { - infcx.instantiate_effect_var_raw(vid, b); - Ok(b) - } - - (_, ty::ConstKind::Infer(ty::InferConst::EffectVar(vid))) => { - infcx.instantiate_effect_var_raw(vid, a); - Ok(a) - } - (ty::ConstKind::Unevaluated(..), _) | (_, ty::ConstKind::Unevaluated(..)) if infcx.cx().features().generic_const_exprs() || infcx.next_trait_solver() => { diff --git a/compiler/stable_mir/src/ty.rs b/compiler/stable_mir/src/ty.rs index 9e6fbc8ea0c14..8db1258b65f74 100644 --- a/compiler/stable_mir/src/ty.rs +++ b/compiler/stable_mir/src/ty.rs @@ -1393,7 +1393,6 @@ pub struct Generics { pub param_def_id_to_index: Vec<(GenericDef, u32)>, pub has_self: bool, pub has_late_bound_regions: Option, - pub host_effect_index: Option, } #[derive(Clone, Debug, Eq, PartialEq, Serialize)] diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs index aed6be4c6277b..1237fc82a171b 100644 --- a/library/core/src/marker.rs +++ b/library/core/src/marker.rs @@ -1069,47 +1069,3 @@ pub trait FnPtr: Copy + Clone { pub macro SmartPointer($item:item) { /* compiler built-in */ } - -// Support traits and types for the desugaring of const traits and -// `~const` bounds. Not supposed to be used by anything other than -// the compiler. -#[doc(hidden)] -#[unstable( - feature = "effect_types", - issue = "none", - reason = "internal module for implementing effects" -)] -#[allow(missing_debug_implementations)] // these unit structs don't need `Debug` impls. -pub mod effects { - #[lang = "EffectsNoRuntime"] - pub struct NoRuntime; - #[lang = "EffectsMaybe"] - pub struct Maybe; - #[lang = "EffectsRuntime"] - pub struct Runtime; - - #[lang = "EffectsCompat"] - pub trait Compat<#[rustc_runtime] const RUNTIME: bool> {} - - impl Compat for NoRuntime {} - impl Compat for Runtime {} - impl<#[rustc_runtime] const RUNTIME: bool> Compat for Maybe {} - - #[lang = "EffectsTyCompat"] - #[marker] - pub trait TyCompat {} - - impl TyCompat for T {} - impl TyCompat for T {} - - #[lang = "EffectsIntersection"] - pub trait Intersection { - #[lang = "EffectsIntersectionOutput"] - type Output: ?Sized; - } - - // FIXME(effects): remove this after next trait solver lands - impl Intersection for () { - type Output = Maybe; - } -} diff --git a/src/librustdoc/clean/auto_trait.rs b/src/librustdoc/clean/auto_trait.rs index d966f9931045d..31e4e79c00a76 100644 --- a/src/librustdoc/clean/auto_trait.rs +++ b/src/librustdoc/clean/auto_trait.rs @@ -156,7 +156,7 @@ fn clean_param_env<'tcx>( .iter() .inspect(|param| { if cfg!(debug_assertions) { - debug_assert!(!param.is_anonymous_lifetime() && !param.is_host_effect()); + debug_assert!(!param.is_anonymous_lifetime()); if let ty::GenericParamDefKind::Type { synthetic, .. } = param.kind { debug_assert!(!synthetic && param.name != kw::SelfUpper); } diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index bf168809e28c4..861ca70cd83dd 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -542,7 +542,7 @@ fn clean_generic_param_def( synthetic, }) } - ty::GenericParamDefKind::Const { has_default, synthetic, is_host_effect: _ } => { + ty::GenericParamDefKind::Const { has_default, synthetic } => { (def.name, GenericParamDefKind::Const { ty: Box::new(clean_middle_ty( ty::Binder::dummy( @@ -617,7 +617,7 @@ fn clean_generic_param<'tcx>( synthetic, }) } - hir::GenericParamKind::Const { ty, default, synthetic, is_host_effect: _ } => { + hir::GenericParamKind::Const { ty, default, synthetic } => { (param.name.ident().name, GenericParamDefKind::Const { ty: Box::new(clean_ty(ty, cx)), default: default.map(|ct| { @@ -797,7 +797,7 @@ fn clean_ty_generics<'tcx>( } true } - ty::GenericParamDefKind::Const { is_host_effect, .. } => !is_host_effect, + ty::GenericParamDefKind::Const { .. } => true, }) .map(|param| clean_generic_param_def(param, ParamDefaults::Yes, cx)) .collect(); diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 6090de16d55bc..c8cb9267eb26b 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -1366,8 +1366,7 @@ impl GenericParamDef { pub(crate) fn is_synthetic_param(&self) -> bool { match self.kind { - GenericParamDefKind::Lifetime { .. } => false, - GenericParamDefKind::Const { synthetic: is_host_effect, .. } => is_host_effect, + GenericParamDefKind::Lifetime { .. } | GenericParamDefKind::Const { .. } => false, GenericParamDefKind::Type { synthetic, .. } => synthetic, } } diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs index fdf628b50fbe4..d3a545fe0b61f 100644 --- a/src/librustdoc/clean/utils.rs +++ b/src/librustdoc/clean/utils.rs @@ -114,10 +114,6 @@ pub(crate) fn clean_middle_generic_args<'tcx>( // Elide internal host effect args. let param = generics.param_at(index, cx.tcx); - if param.is_host_effect() { - return None; - } - let arg = ty::Binder::bind_with_vars(arg, bound_vars); // Elide arguments that coincide with their default. diff --git a/src/tools/clippy/clippy_utils/src/ty/type_certainty/mod.rs b/src/tools/clippy/clippy_utils/src/ty/type_certainty/mod.rs index 91ec120adbf6f..3021f21df1210 100644 --- a/src/tools/clippy/clippy_utils/src/ty/type_certainty/mod.rs +++ b/src/tools/clippy/clippy_utils/src/ty/type_certainty/mod.rs @@ -207,16 +207,7 @@ fn path_segment_certainty( if cx.tcx.res_generics_def_id(path_segment.res).is_some() { let generics = cx.tcx.generics_of(def_id); - let own_count = generics.own_params.len() - - usize::from(generics.host_effect_index.is_some_and(|index| { - // Check that the host index actually belongs to this resolution. - // E.g. for `Add::add`, host_effect_index is `Some(2)`, but it's part of the parent `Add` - // trait's generics. - // Add params: [Self#0, Rhs#1, host#2] parent_count=0, count=3 - // Add::add params: [] parent_count=3, count=3 - // (3..3).contains(&host_effect_index) => false - (generics.parent_count..generics.count()).contains(&index) - })); + let own_count = generics.own_params.len(); let lhs = if (parent_certainty.is_certain() || generics.parent_count == 0) && own_count == 0 { Certainty::Certain(None) } else { @@ -310,8 +301,7 @@ fn type_is_inferable_from_arguments(cx: &LateContext<'_>, expr: &Expr<'_>) -> bo // Check that all type parameters appear in the functions input types. (0..(generics.parent_count + generics.own_params.len()) as u32).all(|index| { - Some(index as usize) == generics.host_effect_index - || fn_sig + fn_sig .inputs() .iter() .any(|input_ty| contains_param(*input_ty.skip_binder(), index)) diff --git a/tests/ui/traits/const-traits/const-fns-are-early-bound.rs b/tests/ui/traits/const-traits/const-fns-are-early-bound.rs index b87387f4d5de3..59a61e4f954de 100644 --- a/tests/ui/traits/const-traits/const-fns-are-early-bound.rs +++ b/tests/ui/traits/const-traits/const-fns-are-early-bound.rs @@ -86,51 +86,3 @@ trait Tuple {} trait LegacyReceiver {} impl LegacyReceiver for &T {} - -impl LegacyReceiver for &mut T {} - -#[stable(feature = "minicore", since = "1.0.0")] -pub mod effects { - use super::Sized; - - #[lang = "EffectsNoRuntime"] - #[stable(feature = "minicore", since = "1.0.0")] - pub struct NoRuntime; - #[lang = "EffectsMaybe"] - #[stable(feature = "minicore", since = "1.0.0")] - pub struct Maybe; - #[lang = "EffectsRuntime"] - #[stable(feature = "minicore", since = "1.0.0")] - pub struct Runtime; - - #[lang = "EffectsCompat"] - #[stable(feature = "minicore", since = "1.0.0")] - pub trait Compat<#[rustc_runtime] const RUNTIME: bool> {} - - #[stable(feature = "minicore", since = "1.0.0")] - impl Compat for NoRuntime {} - #[stable(feature = "minicore", since = "1.0.0")] - impl Compat for Runtime {} - #[stable(feature = "minicore", since = "1.0.0")] - impl<#[rustc_runtime] const RUNTIME: bool> Compat for Maybe {} - - #[lang = "EffectsTyCompat"] - #[marker] - #[stable(feature = "minicore", since = "1.0.0")] - pub trait TyCompat {} - - #[stable(feature = "minicore", since = "1.0.0")] - impl TyCompat for T {} - #[stable(feature = "minicore", since = "1.0.0")] - impl TyCompat for Maybe {} - #[stable(feature = "minicore", since = "1.0.0")] - impl TyCompat for T {} - - #[lang = "EffectsIntersection"] - #[stable(feature = "minicore", since = "1.0.0")] - pub trait Intersection { - #[lang = "EffectsIntersectionOutput"] - #[stable(feature = "minicore", since = "1.0.0")] - type Output: ?Sized; - } -} diff --git a/tests/ui/traits/const-traits/effects/minicore.rs b/tests/ui/traits/const-traits/effects/minicore.rs index 9b615450c68fe..a756f4d9f6c56 100644 --- a/tests/ui/traits/const-traits/effects/minicore.rs +++ b/tests/ui/traits/const-traits/effects/minicore.rs @@ -536,35 +536,3 @@ fn test_const_eval_select() { const_eval_select((), const_fn, rt_fn); } - -mod effects { - use super::Sized; - - #[lang = "EffectsNoRuntime"] - pub struct NoRuntime; - #[lang = "EffectsMaybe"] - pub struct Maybe; - #[lang = "EffectsRuntime"] - pub struct Runtime; - - #[lang = "EffectsCompat"] - pub trait Compat<#[rustc_runtime] const RUNTIME: bool> {} - - impl Compat for NoRuntime {} - impl Compat for Runtime {} - impl<#[rustc_runtime] const RUNTIME: bool> Compat for Maybe {} - - #[lang = "EffectsTyCompat"] - #[marker] - pub trait TyCompat {} - - impl TyCompat for T {} - impl TyCompat for Maybe {} - impl TyCompat for T {} - - #[lang = "EffectsIntersection"] - pub trait Intersection { - #[lang = "EffectsIntersectionOutput"] - type Output: ?Sized; - } -} From cde29b9ec9c49dfdebe06f7e97df4a322f27bd6a Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sun, 20 Oct 2024 19:49:11 +0000 Subject: [PATCH 2/5] Implement const effect predicate in new solver --- compiler/rustc_hir_analysis/src/bounds.rs | 11 + .../src/check/compare_impl_item.rs | 110 ++++++- .../rustc_hir_analysis/src/check/wfcheck.rs | 37 ++- compiler/rustc_hir_analysis/src/collect.rs | 2 + .../src/collect/item_bounds.rs | 36 ++- .../src/collect/predicates_of.rs | 239 +++++++++++++- .../src/hir_ty_lowering/bounds.rs | 42 ++- .../src/hir_ty_lowering/dyn_compatibility.rs | 3 +- .../src/hir_ty_lowering/mod.rs | 51 ++- .../src/impl_wf_check/min_specialization.rs | 3 +- .../src/outlives/explicit.rs | 3 +- compiler/rustc_hir_typeck/src/callee.rs | 47 ++- .../src/fn_ctxt/inspect_obligations.rs | 1 + compiler/rustc_hir_typeck/src/method/probe.rs | 3 +- .../rustc_infer/src/infer/outlives/mod.rs | 14 +- compiler/rustc_lint/src/builtin.rs | 4 +- .../src/rmeta/decoder/cstore_impl.rs | 2 + compiler/rustc_metadata/src/rmeta/encoder.rs | 8 +- compiler/rustc_metadata/src/rmeta/mod.rs | 2 + compiler/rustc_middle/src/query/erase.rs | 1 + compiler/rustc_middle/src/query/mod.rs | 18 ++ compiler/rustc_middle/src/ty/codec.rs | 11 + compiler/rustc_middle/src/ty/context.rs | 32 +- compiler/rustc_middle/src/ty/flags.rs | 6 + compiler/rustc_middle/src/ty/generics.rs | 70 +++++ compiler/rustc_middle/src/ty/mod.rs | 13 +- compiler/rustc_middle/src/ty/parameterized.rs | 1 + compiler/rustc_middle/src/ty/predicate.rs | 4 + compiler/rustc_middle/src/ty/print/pretty.rs | 10 + .../src/solve/effect_goals.rs | 296 ++++++++++++++++++ .../src/solve/eval_ctxt/mod.rs | 3 + .../rustc_next_trait_solver/src/solve/mod.rs | 1 + compiler/rustc_privacy/src/lib.rs | 4 + .../rustc_smir/src/rustc_smir/convert/ty.rs | 3 + .../traits/fulfillment_errors.rs | 44 +-- .../src/traits/auto_trait.rs | 3 +- .../src/traits/dyn_compatibility.rs | 4 +- .../src/traits/fulfill.rs | 10 +- .../query/type_op/implied_outlives_bounds.rs | 2 + .../src/traits/select/mod.rs | 7 + .../rustc_trait_selection/src/traits/wf.rs | 5 + .../src/normalize_erasing_regions.rs | 1 + compiler/rustc_ty_utils/src/ty.rs | 9 + compiler/rustc_type_ir/src/elaborate.rs | 10 + compiler/rustc_type_ir/src/inherent.rs | 8 + compiler/rustc_type_ir/src/interner.rs | 11 + compiler/rustc_type_ir/src/ir_print.rs | 5 +- compiler/rustc_type_ir/src/predicate.rs | 65 ++++ compiler/rustc_type_ir/src/predicate_kind.rs | 7 + src/librustdoc/clean/mod.rs | 4 +- tests/crashes/118320.rs | 14 - tests/crashes/119924-6.rs | 15 - .../const-generics/issues/issue-88119.stderr | 18 -- .../ui/consts/const-block-const-bound.stderr | 10 +- ...constifconst-call-in-const-position.stderr | 20 +- tests/ui/consts/fn_trait_refs.stderr | 74 ++++- .../unstable-const-fn-in-libcore.stderr | 10 +- tests/ui/delegation/ice-issue-124347.rs | 2 +- tests/ui/delegation/ice-issue-124347.stderr | 12 +- tests/ui/delegation/unsupported.rs | 2 +- tests/ui/delegation/unsupported.stderr | 12 +- .../impl-trait/normalize-tait-in-const.stderr | 18 +- .../ui/specialization/const_trait_impl.stderr | 62 +--- .../assoc-type-const-bound-usage-0.stderr | 41 +-- .../assoc-type-const-bound-usage-1.stderr | 41 +-- .../call-const-trait-method-fail.stderr | 15 +- .../call-const-trait-method-pass.stderr | 14 +- .../const-traits/call-generic-in-impl.stderr | 16 +- .../call-generic-method-chain.stderr | 18 +- .../call-generic-method-dup-bound.stderr | 18 +- .../call-generic-method-nonconst.stderr | 16 +- .../call-generic-method-pass.stderr | 10 +- .../const-bounds-non-const-trait.rs | 1 + .../const-bounds-non-const-trait.stderr | 12 +- .../const-closure-trait-method-fail.stderr | 18 +- .../const-closure-trait-method.stderr | 18 +- .../traits/const-traits/const-closures.stderr | 34 +- .../const-default-method-bodies.stderr | 17 +- .../const-traits/const-drop-bound.stderr | 26 +- .../const-traits/const-drop-fail-2.stderr | 10 +- .../const-drop-fail.precise.stderr | 10 +- .../const-traits/const-drop-fail.stock.stderr | 10 +- .../const-traits/const-drop.precise.stderr | 24 +- .../const-traits/const-drop.stock.stderr | 24 +- .../const-traits/const-fns-are-early-bound.rs | 2 + .../const-fns-are-early-bound.stderr | 20 -- .../const-traits/const-impl-trait.stderr | 249 --------------- .../derive-const-with-params.stderr | 11 +- .../const-traits/cross-crate.gatednc.stderr | 17 +- ...-method-body-is-const-same-trait-ck.stderr | 17 +- .../const-traits/effects/minicore.stderr | 8 +- ...o-explicit-const-params-cross-crate.stderr | 16 +- .../effects/no-explicit-const-params.rs | 1 - .../effects/no-explicit-const-params.stderr | 30 +- .../effects/spec-effectvar-ice.rs | 3 +- .../effects/spec-effectvar-ice.stderr | 30 +- .../ice-123664-unexpected-bound-var.rs | 1 + .../ice-123664-unexpected-bound-var.stderr | 10 +- .../ui/traits/const-traits/issue-92111.stderr | 10 +- .../non-const-op-in-closure-in-const.stderr | 16 +- ...t-bound-non-const-specialized-bound.stderr | 32 +- .../const-default-const-specialized.stderr | 25 +- .../specialization/default-keyword.rs | 3 +- .../specialization/default-keyword.stderr | 12 - .../issue-95186-specialize-on-tilde-const.rs | 3 +- ...sue-95186-specialize-on-tilde-const.stderr | 43 --- ...87-same-trait-bound-different-constness.rs | 3 +- ...ame-trait-bound-different-constness.stderr | 43 --- ...non-const-default-const-specialized.stderr | 25 +- .../specializing-constness-2.stderr | 25 +- .../const-traits/specializing-constness.rs | 2 - .../specializing-constness.stderr | 14 +- .../super-traits-fail-2.ny.stderr | 18 +- .../const-traits/super-traits-fail-2.rs | 4 +- .../super-traits-fail-2.yn.stderr | 17 +- .../super-traits-fail-2.yy.stderr | 17 +- .../super-traits-fail-3.nn.stderr | 12 +- .../super-traits-fail-3.ny.stderr | 18 +- .../const-traits/super-traits-fail-3.rs | 5 +- .../super-traits-fail-3.yn.stderr | 29 +- .../traits/const-traits/super-traits-fail.rs | 1 - .../const-traits/super-traits-fail.stderr | 23 +- .../tilde-const-and-const-params.rs | 2 - .../tilde-const-and-const-params.stderr | 25 +- .../const-traits/trait-where-clause-const.rs | 6 +- .../trait-where-clause-const.stderr | 51 +-- .../unsatisfied-const-trait-bound.stderr | 25 +- 127 files changed, 1702 insertions(+), 1170 deletions(-) create mode 100644 compiler/rustc_next_trait_solver/src/solve/effect_goals.rs delete mode 100644 tests/crashes/118320.rs delete mode 100644 tests/crashes/119924-6.rs delete mode 100644 tests/ui/traits/const-traits/const-fns-are-early-bound.stderr delete mode 100644 tests/ui/traits/const-traits/const-impl-trait.stderr delete mode 100644 tests/ui/traits/const-traits/specialization/default-keyword.stderr delete mode 100644 tests/ui/traits/const-traits/specialization/issue-95186-specialize-on-tilde-const.stderr delete mode 100644 tests/ui/traits/const-traits/specialization/issue-95187-same-trait-bound-different-constness.stderr diff --git a/compiler/rustc_hir_analysis/src/bounds.rs b/compiler/rustc_hir_analysis/src/bounds.rs index d0c45a7c04c73..7a919bb250059 100644 --- a/compiler/rustc_hir_analysis/src/bounds.rs +++ b/compiler/rustc_hir_analysis/src/bounds.rs @@ -81,6 +81,17 @@ impl<'tcx> Bounds<'tcx> { self.clauses.insert(0, (trait_ref.upcast(tcx), span)); } + /// Push a `const` or `~const` bound as a `HostEffect` predicate. + pub(crate) fn push_const_bound( + &mut self, + tcx: TyCtxt<'tcx>, + bound_trait_ref: ty::PolyTraitRef<'tcx>, + host: ty::HostPolarity, + span: Span, + ) { + self.clauses.push((bound_trait_ref.to_host_effect_clause(tcx, host), span)); + } + pub(crate) fn clauses( &self, // FIXME(effects): remove tcx diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs index 7a56b3784f8b3..439e6d7842839 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs @@ -181,6 +181,7 @@ fn compare_method_predicate_entailment<'tcx>( }); // Create mapping from trait method to impl method. + let impl_def_id = impl_m.container_id(tcx); let trait_to_impl_args = GenericArgs::identity_for_item(tcx, impl_m.def_id).rebase_onto( tcx, impl_m.container_id(tcx), @@ -204,6 +205,24 @@ fn compare_method_predicate_entailment<'tcx>( trait_m_predicates.instantiate_own(tcx, trait_to_impl_args).map(|(predicate, _)| predicate), ); + // FIXME(effects): This should be replaced with a more dedicated method. + let check_const_if_const = tcx.constness(impl_def_id) == hir::Constness::Const; + if check_const_if_const { + // Augment the hybrid param-env with the const conditions + // of the impl header and the trait method. + hybrid_preds.extend( + tcx.const_conditions(impl_def_id) + .instantiate_identity(tcx) + .into_iter() + .chain( + tcx.const_conditions(trait_m.def_id).instantiate_own(tcx, trait_to_impl_args), + ) + .map(|(trait_ref, _)| { + trait_ref.to_host_effect_clause(tcx, ty::HostPolarity::Maybe) + }), + ); + } + let normalize_cause = traits::ObligationCause::misc(impl_m_span, impl_m_def_id); let param_env = ty::ParamEnv::new(tcx.mk_clauses(&hybrid_preds), Reveal::UserFacing); let param_env = traits::normalize_param_env_or_error(tcx, param_env, normalize_cause); @@ -230,6 +249,34 @@ fn compare_method_predicate_entailment<'tcx>( ocx.register_obligation(traits::Obligation::new(tcx, cause, param_env, predicate)); } + // If we're within a const implementation, we need to make sure that the method + // does not assume stronger `~const` bounds than the trait definition. + // + // This registers the `~const` bounds of the impl method, which we will prove + // using the hybrid param-env that we earlier augmented with the const conditions + // from the impl header and trait method declaration. + if check_const_if_const { + for (const_condition, span) in + tcx.const_conditions(impl_m.def_id).instantiate_own_identity() + { + let normalize_cause = traits::ObligationCause::misc(span, impl_m_def_id); + let const_condition = ocx.normalize(&normalize_cause, param_env, const_condition); + + let cause = + ObligationCause::new(span, impl_m_def_id, ObligationCauseCode::CompareImplItem { + impl_item_def_id: impl_m_def_id, + trait_item_def_id: trait_m.def_id, + kind: impl_m.kind, + }); + ocx.register_obligation(traits::Obligation::new( + tcx, + cause, + param_env, + const_condition.to_host_effect_clause(tcx, ty::HostPolarity::Maybe), + )); + } + } + // We now need to check that the signature of the impl method is // compatible with that of the trait method. We do this by // checking that `impl_fty <: trait_fty`. @@ -1846,9 +1893,10 @@ fn compare_type_predicate_entailment<'tcx>( trait_ty: ty::AssocItem, impl_trait_ref: ty::TraitRef<'tcx>, ) -> Result<(), ErrorGuaranteed> { + let impl_def_id = impl_ty.container_id(tcx); let trait_to_impl_args = GenericArgs::identity_for_item(tcx, impl_ty.def_id).rebase_onto( tcx, - impl_ty.container_id(tcx), + impl_def_id, impl_trait_ref.args, ); @@ -1856,7 +1904,9 @@ fn compare_type_predicate_entailment<'tcx>( let trait_ty_predicates = tcx.predicates_of(trait_ty.def_id); let impl_ty_own_bounds = impl_ty_predicates.instantiate_own_identity(); - if impl_ty_own_bounds.len() == 0 { + let impl_ty_own_const_conditions = + tcx.const_conditions(impl_ty.def_id).instantiate_own_identity(); + if impl_ty_own_bounds.len() == 0 && impl_ty_own_const_conditions.len() == 0 { // Nothing to check. return Ok(()); } @@ -1881,6 +1931,23 @@ fn compare_type_predicate_entailment<'tcx>( let impl_ty_span = tcx.def_span(impl_ty_def_id); let normalize_cause = ObligationCause::misc(impl_ty_span, impl_ty_def_id); + let check_const_if_const = tcx.constness(impl_def_id) == hir::Constness::Const; + if check_const_if_const { + // Augment the hybrid param-env with the const conditions + // of the impl header and the trait assoc type. + hybrid_preds.extend( + tcx.const_conditions(impl_ty_predicates.parent.unwrap()) + .instantiate_identity(tcx) + .into_iter() + .chain( + tcx.const_conditions(trait_ty.def_id).instantiate_own(tcx, trait_to_impl_args), + ) + .map(|(trait_ref, _)| { + trait_ref.to_host_effect_clause(tcx, ty::HostPolarity::Maybe) + }), + ); + } + let param_env = ty::ParamEnv::new(tcx.mk_clauses(&hybrid_preds), Reveal::UserFacing); let param_env = traits::normalize_param_env_or_error(tcx, param_env, normalize_cause); debug!(caller_bounds=?param_env.caller_bounds()); @@ -1901,6 +1968,27 @@ fn compare_type_predicate_entailment<'tcx>( ocx.register_obligation(traits::Obligation::new(tcx, cause, param_env, predicate)); } + if check_const_if_const { + // Validate the const conditions of the impl associated type. + for (const_condition, span) in impl_ty_own_const_conditions { + let normalize_cause = traits::ObligationCause::misc(span, impl_ty_def_id); + let const_condition = ocx.normalize(&normalize_cause, param_env, const_condition); + + let cause = + ObligationCause::new(span, impl_ty_def_id, ObligationCauseCode::CompareImplItem { + impl_item_def_id: impl_ty_def_id, + trait_item_def_id: trait_ty.def_id, + kind: impl_ty.kind, + }); + ocx.register_obligation(traits::Obligation::new( + tcx, + cause, + param_env, + const_condition.to_host_effect_clause(tcx, ty::HostPolarity::Maybe), + )); + } + } + // Check that all obligations are satisfied by the implementation's // version. let errors = ocx.select_all_or_error(); @@ -1983,7 +2071,7 @@ pub(super) fn check_type_bounds<'tcx>( ObligationCause::new(impl_ty_span, impl_ty_def_id, code) }; - let obligations: Vec<_> = tcx + let mut obligations: Vec<_> = tcx .explicit_item_bounds(trait_ty.def_id) .iter_instantiated_copied(tcx, rebased_args) .map(|(concrete_ty_bound, span)| { @@ -1991,6 +2079,22 @@ pub(super) fn check_type_bounds<'tcx>( traits::Obligation::new(tcx, mk_cause(span), param_env, concrete_ty_bound) }) .collect(); + + // Only in a const implementation do we need to check that the `~const` item bounds hold. + if tcx.constness(container_id) == hir::Constness::Const { + obligations.extend( + tcx.implied_const_bounds(trait_ty.def_id) + .iter_instantiated_copied(tcx, rebased_args) + .map(|(c, span)| { + traits::Obligation::new( + tcx, + mk_cause(span), + param_env, + c.to_host_effect_clause(tcx, ty::HostPolarity::Maybe), + ) + }), + ); + } debug!(item_bounds=?obligations); // Normalize predicates with the assumption that the GAT may always normalize diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index 79e579841746f..f0041a577424f 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -32,7 +32,8 @@ use rustc_trait_selection::traits::misc::{ use rustc_trait_selection::traits::outlives_bounds::InferCtxtExt as _; use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt as _; use rustc_trait_selection::traits::{ - self, FulfillmentError, ObligationCause, ObligationCauseCode, ObligationCtxt, WellFormedLoc, + self, FulfillmentError, Obligation, ObligationCause, ObligationCauseCode, ObligationCtxt, + WellFormedLoc, }; use rustc_type_ir::TypeFlags; use rustc_type_ir::solve::NoSolution; @@ -86,7 +87,7 @@ impl<'tcx> WfCheckingCtxt<'_, 'tcx> { self.body_def_id, ObligationCauseCode::WellFormed(loc), ); - self.ocx.register_obligation(traits::Obligation::new( + self.ocx.register_obligation(Obligation::new( self.tcx(), cause, self.param_env, @@ -1173,7 +1174,7 @@ fn check_type_defn<'tcx>( wfcx.body_def_id, ObligationCauseCode::Misc, ); - wfcx.register_obligation(traits::Obligation::new( + wfcx.register_obligation(Obligation::new( tcx, cause, wfcx.param_env, @@ -1369,6 +1370,30 @@ fn check_impl<'tcx>( obligation.cause.span = hir_self_ty.span; } } + + // Ensure that the `~const` where clauses of the trait hold for the impl. + if tcx.constness(item.owner_id.def_id) == hir::Constness::Const { + for (bound, _) in + tcx.const_conditions(trait_ref.def_id).instantiate(tcx, trait_ref.args) + { + let bound = wfcx.normalize( + item.span, + Some(WellFormedLoc::Ty(item.hir_id().expect_owner().def_id)), + bound, + ); + wfcx.register_obligation(Obligation::new( + tcx, + ObligationCause::new( + hir_self_ty.span, + wfcx.body_def_id, + ObligationCauseCode::WellFormed(None), + ), + wfcx.param_env, + bound.to_host_effect_clause(tcx, ty::HostPolarity::Maybe), + )) + } + } + debug!(?obligations); wfcx.register_obligations(obligations); } @@ -1561,7 +1586,7 @@ fn check_where_clauses<'tcx>(wfcx: &WfCheckingCtxt<'_, 'tcx>, span: Span, def_id wfcx.body_def_id, ObligationCauseCode::WhereClause(def_id.to_def_id(), DUMMY_SP), ); - traits::Obligation::new(tcx, cause, wfcx.param_env, pred) + Obligation::new(tcx, cause, wfcx.param_env, pred) }); let predicates = predicates.instantiate_identity(tcx); @@ -1852,7 +1877,7 @@ fn receiver_is_implemented<'tcx>( let tcx = wfcx.tcx(); let trait_ref = ty::TraitRef::new(tcx, receiver_trait_def_id, [receiver_ty]); - let obligation = traits::Obligation::new(tcx, cause, wfcx.param_env, trait_ref); + let obligation = Obligation::new(tcx, cause, wfcx.param_env, trait_ref); if wfcx.infcx.predicate_must_hold_modulo_regions(&obligation) { true @@ -2188,7 +2213,7 @@ impl<'tcx> WfCheckingCtxt<'_, 'tcx> { .unwrap_or(obligation_span); } - let obligation = traits::Obligation::new( + let obligation = Obligation::new( tcx, traits::ObligationCause::new( span, diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index acc21d0994bf6..f46b7a8bc9cc4 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -77,6 +77,8 @@ pub fn provide(providers: &mut Providers) { explicit_supertraits_containing_assoc_item: predicates_of::explicit_supertraits_containing_assoc_item, trait_explicit_predicates_and_bounds: predicates_of::trait_explicit_predicates_and_bounds, + const_conditions: predicates_of::const_conditions, + implied_const_bounds: predicates_of::implied_const_bounds, type_param_predicates: predicates_of::type_param_predicates, trait_def, adt_def, diff --git a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs index 69ebd3a928a3a..075faea3d2aac 100644 --- a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs +++ b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs @@ -40,7 +40,16 @@ fn associated_type_bounds<'tcx>( let mut bounds = Bounds::default(); icx.lowerer().lower_bounds(item_ty, hir_bounds, &mut bounds, ty::List::empty(), filter); // Associated types are implicitly sized unless a `?Sized` bound is found - icx.lowerer().add_sized_bound(&mut bounds, item_ty, hir_bounds, None, span); + match filter { + PredicateFilter::All + | PredicateFilter::SelfOnly + | PredicateFilter::SelfThatDefines(_) + | PredicateFilter::SelfAndAssociatedTypeBounds => { + icx.lowerer().add_sized_bound(&mut bounds, item_ty, hir_bounds, None, span); + } + // `ConstIfConst` is only interested in `~const` bounds. + PredicateFilter::ConstIfConst | PredicateFilter::SelfConstIfConst => {} + } let trait_def_id = tcx.local_parent(assoc_item_def_id); let trait_predicates = tcx.trait_explicit_predicates_and_bounds(trait_def_id); @@ -109,10 +118,19 @@ fn remap_gat_vars_and_recurse_into_nested_projections<'tcx>( } else { // Only collect *self* type bounds if the filter is for self. match filter { - PredicateFilter::SelfOnly | PredicateFilter::SelfThatDefines(_) => { + PredicateFilter::All => {} + PredicateFilter::SelfOnly => { return None; } - PredicateFilter::All | PredicateFilter::SelfAndAssociatedTypeBounds => {} + PredicateFilter::SelfThatDefines(_) + | PredicateFilter::SelfConstIfConst + | PredicateFilter::SelfAndAssociatedTypeBounds + | PredicateFilter::ConstIfConst => { + unreachable!( + "invalid predicate filter for \ + `remap_gat_vars_and_recurse_into_nested_projections`" + ) + } } clause_ty = alias_ty.self_ty(); @@ -308,7 +326,17 @@ fn opaque_type_bounds<'tcx>( let mut bounds = Bounds::default(); icx.lowerer().lower_bounds(item_ty, hir_bounds, &mut bounds, ty::List::empty(), filter); // Opaque types are implicitly sized unless a `?Sized` bound is found - icx.lowerer().add_sized_bound(&mut bounds, item_ty, hir_bounds, None, span); + match filter { + PredicateFilter::All + | PredicateFilter::SelfOnly + | PredicateFilter::SelfThatDefines(_) + | PredicateFilter::SelfAndAssociatedTypeBounds => { + // Associated types are implicitly sized unless a `?Sized` bound is found + icx.lowerer().add_sized_bound(&mut bounds, item_ty, hir_bounds, None, span); + } + //`ConstIfConst` is only interested in `~const` bounds. + PredicateFilter::ConstIfConst | PredicateFilter::SelfConstIfConst => {} + } debug!(?bounds); tcx.arena.alloc_from_iter(bounds.clauses(tcx)) diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs index f9460ed5b4732..ec5773d174f82 100644 --- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs @@ -12,6 +12,7 @@ use rustc_span::symbol::Ident; use rustc_span::{DUMMY_SP, Span}; use tracing::{debug, instrument, trace}; +use super::item_bounds::explicit_item_bounds_with_filter; use crate::bounds::Bounds; use crate::collect::ItemCtxt; use crate::constrained_generic_params as cgp; @@ -685,29 +686,76 @@ pub(super) fn assert_only_contains_predicates_from<'tcx>( assert_eq!( trait_predicate.self_ty(), ty, - "expected `Self` predicate when computing `{filter:?}` implied bounds: {clause:?}" + "expected `Self` predicate when computing \ + `{filter:?}` implied bounds: {clause:?}" ); } ty::ClauseKind::Projection(projection_predicate) => { assert_eq!( projection_predicate.self_ty(), ty, - "expected `Self` predicate when computing `{filter:?}` implied bounds: {clause:?}" + "expected `Self` predicate when computing \ + `{filter:?}` implied bounds: {clause:?}" ); } ty::ClauseKind::TypeOutlives(outlives_predicate) => { assert_eq!( outlives_predicate.0, ty, - "expected `Self` predicate when computing `{filter:?}` implied bounds: {clause:?}" + "expected `Self` predicate when computing \ + `{filter:?}` implied bounds: {clause:?}" ); } ty::ClauseKind::RegionOutlives(_) | ty::ClauseKind::ConstArgHasType(_, _) | ty::ClauseKind::WellFormed(_) - | ty::ClauseKind::ConstEvaluatable(_) => { + | ty::ClauseKind::ConstEvaluatable(_) + | ty::ClauseKind::HostEffect(..) => { bug!( - "unexpected non-`Self` predicate when computing `{filter:?}` implied bounds: {clause:?}" + "unexpected non-`Self` predicate when computing \ + `{filter:?}` implied bounds: {clause:?}" + ); + } + } + } + } + PredicateFilter::ConstIfConst => { + for (clause, _) in bounds { + match clause.kind().skip_binder() { + ty::ClauseKind::HostEffect(ty::HostEffectPredicate { + trait_ref: _, + host: ty::HostPolarity::Maybe, + }) => {} + _ => { + bug!( + "unexpected non-`HostEffect` predicate when computing \ + `{filter:?}` implied bounds: {clause:?}" + ); + } + } + } + } + PredicateFilter::SelfConstIfConst => { + for (clause, _) in bounds { + match clause.kind().skip_binder() { + ty::ClauseKind::HostEffect(pred) => { + assert_eq!( + pred.host, + ty::HostPolarity::Maybe, + "expected `~const` predicate when computing `{filter:?}` \ + implied bounds: {clause:?}", + ); + assert_eq!( + pred.trait_ref.self_ty(), + ty, + "expected `Self` predicate when computing `{filter:?}` \ + implied bounds: {clause:?}" + ); + } + _ => { + bug!( + "unexpected non-`HostEffect` predicate when computing \ + `{filter:?}` implied bounds: {clause:?}" ); } } @@ -829,3 +877,184 @@ impl<'tcx> ItemCtxt<'tcx> { bounds.clauses(self.tcx).collect() } } + +/// Compute the conditions that need to hold for a conditionally-const item to be const. +/// That is, compute the set of `~const` where clauses for a given item. +/// +/// This query also computes the `~const` where clauses for associated types, which are +/// not "const", but which have item bounds which may be `~const`. These must hold for +/// the `~const` item bound to hold. +pub(super) fn const_conditions<'tcx>( + tcx: TyCtxt<'tcx>, + def_id: LocalDefId, +) -> ty::ConstConditions<'tcx> { + // This logic is spaghetti, and should be cleaned up. The current methods that are + // defined to deal with constness are very unintuitive. + if tcx.is_const_fn_raw(def_id.to_def_id()) { + // Ok, const fn or method in const trait. + } else { + match tcx.def_kind(def_id) { + DefKind::Trait => { + if !tcx.is_const_trait(def_id.to_def_id()) { + return Default::default(); + } + } + DefKind::Impl { .. } => { + // FIXME(effects): Should be using a dedicated function to + // test if this is a const trait impl. + if tcx.constness(def_id) != hir::Constness::Const { + return Default::default(); + } + } + DefKind::AssocTy | DefKind::AssocFn => { + let parent_def_id = tcx.local_parent(def_id).to_def_id(); + match tcx.associated_item(def_id).container { + ty::AssocItemContainer::TraitContainer => { + if !tcx.is_const_trait(parent_def_id) { + return Default::default(); + } + } + ty::AssocItemContainer::ImplContainer => { + // FIXME(effects): Should be using a dedicated function to + // test if this is a const trait impl. + if tcx.constness(parent_def_id) != hir::Constness::Const { + return Default::default(); + } + } + } + } + DefKind::Closure | DefKind::OpaqueTy => { + // Closures and RPITs will eventually have const conditions + // for `~const` bounds. + return Default::default(); + } + _ => return Default::default(), + } + } + + let (generics, trait_def_id_and_supertraits, has_parent) = match tcx.hir_node_by_def_id(def_id) + { + Node::Item(item) => match item.kind { + hir::ItemKind::Impl(impl_) => (impl_.generics, None, false), + hir::ItemKind::Fn(_, generics, _) => (generics, None, false), + hir::ItemKind::Trait(_, _, generics, supertraits, _) => { + (generics, Some((item.owner_id.def_id, supertraits)), false) + } + _ => return Default::default(), + }, + // While associated types are not really const, we do allow them to have `~const` + // bounds and where clauses. `const_conditions` is responsible for gathering + // these up so we can check them in `compare_type_predicate_entailment`, and + // in `HostEffect` goal computation. + Node::TraitItem(item) => match item.kind { + hir::TraitItemKind::Fn(_, _) | hir::TraitItemKind::Type(_, _) => { + (item.generics, None, true) + } + _ => return Default::default(), + }, + Node::ImplItem(item) => match item.kind { + hir::ImplItemKind::Fn(_, _) | hir::ImplItemKind::Type(_) => (item.generics, None, true), + _ => return Default::default(), + }, + _ => return Default::default(), + }; + + let icx = ItemCtxt::new(tcx, def_id); + let mut bounds = Bounds::default(); + + for pred in generics.predicates { + match pred { + hir::WherePredicate::BoundPredicate(bound_pred) => { + let ty = icx.lowerer().lower_ty_maybe_return_type_notation(bound_pred.bounded_ty); + let bound_vars = tcx.late_bound_vars(bound_pred.hir_id); + icx.lowerer().lower_bounds( + ty, + bound_pred.bounds.iter(), + &mut bounds, + bound_vars, + PredicateFilter::ConstIfConst, + ); + } + _ => {} + } + } + + if let Some((def_id, supertraits)) = trait_def_id_and_supertraits { + bounds.push_const_bound( + tcx, + ty::Binder::dummy(ty::TraitRef::identity(tcx, def_id.to_def_id())), + ty::HostPolarity::Maybe, + DUMMY_SP, + ); + + icx.lowerer().lower_bounds( + tcx.types.self_param, + supertraits.into_iter(), + &mut bounds, + ty::List::empty(), + PredicateFilter::ConstIfConst, + ); + } + + ty::ConstConditions { + parent: has_parent.then(|| tcx.local_parent(def_id).to_def_id()), + predicates: tcx.arena.alloc_from_iter(bounds.clauses(tcx).map(|(clause, span)| { + ( + clause.kind().map_bound(|clause| match clause { + ty::ClauseKind::HostEffect(ty::HostEffectPredicate { + trait_ref, + host: ty::HostPolarity::Maybe, + }) => trait_ref, + _ => bug!("converted {clause:?}"), + }), + span, + ) + })), + } +} + +pub(super) fn implied_const_bounds<'tcx>( + tcx: TyCtxt<'tcx>, + def_id: LocalDefId, +) -> ty::EarlyBinder<'tcx, &'tcx [(ty::PolyTraitRef<'tcx>, Span)]> { + let bounds = match tcx.hir_node_by_def_id(def_id) { + Node::Item(hir::Item { kind: hir::ItemKind::Trait(..), .. }) => { + if !tcx.is_const_trait(def_id.to_def_id()) { + return ty::EarlyBinder::bind(&[]); + } + + implied_predicates_with_filter( + tcx, + def_id.to_def_id(), + PredicateFilter::SelfConstIfConst, + ) + } + Node::TraitItem(hir::TraitItem { kind: hir::TraitItemKind::Type(..), .. }) => { + if !tcx.is_const_trait(tcx.local_parent(def_id).to_def_id()) { + return ty::EarlyBinder::bind(&[]); + } + + explicit_item_bounds_with_filter(tcx, def_id, PredicateFilter::ConstIfConst) + } + Node::OpaqueTy(..) => { + // We should eventually collect the `~const` bounds on opaques. + return ty::EarlyBinder::bind(&[]); + } + _ => return ty::EarlyBinder::bind(&[]), + }; + + bounds.map_bound(|bounds| { + &*tcx.arena.alloc_from_iter(bounds.iter().copied().map(|(clause, span)| { + ( + clause.kind().map_bound(|clause| match clause { + ty::ClauseKind::HostEffect(ty::HostEffectPredicate { + trait_ref, + host: ty::HostPolarity::Maybe, + }) => trait_ref, + _ => bug!("converted {clause:?}"), + }), + span, + ) + })) + }) +} diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs index 2b0e1350108f1..c902e85c2673c 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs @@ -154,7 +154,6 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { for hir_bound in hir_bounds { // In order to avoid cycles, when we're lowering `SelfThatDefines`, // we skip over any traits that don't define the given associated type. - if let PredicateFilter::SelfThatDefines(assoc_name) = predicate_filter { if let Some(trait_ref) = hir_bound.trait_ref() && let Some(trait_did) = trait_ref.trait_def_id() @@ -193,6 +192,14 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { ); } hir::GenericBound::Outlives(lifetime) => { + // `ConstIfConst` is only interested in `~const` bounds. + if matches!( + predicate_filter, + PredicateFilter::ConstIfConst | PredicateFilter::SelfConstIfConst + ) { + continue; + } + let region = self.lower_lifetime(lifetime, RegionInferReason::OutlivesBound); bounds.push_region_bound( self.tcx(), @@ -392,21 +399,31 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { }, ); - bounds.push_projection_bound( - tcx, - projection_term.map_bound(|projection_term| ty::ProjectionPredicate { - projection_term, - term, - }), - constraint.span, - ); + match predicate_filter { + PredicateFilter::All + | PredicateFilter::SelfOnly + | PredicateFilter::SelfThatDefines(_) + | PredicateFilter::SelfAndAssociatedTypeBounds => { + bounds.push_projection_bound( + tcx, + projection_term.map_bound(|projection_term| ty::ProjectionPredicate { + projection_term, + term, + }), + constraint.span, + ); + } + // `ConstIfConst` is only interested in `~const` bounds. + PredicateFilter::ConstIfConst | PredicateFilter::SelfConstIfConst => {} + } } // Lower a constraint like `Item: Debug` as found in HIR bound `T: Iterator` // to a bound involving a projection: `::Item: Debug`. hir::AssocItemConstraintKind::Bound { bounds: hir_bounds } => { match predicate_filter { - PredicateFilter::SelfOnly | PredicateFilter::SelfThatDefines(_) => {} - PredicateFilter::All | PredicateFilter::SelfAndAssociatedTypeBounds => { + PredicateFilter::All + | PredicateFilter::SelfAndAssociatedTypeBounds + | PredicateFilter::ConstIfConst => { let projection_ty = projection_term .map_bound(|projection_term| projection_term.expect_ty(self.tcx())); // Calling `skip_binder` is okay, because `lower_bounds` expects the `param_ty` @@ -421,6 +438,9 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { predicate_filter, ); } + PredicateFilter::SelfOnly + | PredicateFilter::SelfThatDefines(_) + | PredicateFilter::SelfConstIfConst => {} } } } diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs index 2cee7c77aa538..3449270564a7b 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs @@ -78,7 +78,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { ty::ClauseKind::RegionOutlives(_) | ty::ClauseKind::ConstArgHasType(..) | ty::ClauseKind::WellFormed(_) - | ty::ClauseKind::ConstEvaluatable(_) => { + | ty::ClauseKind::ConstEvaluatable(_) + | ty::ClauseKind::HostEffect(..) => { span_bug!(span, "did not expect {pred} clause in object bounds"); } } diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs index d2636c1573e0d..863c077a9e03c 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -81,6 +81,12 @@ pub enum PredicateFilter { /// For example, given `Self: Tr`, this would expand to `Self: Tr` /// and `::A: B`. SelfAndAssociatedTypeBounds, + + /// Filter only the `~const` bounds, which are lowered into `HostEffect` clauses. + ConstIfConst, + + /// Filter only the `~const` bounds which are *also* in the supertrait position. + SelfConstIfConst, } #[derive(Debug)] @@ -693,8 +699,49 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { bound_vars, ); - debug!(?poly_trait_ref); - bounds.push_trait_bound(tcx, poly_trait_ref, span, polarity); + match predicate_filter { + PredicateFilter::All + | PredicateFilter::SelfOnly + | PredicateFilter::SelfThatDefines(..) + | PredicateFilter::SelfAndAssociatedTypeBounds => { + debug!(?poly_trait_ref); + bounds.push_trait_bound(tcx, poly_trait_ref, span, polarity); + + match constness { + Some(ty::BoundConstness::Const) => { + if polarity == ty::PredicatePolarity::Positive { + bounds.push_const_bound( + tcx, + poly_trait_ref, + ty::HostPolarity::Const, + span, + ); + } + } + Some(ty::BoundConstness::ConstIfConst) => { + // We don't emit a const bound here, since that would mean that we + // unconditionally need to prove a `HostEffect` predicate, even when + // the predicates are being instantiated in a non-const context. This + // is instead handled in the `const_conditions` query. + } + None => {} + } + } + // On the flip side, when filtering `ConstIfConst` bounds, we only need to convert + // `~const` bounds. All other predicates are handled in their respective queries. + // + // Note that like `PredicateFilter::SelfOnly`, we don't need to do any filtering + // here because we only call this on self bounds, and deal with the recursive case + // in `lower_assoc_item_constraint`. + PredicateFilter::ConstIfConst | PredicateFilter::SelfConstIfConst => match constness { + Some(ty::BoundConstness::ConstIfConst) => { + if polarity == ty::PredicatePolarity::Positive { + bounds.push_const_bound(tcx, poly_trait_ref, ty::HostPolarity::Maybe, span); + } + } + None | Some(ty::BoundConstness::Const) => {} + }, + } let mut dup_constraints = FxIndexMap::default(); for constraint in trait_segment.args().constraints { diff --git a/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs b/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs index 0355adfcb11e1..a394fc2fbb199 100644 --- a/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs +++ b/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs @@ -530,6 +530,7 @@ fn trait_specialization_kind<'tcx>( | ty::ClauseKind::Projection(_) | ty::ClauseKind::ConstArgHasType(..) | ty::ClauseKind::WellFormed(_) - | ty::ClauseKind::ConstEvaluatable(..) => None, + | ty::ClauseKind::ConstEvaluatable(..) + | ty::ClauseKind::HostEffect(..) => None, } } diff --git a/compiler/rustc_hir_analysis/src/outlives/explicit.rs b/compiler/rustc_hir_analysis/src/outlives/explicit.rs index f576499ecac38..2c1d443f9512f 100644 --- a/compiler/rustc_hir_analysis/src/outlives/explicit.rs +++ b/compiler/rustc_hir_analysis/src/outlives/explicit.rs @@ -53,7 +53,8 @@ impl<'tcx> ExplicitPredicatesMap<'tcx> { | ty::ClauseKind::Projection(_) | ty::ClauseKind::ConstArgHasType(_, _) | ty::ClauseKind::WellFormed(_) - | ty::ClauseKind::ConstEvaluatable(_) => {} + | ty::ClauseKind::ConstEvaluatable(_) + | ty::ClauseKind::HostEffect(..) => {} } } diff --git a/compiler/rustc_hir_typeck/src/callee.rs b/compiler/rustc_hir_typeck/src/callee.rs index b642ba03aee2e..081cb8c18e65d 100644 --- a/compiler/rustc_hir_typeck/src/callee.rs +++ b/compiler/rustc_hir_typeck/src/callee.rs @@ -836,14 +836,51 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { fn_sig.output() } - #[tracing::instrument(level = "debug", skip(self, _span))] + #[tracing::instrument(level = "debug", skip(self, span))] pub(super) fn enforce_context_effects( &self, - _span: Span, - _callee_did: DefId, - _callee_args: GenericArgsRef<'tcx>, + span: Span, + callee_did: DefId, + callee_args: GenericArgsRef<'tcx>, ) { - todo!() + // FIXME(effects): We should be enforcing these effects unconditionally. + // This can be done as soon as we convert the standard library back to + // using const traits, since if we were to enforce these conditions now, + // we'd fail on basically every builtin trait call (i.e. `1 + 2`). + if !self.tcx.features().effects() { + return; + } + + let host = match self.tcx.hir().body_const_context(self.body_id) { + Some(hir::ConstContext::Const { .. } | hir::ConstContext::Static(_)) => { + ty::HostPolarity::Const + } + Some(hir::ConstContext::ConstFn) => ty::HostPolarity::Maybe, + None => return, + }; + + // FIXME(effects): Should this be `is_const_fn_raw`? It depends on if we move + // const stability checking here too, I guess. + if self.tcx.is_const_fn(callee_did) + || self + .tcx + .trait_of_item(callee_did) + .is_some_and(|def_id| self.tcx.is_const_trait(def_id)) + { + let q = self.tcx.const_conditions(callee_did); + // FIXME(effects): Use this span with a better cause code. + for (cond, _) in q.instantiate(self.tcx, callee_args) { + self.register_predicate(Obligation::new( + self.tcx, + self.misc(span), + self.param_env, + cond.to_host_effect_clause(self.tcx, host), + )); + } + } else { + // FIXME(effects): This should eventually be caught here. + // For now, though, we defer some const checking to MIR. + } } fn confirm_overloaded_call( diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/inspect_obligations.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/inspect_obligations.rs index 693cb4465cc15..eb5fe3a86e4c5 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/inspect_obligations.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/inspect_obligations.rs @@ -52,6 +52,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { | ty::PredicateKind::AliasRelate(..) | ty::PredicateKind::Clause(ty::ClauseKind::ConstEvaluatable(..)) | ty::PredicateKind::ConstEquate(..) + | ty::PredicateKind::Clause(ty::ClauseKind::HostEffect(..)) | ty::PredicateKind::Ambiguous => false, } } diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs index b60fa8bbfa148..569fdea11ce77 100644 --- a/compiler/rustc_hir_typeck/src/method/probe.rs +++ b/compiler/rustc_hir_typeck/src/method/probe.rs @@ -813,7 +813,8 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { | ty::ClauseKind::Projection(_) | ty::ClauseKind::ConstArgHasType(_, _) | ty::ClauseKind::WellFormed(_) - | ty::ClauseKind::ConstEvaluatable(_) => None, + | ty::ClauseKind::ConstEvaluatable(_) + | ty::ClauseKind::HostEffect(..) => None, } }); diff --git a/compiler/rustc_infer/src/infer/outlives/mod.rs b/compiler/rustc_infer/src/infer/outlives/mod.rs index e23bb1aaa5631..1afe50e336da2 100644 --- a/compiler/rustc_infer/src/infer/outlives/mod.rs +++ b/compiler/rustc_infer/src/infer/outlives/mod.rs @@ -24,19 +24,9 @@ pub fn explicit_outlives_bounds<'tcx>( param_env .caller_bounds() .into_iter() - .map(ty::Clause::kind) + .filter_map(ty::Clause::as_region_outlives_clause) .filter_map(ty::Binder::no_bound_vars) - .filter_map(move |kind| match kind { - ty::ClauseKind::RegionOutlives(ty::OutlivesPredicate(r_a, r_b)) => { - Some(OutlivesBound::RegionSubRegion(r_b, r_a)) - } - ty::ClauseKind::Trait(_) - | ty::ClauseKind::TypeOutlives(_) - | ty::ClauseKind::Projection(_) - | ty::ClauseKind::ConstArgHasType(_, _) - | ty::ClauseKind::WellFormed(_) - | ty::ClauseKind::ConstEvaluatable(_) => None, - }) + .map(|ty::OutlivesPredicate(r_a, r_b)| OutlivesBound::RegionSubRegion(r_b, r_a)) } impl<'tcx> InferCtxt<'tcx> { diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index 71c667b2cd6b6..cf889e958a9d4 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -1554,7 +1554,9 @@ impl<'tcx> LateLintPass<'tcx> for TrivialConstraints { // Ignore bounds that a user can't type | ClauseKind::WellFormed(..) // FIXME(generic_const_exprs): `ConstEvaluatable` can be written - | ClauseKind::ConstEvaluatable(..) => continue, + | ClauseKind::ConstEvaluatable(..) + // Users don't write this directly, only via another trait ref. + | ty::ClauseKind::HostEffect(..) => continue, }; if predicate.is_global() { cx.emit_span_lint(TRIVIAL_BOUNDS, span, BuiltinTrivialBounds { diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs index d4cbf6e13afbc..71c7231a78826 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs @@ -275,6 +275,8 @@ provide! { tcx, def_id, other, cdata, impl_parent => { table } defaultness => { table_direct } constness => { table_direct } + const_conditions => { table } + implied_const_bounds => { table_defaulted_array } coerce_unsized_info => { Ok(cdata .root diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index 80b979fe088f5..a71d1993c6c16 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -1423,6 +1423,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { let g = tcx.generics_of(def_id); record!(self.tables.generics_of[def_id] <- g); record!(self.tables.explicit_predicates_of[def_id] <- self.tcx.explicit_predicates_of(def_id)); + record!(self.tables.const_conditions[def_id] <- self.tcx.const_conditions(def_id)); let inferred_outlives = self.tcx.inferred_outlives_of(def_id); record_defaulted_array!(self.tables.inferred_outlives_of[def_id] <- inferred_outlives); @@ -1456,7 +1457,8 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { self.tcx.explicit_super_predicates_of(def_id).skip_binder()); record_defaulted_array!(self.tables.explicit_implied_predicates_of[def_id] <- self.tcx.explicit_implied_predicates_of(def_id).skip_binder()); - + record_defaulted_array!(self.tables.implied_const_bounds[def_id] + <- self.tcx.implied_const_bounds(def_id).skip_binder()); let module_children = self.tcx.module_children_local(local_id); record_array!(self.tables.module_children_non_reexports[def_id] <- module_children.iter().map(|child| child.res.def_id().index)); @@ -1467,6 +1469,8 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { self.tcx.explicit_super_predicates_of(def_id).skip_binder()); record_defaulted_array!(self.tables.explicit_implied_predicates_of[def_id] <- self.tcx.explicit_implied_predicates_of(def_id).skip_binder()); + record_defaulted_array!(self.tables.implied_const_bounds[def_id] + <- self.tcx.implied_const_bounds(def_id).skip_binder()); } if let DefKind::Trait | DefKind::Impl { .. } = def_kind { let associated_item_def_ids = self.tcx.associated_item_def_ids(def_id); @@ -1649,6 +1653,8 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { if let ty::AssocKind::Type = item.kind { self.encode_explicit_item_bounds(def_id); self.encode_explicit_item_super_predicates(def_id); + record_defaulted_array!(self.tables.implied_const_bounds[def_id] + <- self.tcx.implied_const_bounds(def_id).skip_binder()); } } AssocItemContainer::ImplContainer => { diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs index 8da1be8054460..a00ca27aacc0c 100644 --- a/compiler/rustc_metadata/src/rmeta/mod.rs +++ b/compiler/rustc_metadata/src/rmeta/mod.rs @@ -392,6 +392,7 @@ define_tables! { inferred_outlives_of: Table, Span)>>, explicit_super_predicates_of: Table, Span)>>, explicit_implied_predicates_of: Table, Span)>>, + implied_const_bounds: Table, Span)>>, inherent_impls: Table>, associated_types_for_impl_traits_in_associated_fn: Table>, opt_rpitit_info: Table>>, @@ -435,6 +436,7 @@ define_tables! { thir_abstract_const: Table>>>, impl_parent: Table, constness: Table, + const_conditions: Table>>, defaultness: Table, // FIXME(eddyb) perhaps compute this on the fly if cheap enough? coerce_unsized_info: Table>, diff --git a/compiler/rustc_middle/src/query/erase.rs b/compiler/rustc_middle/src/query/erase.rs index 48bf4ffced0ce..5f8427bd707aa 100644 --- a/compiler/rustc_middle/src/query/erase.rs +++ b/compiler/rustc_middle/src/query/erase.rs @@ -370,6 +370,7 @@ tcx_lifetime! { rustc_middle::ty::FnSig, rustc_middle::ty::GenericArg, rustc_middle::ty::GenericPredicates, + rustc_middle::ty::ConstConditions, rustc_middle::ty::inhabitedness::InhabitedPredicate, rustc_middle::ty::Instance, rustc_middle::ty::InstanceKind, diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 0b751779501d9..d03fc39c9ade1 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -683,6 +683,24 @@ rustc_queries! { } } + query const_conditions( + key: DefId + ) -> ty::ConstConditions<'tcx> { + desc { |tcx| "computing the conditions for `{}` to be considered const", + tcx.def_path_str(key) + } + separate_provide_extern + } + + query implied_const_bounds( + key: DefId + ) -> ty::EarlyBinder<'tcx, &'tcx [(ty::PolyTraitRef<'tcx>, Span)]> { + desc { |tcx| "computing the implied `~const` bounds for `{}`", + tcx.def_path_str(key) + } + separate_provide_extern + } + /// To avoid cycles within the predicates of a single item we compute /// per-type-parameter predicates for resolving `T::AssocTy`. query type_param_predicates( diff --git a/compiler/rustc_middle/src/ty/codec.rs b/compiler/rustc_middle/src/ty/codec.rs index 7e533bc4291a1..ef9dfdd2f9624 100644 --- a/compiler/rustc_middle/src/ty/codec.rs +++ b/compiler/rustc_middle/src/ty/codec.rs @@ -386,6 +386,17 @@ impl<'tcx, D: TyDecoder>> RefDecodable<'tcx, D> for [(ty::Claus } } +impl<'tcx, D: TyDecoder>> RefDecodable<'tcx, D> + for [(ty::PolyTraitRef<'tcx>, Span)] +{ + fn decode(decoder: &mut D) -> &'tcx Self { + decoder + .interner() + .arena + .alloc_from_iter((0..decoder.read_usize()).map(|_| Decodable::decode(decoder))) + } +} + impl<'tcx, D: TyDecoder>> RefDecodable<'tcx, D> for ty::List { diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 281899647efb5..c8fe6cbf4c657 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -78,10 +78,10 @@ use crate::traits::solve::{ use crate::ty::predicate::ExistentialPredicateStableCmpExt as _; use crate::ty::{ self, AdtDef, AdtDefData, AdtKind, Binder, Clause, Clauses, Const, GenericArg, GenericArgs, - GenericArgsRef, GenericParamDefKind, ImplPolarity, List, ListWithCachedTypeInfo, ParamConst, - ParamTy, Pattern, PatternKind, PolyExistentialPredicate, PolyFnSig, Predicate, PredicateKind, - PredicatePolarity, Region, RegionKind, ReprOptions, TraitObjectVisitor, Ty, TyKind, TyVid, - Visibility, + GenericArgsRef, GenericParamDefKind, HostPolarity, ImplPolarity, List, ListWithCachedTypeInfo, + ParamConst, ParamTy, Pattern, PatternKind, PolyExistentialPredicate, PolyFnSig, Predicate, + PredicateKind, PredicatePolarity, Region, RegionKind, ReprOptions, TraitObjectVisitor, Ty, + TyKind, TyVid, Visibility, }; #[allow(rustc::usage_of_ty_tykind)] @@ -383,6 +383,28 @@ impl<'tcx> Interner for TyCtxt<'tcx> { self.explicit_implied_predicates_of(def_id).map_bound(|preds| preds.into_iter().copied()) } + fn is_const_impl(self, def_id: DefId) -> bool { + self.constness(def_id) == hir::Constness::Const + } + + fn const_conditions( + self, + def_id: DefId, + ) -> ty::EarlyBinder<'tcx, impl IntoIterator>>> { + ty::EarlyBinder::bind( + self.const_conditions(def_id).instantiate_identity(self).into_iter().map(|(c, _)| c), + ) + } + + fn implied_const_bounds( + self, + def_id: DefId, + ) -> ty::EarlyBinder<'tcx, impl IntoIterator>>> { + ty::EarlyBinder::bind( + self.implied_const_bounds(def_id).iter_identity_copied().map(|(c, _)| c), + ) + } + fn has_target_features(self, def_id: DefId) -> bool { !self.codegen_fn_attrs(def_id).target_features.is_empty() } @@ -2189,7 +2211,7 @@ macro_rules! nop_slice_lift { nop_slice_lift! {ty::ValTree<'a> => ty::ValTree<'tcx>} TrivialLiftImpls! { - ImplPolarity, PredicatePolarity, Promoted + ImplPolarity, PredicatePolarity, Promoted, HostPolarity, } macro_rules! sty_debug_print { diff --git a/compiler/rustc_middle/src/ty/flags.rs b/compiler/rustc_middle/src/ty/flags.rs index 39899f1d32be6..704a197aa49d0 100644 --- a/compiler/rustc_middle/src/ty/flags.rs +++ b/compiler/rustc_middle/src/ty/flags.rs @@ -265,6 +265,12 @@ impl FlagComputation { ty::PredicateKind::Clause(ty::ClauseKind::Trait(trait_pred)) => { self.add_args(trait_pred.trait_ref.args); } + ty::PredicateKind::Clause(ty::ClauseKind::HostEffect(ty::HostEffectPredicate { + trait_ref, + host: _, + })) => { + self.add_args(trait_ref.args); + } ty::PredicateKind::Clause(ty::ClauseKind::RegionOutlives(ty::OutlivesPredicate( a, b, diff --git a/compiler/rustc_middle/src/ty/generics.rs b/compiler/rustc_middle/src/ty/generics.rs index e24a3f281fc50..ab1b8fa6a7329 100644 --- a/compiler/rustc_middle/src/ty/generics.rs +++ b/compiler/rustc_middle/src/ty/generics.rs @@ -422,3 +422,73 @@ impl<'tcx> GenericPredicates<'tcx> { instantiated.spans.extend(self.predicates.iter().map(|(_, s)| s)); } } + +/// `~const` bounds for a given item. This is represented using a struct much like +/// `GenericPredicates`, where you can either choose to only instantiate the "own" +/// bounds or all of the bounds including those from the parent. This distinction +/// is necessary for code like `compare_method_predicate_entailment`. +#[derive(Copy, Clone, Default, Debug, TyEncodable, TyDecodable, HashStable)] +pub struct ConstConditions<'tcx> { + pub parent: Option, + pub predicates: &'tcx [(ty::PolyTraitRef<'tcx>, Span)], +} + +impl<'tcx> ConstConditions<'tcx> { + pub fn instantiate( + self, + tcx: TyCtxt<'tcx>, + args: GenericArgsRef<'tcx>, + ) -> Vec<(ty::PolyTraitRef<'tcx>, Span)> { + let mut instantiated = vec![]; + self.instantiate_into(tcx, &mut instantiated, args); + instantiated + } + + pub fn instantiate_own( + self, + tcx: TyCtxt<'tcx>, + args: GenericArgsRef<'tcx>, + ) -> impl Iterator, Span)> + DoubleEndedIterator + ExactSizeIterator + { + EarlyBinder::bind(self.predicates).iter_instantiated_copied(tcx, args) + } + + pub fn instantiate_own_identity( + self, + ) -> impl Iterator, Span)> + DoubleEndedIterator + ExactSizeIterator + { + EarlyBinder::bind(self.predicates).iter_identity_copied() + } + + #[instrument(level = "debug", skip(self, tcx))] + fn instantiate_into( + self, + tcx: TyCtxt<'tcx>, + instantiated: &mut Vec<(ty::PolyTraitRef<'tcx>, Span)>, + args: GenericArgsRef<'tcx>, + ) { + if let Some(def_id) = self.parent { + tcx.const_conditions(def_id).instantiate_into(tcx, instantiated, args); + } + instantiated.extend( + self.predicates.iter().map(|&(p, s)| (EarlyBinder::bind(p).instantiate(tcx, args), s)), + ); + } + + pub fn instantiate_identity(self, tcx: TyCtxt<'tcx>) -> Vec<(ty::PolyTraitRef<'tcx>, Span)> { + let mut instantiated = vec![]; + self.instantiate_identity_into(tcx, &mut instantiated); + instantiated + } + + fn instantiate_identity_into( + self, + tcx: TyCtxt<'tcx>, + instantiated: &mut Vec<(ty::PolyTraitRef<'tcx>, Span)>, + ) { + if let Some(def_id) = self.parent { + tcx.const_conditions(def_id).instantiate_identity_into(tcx, instantiated); + } + instantiated.extend(self.predicates.iter().copied()); + } +} diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index ed24fcc7eb88a..84e1897019e7e 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -84,12 +84,13 @@ pub use self::parameterized::ParameterizedOverTcx; pub use self::pattern::{Pattern, PatternKind}; pub use self::predicate::{ AliasTerm, Clause, ClauseKind, CoercePredicate, ExistentialPredicate, - ExistentialPredicateStableCmpExt, ExistentialProjection, ExistentialTraitRef, NormalizesTo, - OutlivesPredicate, PolyCoercePredicate, PolyExistentialPredicate, PolyExistentialProjection, - PolyExistentialTraitRef, PolyProjectionPredicate, PolyRegionOutlivesPredicate, - PolySubtypePredicate, PolyTraitPredicate, PolyTraitRef, PolyTypeOutlivesPredicate, Predicate, - PredicateKind, ProjectionPredicate, RegionOutlivesPredicate, SubtypePredicate, ToPolyTraitRef, - TraitPredicate, TraitRef, TypeOutlivesPredicate, + ExistentialPredicateStableCmpExt, ExistentialProjection, ExistentialTraitRef, + HostEffectPredicate, NormalizesTo, OutlivesPredicate, PolyCoercePredicate, + PolyExistentialPredicate, PolyExistentialProjection, PolyExistentialTraitRef, + PolyProjectionPredicate, PolyRegionOutlivesPredicate, PolySubtypePredicate, PolyTraitPredicate, + PolyTraitRef, PolyTypeOutlivesPredicate, Predicate, PredicateKind, ProjectionPredicate, + RegionOutlivesPredicate, SubtypePredicate, ToPolyTraitRef, TraitPredicate, TraitRef, + TypeOutlivesPredicate, }; pub use self::region::BoundRegionKind::*; pub use self::region::{ diff --git a/compiler/rustc_middle/src/ty/parameterized.rs b/compiler/rustc_middle/src/ty/parameterized.rs index 7e1255f606c35..43bdce5b576dd 100644 --- a/compiler/rustc_middle/src/ty/parameterized.rs +++ b/compiler/rustc_middle/src/ty/parameterized.rs @@ -132,6 +132,7 @@ parameterized_over_tcx! { ty::Ty, ty::FnSig, ty::GenericPredicates, + ty::ConstConditions, ty::TraitRef, ty::Const, ty::Predicate, diff --git a/compiler/rustc_middle/src/ty/predicate.rs b/compiler/rustc_middle/src/ty/predicate.rs index d20cb368278b3..3ecaa3e22d39c 100644 --- a/compiler/rustc_middle/src/ty/predicate.rs +++ b/compiler/rustc_middle/src/ty/predicate.rs @@ -19,6 +19,7 @@ pub type ExistentialPredicate<'tcx> = ir::ExistentialPredicate>; pub type ExistentialTraitRef<'tcx> = ir::ExistentialTraitRef>; pub type ExistentialProjection<'tcx> = ir::ExistentialProjection>; pub type TraitPredicate<'tcx> = ir::TraitPredicate>; +pub type HostEffectPredicate<'tcx> = ir::HostEffectPredicate>; pub type ClauseKind<'tcx> = ir::ClauseKind>; pub type PredicateKind<'tcx> = ir::PredicateKind>; pub type NormalizesTo<'tcx> = ir::NormalizesTo>; @@ -143,6 +144,7 @@ impl<'tcx> Predicate<'tcx> { | PredicateKind::AliasRelate(..) | PredicateKind::NormalizesTo(..) => false, PredicateKind::Clause(ClauseKind::Trait(_)) + | PredicateKind::Clause(ClauseKind::HostEffect(..)) | PredicateKind::Clause(ClauseKind::RegionOutlives(_)) | PredicateKind::Clause(ClauseKind::TypeOutlives(_)) | PredicateKind::Clause(ClauseKind::Projection(_)) @@ -644,6 +646,7 @@ impl<'tcx> Predicate<'tcx> { match predicate.skip_binder() { PredicateKind::Clause(ClauseKind::Trait(t)) => Some(predicate.rebind(t)), PredicateKind::Clause(ClauseKind::Projection(..)) + | PredicateKind::Clause(ClauseKind::HostEffect(..)) | PredicateKind::Clause(ClauseKind::ConstArgHasType(..)) | PredicateKind::NormalizesTo(..) | PredicateKind::AliasRelate(..) @@ -664,6 +667,7 @@ impl<'tcx> Predicate<'tcx> { match predicate.skip_binder() { PredicateKind::Clause(ClauseKind::Projection(t)) => Some(predicate.rebind(t)), PredicateKind::Clause(ClauseKind::Trait(..)) + | PredicateKind::Clause(ClauseKind::HostEffect(..)) | PredicateKind::Clause(ClauseKind::ConstArgHasType(..)) | PredicateKind::NormalizesTo(..) | PredicateKind::AliasRelate(..) diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index 10c3522eb0e98..0248aad53e248 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -3075,6 +3075,15 @@ define_print! { p!(print(self.trait_ref.print_trait_sugared())) } + ty::HostEffectPredicate<'tcx> { + let constness = match self.host { + ty::HostPolarity::Const => { "const" } + ty::HostPolarity::Maybe => { "~const" } + }; + p!(print(self.trait_ref.self_ty()), ": {constness} "); + p!(print(self.trait_ref.print_trait_sugared())) + } + ty::TypeAndMut<'tcx> { p!(write("{}", self.mutbl.prefix_str()), print(self.ty)) } @@ -3087,6 +3096,7 @@ define_print! { ty::ClauseKind::RegionOutlives(predicate) => p!(print(predicate)), ty::ClauseKind::TypeOutlives(predicate) => p!(print(predicate)), ty::ClauseKind::Projection(predicate) => p!(print(predicate)), + ty::ClauseKind::HostEffect(predicate) => p!(print(predicate)), ty::ClauseKind::ConstArgHasType(ct, ty) => { p!("the constant `", print(ct), "` has type `", print(ty), "`") }, diff --git a/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs b/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs new file mode 100644 index 0000000000000..62b4bb0004cad --- /dev/null +++ b/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs @@ -0,0 +1,296 @@ +//! Dealing with host effect goals, i.e. enforcing the constness in +//! `T: const Trait` or `T: ~const Trait`. + +use rustc_type_ir::fast_reject::DeepRejectCtxt; +use rustc_type_ir::inherent::*; +use rustc_type_ir::{self as ty, Interner}; +use tracing::instrument; + +use super::assembly::Candidate; +use crate::delegate::SolverDelegate; +use crate::solve::assembly::{self}; +use crate::solve::{ + BuiltinImplSource, CandidateSource, Certainty, EvalCtxt, Goal, GoalSource, NoSolution, + QueryResult, +}; + +impl assembly::GoalKind for ty::HostEffectPredicate +where + D: SolverDelegate, + I: Interner, +{ + fn self_ty(self) -> I::Ty { + self.self_ty() + } + + fn trait_ref(self, _: I) -> ty::TraitRef { + self.trait_ref + } + + fn with_self_ty(self, cx: I, self_ty: I::Ty) -> Self { + self.with_self_ty(cx, self_ty) + } + + fn trait_def_id(self, _: I) -> I::DefId { + self.def_id() + } + + fn probe_and_match_goal_against_assumption( + ecx: &mut EvalCtxt<'_, D>, + source: rustc_type_ir::solve::CandidateSource, + goal: Goal, + assumption: ::Clause, + then: impl FnOnce(&mut EvalCtxt<'_, D>) -> QueryResult, + ) -> Result, NoSolution> { + if let Some(host_clause) = assumption.as_host_effect_clause() { + if host_clause.def_id() == goal.predicate.def_id() + && host_clause.host().satisfies(goal.predicate.host) + { + if !DeepRejectCtxt::relate_rigid_rigid(ecx.cx()).args_may_unify( + goal.predicate.trait_ref.args, + host_clause.skip_binder().trait_ref.args, + ) { + return Err(NoSolution); + } + + ecx.probe_trait_candidate(source).enter(|ecx| { + let assumption_trait_pred = ecx.instantiate_binder_with_infer(host_clause); + ecx.eq( + goal.param_env, + goal.predicate.trait_ref, + assumption_trait_pred.trait_ref, + )?; + then(ecx) + }) + } else { + Err(NoSolution) + } + } else { + Err(NoSolution) + } + } + + fn consider_impl_candidate( + ecx: &mut EvalCtxt<'_, D>, + goal: Goal, + impl_def_id: ::DefId, + ) -> Result, NoSolution> { + let cx = ecx.cx(); + + let impl_trait_ref = cx.impl_trait_ref(impl_def_id); + if !DeepRejectCtxt::relate_rigid_infer(ecx.cx()) + .args_may_unify(goal.predicate.trait_ref.args, impl_trait_ref.skip_binder().args) + { + return Err(NoSolution); + } + + let impl_polarity = cx.impl_polarity(impl_def_id); + match impl_polarity { + ty::ImplPolarity::Negative => return Err(NoSolution), + ty::ImplPolarity::Reservation => { + unimplemented!("reservation impl for const trait: {:?}", goal) + } + ty::ImplPolarity::Positive => {} + }; + + if !cx.is_const_impl(impl_def_id) { + return Err(NoSolution); + } + + ecx.probe_trait_candidate(CandidateSource::Impl(impl_def_id)).enter(|ecx| { + let impl_args = ecx.fresh_args_for_item(impl_def_id); + ecx.record_impl_args(impl_args); + let impl_trait_ref = impl_trait_ref.instantiate(cx, impl_args); + + ecx.eq(goal.param_env, goal.predicate.trait_ref, impl_trait_ref)?; + let where_clause_bounds = cx + .predicates_of(impl_def_id) + .iter_instantiated(cx, impl_args) + .map(|pred| goal.with(cx, pred)); + ecx.add_goals(GoalSource::ImplWhereBound, where_clause_bounds); + + // For this impl to be `const`, we need to check its `~const` bounds too. + let const_conditions = cx + .const_conditions(impl_def_id) + .iter_instantiated(cx, impl_args) + .map(|bound_trait_ref| { + goal.with(cx, bound_trait_ref.to_host_effect_clause(cx, goal.predicate.host)) + }); + ecx.add_goals(GoalSource::ImplWhereBound, const_conditions); + + ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) + }) + } + + fn consider_error_guaranteed_candidate( + ecx: &mut EvalCtxt<'_, D>, + _guar: ::ErrorGuaranteed, + ) -> Result, NoSolution> { + ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc) + .enter(|ecx| ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)) + } + + fn consider_auto_trait_candidate( + _ecx: &mut EvalCtxt<'_, D>, + _goal: Goal, + ) -> Result, NoSolution> { + unreachable!("auto traits are never const") + } + + fn consider_trait_alias_candidate( + _ecx: &mut EvalCtxt<'_, D>, + _goal: Goal, + ) -> Result, NoSolution> { + unreachable!("trait aliases are never const") + } + + fn consider_builtin_sized_candidate( + _ecx: &mut EvalCtxt<'_, D>, + _goal: Goal, + ) -> Result, NoSolution> { + unreachable!("Sized is never const") + } + + fn consider_builtin_copy_clone_candidate( + _ecx: &mut EvalCtxt<'_, D>, + _goal: Goal, + ) -> Result, NoSolution> { + todo!("Copy/Clone is not yet const") + } + + fn consider_builtin_pointer_like_candidate( + _ecx: &mut EvalCtxt<'_, D>, + _goal: Goal, + ) -> Result, NoSolution> { + unreachable!("PointerLike is not const") + } + + fn consider_builtin_fn_ptr_trait_candidate( + _ecx: &mut EvalCtxt<'_, D>, + _goal: Goal, + ) -> Result, NoSolution> { + todo!("Fn* are not yet const") + } + + fn consider_builtin_fn_trait_candidates( + _ecx: &mut EvalCtxt<'_, D>, + _goal: Goal, + _kind: rustc_type_ir::ClosureKind, + ) -> Result, NoSolution> { + todo!("Fn* are not yet const") + } + + fn consider_builtin_async_fn_trait_candidates( + _ecx: &mut EvalCtxt<'_, D>, + _goal: Goal, + _kind: rustc_type_ir::ClosureKind, + ) -> Result, NoSolution> { + todo!("AsyncFn* are not yet const") + } + + fn consider_builtin_async_fn_kind_helper_candidate( + _ecx: &mut EvalCtxt<'_, D>, + _goal: Goal, + ) -> Result, NoSolution> { + unreachable!("AsyncFnKindHelper is not const") + } + + fn consider_builtin_tuple_candidate( + _ecx: &mut EvalCtxt<'_, D>, + _goal: Goal, + ) -> Result, NoSolution> { + unreachable!("Tuple trait is not const") + } + + fn consider_builtin_pointee_candidate( + _ecx: &mut EvalCtxt<'_, D>, + _goal: Goal, + ) -> Result, NoSolution> { + unreachable!("Pointee is not const") + } + + fn consider_builtin_future_candidate( + _ecx: &mut EvalCtxt<'_, D>, + _goal: Goal, + ) -> Result, NoSolution> { + unreachable!("Future is not const") + } + + fn consider_builtin_iterator_candidate( + _ecx: &mut EvalCtxt<'_, D>, + _goal: Goal, + ) -> Result, NoSolution> { + todo!("Iterator is not yet const") + } + + fn consider_builtin_fused_iterator_candidate( + _ecx: &mut EvalCtxt<'_, D>, + _goal: Goal, + ) -> Result, NoSolution> { + unreachable!("FusedIterator is not const") + } + + fn consider_builtin_async_iterator_candidate( + _ecx: &mut EvalCtxt<'_, D>, + _goal: Goal, + ) -> Result, NoSolution> { + unreachable!("AsyncIterator is not const") + } + + fn consider_builtin_coroutine_candidate( + _ecx: &mut EvalCtxt<'_, D>, + _goal: Goal, + ) -> Result, NoSolution> { + unreachable!("Coroutine is not const") + } + + fn consider_builtin_discriminant_kind_candidate( + _ecx: &mut EvalCtxt<'_, D>, + _goal: Goal, + ) -> Result, NoSolution> { + unreachable!("DiscriminantKind is not const") + } + + fn consider_builtin_async_destruct_candidate( + _ecx: &mut EvalCtxt<'_, D>, + _goal: Goal, + ) -> Result, NoSolution> { + unreachable!("AsyncDestruct is not const") + } + + fn consider_builtin_destruct_candidate( + _ecx: &mut EvalCtxt<'_, D>, + _goal: Goal, + ) -> Result, NoSolution> { + unreachable!("Destruct is not const") + } + + fn consider_builtin_transmute_candidate( + _ecx: &mut EvalCtxt<'_, D>, + _goal: Goal, + ) -> Result, NoSolution> { + unreachable!("TransmuteFrom is not const") + } + + fn consider_structural_builtin_unsize_candidates( + _ecx: &mut EvalCtxt<'_, D>, + _goal: Goal, + ) -> Vec> { + unreachable!("Unsize is not const") + } +} + +impl EvalCtxt<'_, D> +where + D: SolverDelegate, + I: Interner, +{ + #[instrument(level = "trace", skip(self))] + pub(super) fn compute_host_effect_goal( + &mut self, + goal: Goal>, + ) -> QueryResult { + let candidates = self.assemble_and_evaluate_candidates(goal); + self.merge_candidates(candidates) + } +} diff --git a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs index 250174e033e3a..7608253882a27 100644 --- a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs @@ -443,6 +443,9 @@ where ty::PredicateKind::Clause(ty::ClauseKind::Trait(predicate)) => { self.compute_trait_goal(Goal { param_env, predicate }) } + ty::PredicateKind::Clause(ty::ClauseKind::HostEffect(predicate)) => { + self.compute_host_effect_goal(Goal { param_env, predicate }) + } ty::PredicateKind::Clause(ty::ClauseKind::Projection(predicate)) => { self.compute_projection_goal(Goal { param_env, predicate }) } diff --git a/compiler/rustc_next_trait_solver/src/solve/mod.rs b/compiler/rustc_next_trait_solver/src/solve/mod.rs index b7fdc339be5cd..6793779b205d1 100644 --- a/compiler/rustc_next_trait_solver/src/solve/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/mod.rs @@ -13,6 +13,7 @@ mod alias_relate; mod assembly; +mod effect_goals; mod eval_ctxt; pub mod inspect; mod normalizes_to; diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs index 7827975d3cafb..05954143aee00 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -137,6 +137,10 @@ where ty::ClauseKind::Trait(ty::TraitPredicate { trait_ref, polarity: _ }) => { self.visit_trait(trait_ref) } + ty::ClauseKind::HostEffect(pred) => { + try_visit!(self.visit_trait(pred.trait_ref)); + pred.host.visit_with(self) + } ty::ClauseKind::Projection(ty::ProjectionPredicate { projection_term: projection_ty, term, diff --git a/compiler/rustc_smir/src/rustc_smir/convert/ty.rs b/compiler/rustc_smir/src/rustc_smir/convert/ty.rs index 0abc89ddb81a8..8f05f859c0776 100644 --- a/compiler/rustc_smir/src/rustc_smir/convert/ty.rs +++ b/compiler/rustc_smir/src/rustc_smir/convert/ty.rs @@ -689,6 +689,9 @@ impl<'tcx> Stable<'tcx> for ty::ClauseKind<'tcx> { ClauseKind::ConstEvaluatable(const_) => { stable_mir::ty::ClauseKind::ConstEvaluatable(const_.stable(tables)) } + ClauseKind::HostEffect(..) => { + todo!() + } } } } diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs index b0175fff8a7f2..b7e2ed391cd4b 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs @@ -156,8 +156,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { (leaf_trait_predicate, &obligation) }; - let (main_trait_predicate, leaf_trait_predicate, predicate_constness) = self.get_effects_trait_pred_override(main_trait_predicate, leaf_trait_predicate, span); - let main_trait_ref = main_trait_predicate.to_poly_trait_ref(); let leaf_trait_ref = leaf_trait_predicate.to_poly_trait_ref(); @@ -228,7 +226,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { let err_msg = self.get_standard_error_message( main_trait_predicate, message, - predicate_constness, + None, append_const_msg, post_message, ); @@ -289,13 +287,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { ); } - if tcx.is_lang_item(leaf_trait_ref.def_id(), LangItem::Drop) - && matches!(predicate_constness, Some(ty::BoundConstness::ConstIfConst | ty::BoundConstness::Const)) - { - err.note("`~const Drop` was renamed to `~const Destruct`"); - err.note("See for more details"); - } - let explanation = get_explanation_based_on_obligation( self.tcx, &obligation, @@ -541,6 +532,29 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { err } + ty::PredicateKind::Clause(ty::ClauseKind::HostEffect(predicate)) => { + // FIXME(effects): We should recompute the predicate with `~const` + // if it's `const`, and if it holds, explain that this bound only + // *conditionally* holds. If that fails, we should also do selection + // to drill this down to an impl or built-in source, so we can + // point at it and explain that while the trait *is* implemented, + // that implementation is not const. + let err_msg = self.get_standard_error_message( + bound_predicate.rebind(ty::TraitPredicate { + trait_ref: predicate.trait_ref, + polarity: ty::PredicatePolarity::Positive, + }), + None, + Some(match predicate.host { + ty::HostPolarity::Maybe => ty::BoundConstness::ConstIfConst, + ty::HostPolarity::Const => ty::BoundConstness::Const, + }), + None, + String::new(), + ); + struct_span_code_err!(self.dcx(), span, E0277, "{}", err_msg) + } + ty::PredicateKind::Subtype(predicate) => { // Errors for Subtype predicates show up as // `FulfillmentErrorCode::SubtypeError`, @@ -2374,16 +2388,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { }) } - // FIXME(effects): Remove this. - fn get_effects_trait_pred_override( - &self, - p: ty::PolyTraitPredicate<'tcx>, - leaf: ty::PolyTraitPredicate<'tcx>, - _span: Span, - ) -> (ty::PolyTraitPredicate<'tcx>, ty::PolyTraitPredicate<'tcx>, ty::BoundConstness) { - (p, leaf, ty::BoundConstness::NotConst) - } - fn add_tuple_trait_message( &self, obligation_cause_code: &ObligationCauseCode<'tcx>, diff --git a/compiler/rustc_trait_selection/src/traits/auto_trait.rs b/compiler/rustc_trait_selection/src/traits/auto_trait.rs index 12aeee0d02fe7..934fe9ec47c0e 100644 --- a/compiler/rustc_trait_selection/src/traits/auto_trait.rs +++ b/compiler/rustc_trait_selection/src/traits/auto_trait.rs @@ -806,7 +806,8 @@ impl<'tcx> AutoTraitFinder<'tcx> { | ty::PredicateKind::Subtype(..) // FIXME(generic_const_exprs): you can absolutely add this as a where clauses | ty::PredicateKind::Clause(ty::ClauseKind::ConstEvaluatable(..)) - | ty::PredicateKind::Coerce(..) => {} + | ty::PredicateKind::Coerce(..) + | ty::PredicateKind::Clause(ty::ClauseKind::HostEffect(..)) => {} ty::PredicateKind::Ambiguous => return false, }; } diff --git a/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs b/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs index cc0450e0b057b..a068f25fe35ec 100644 --- a/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs +++ b/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs @@ -245,6 +245,7 @@ fn predicate_references_self<'tcx>( | ty::ClauseKind::RegionOutlives(..) // FIXME(generic_const_exprs): this can mention `Self` | ty::ClauseKind::ConstEvaluatable(..) + | ty::ClauseKind::HostEffect(..) => None, } } @@ -284,7 +285,8 @@ fn generics_require_sized_self(tcx: TyCtxt<'_>, def_id: DefId) -> bool { | ty::ClauseKind::Projection(_) | ty::ClauseKind::ConstArgHasType(_, _) | ty::ClauseKind::WellFormed(_) - | ty::ClauseKind::ConstEvaluatable(_) => false, + | ty::ClauseKind::ConstEvaluatable(_) + | ty::ClauseKind::HostEffect(..) => false, }) } diff --git a/compiler/rustc_trait_selection/src/traits/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs index ca9e6cd662d9a..1754418156d96 100644 --- a/compiler/rustc_trait_selection/src/traits/fulfill.rs +++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs @@ -372,7 +372,11 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> { | ty::PredicateKind::Subtype(_) | ty::PredicateKind::Coerce(_) | ty::PredicateKind::Clause(ty::ClauseKind::ConstEvaluatable(..)) - | ty::PredicateKind::ConstEquate(..) => { + | ty::PredicateKind::ConstEquate(..) + // FIXME(effects): We may need to do this using the higher-ranked + // pred instead of just instantiating it with placeholders b/c of + // higher-ranked implied bound issues in the old solver. + | ty::PredicateKind::Clause(ty::ClauseKind::HostEffect(..)) => { let pred = ty::Binder::dummy(infcx.enter_forall_and_leak_universe(binder)); let mut obligations = PredicateObligations::with_capacity(1); obligations.push(obligation.with(infcx.tcx, pred)); @@ -398,6 +402,10 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> { ) } + ty::PredicateKind::Clause(ty::ClauseKind::HostEffect(..)) => { + ProcessResult::Changed(Default::default()) + } + ty::PredicateKind::Clause(ty::ClauseKind::RegionOutlives(data)) => { if infcx.considering_regions { infcx.region_outlives_predicate(&obligation.cause, Binder::dummy(data)); diff --git a/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs index dfd0cab69058b..c6e41e57f0cec 100644 --- a/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs +++ b/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs @@ -96,6 +96,7 @@ pub fn compute_implied_outlives_bounds_inner<'tcx>( // FIXME(const_generics): Make sure that `<'a, 'b, const N: &'a &'b u32>` is sound // if we ever support that ty::PredicateKind::Clause(ty::ClauseKind::Trait(..)) + | ty::PredicateKind::Clause(ty::ClauseKind::HostEffect(..)) | ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(..)) | ty::PredicateKind::Subtype(..) | ty::PredicateKind::Coerce(..) @@ -200,6 +201,7 @@ pub fn compute_implied_outlives_bounds_compat_inner<'tcx>( // FIXME(const_generics): Make sure that `<'a, 'b, const N: &'a &'b u32>` is sound // if we ever support that ty::PredicateKind::Clause(ty::ClauseKind::Trait(..)) + | ty::PredicateKind::Clause(ty::ClauseKind::HostEffect(..)) | ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(..)) | ty::PredicateKind::Subtype(..) | ty::PredicateKind::Coerce(..) diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 4d7e2769af5f4..ec4114fd9d729 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -645,6 +645,13 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { self.evaluate_trait_predicate_recursively(previous_stack, obligation) } + ty::PredicateKind::Clause(ty::ClauseKind::HostEffect(..)) => { + // FIXME(effects): It should be relatively straightforward to implement + // old trait solver support for `HostEffect` bounds; or at least basic + // support for them. + todo!() + } + ty::PredicateKind::Subtype(p) => { let p = bound_predicate.rebind(p); // Does this code ever run? diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs index 8904a9a685807..437343b569c4f 100644 --- a/compiler/rustc_trait_selection/src/traits/wf.rs +++ b/compiler/rustc_trait_selection/src/traits/wf.rs @@ -170,6 +170,10 @@ pub fn clause_obligations<'tcx>( ty::ClauseKind::Trait(t) => { wf.compute_trait_pred(t, Elaborate::None); } + ty::ClauseKind::HostEffect(..) => { + // Technically the well-formedness of this predicate is implied by + // the corresponding trait predicate it should've been generated beside. + } ty::ClauseKind::RegionOutlives(..) => {} ty::ClauseKind::TypeOutlives(ty::OutlivesPredicate(ty, _reg)) => { wf.compute(ty.into()); @@ -1021,6 +1025,7 @@ pub(crate) fn required_region_bounds<'tcx>( } } ty::ClauseKind::Trait(_) + | ty::ClauseKind::HostEffect(..) | ty::ClauseKind::RegionOutlives(_) | ty::ClauseKind::Projection(_) | ty::ClauseKind::ConstArgHasType(_, _) diff --git a/compiler/rustc_traits/src/normalize_erasing_regions.rs b/compiler/rustc_traits/src/normalize_erasing_regions.rs index f01a12b0a00c9..3e2794f6489f8 100644 --- a/compiler/rustc_traits/src/normalize_erasing_regions.rs +++ b/compiler/rustc_traits/src/normalize_erasing_regions.rs @@ -55,6 +55,7 @@ fn not_outlives_predicate(p: ty::Predicate<'_>) -> bool { | ty::PredicateKind::Clause(ty::ClauseKind::TypeOutlives(..)) => false, ty::PredicateKind::Clause(ty::ClauseKind::Trait(..)) | ty::PredicateKind::Clause(ty::ClauseKind::Projection(..)) + | ty::PredicateKind::Clause(ty::ClauseKind::HostEffect(..)) | ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(..)) | ty::PredicateKind::NormalizesTo(..) | ty::PredicateKind::AliasRelate(..) diff --git a/compiler/rustc_ty_utils/src/ty.rs b/compiler/rustc_ty_utils/src/ty.rs index 28a81b1b06217..ac2708a29f4a3 100644 --- a/compiler/rustc_ty_utils/src/ty.rs +++ b/compiler/rustc_ty_utils/src/ty.rs @@ -150,6 +150,15 @@ fn param_env(tcx: TyCtxt<'_>, def_id: DefId) -> ty::ParamEnv<'_> { }); } + // We extend the param-env of our item with the const conditions of the item, + // since we're allowed to assume `~const` bounds hold within the item itself. + predicates.extend( + tcx.const_conditions(def_id) + .instantiate_identity(tcx) + .into_iter() + .map(|(trait_ref, _)| trait_ref.to_host_effect_clause(tcx, ty::HostPolarity::Maybe)), + ); + let local_did = def_id.as_local(); let unnormalized_env = diff --git a/compiler/rustc_type_ir/src/elaborate.rs b/compiler/rustc_type_ir/src/elaborate.rs index 56a72f943ab4e..72d392ecd7bdc 100644 --- a/compiler/rustc_type_ir/src/elaborate.rs +++ b/compiler/rustc_type_ir/src/elaborate.rs @@ -155,6 +155,16 @@ impl> Elaborator { ), }; } + // `T: ~const Trait` implies `T: ~const Supertrait`. + ty::ClauseKind::HostEffect(data) => self.extend_deduped( + cx.implied_const_bounds(data.def_id()).iter_identity().map(|trait_ref| { + elaboratable.child( + trait_ref + .to_host_effect_clause(cx, data.host) + .instantiate_supertrait(cx, bound_clause.rebind(data.trait_ref)), + ) + }), + ), ty::ClauseKind::TypeOutlives(ty::OutlivesPredicate(ty_max, r_min)) => { // We know that `T: 'a` for some type `T`. We can // often elaborate this. For example, if we know that diff --git a/compiler/rustc_type_ir/src/inherent.rs b/compiler/rustc_type_ir/src/inherent.rs index 02ec29a7f3d52..5af1aa2f8faa9 100644 --- a/compiler/rustc_type_ir/src/inherent.rs +++ b/compiler/rustc_type_ir/src/inherent.rs @@ -468,6 +468,14 @@ pub trait Clause>: .transpose() } + fn as_host_effect_clause(self) -> Option>> { + self.kind() + .map_bound( + |clause| if let ty::ClauseKind::HostEffect(t) = clause { Some(t) } else { None }, + ) + .transpose() + } + fn as_projection_clause(self) -> Option>> { self.kind() .map_bound( diff --git a/compiler/rustc_type_ir/src/interner.rs b/compiler/rustc_type_ir/src/interner.rs index 4184e9e313ff7..6a8113b38b7bd 100644 --- a/compiler/rustc_type_ir/src/interner.rs +++ b/compiler/rustc_type_ir/src/interner.rs @@ -24,6 +24,7 @@ pub trait Interner: + IrPrint> + IrPrint> + IrPrint> + + IrPrint> + IrPrint> + IrPrint> + IrPrint> @@ -228,6 +229,16 @@ pub trait Interner: def_id: Self::DefId, ) -> ty::EarlyBinder>; + fn is_const_impl(self, def_id: Self::DefId) -> bool; + fn const_conditions( + self, + def_id: Self::DefId, + ) -> ty::EarlyBinder>>>; + fn implied_const_bounds( + self, + def_id: Self::DefId, + ) -> ty::EarlyBinder>>>; + fn has_target_features(self, def_id: Self::DefId) -> bool; fn require_lang_item(self, lang_item: TraitSolverLangItem) -> Self::DefId; diff --git a/compiler/rustc_type_ir/src/ir_print.rs b/compiler/rustc_type_ir/src/ir_print.rs index d57d0816680bf..0c71f3a3df2a2 100644 --- a/compiler/rustc_type_ir/src/ir_print.rs +++ b/compiler/rustc_type_ir/src/ir_print.rs @@ -2,8 +2,8 @@ use std::fmt; use crate::{ AliasTerm, AliasTy, Binder, CoercePredicate, ExistentialProjection, ExistentialTraitRef, FnSig, - Interner, NormalizesTo, OutlivesPredicate, ProjectionPredicate, SubtypePredicate, - TraitPredicate, TraitRef, + HostEffectPredicate, Interner, NormalizesTo, OutlivesPredicate, ProjectionPredicate, + SubtypePredicate, TraitPredicate, TraitRef, }; pub trait IrPrint { @@ -53,6 +53,7 @@ define_display_via_print!( NormalizesTo, SubtypePredicate, CoercePredicate, + HostEffectPredicate, AliasTy, AliasTerm, FnSig, diff --git a/compiler/rustc_type_ir/src/predicate.rs b/compiler/rustc_type_ir/src/predicate.rs index e8ce39be3e50e..c316455034873 100644 --- a/compiler/rustc_type_ir/src/predicate.rs +++ b/compiler/rustc_type_ir/src/predicate.rs @@ -111,6 +111,13 @@ impl ty::Binder> { pub fn def_id(&self) -> I::DefId { self.skip_binder().def_id } + + pub fn to_host_effect_clause(self, cx: I, host: HostPolarity) -> I::Clause { + self.map_bound(|trait_ref| { + ty::ClauseKind::HostEffect(HostEffectPredicate { trait_ref, host }) + }) + .upcast(cx) + } } #[derive_where(Clone, Copy, Hash, PartialEq, Eq; I: Interner)] @@ -745,6 +752,64 @@ impl fmt::Debug for NormalizesTo { } } +#[derive_where(Clone, Copy, Hash, PartialEq, Eq, Debug; I: Interner)] +#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)] +#[cfg_attr(feature = "nightly", derive(TyEncodable, TyDecodable, HashStable_NoContext))] +pub struct HostEffectPredicate { + pub trait_ref: ty::TraitRef, + pub host: HostPolarity, +} + +impl HostEffectPredicate { + pub fn self_ty(self) -> I::Ty { + self.trait_ref.self_ty() + } + + pub fn with_self_ty(self, interner: I, self_ty: I::Ty) -> Self { + Self { trait_ref: self.trait_ref.with_self_ty(interner, self_ty), ..self } + } + + pub fn def_id(self) -> I::DefId { + self.trait_ref.def_id + } +} + +impl ty::Binder> { + pub fn def_id(self) -> I::DefId { + // Ok to skip binder since trait `DefId` does not care about regions. + self.skip_binder().def_id() + } + + pub fn self_ty(self) -> ty::Binder { + self.map_bound(|trait_ref| trait_ref.self_ty()) + } + + #[inline] + pub fn host(self) -> HostPolarity { + self.skip_binder().host + } +} + +#[derive(Clone, Copy, Hash, PartialEq, Eq, Debug)] +#[derive(TypeVisitable_Generic, TypeFoldable_Generic)] +#[cfg_attr(feature = "nightly", derive(TyEncodable, TyDecodable, HashStable_NoContext))] +pub enum HostPolarity { + /// May be called in const environments if the callee is const. + Maybe, + /// Always allowed to be called in const environments. + Const, +} + +impl HostPolarity { + pub fn satisfies(self, goal: HostPolarity) -> bool { + match (self, goal) { + (HostPolarity::Const, HostPolarity::Const | HostPolarity::Maybe) => true, + (HostPolarity::Maybe, HostPolarity::Maybe) => true, + (HostPolarity::Maybe, HostPolarity::Const) => false, + } + } +} + /// Encodes that `a` must be a subtype of `b`. The `a_is_expected` flag indicates /// whether the `a` type is the type that we should label as "expected" when /// presenting user diagnostics. diff --git a/compiler/rustc_type_ir/src/predicate_kind.rs b/compiler/rustc_type_ir/src/predicate_kind.rs index 46202dbb0f276..21f4456abd114 100644 --- a/compiler/rustc_type_ir/src/predicate_kind.rs +++ b/compiler/rustc_type_ir/src/predicate_kind.rs @@ -37,6 +37,12 @@ pub enum ClauseKind { /// Constant initializer must evaluate successfully. ConstEvaluatable(I::Const), + + /// Enforces the constness of the predicate we're calling. Like a projection + /// goal from a where clause, it's always going to be paired with a + /// corresponding trait clause; this just enforces the *constness* of that + /// implementation. + HostEffect(ty::HostEffectPredicate), } #[derive_where(Clone, Copy, Hash, PartialEq, Eq; I: Interner)] @@ -110,6 +116,7 @@ impl fmt::Debug for ClauseKind { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { ClauseKind::ConstArgHasType(ct, ty) => write!(f, "ConstArgHasType({ct:?}, {ty:?})"), + ClauseKind::HostEffect(data) => data.fmt(f), ClauseKind::Trait(a) => a.fmt(f), ClauseKind::RegionOutlives(pair) => pair.fmt(f), ClauseKind::TypeOutlives(pair) => pair.fmt(f), diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 861ca70cd83dd..81264b49dfd0e 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -368,7 +368,9 @@ pub(crate) fn clean_predicate<'tcx>( // FIXME(generic_const_exprs): should this do something? ty::ClauseKind::ConstEvaluatable(..) | ty::ClauseKind::WellFormed(..) - | ty::ClauseKind::ConstArgHasType(..) => None, + | ty::ClauseKind::ConstArgHasType(..) + // FIXME(effects): We can probably use this `HostEffect` pred to render `~const`. + | ty::ClauseKind::HostEffect(_) => None, } } diff --git a/tests/crashes/118320.rs b/tests/crashes/118320.rs deleted file mode 100644 index 093c58e1c05fb..0000000000000 --- a/tests/crashes/118320.rs +++ /dev/null @@ -1,14 +0,0 @@ -//@ known-bug: #118320 -//@ edition:2021 -#![feature(const_trait_impl, effects, const_closures)] - -#[const_trait] -trait Bar { - fn foo(&self); -} - -impl Bar for () {} - -const FOO: () = { - (const || (()).foo())(); -}; diff --git a/tests/crashes/119924-6.rs b/tests/crashes/119924-6.rs deleted file mode 100644 index f1cc9d2915915..0000000000000 --- a/tests/crashes/119924-6.rs +++ /dev/null @@ -1,15 +0,0 @@ -//@ known-bug: #119924 -//@ compile-flags: -Znext-solver -#![feature(const_trait_impl, effects)] - -struct S; -#[const_trait] -trait Trait {} - -const fn f>(U); // should've gotten rejected during AST validation - //~^ ICE no host param id for call in const yet no errors reported - 0 -}>>() {} - -pub fn main() {} diff --git a/tests/ui/const-generics/issues/issue-88119.stderr b/tests/ui/const-generics/issues/issue-88119.stderr index 98bb81968100b..a0ca33e38ef83 100644 --- a/tests/ui/const-generics/issues/issue-88119.stderr +++ b/tests/ui/const-generics/issues/issue-88119.stderr @@ -11,30 +11,12 @@ error[E0284]: type annotations needed: cannot normalize `<&T as ConstName>::{con | LL | impl const ConstName for &T | ^^ cannot normalize `<&T as ConstName>::{constant#0}` - | -note: required for `&T` to implement `ConstName` - --> $DIR/issue-88119.rs:19:35 - | -LL | impl const ConstName for &T - | ^^^^^^^^^ ^^ -LL | where -LL | [(); name_len::()]:, - | --------------------- unsatisfied trait bound introduced here error[E0284]: type annotations needed: cannot normalize `<&mut T as ConstName>::{constant#0}` --> $DIR/issue-88119.rs:26:49 | LL | impl const ConstName for &mut T | ^^^^^^ cannot normalize `<&mut T as ConstName>::{constant#0}` - | -note: required for `&mut T` to implement `ConstName` - --> $DIR/issue-88119.rs:26:35 - | -LL | impl const ConstName for &mut T - | ^^^^^^^^^ ^^^^^^ -LL | where -LL | [(); name_len::()]:, - | --------------------- unsatisfied trait bound introduced here error: aborting due to 3 previous errors diff --git a/tests/ui/consts/const-block-const-bound.stderr b/tests/ui/consts/const-block-const-bound.stderr index 42a42ae3938b7..8cb91d78f6cac 100644 --- a/tests/ui/consts/const-block-const-bound.stderr +++ b/tests/ui/consts/const-block-const-bound.stderr @@ -4,6 +4,14 @@ error: `~const` can only be applied to `#[const_trait]` traits LL | const fn f(x: T) {} | ^^^^^^^^ +error: `~const` can only be applied to `#[const_trait]` traits + --> $DIR/const-block-const-bound.rs:8:22 + | +LL | const fn f(x: T) {} + | ^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + error[E0493]: destructor of `T` cannot be evaluated at compile-time --> $DIR/const-block-const-bound.rs:8:32 | @@ -12,6 +20,6 @@ LL | const fn f(x: T) {} | | | the destructor for this type cannot be evaluated in constant functions -error: aborting due to 2 previous errors +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0493`. diff --git a/tests/ui/consts/constifconst-call-in-const-position.stderr b/tests/ui/consts/constifconst-call-in-const-position.stderr index 7de10f0287b4b..2195cab3f4d03 100644 --- a/tests/ui/consts/constifconst-call-in-const-position.stderr +++ b/tests/ui/consts/constifconst-call-in-const-position.stderr @@ -3,24 +3,12 @@ error: using `#![feature(effects)]` without enabling next trait solver globally = note: the next trait solver must be enabled globally for the effects feature to work correctly = help: use `-Znext-solver` to enable -error[E0308]: mismatched types +error[E0080]: evaluation of `foo::<()>::{constant#0}` failed --> $DIR/constifconst-call-in-const-position.rs:17:38 | LL | const fn foo() -> [u8; T::a()] { - | ^^^^^^ expected `false`, found `host` - | - = note: expected constant `false` - found constant `host` - -error[E0308]: mismatched types - --> $DIR/constifconst-call-in-const-position.rs:18:9 - | -LL | [0; T::a()] - | ^^^^^^ expected `false`, found `host` - | - = note: expected constant `false` - found constant `host` + | ^^^^^^ calling non-const function `<() as Tr>::a` -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0308`. +For more information about this error, try `rustc --explain E0080`. diff --git a/tests/ui/consts/fn_trait_refs.stderr b/tests/ui/consts/fn_trait_refs.stderr index 218c90f89a9e2..2b012432afd41 100644 --- a/tests/ui/consts/fn_trait_refs.stderr +++ b/tests/ui/consts/fn_trait_refs.stderr @@ -30,6 +30,22 @@ LL | T: ~const Fn<()> + ~const Destruct, | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` +error: `~const` can only be applied to `#[const_trait]` traits + --> $DIR/fn_trait_refs.rs:13:15 + | +LL | T: ~const Fn<()> + ~const Destruct, + | ^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: `~const` can only be applied to `#[const_trait]` traits + --> $DIR/fn_trait_refs.rs:13:31 + | +LL | T: ~const Fn<()> + ~const Destruct, + | ^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + error: `~const` can only be applied to `#[const_trait]` traits --> $DIR/fn_trait_refs.rs:20:15 | @@ -50,11 +66,35 @@ LL | T: ~const FnMut<()> + ~const Destruct, | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` +error: `~const` can only be applied to `#[const_trait]` traits + --> $DIR/fn_trait_refs.rs:20:15 + | +LL | T: ~const FnMut<()> + ~const Destruct, + | ^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: `~const` can only be applied to `#[const_trait]` traits + --> $DIR/fn_trait_refs.rs:20:34 + | +LL | T: ~const FnMut<()> + ~const Destruct, + | ^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: `~const` can only be applied to `#[const_trait]` traits + --> $DIR/fn_trait_refs.rs:27:15 + | +LL | T: ~const FnOnce<()>, + | ^^^^^^^^^^ + error: `~const` can only be applied to `#[const_trait]` traits --> $DIR/fn_trait_refs.rs:27:15 | LL | T: ~const FnOnce<()>, | ^^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: `~const` can only be applied to `#[const_trait]` traits --> $DIR/fn_trait_refs.rs:27:15 @@ -84,6 +124,22 @@ LL | T: ~const Fn<()> + ~const Destruct, | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` +error: `~const` can only be applied to `#[const_trait]` traits + --> $DIR/fn_trait_refs.rs:34:15 + | +LL | T: ~const Fn<()> + ~const Destruct, + | ^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: `~const` can only be applied to `#[const_trait]` traits + --> $DIR/fn_trait_refs.rs:34:31 + | +LL | T: ~const Fn<()> + ~const Destruct, + | ^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + error: `~const` can only be applied to `#[const_trait]` traits --> $DIR/fn_trait_refs.rs:48:15 | @@ -104,6 +160,22 @@ LL | T: ~const FnMut<()> + ~const Destruct, | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` +error: `~const` can only be applied to `#[const_trait]` traits + --> $DIR/fn_trait_refs.rs:48:15 + | +LL | T: ~const FnMut<()> + ~const Destruct, + | ^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: `~const` can only be applied to `#[const_trait]` traits + --> $DIR/fn_trait_refs.rs:48:34 + | +LL | T: ~const FnMut<()> + ~const Destruct, + | ^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + error[E0015]: cannot call non-const operator in constants --> $DIR/fn_trait_refs.rs:70:17 | @@ -212,7 +284,7 @@ LL | const fn test_fn_mut(mut f: T) -> (T::Output, T::Output) LL | } | - value is dropped here -error: aborting due to 25 previous errors +error: aborting due to 34 previous errors Some errors have detailed explanations: E0015, E0493, E0635. For more information about an error, try `rustc --explain E0015`. diff --git a/tests/ui/consts/unstable-const-fn-in-libcore.stderr b/tests/ui/consts/unstable-const-fn-in-libcore.stderr index 6c83eff4de013..59476f9860321 100644 --- a/tests/ui/consts/unstable-const-fn-in-libcore.stderr +++ b/tests/ui/consts/unstable-const-fn-in-libcore.stderr @@ -4,6 +4,14 @@ error: `~const` can only be applied to `#[const_trait]` traits LL | const fn unwrap_or_else T>(self, f: F) -> T { | ^^^^^^^^^^^^^ +error: `~const` can only be applied to `#[const_trait]` traits + --> $DIR/unstable-const-fn-in-libcore.rs:19:39 + | +LL | const fn unwrap_or_else T>(self, f: F) -> T { + | ^^^^^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + error[E0015]: cannot call non-const closure in constant functions --> $DIR/unstable-const-fn-in-libcore.rs:24:26 | @@ -38,7 +46,7 @@ LL | const fn unwrap_or_else T>(self, f: F) -> T { LL | } | - value is dropped here -error: aborting due to 4 previous errors +error: aborting due to 5 previous errors Some errors have detailed explanations: E0015, E0493. For more information about an error, try `rustc --explain E0015`. diff --git a/tests/ui/delegation/ice-issue-124347.rs b/tests/ui/delegation/ice-issue-124347.rs index ee2bf9e33eb89..b2b3c61a722b3 100644 --- a/tests/ui/delegation/ice-issue-124347.rs +++ b/tests/ui/delegation/ice-issue-124347.rs @@ -4,7 +4,7 @@ // FIXME(fn_delegation): `recursive delegation` error should be emitted here trait Trait { reuse Trait::foo { &self.0 } - //~^ ERROR cycle detected when computing generics of `Trait::foo` + //~^ ERROR recursive delegation is not supported yet } reuse foo; diff --git a/tests/ui/delegation/ice-issue-124347.stderr b/tests/ui/delegation/ice-issue-124347.stderr index bd0bc970b94c2..74c4b5cd949a3 100644 --- a/tests/ui/delegation/ice-issue-124347.stderr +++ b/tests/ui/delegation/ice-issue-124347.stderr @@ -1,16 +1,8 @@ -error[E0391]: cycle detected when computing generics of `Trait::foo` +error: recursive delegation is not supported yet --> $DIR/ice-issue-124347.rs:6:18 | LL | reuse Trait::foo { &self.0 } - | ^^^ - | - = note: ...which immediately requires computing generics of `Trait::foo` again -note: cycle used when inheriting delegation signature - --> $DIR/ice-issue-124347.rs:6:18 - | -LL | reuse Trait::foo { &self.0 } - | ^^^ - = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information + | ^^^ callee defined here error[E0391]: cycle detected when computing generics of `foo` --> $DIR/ice-issue-124347.rs:10:7 diff --git a/tests/ui/delegation/unsupported.rs b/tests/ui/delegation/unsupported.rs index e57effff48d81..56296db85a3fa 100644 --- a/tests/ui/delegation/unsupported.rs +++ b/tests/ui/delegation/unsupported.rs @@ -51,7 +51,7 @@ mod effects { } reuse Trait::foo; - //~^ ERROR delegation to a function with effect parameter is not supported yet + //~^ ERROR type annotations needed } fn main() {} diff --git a/tests/ui/delegation/unsupported.stderr b/tests/ui/delegation/unsupported.stderr index 6a627be3b64e7..1c79a603503f6 100644 --- a/tests/ui/delegation/unsupported.stderr +++ b/tests/ui/delegation/unsupported.stderr @@ -81,15 +81,15 @@ LL | pub reuse to_reuse2::foo; LL | reuse to_reuse1::foo; | ^^^ -error: delegation to a function with effect parameter is not supported yet +error[E0283]: type annotations needed --> $DIR/unsupported.rs:53:18 | -LL | fn foo(); - | --------- callee defined here -... LL | reuse Trait::foo; - | ^^^ + | ^^^ cannot infer type + | + = note: cannot satisfy `_: effects::Trait` error: aborting due to 5 previous errors; 2 warnings emitted -For more information about this error, try `rustc --explain E0391`. +Some errors have detailed explanations: E0283, E0391. +For more information about an error, try `rustc --explain E0283`. diff --git a/tests/ui/impl-trait/normalize-tait-in-const.stderr b/tests/ui/impl-trait/normalize-tait-in-const.stderr index e0d193b5d4027..f1e6207ed817d 100644 --- a/tests/ui/impl-trait/normalize-tait-in-const.stderr +++ b/tests/ui/impl-trait/normalize-tait-in-const.stderr @@ -10,6 +10,22 @@ error: `~const` can only be applied to `#[const_trait]` traits LL | const fn with_positive ~const Fn(&'a Alias<'a>) + ~const Destruct>(fun: F) { | ^^^^^^^^ +error: `~const` can only be applied to `#[const_trait]` traits + --> $DIR/normalize-tait-in-const.rs:26:42 + | +LL | const fn with_positive ~const Fn(&'a Alias<'a>) + ~const Destruct>(fun: F) { + | ^^^^^^^^^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: `~const` can only be applied to `#[const_trait]` traits + --> $DIR/normalize-tait-in-const.rs:26:69 + | +LL | const fn with_positive ~const Fn(&'a Alias<'a>) + ~const Destruct>(fun: F) { + | ^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + error[E0015]: cannot call non-const closure in constant functions --> $DIR/normalize-tait-in-const.rs:27:5 | @@ -35,7 +51,7 @@ LL | fun(filter_positive()); LL | } | - value is dropped here -error: aborting due to 4 previous errors +error: aborting due to 6 previous errors Some errors have detailed explanations: E0015, E0493. For more information about an error, try `rustc --explain E0015`. diff --git a/tests/ui/specialization/const_trait_impl.stderr b/tests/ui/specialization/const_trait_impl.stderr index 643f1de3e8d79..746b08fa71058 100644 --- a/tests/ui/specialization/const_trait_impl.stderr +++ b/tests/ui/specialization/const_trait_impl.stderr @@ -1,23 +1,3 @@ -error[E0049]: associated function `foo` has 1 const parameter but its trait declaration has 0 const parameters - --> $DIR/const_trait_impl.rs:6:1 - | -LL | #[const_trait] - | ^^^^^^^^^^^^^^ found 1 const parameter -LL | pub unsafe trait Sup { -LL | fn foo() -> u32; - | - expected 0 const parameters - -error[E0049]: associated function `foo` has 1 const parameter but its trait declaration has 0 const parameters - --> $DIR/const_trait_impl.rs:6:1 - | -LL | #[const_trait] - | ^^^^^^^^^^^^^^ found 1 const parameter -LL | pub unsafe trait Sup { -LL | fn foo() -> u32; - | - expected 0 const parameters - | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - error: `~const` can only be applied to `#[const_trait]` traits --> $DIR/const_trait_impl.rs:34:16 | @@ -36,34 +16,27 @@ error: `~const` can only be applied to `#[const_trait]` traits LL | impl const A for T { | ^^^^^^^ -error[E0049]: associated function `a` has 1 const parameter but its trait declaration has 0 const parameters - --> $DIR/const_trait_impl.rs:29:1 - | -LL | #[const_trait] - | ^^^^^^^^^^^^^^ found 1 const parameter -LL | pub trait A { -LL | fn a() -> u32; - | - expected 0 const parameters +error: `~const` can only be applied to `#[const_trait]` traits + --> $DIR/const_trait_impl.rs:40:16 + | +LL | impl const A for T { + | ^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -error[E0049]: associated function `a` has 1 const parameter but its trait declaration has 0 const parameters - --> $DIR/const_trait_impl.rs:29:1 +error: `~const` can only be applied to `#[const_trait]` traits + --> $DIR/const_trait_impl.rs:34:16 | -LL | #[const_trait] - | ^^^^^^^^^^^^^^ found 1 const parameter -LL | pub trait A { -LL | fn a() -> u32; - | - expected 0 const parameters +LL | impl const A for T { + | ^^^^^^^ | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -error[E0049]: associated function `a` has 1 const parameter but its trait declaration has 0 const parameters - --> $DIR/const_trait_impl.rs:29:1 +error: `~const` can only be applied to `#[const_trait]` traits + --> $DIR/const_trait_impl.rs:46:16 | -LL | #[const_trait] - | ^^^^^^^^^^^^^^ found 1 const parameter -LL | pub trait A { -LL | fn a() -> u32; - | - expected 0 const parameters +LL | impl const A for T { + | ^^^^^^^ | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` @@ -115,7 +88,6 @@ help: add `#![feature(effects)]` to the crate attributes to enable LL + #![feature(effects)] | -error: aborting due to 12 previous errors +error: aborting due to 10 previous errors -Some errors have detailed explanations: E0015, E0049. -For more information about an error, try `rustc --explain E0015`. +For more information about this error, try `rustc --explain E0015`. diff --git a/tests/ui/traits/const-traits/assoc-type-const-bound-usage-0.stderr b/tests/ui/traits/const-traits/assoc-type-const-bound-usage-0.stderr index 8288c660ce7c8..20448f51de22c 100644 --- a/tests/ui/traits/const-traits/assoc-type-const-bound-usage-0.stderr +++ b/tests/ui/traits/const-traits/assoc-type-const-bound-usage-0.stderr @@ -3,44 +3,5 @@ error: using `#![feature(effects)]` without enabling next trait solver globally = note: the next trait solver must be enabled globally for the effects feature to work correctly = help: use `-Znext-solver` to enable -error[E0277]: the trait bound `::Assoc: Trait` is not satisfied - --> $DIR/assoc-type-const-bound-usage-0.rs:13:5 - | -LL | T::Assoc::func() - | ^^^^^^^^ the trait `Trait` is not implemented for `::Assoc` - | -note: required by a bound in `Trait::func` - --> $DIR/assoc-type-const-bound-usage-0.rs:6:1 - | -LL | #[const_trait] - | ^^^^^^^^^^^^^^ required by this bound in `Trait::func` -... -LL | fn func() -> i32; - | ---- required by a bound in this associated function -help: consider further restricting the associated type - | -LL | const fn unqualified() -> i32 where ::Assoc: Trait { - | ++++++++++++++++++++++++++++++++ - -error[E0277]: the trait bound `::Assoc: Trait` is not satisfied - --> $DIR/assoc-type-const-bound-usage-0.rs:17:5 - | -LL | ::Assoc::func() - | ^^^^^^^^^^^^^^^^^^^ the trait `Trait` is not implemented for `::Assoc` - | -note: required by a bound in `Trait::func` - --> $DIR/assoc-type-const-bound-usage-0.rs:6:1 - | -LL | #[const_trait] - | ^^^^^^^^^^^^^^ required by this bound in `Trait::func` -... -LL | fn func() -> i32; - | ---- required by a bound in this associated function -help: consider further restricting the associated type - | -LL | const fn qualified() -> i32 where ::Assoc: Trait { - | ++++++++++++++++++++++++++++++++ - -error: aborting due to 3 previous errors +error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/traits/const-traits/assoc-type-const-bound-usage-1.stderr b/tests/ui/traits/const-traits/assoc-type-const-bound-usage-1.stderr index 0792d090321d3..20448f51de22c 100644 --- a/tests/ui/traits/const-traits/assoc-type-const-bound-usage-1.stderr +++ b/tests/ui/traits/const-traits/assoc-type-const-bound-usage-1.stderr @@ -3,44 +3,5 @@ error: using `#![feature(effects)]` without enabling next trait solver globally = note: the next trait solver must be enabled globally for the effects feature to work correctly = help: use `-Znext-solver` to enable -error[E0277]: the trait bound `::Assoc: Trait` is not satisfied - --> $DIR/assoc-type-const-bound-usage-1.rs:15:44 - | -LL | fn unqualified() -> Type<{ T::Assoc::func() }> { - | ^^^^^^^^ the trait `Trait` is not implemented for `::Assoc` - | -note: required by a bound in `Trait::func` - --> $DIR/assoc-type-const-bound-usage-1.rs:7:1 - | -LL | #[const_trait] - | ^^^^^^^^^^^^^^ required by this bound in `Trait::func` -... -LL | fn func() -> i32; - | ---- required by a bound in this associated function -help: consider further restricting the associated type - | -LL | fn unqualified() -> Type<{ T::Assoc::func() }> where ::Assoc: Trait { - | ++++++++++++++++++++++++++++++++ - -error[E0277]: the trait bound `::Assoc: Trait` is not satisfied - --> $DIR/assoc-type-const-bound-usage-1.rs:19:42 - | -LL | fn qualified() -> Type<{ ::Assoc::func() }> { - | ^^^^^^^^^^^^^^^^^^^ the trait `Trait` is not implemented for `::Assoc` - | -note: required by a bound in `Trait::func` - --> $DIR/assoc-type-const-bound-usage-1.rs:7:1 - | -LL | #[const_trait] - | ^^^^^^^^^^^^^^ required by this bound in `Trait::func` -... -LL | fn func() -> i32; - | ---- required by a bound in this associated function -help: consider further restricting the associated type - | -LL | fn qualified() -> Type<{ ::Assoc::func() }> where ::Assoc: Trait { - | ++++++++++++++++++++++++++++++++ - -error: aborting due to 3 previous errors +error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/traits/const-traits/call-const-trait-method-fail.stderr b/tests/ui/traits/const-traits/call-const-trait-method-fail.stderr index 5d2333d94fe89..40a06af85edca 100644 --- a/tests/ui/traits/const-traits/call-const-trait-method-fail.stderr +++ b/tests/ui/traits/const-traits/call-const-trait-method-fail.stderr @@ -2,20 +2,7 @@ error[E0277]: the trait bound `u32: ~const Plus` is not satisfied --> $DIR/call-const-trait-method-fail.rs:27:5 | LL | a.plus(b) - | ^ the trait `Plus` is not implemented for `u32` - | -note: required by a bound in `Plus::plus` - --> $DIR/call-const-trait-method-fail.rs:5:1 - | -LL | #[const_trait] - | ^^^^^^^^^^^^^^ required by this bound in `Plus::plus` -LL | pub trait Plus { -LL | fn plus(self, rhs: Self) -> Self; - | ---- required by a bound in this associated function -help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement - | -LL | pub const fn add_u32(a: u32, b: u32) -> u32 where u32: Plus { - | +++++++++++++++ + | ^^^^^^^^^ error: aborting due to 1 previous error diff --git a/tests/ui/traits/const-traits/call-const-trait-method-pass.stderr b/tests/ui/traits/const-traits/call-const-trait-method-pass.stderr index bf455a714a343..c1cead542163e 100644 --- a/tests/ui/traits/const-traits/call-const-trait-method-pass.stderr +++ b/tests/ui/traits/const-traits/call-const-trait-method-pass.stderr @@ -16,15 +16,6 @@ LL | impl const PartialEq for Int { = 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[E0049]: method `plus` has 1 const parameter but its trait declaration has 0 const parameters - --> $DIR/call-const-trait-method-pass.rs:24:1 - | -LL | #[const_trait] - | ^^^^^^^^^^^^^^ found 1 const parameter -LL | pub trait Plus { -LL | fn plus(self, rhs: Self) -> Self; - | - expected 0 const parameters - error[E0015]: cannot call non-const operator in constants --> $DIR/call-const-trait-method-pass.rs:39:22 | @@ -73,7 +64,6 @@ help: add `#![feature(effects)]` to the crate attributes to enable LL + #![feature(effects)] | -error: aborting due to 7 previous errors +error: aborting due to 6 previous errors -Some errors have detailed explanations: E0015, E0049. -For more information about an error, try `rustc --explain E0015`. +For more information about this error, try `rustc --explain E0015`. diff --git a/tests/ui/traits/const-traits/call-generic-in-impl.stderr b/tests/ui/traits/const-traits/call-generic-in-impl.stderr index 5cd274c6c5a22..368c22675e7f6 100644 --- a/tests/ui/traits/const-traits/call-generic-in-impl.stderr +++ b/tests/ui/traits/const-traits/call-generic-in-impl.stderr @@ -4,14 +4,13 @@ error: `~const` can only be applied to `#[const_trait]` traits LL | impl const MyPartialEq for T { | ^^^^^^^^^ -error[E0049]: method `eq` has 1 const parameter but its trait declaration has 0 const parameters - --> $DIR/call-generic-in-impl.rs:5:1 +error: `~const` can only be applied to `#[const_trait]` traits + --> $DIR/call-generic-in-impl.rs:10:16 + | +LL | impl const MyPartialEq for T { + | ^^^^^^^^^ | -LL | #[const_trait] - | ^^^^^^^^^^^^^^ found 1 const parameter -LL | trait MyPartialEq { -LL | fn eq(&self, other: &Self) -> bool; - | - expected 0 const parameters + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error[E0015]: cannot call non-const fn `::eq` in constant functions --> $DIR/call-generic-in-impl.rs:12:9 @@ -27,5 +26,4 @@ LL + #![feature(effects)] error: aborting due to 3 previous errors -Some errors have detailed explanations: E0015, E0049. -For more information about an error, try `rustc --explain E0015`. +For more information about this error, try `rustc --explain E0015`. diff --git a/tests/ui/traits/const-traits/call-generic-method-chain.stderr b/tests/ui/traits/const-traits/call-generic-method-chain.stderr index 57d57dfd5b935..dce9f0853904d 100644 --- a/tests/ui/traits/const-traits/call-generic-method-chain.stderr +++ b/tests/ui/traits/const-traits/call-generic-method-chain.stderr @@ -27,11 +27,27 @@ error: `~const` can only be applied to `#[const_trait]` traits LL | const fn equals_self(t: &T) -> bool { | ^^^^^^^^^ +error: `~const` can only be applied to `#[const_trait]` traits + --> $DIR/call-generic-method-chain.rs:19:32 + | +LL | const fn equals_self(t: &T) -> bool { + | ^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + error: `~const` can only be applied to `#[const_trait]` traits --> $DIR/call-generic-method-chain.rs:23:40 | LL | const fn equals_self_wrapper(t: &T) -> bool { | ^^^^^^^^^ -error: aborting due to 4 previous errors; 1 warning emitted +error: `~const` can only be applied to `#[const_trait]` traits + --> $DIR/call-generic-method-chain.rs:23:40 + | +LL | const fn equals_self_wrapper(t: &T) -> bool { + | ^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: aborting due to 6 previous errors; 1 warning emitted diff --git a/tests/ui/traits/const-traits/call-generic-method-dup-bound.stderr b/tests/ui/traits/const-traits/call-generic-method-dup-bound.stderr index 0088ed2eb13db..5da511a580e21 100644 --- a/tests/ui/traits/const-traits/call-generic-method-dup-bound.stderr +++ b/tests/ui/traits/const-traits/call-generic-method-dup-bound.stderr @@ -27,11 +27,27 @@ error: `~const` can only be applied to `#[const_trait]` traits LL | const fn equals_self(t: &T) -> bool { | ^^^^^^^^^ +error: `~const` can only be applied to `#[const_trait]` traits + --> $DIR/call-generic-method-dup-bound.rs:19:44 + | +LL | const fn equals_self(t: &T) -> bool { + | ^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + error: `~const` can only be applied to `#[const_trait]` traits --> $DIR/call-generic-method-dup-bound.rs:26:37 | LL | const fn equals_self2(t: &T) -> bool { | ^^^^^^^^^ -error: aborting due to 4 previous errors; 1 warning emitted +error: `~const` can only be applied to `#[const_trait]` traits + --> $DIR/call-generic-method-dup-bound.rs:26:37 + | +LL | const fn equals_self2(t: &T) -> bool { + | ^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: aborting due to 6 previous errors; 1 warning emitted diff --git a/tests/ui/traits/const-traits/call-generic-method-nonconst.stderr b/tests/ui/traits/const-traits/call-generic-method-nonconst.stderr index 68c9fc400104e..06b99375cdaa7 100644 --- a/tests/ui/traits/const-traits/call-generic-method-nonconst.stderr +++ b/tests/ui/traits/const-traits/call-generic-method-nonconst.stderr @@ -1,20 +1,8 @@ error[E0277]: the trait bound `S: const Foo` is not satisfied - --> $DIR/call-generic-method-nonconst.rs:25:34 + --> $DIR/call-generic-method-nonconst.rs:25:22 | LL | pub const EQ: bool = equals_self(&S); - | ----------- ^^ the trait `Foo` is not implemented for `S` - | | - | required by a bound introduced by this call - | -note: required by a bound in `equals_self` - --> $DIR/call-generic-method-nonconst.rs:18:25 - | -LL | const fn equals_self(t: &T) -> bool { - | ^^^^^^^^^^ required by this bound in `equals_self` -help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement - | -LL | pub const EQ: bool where S: Foo = equals_self(&S); - | ++++++++++++ + | ^^^^^^^^^^^^^^^ error: aborting due to 1 previous error diff --git a/tests/ui/traits/const-traits/call-generic-method-pass.stderr b/tests/ui/traits/const-traits/call-generic-method-pass.stderr index 4a6100c3c1aac..52579813b691b 100644 --- a/tests/ui/traits/const-traits/call-generic-method-pass.stderr +++ b/tests/ui/traits/const-traits/call-generic-method-pass.stderr @@ -27,5 +27,13 @@ error: `~const` can only be applied to `#[const_trait]` traits LL | const fn equals_self(t: &T) -> bool { | ^^^^^^^^^ -error: aborting due to 3 previous errors; 1 warning emitted +error: `~const` can only be applied to `#[const_trait]` traits + --> $DIR/call-generic-method-pass.rs:19:32 + | +LL | const fn equals_self(t: &T) -> bool { + | ^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: aborting due to 4 previous errors; 1 warning emitted diff --git a/tests/ui/traits/const-traits/const-bounds-non-const-trait.rs b/tests/ui/traits/const-traits/const-bounds-non-const-trait.rs index db446f8bc2eab..d51d231b8a977 100644 --- a/tests/ui/traits/const-traits/const-bounds-non-const-trait.rs +++ b/tests/ui/traits/const-traits/const-bounds-non-const-trait.rs @@ -5,6 +5,7 @@ trait NonConst {} const fn perform() {} //~^ ERROR `~const` can only be applied to `#[const_trait]` traits +//~| ERROR `~const` can only be applied to `#[const_trait]` traits fn operate() {} //~^ ERROR `const` can only be applied to `#[const_trait]` traits diff --git a/tests/ui/traits/const-traits/const-bounds-non-const-trait.stderr b/tests/ui/traits/const-traits/const-bounds-non-const-trait.stderr index e1a85fc54144b..6c3c11c6a4756 100644 --- a/tests/ui/traits/const-traits/const-bounds-non-const-trait.stderr +++ b/tests/ui/traits/const-traits/const-bounds-non-const-trait.stderr @@ -18,11 +18,19 @@ error: `~const` can only be applied to `#[const_trait]` traits LL | const fn perform() {} | ^^^^^^^^ +error: `~const` can only be applied to `#[const_trait]` traits + --> $DIR/const-bounds-non-const-trait.rs:6:28 + | +LL | const fn perform() {} + | ^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + error: `const` can only be applied to `#[const_trait]` traits - --> $DIR/const-bounds-non-const-trait.rs:9:21 + --> $DIR/const-bounds-non-const-trait.rs:10:21 | LL | fn operate() {} | ^^^^^^^^ -error: aborting due to 3 previous errors; 1 warning emitted +error: aborting due to 4 previous errors; 1 warning emitted diff --git a/tests/ui/traits/const-traits/const-closure-trait-method-fail.stderr b/tests/ui/traits/const-traits/const-closure-trait-method-fail.stderr index 507ceaae2eab3..4e6707bba51ce 100644 --- a/tests/ui/traits/const-traits/const-closure-trait-method-fail.stderr +++ b/tests/ui/traits/const-traits/const-closure-trait-method-fail.stderr @@ -1,17 +1,16 @@ -error[E0049]: method `a` has 1 const parameter but its trait declaration has 0 const parameters - --> $DIR/const-closure-trait-method-fail.rs:5:1 - | -LL | #[const_trait] - | ^^^^^^^^^^^^^^ found 1 const parameter -LL | trait Tr { -LL | fn a(self) -> i32; - | - expected 0 const parameters +error: `~const` can only be applied to `#[const_trait]` traits + --> $DIR/const-closure-trait-method-fail.rs:14:39 + | +LL | const fn need_const_closure i32>(x: T) -> i32 { + | ^^^^^^^^^^^^^^^^^ error: `~const` can only be applied to `#[const_trait]` traits --> $DIR/const-closure-trait-method-fail.rs:14:39 | LL | const fn need_const_closure i32>(x: T) -> i32 { | ^^^^^^^^^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error[E0015]: cannot call non-const closure in constant functions --> $DIR/const-closure-trait-method-fail.rs:15:5 @@ -31,5 +30,4 @@ LL + #![feature(effects)] error: aborting due to 3 previous errors -Some errors have detailed explanations: E0015, E0049. -For more information about an error, try `rustc --explain E0015`. +For more information about this error, try `rustc --explain E0015`. diff --git a/tests/ui/traits/const-traits/const-closure-trait-method.stderr b/tests/ui/traits/const-traits/const-closure-trait-method.stderr index 2a54cd5d7f6e5..0f0cd73cc102c 100644 --- a/tests/ui/traits/const-traits/const-closure-trait-method.stderr +++ b/tests/ui/traits/const-traits/const-closure-trait-method.stderr @@ -1,17 +1,16 @@ -error[E0049]: method `a` has 1 const parameter but its trait declaration has 0 const parameters - --> $DIR/const-closure-trait-method.rs:5:1 - | -LL | #[const_trait] - | ^^^^^^^^^^^^^^ found 1 const parameter -LL | trait Tr { -LL | fn a(self) -> i32; - | - expected 0 const parameters +error: `~const` can only be applied to `#[const_trait]` traits + --> $DIR/const-closure-trait-method.rs:14:39 + | +LL | const fn need_const_closure i32>(x: T) -> i32 { + | ^^^^^^^^^^^^^^^^^ error: `~const` can only be applied to `#[const_trait]` traits --> $DIR/const-closure-trait-method.rs:14:39 | LL | const fn need_const_closure i32>(x: T) -> i32 { | ^^^^^^^^^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error[E0015]: cannot call non-const closure in constant functions --> $DIR/const-closure-trait-method.rs:15:5 @@ -31,5 +30,4 @@ LL + #![feature(effects)] error: aborting due to 3 previous errors -Some errors have detailed explanations: E0015, E0049. -For more information about an error, try `rustc --explain E0015`. +For more information about this error, try `rustc --explain E0015`. diff --git a/tests/ui/traits/const-traits/const-closures.stderr b/tests/ui/traits/const-traits/const-closures.stderr index a0f053253892f..4d354cb281fea 100644 --- a/tests/ui/traits/const-traits/const-closures.stderr +++ b/tests/ui/traits/const-traits/const-closures.stderr @@ -16,12 +16,44 @@ error: `~const` can only be applied to `#[const_trait]` traits LL | F: ~const Fn() -> u8, | ^^^^^^^^^^ +error: `~const` can only be applied to `#[const_trait]` traits + --> $DIR/const-closures.rs:8:19 + | +LL | F: ~const FnOnce() -> u8, + | ^^^^^^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: `~const` can only be applied to `#[const_trait]` traits + --> $DIR/const-closures.rs:9:19 + | +LL | F: ~const FnMut() -> u8, + | ^^^^^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: `~const` can only be applied to `#[const_trait]` traits + --> $DIR/const-closures.rs:10:19 + | +LL | F: ~const Fn() -> u8, + | ^^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + error: `~const` can only be applied to `#[const_trait]` traits --> $DIR/const-closures.rs:23:27 | LL | const fn answer u8>(f: &F) -> u8 { | ^^^^^^^^^^ +error: `~const` can only be applied to `#[const_trait]` traits + --> $DIR/const-closures.rs:23:27 + | +LL | const fn answer u8>(f: &F) -> u8 { + | ^^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + error[E0015]: cannot call non-const closure in constant functions --> $DIR/const-closures.rs:24:5 | @@ -70,6 +102,6 @@ help: add `#![feature(effects)]` to the crate attributes to enable LL + #![feature(effects)] | -error: aborting due to 7 previous errors +error: aborting due to 11 previous errors For more information about this error, try `rustc --explain E0015`. diff --git a/tests/ui/traits/const-traits/const-default-method-bodies.stderr b/tests/ui/traits/const-traits/const-default-method-bodies.stderr index 0809d9c1e1d32..071eaf495418a 100644 --- a/tests/ui/traits/const-traits/const-default-method-bodies.stderr +++ b/tests/ui/traits/const-traits/const-default-method-bodies.stderr @@ -1,21 +1,8 @@ error[E0277]: the trait bound `NonConstImpl: ~const ConstDefaultFn` is not satisfied - --> $DIR/const-default-method-bodies.rs:26:18 + --> $DIR/const-default-method-bodies.rs:26:5 | LL | NonConstImpl.a(); - | ^ the trait `ConstDefaultFn` is not implemented for `NonConstImpl` - | -note: required by a bound in `ConstDefaultFn::a` - --> $DIR/const-default-method-bodies.rs:5:1 - | -LL | #[const_trait] - | ^^^^^^^^^^^^^^ required by this bound in `ConstDefaultFn::a` -... -LL | fn a(self) { - | - required by a bound in this associated function -help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement - | -LL | const fn test() where NonConstImpl: ConstDefaultFn { - | ++++++++++++++++++++++++++++++++++ + | ^^^^^^^^^^^^^^^^ error: aborting due to 1 previous error diff --git a/tests/ui/traits/const-traits/const-drop-bound.stderr b/tests/ui/traits/const-traits/const-drop-bound.stderr index be197006f021a..d94b0542324f6 100644 --- a/tests/ui/traits/const-traits/const-drop-bound.stderr +++ b/tests/ui/traits/const-traits/const-drop-bound.stderr @@ -4,6 +4,14 @@ error: `~const` can only be applied to `#[const_trait]` traits LL | const fn foo(res: Result) -> Option where E: ~const Destruct { | ^^^^^^^^ +error: `~const` can only be applied to `#[const_trait]` traits + --> $DIR/const-drop-bound.rs:9:68 + | +LL | const fn foo(res: Result) -> Option where E: ~const Destruct { + | ^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + error: `~const` can only be applied to `#[const_trait]` traits --> $DIR/const-drop-bound.rs:20:15 | @@ -16,12 +24,28 @@ error: `~const` can only be applied to `#[const_trait]` traits LL | E: ~const Destruct, | ^^^^^^^^ +error: `~const` can only be applied to `#[const_trait]` traits + --> $DIR/const-drop-bound.rs:20:15 + | +LL | T: ~const Destruct, + | ^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: `~const` can only be applied to `#[const_trait]` traits + --> $DIR/const-drop-bound.rs:21:15 + | +LL | E: ~const Destruct, + | ^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + error[E0493]: destructor of `E` cannot be evaluated at compile-time --> $DIR/const-drop-bound.rs:12:13 | LL | Err(_e) => None, | ^^ the destructor for this type cannot be evaluated in constant functions -error: aborting due to 4 previous errors +error: aborting due to 7 previous errors For more information about this error, try `rustc --explain E0493`. diff --git a/tests/ui/traits/const-traits/const-drop-fail-2.stderr b/tests/ui/traits/const-traits/const-drop-fail-2.stderr index faf24c6d91145..27e8053c9690a 100644 --- a/tests/ui/traits/const-traits/const-drop-fail-2.stderr +++ b/tests/ui/traits/const-traits/const-drop-fail-2.stderr @@ -13,6 +13,14 @@ error: `~const` can only be applied to `#[const_trait]` traits LL | const fn check(_: T) {} | ^^^^^^^^ +error: `~const` can only be applied to `#[const_trait]` traits + --> $DIR/const-drop-fail-2.rs:20:26 + | +LL | const fn check(_: T) {} + | ^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + error[E0493]: destructor of `T` cannot be evaluated at compile-time --> $DIR/const-drop-fail-2.rs:20:36 | @@ -33,7 +41,7 @@ help: add `#![feature(effects)]` to the crate attributes to enable LL + #![feature(effects)] | -error: aborting due to 4 previous errors +error: aborting due to 5 previous errors Some errors have detailed explanations: E0015, E0493. For more information about an error, try `rustc --explain E0015`. diff --git a/tests/ui/traits/const-traits/const-drop-fail.precise.stderr b/tests/ui/traits/const-traits/const-drop-fail.precise.stderr index 3d400bf015871..bde13b4d6cfa8 100644 --- a/tests/ui/traits/const-traits/const-drop-fail.precise.stderr +++ b/tests/ui/traits/const-traits/const-drop-fail.precise.stderr @@ -13,6 +13,14 @@ error: `~const` can only be applied to `#[const_trait]` traits LL | const fn check(_: T) {} | ^^^^^^^^ +error: `~const` can only be applied to `#[const_trait]` traits + --> $DIR/const-drop-fail.rs:23:26 + | +LL | const fn check(_: T) {} + | ^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + error[E0493]: destructor of `T` cannot be evaluated at compile-time --> $DIR/const-drop-fail.rs:23:36 | @@ -71,7 +79,7 @@ LL | | } | |_- in this macro invocation = note: this error originates in the macro `check_all` (in Nightly builds, run with -Z macro-backtrace for more info) -error: aborting due to 5 previous errors +error: aborting due to 6 previous errors Some errors have detailed explanations: E0080, E0493. For more information about an error, try `rustc --explain E0080`. diff --git a/tests/ui/traits/const-traits/const-drop-fail.stock.stderr b/tests/ui/traits/const-traits/const-drop-fail.stock.stderr index fd0f6d02684a6..064ffacca4274 100644 --- a/tests/ui/traits/const-traits/const-drop-fail.stock.stderr +++ b/tests/ui/traits/const-traits/const-drop-fail.stock.stderr @@ -13,6 +13,14 @@ error: `~const` can only be applied to `#[const_trait]` traits LL | const fn check(_: T) {} | ^^^^^^^^ +error: `~const` can only be applied to `#[const_trait]` traits + --> $DIR/const-drop-fail.rs:23:26 + | +LL | const fn check(_: T) {} + | ^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + error[E0493]: destructor of `T` cannot be evaluated at compile-time --> $DIR/const-drop-fail.rs:23:36 | @@ -21,6 +29,6 @@ LL | const fn check(_: T) {} | | | the destructor for this type cannot be evaluated in constant functions -error: aborting due to 3 previous errors +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0493`. diff --git a/tests/ui/traits/const-traits/const-drop.precise.stderr b/tests/ui/traits/const-traits/const-drop.precise.stderr index dd3ea5d241d76..7b6d185c7cc8b 100644 --- a/tests/ui/traits/const-traits/const-drop.precise.stderr +++ b/tests/ui/traits/const-traits/const-drop.precise.stderr @@ -40,23 +40,11 @@ error: `~const` can only be applied to `#[const_trait]` traits LL | const fn a(_: T) {} | ^^^^^^^^ -error[E0049]: associated function `foo` has 1 const parameter but its trait declaration has 0 const parameters - --> $DIR/const-drop.rs:53:5 - | -LL | #[const_trait] - | ^^^^^^^^^^^^^^ found 1 const parameter -LL | pub trait SomeTrait { -LL | fn foo(); - | - expected 0 const parameters - -error[E0049]: associated function `foo` has 1 const parameter but its trait declaration has 0 const parameters - --> $DIR/const-drop.rs:53:5 +error: `~const` can only be applied to `#[const_trait]` traits + --> $DIR/const-drop.rs:18:22 | -LL | #[const_trait] - | ^^^^^^^^^^^^^^ found 1 const parameter -LL | pub trait SomeTrait { -LL | fn foo(); - | - expected 0 const parameters +LL | const fn a(_: T) {} + | ^^^^^^^^ | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` @@ -78,7 +66,7 @@ help: add `#![feature(effects)]` to the crate attributes to enable LL + #![feature(effects)] | -error: aborting due to 9 previous errors +error: aborting due to 8 previous errors -Some errors have detailed explanations: E0015, E0049, E0493. +Some errors have detailed explanations: E0015, E0493. For more information about an error, try `rustc --explain E0015`. diff --git a/tests/ui/traits/const-traits/const-drop.stock.stderr b/tests/ui/traits/const-traits/const-drop.stock.stderr index aa59e1c8dc492..b497c39b08aaf 100644 --- a/tests/ui/traits/const-traits/const-drop.stock.stderr +++ b/tests/ui/traits/const-traits/const-drop.stock.stderr @@ -40,23 +40,11 @@ error: `~const` can only be applied to `#[const_trait]` traits LL | const fn a(_: T) {} | ^^^^^^^^ -error[E0049]: associated function `foo` has 1 const parameter but its trait declaration has 0 const parameters - --> $DIR/const-drop.rs:53:5 - | -LL | #[const_trait] - | ^^^^^^^^^^^^^^ found 1 const parameter -LL | pub trait SomeTrait { -LL | fn foo(); - | - expected 0 const parameters - -error[E0049]: associated function `foo` has 1 const parameter but its trait declaration has 0 const parameters - --> $DIR/const-drop.rs:53:5 +error: `~const` can only be applied to `#[const_trait]` traits + --> $DIR/const-drop.rs:18:22 | -LL | #[const_trait] - | ^^^^^^^^^^^^^^ found 1 const parameter -LL | pub trait SomeTrait { -LL | fn foo(); - | - expected 0 const parameters +LL | const fn a(_: T) {} + | ^^^^^^^^ | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` @@ -80,7 +68,7 @@ help: add `#![feature(effects)]` to the crate attributes to enable LL + #![feature(effects)] | -error: aborting due to 9 previous errors +error: aborting due to 8 previous errors -Some errors have detailed explanations: E0015, E0049, E0493. +Some errors have detailed explanations: E0015, E0493. For more information about an error, try `rustc --explain E0015`. diff --git a/tests/ui/traits/const-traits/const-fns-are-early-bound.rs b/tests/ui/traits/const-traits/const-fns-are-early-bound.rs index 59a61e4f954de..6d08d8bdd919e 100644 --- a/tests/ui/traits/const-traits/const-fns-are-early-bound.rs +++ b/tests/ui/traits/const-traits/const-fns-are-early-bound.rs @@ -1,4 +1,6 @@ //@ known-bug: #110395 +//@ failure-status: 101 +//@ dont-check-compiler-stderr // FIXME(effects) check-pass //@ compile-flags: -Znext-solver diff --git a/tests/ui/traits/const-traits/const-fns-are-early-bound.stderr b/tests/ui/traits/const-traits/const-fns-are-early-bound.stderr deleted file mode 100644 index 9eda9d98ec552..0000000000000 --- a/tests/ui/traits/const-traits/const-fns-are-early-bound.stderr +++ /dev/null @@ -1,20 +0,0 @@ -error[E0277]: the trait bound `fn() {foo}: const FnOnce()` is not satisfied - --> $DIR/const-fns-are-early-bound.rs:31:17 - | -LL | is_const_fn(foo); - | ----------- ^^^ the trait `FnOnce()` is not implemented for fn item `fn() {foo}` - | | - | required by a bound introduced by this call - | -note: required by a bound in `is_const_fn` - --> $DIR/const-fns-are-early-bound.rs:25:12 - | -LL | fn is_const_fn(_: F) - | ----------- required by a bound in this function -LL | where -LL | F: const FnOnce<()>, - | ^^^^^^^^^^^^^^^^ required by this bound in `is_const_fn` - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/traits/const-traits/const-impl-trait.stderr b/tests/ui/traits/const-traits/const-impl-trait.stderr deleted file mode 100644 index 1040af7541c08..0000000000000 --- a/tests/ui/traits/const-traits/const-impl-trait.stderr +++ /dev/null @@ -1,249 +0,0 @@ -error[E0635]: unknown feature `const_cmp` - --> $DIR/const-impl-trait.rs:8:5 - | -LL | const_cmp, - | ^^^^^^^^^ - -error: using `#![feature(effects)]` without enabling next trait solver globally - | - = note: the next trait solver must be enabled globally for the effects feature to work correctly - = help: use `-Znext-solver` to enable - -error: `~const` can only be applied to `#[const_trait]` traits - --> $DIR/const-impl-trait.rs:13: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:17: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:17:49 - | -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:18:20 - | -LL | -> impl ~const PartialEq + ~const Destruct - | ^^^^^^^^^ - -error: `~const` can only be applied to `#[const_trait]` traits - --> $DIR/const-impl-trait.rs:18:39 - | -LL | -> impl ~const PartialEq + ~const Destruct - | ^^^^^^^^ - -error: `~const` can only be applied to `#[const_trait]` traits - --> $DIR/const-impl-trait.rs:18:20 - | -LL | -> impl ~const PartialEq + ~const Destruct - | ^^^^^^^^^ - | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error: `~const` can only be applied to `#[const_trait]` traits - --> $DIR/const-impl-trait.rs:18:39 - | -LL | -> impl ~const PartialEq + ~const Destruct - | ^^^^^^^^ - | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error: `~const` can only be applied to `#[const_trait]` traits - --> $DIR/const-impl-trait.rs:25: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:25:48 - | -LL | fn huh() -> impl ~const PartialEq + ~const Destruct + Copy; - | ^^^^^^^^ - -error: `~const` can only be applied to `#[const_trait]` traits - --> $DIR/const-impl-trait.rs:29: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:29:48 - | -LL | fn huh() -> impl ~const PartialEq + ~const Destruct + Copy { - | ^^^^^^^^ - -error: `~const` can only be applied to `#[const_trait]` traits - --> $DIR/const-impl-trait.rs:29:29 - | -LL | fn huh() -> impl ~const PartialEq + ~const Destruct + Copy { - | ^^^^^^^^^ - | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error: `~const` can only be applied to `#[const_trait]` traits - --> $DIR/const-impl-trait.rs:29:48 - | -LL | fn huh() -> impl ~const PartialEq + ~const Destruct + Copy { - | ^^^^^^^^ - | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error: `~const` can only be applied to `#[const_trait]` traits - --> $DIR/const-impl-trait.rs:50:41 - | -LL | const fn apit(_: impl ~const T + ~const Destruct) {} - | ^^^^^^^^ - -error: `~const` can only be applied to `#[const_trait]` traits - --> $DIR/const-impl-trait.rs:54:73 - | -LL | const fn apit_assoc_bound(_: impl IntoIterator + ~const Destruct) {} - | ^^^^^^^^ - -error: `~const` can only be applied to `#[const_trait]` traits - --> $DIR/const-impl-trait.rs:25:29 - | -LL | fn huh() -> impl ~const PartialEq + ~const Destruct + Copy; - | ^^^^^^^^^ - | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error: `~const` can only be applied to `#[const_trait]` traits - --> $DIR/const-impl-trait.rs:25:48 - | -LL | fn huh() -> impl ~const PartialEq + ~const Destruct + Copy; - | ^^^^^^^^ - | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error: `~const` can only be applied to `#[const_trait]` traits - --> $DIR/const-impl-trait.rs:25:29 - | -LL | fn huh() -> impl ~const PartialEq + ~const Destruct + Copy; - | ^^^^^^^^^ - | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error: `~const` can only be applied to `#[const_trait]` traits - --> $DIR/const-impl-trait.rs:25:48 - | -LL | fn huh() -> impl ~const PartialEq + ~const Destruct + Copy; - | ^^^^^^^^ - | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error: `~const` can only be applied to `#[const_trait]` traits - --> $DIR/const-impl-trait.rs:25:29 - | -LL | fn huh() -> impl ~const PartialEq + ~const Destruct + Copy; - | ^^^^^^^^^ - | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error: `~const` can only be applied to `#[const_trait]` traits - --> $DIR/const-impl-trait.rs:25:48 - | -LL | fn huh() -> impl ~const PartialEq + ~const Destruct + Copy; - | ^^^^^^^^ - | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error[E0493]: destructor of `impl PartialEq + Destruct` cannot be evaluated at compile-time - --> $DIR/const-impl-trait.rs:37:26 - | -LL | assert!(wrap(123) == wrap(123)); - | ^^^^^^^^^- value is dropped here - | | - | the destructor for this type cannot be evaluated in constants - -error[E0493]: destructor of `impl PartialEq + Destruct` cannot be evaluated at compile-time - --> $DIR/const-impl-trait.rs:37:26 - | -LL | assert!(wrap(123) == wrap(123)); - | ^^^^^^^^^- value is dropped here - | | - | the destructor for this type cannot be evaluated in constants - | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error[E0493]: destructor of `impl PartialEq + Destruct` cannot be evaluated at compile-time - --> $DIR/const-impl-trait.rs:37:13 - | -LL | assert!(wrap(123) == wrap(123)); - | ^^^^^^^^^ - value is dropped here - | | - | the destructor for this type cannot be evaluated in constants - -error[E0493]: destructor of `impl PartialEq + Destruct` cannot be evaluated at compile-time - --> $DIR/const-impl-trait.rs:37:13 - | -LL | assert!(wrap(123) == wrap(123)); - | ^^^^^^^^^ - value is dropped here - | | - | the destructor for this type cannot be evaluated in constants - | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error[E0493]: destructor of `impl PartialEq + Destruct` cannot be evaluated at compile-time - --> $DIR/const-impl-trait.rs:38:26 - | -LL | assert!(wrap(123) != wrap(456)); - | ^^^^^^^^^- value is dropped here - | | - | the destructor for this type cannot be evaluated in constants - -error[E0493]: destructor of `impl PartialEq + Destruct` cannot be evaluated at compile-time - --> $DIR/const-impl-trait.rs:38:26 - | -LL | assert!(wrap(123) != wrap(456)); - | ^^^^^^^^^- value is dropped here - | | - | the destructor for this type cannot be evaluated in constants - | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error[E0493]: destructor of `impl PartialEq + Destruct` cannot be evaluated at compile-time - --> $DIR/const-impl-trait.rs:38:13 - | -LL | assert!(wrap(123) != wrap(456)); - | ^^^^^^^^^ - value is dropped here - | | - | the destructor for this type cannot be evaluated in constants - -error[E0493]: destructor of `impl PartialEq + Destruct` cannot be evaluated at compile-time - --> $DIR/const-impl-trait.rs:38:13 - | -LL | assert!(wrap(123) != wrap(456)); - | ^^^^^^^^^ - value is dropped here - | | - | the destructor for this type cannot be evaluated in constants - | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error[E0493]: destructor of `impl ~const T + ~const Destruct` cannot be evaluated at compile-time - --> $DIR/const-impl-trait.rs:50:15 - | -LL | const fn apit(_: impl ~const T + ~const Destruct) {} - | ^ - value is dropped here - | | - | the destructor for this type cannot be evaluated in constant functions - -error[E0493]: destructor of `impl IntoIterator + ~const Destruct` cannot be evaluated at compile-time - --> $DIR/const-impl-trait.rs:54:27 - | -LL | const fn apit_assoc_bound(_: impl IntoIterator + ~const Destruct) {} - | ^ - value is dropped here - | | - | the destructor for this type cannot be evaluated in constant functions - -error: aborting due to 33 previous errors - -Some errors have detailed explanations: E0493, E0635. -For more information about an error, try `rustc --explain E0493`. diff --git a/tests/ui/traits/const-traits/const_derives/derive-const-with-params.stderr b/tests/ui/traits/const-traits/const_derives/derive-const-with-params.stderr index addce8dcd6c75..3388ee30a5d33 100644 --- a/tests/ui/traits/const-traits/const_derives/derive-const-with-params.stderr +++ b/tests/ui/traits/const-traits/const_derives/derive-const-with-params.stderr @@ -30,5 +30,14 @@ 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 3 previous errors; 1 warning emitted +error: `~const` can only be applied to `#[const_trait]` traits + --> $DIR/derive-const-with-params.rs:7:16 + | +LL | #[derive_const(PartialEq)] + | ^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + = note: this error originates in the derive macro `PartialEq` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 4 previous errors; 1 warning emitted diff --git a/tests/ui/traits/const-traits/cross-crate.gatednc.stderr b/tests/ui/traits/const-traits/cross-crate.gatednc.stderr index a34bae843c816..b6f2434140d6a 100644 --- a/tests/ui/traits/const-traits/cross-crate.gatednc.stderr +++ b/tests/ui/traits/const-traits/cross-crate.gatednc.stderr @@ -1,21 +1,8 @@ error[E0277]: the trait bound `cross_crate::NonConst: ~const cross_crate::MyTrait` is not satisfied - --> $DIR/cross-crate.rs:19:14 + --> $DIR/cross-crate.rs:19:5 | LL | NonConst.func(); - | ^^^^ the trait `cross_crate::MyTrait` is not implemented for `cross_crate::NonConst` - | -note: required by a bound in `func` - --> $DIR/auxiliary/cross-crate.rs:5:1 - | -LL | #[const_trait] - | ^^^^^^^^^^^^^^ required by this bound in `MyTrait::func` -... -LL | fn func(self); - | ---- required by a bound in this associated function -help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement - | -LL | const fn const_context() where cross_crate::NonConst: cross_crate::MyTrait { - | +++++++++++++++++++++++++++++++++++++++++++++++++ + | ^^^^^^^^^^^^^^^ error: aborting due to 1 previous error diff --git a/tests/ui/traits/const-traits/default-method-body-is-const-same-trait-ck.stderr b/tests/ui/traits/const-traits/default-method-body-is-const-same-trait-ck.stderr index d0f22c0b9b62b..7b4d512e39180 100644 --- a/tests/ui/traits/const-traits/default-method-body-is-const-same-trait-ck.stderr +++ b/tests/ui/traits/const-traits/default-method-body-is-const-same-trait-ck.stderr @@ -1,21 +1,8 @@ error[E0277]: the trait bound `(): ~const Tr` is not satisfied - --> $DIR/default-method-body-is-const-same-trait-ck.rs:10:12 + --> $DIR/default-method-body-is-const-same-trait-ck.rs:10:9 | LL | ().a() - | ^ the trait `Tr` is not implemented for `()` - | -note: required by a bound in `Tr::a` - --> $DIR/default-method-body-is-const-same-trait-ck.rs:5:1 - | -LL | #[const_trait] - | ^^^^^^^^^^^^^^ required by this bound in `Tr::a` -LL | pub trait Tr { -LL | fn a(&self) {} - | - required by a bound in this associated function -help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement - | -LL | pub trait Tr where (): Tr { - | ++++++++++++ + | ^^^^^^ error: aborting due to 1 previous error diff --git a/tests/ui/traits/const-traits/effects/minicore.stderr b/tests/ui/traits/const-traits/effects/minicore.stderr index 823ab69df9cb5..568d98cfe8715 100644 --- a/tests/ui/traits/const-traits/effects/minicore.stderr +++ b/tests/ui/traits/const-traits/effects/minicore.stderr @@ -1,13 +1,13 @@ error: the compiler unexpectedly panicked. this is a bug. query stack during panic: -#0 [check_well_formed] checking that `` is well-formed -#1 [check_mod_type_wf] checking that types are well-formed in top-level module +#0 [typeck] type-checking `Clone::clone_from` +#1 [analysis] running analysis passes on this crate end of query stack error: the compiler unexpectedly panicked. this is a bug. query stack during panic: -#0 [check_well_formed] checking that `drop` is well-formed -#1 [check_mod_type_wf] checking that types are well-formed in top-level module +#0 [typeck] type-checking `test_const_eval_select` +#1 [analysis] running analysis passes on this crate end of query stack diff --git a/tests/ui/traits/const-traits/effects/no-explicit-const-params-cross-crate.stderr b/tests/ui/traits/const-traits/effects/no-explicit-const-params-cross-crate.stderr index 8c591edac5404..eea6a06c1c818 100644 --- a/tests/ui/traits/const-traits/effects/no-explicit-const-params-cross-crate.stderr +++ b/tests/ui/traits/const-traits/effects/no-explicit-const-params-cross-crate.stderr @@ -16,17 +16,15 @@ error[E0107]: trait takes 0 generic arguments but 1 generic argument was supplie --> $DIR/no-explicit-const-params-cross-crate.rs:16:12 | LL | <() as Bar>::bar(); - | ^^^ expected 0 generic arguments + | ^^^------- help: remove the unnecessary generics + | | + | expected 0 generic arguments | note: trait defined here, with 0 generic parameters --> $DIR/auxiliary/cross-crate.rs:8:11 | LL | pub trait Bar { | ^^^ -help: replace the generic bound with the associated type - | -LL | <() as Bar< = false>>::bar(); - | + error[E0107]: function takes 0 generic arguments but 1 generic argument was supplied --> $DIR/no-explicit-const-params-cross-crate.rs:7:5 @@ -46,17 +44,15 @@ error[E0107]: trait takes 0 generic arguments but 1 generic argument was supplie --> $DIR/no-explicit-const-params-cross-crate.rs:9:12 | LL | <() as Bar>::bar(); - | ^^^ expected 0 generic arguments + | ^^^------ help: remove the unnecessary generics + | | + | expected 0 generic arguments | note: trait defined here, with 0 generic parameters --> $DIR/auxiliary/cross-crate.rs:8:11 | LL | pub trait Bar { | ^^^ -help: replace the generic bound with the associated type - | -LL | <() as Bar< = true>>::bar(); - | + error: aborting due to 4 previous errors diff --git a/tests/ui/traits/const-traits/effects/no-explicit-const-params.rs b/tests/ui/traits/const-traits/effects/no-explicit-const-params.rs index 84f5f2803e156..b08aba9acbcd3 100644 --- a/tests/ui/traits/const-traits/effects/no-explicit-const-params.rs +++ b/tests/ui/traits/const-traits/effects/no-explicit-const-params.rs @@ -23,5 +23,4 @@ const FOO: () = { //~^ ERROR: function takes 0 generic arguments but 1 generic argument was supplied <() as Bar>::bar(); //~^ ERROR: trait takes 0 generic arguments but 1 generic argument was supplied - //~| ERROR: mismatched types }; diff --git a/tests/ui/traits/const-traits/effects/no-explicit-const-params.stderr b/tests/ui/traits/const-traits/effects/no-explicit-const-params.stderr index cc08114ddb565..a3aa970e94d24 100644 --- a/tests/ui/traits/const-traits/effects/no-explicit-const-params.stderr +++ b/tests/ui/traits/const-traits/effects/no-explicit-const-params.stderr @@ -30,26 +30,15 @@ error[E0107]: trait takes 0 generic arguments but 1 generic argument was supplie --> $DIR/no-explicit-const-params.rs:24:12 | LL | <() as Bar>::bar(); - | ^^^ expected 0 generic arguments + | ^^^------- help: remove the unnecessary generics + | | + | expected 0 generic arguments | note: trait defined here, with 0 generic parameters --> $DIR/no-explicit-const-params.rs:6:7 | LL | trait Bar { | ^^^ -help: replace the generic bound with the associated type - | -LL | <() as Bar< = false>>::bar(); - | + - -error[E0308]: mismatched types - --> $DIR/no-explicit-const-params.rs:24:5 - | -LL | <() as Bar>::bar(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^ expected `false`, found `true` - | - = note: expected constant `false` - found constant `true` error[E0107]: function takes 0 generic arguments but 1 generic argument was supplied --> $DIR/no-explicit-const-params.rs:15:5 @@ -69,19 +58,16 @@ error[E0107]: trait takes 0 generic arguments but 1 generic argument was supplie --> $DIR/no-explicit-const-params.rs:17:12 | LL | <() as Bar>::bar(); - | ^^^ expected 0 generic arguments + | ^^^------ help: remove the unnecessary generics + | | + | expected 0 generic arguments | note: trait defined here, with 0 generic parameters --> $DIR/no-explicit-const-params.rs:6:7 | LL | trait Bar { | ^^^ -help: replace the generic bound with the associated type - | -LL | <() as Bar< = true>>::bar(); - | + -error: aborting due to 6 previous errors; 1 warning emitted +error: aborting due to 5 previous errors; 1 warning emitted -Some errors have detailed explanations: E0107, E0308. -For more information about an error, try `rustc --explain E0107`. +For more information about this error, try `rustc --explain E0107`. diff --git a/tests/ui/traits/const-traits/effects/spec-effectvar-ice.rs b/tests/ui/traits/const-traits/effects/spec-effectvar-ice.rs index 0508b1c5e26b6..73d3e883aad9c 100644 --- a/tests/ui/traits/const-traits/effects/spec-effectvar-ice.rs +++ b/tests/ui/traits/const-traits/effects/spec-effectvar-ice.rs @@ -1,4 +1,3 @@ -//@ check-fail // Fixes #119830 #![feature(effects)] //~ WARN the feature `effects` is incomplete @@ -15,7 +14,9 @@ impl const Foo for T {} impl const Foo for T where T: const Specialize {} //~^ error: const `impl` for trait `Foo` which is not marked with `#[const_trait]` //~| error: `const` can only be applied to `#[const_trait]` traits +//~| error: `const` can only be applied to `#[const_trait]` traits //~| error: specialization impl does not specialize any associated items //~| error: cannot specialize on trait `Specialize` +//~| ERROR cannot specialize on predicate fn main() {} diff --git a/tests/ui/traits/const-traits/effects/spec-effectvar-ice.stderr b/tests/ui/traits/const-traits/effects/spec-effectvar-ice.stderr index e97a9615ae1a0..2556903150b47 100644 --- a/tests/ui/traits/const-traits/effects/spec-effectvar-ice.stderr +++ b/tests/ui/traits/const-traits/effects/spec-effectvar-ice.stderr @@ -1,5 +1,5 @@ warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/spec-effectvar-ice.rs:4:12 + --> $DIR/spec-effectvar-ice.rs:3:12 | LL | #![feature(effects)] | ^^^^^^^ @@ -13,7 +13,7 @@ error: using `#![feature(effects)]` without enabling next trait solver globally = help: use `-Znext-solver` to enable error: const `impl` for trait `Foo` which is not marked with `#[const_trait]` - --> $DIR/spec-effectvar-ice.rs:12:15 + --> $DIR/spec-effectvar-ice.rs:11:15 | LL | trait Foo {} | - help: mark `Foo` as const: `#[const_trait]` @@ -25,7 +25,7 @@ LL | impl const Foo for T {} = note: adding a non-const method body in the future would be a breaking change error: const `impl` for trait `Foo` which is not marked with `#[const_trait]` - --> $DIR/spec-effectvar-ice.rs:15:15 + --> $DIR/spec-effectvar-ice.rs:14:15 | LL | trait Foo {} | - help: mark `Foo` as const: `#[const_trait]` @@ -37,28 +37,42 @@ LL | impl const Foo for T where T: const Specialize {} = note: adding a non-const method body in the future would be a breaking change error: `const` can only be applied to `#[const_trait]` traits - --> $DIR/spec-effectvar-ice.rs:15:40 + --> $DIR/spec-effectvar-ice.rs:14:40 | LL | impl const Foo for T where T: const Specialize {} | ^^^^^^^^^^ +error: `const` can only be applied to `#[const_trait]` traits + --> $DIR/spec-effectvar-ice.rs:14:40 + | +LL | impl const Foo for T where T: const Specialize {} + | ^^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + error: specialization impl does not specialize any associated items - --> $DIR/spec-effectvar-ice.rs:15:1 + --> $DIR/spec-effectvar-ice.rs:14:1 | LL | impl const Foo for T where T: const Specialize {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: impl is a specialization of this impl - --> $DIR/spec-effectvar-ice.rs:12:1 + --> $DIR/spec-effectvar-ice.rs:11:1 | LL | impl const Foo for T {} | ^^^^^^^^^^^^^^^^^^^^^^^ +error: cannot specialize on predicate `T: const Specialize` + --> $DIR/spec-effectvar-ice.rs:14:34 + | +LL | impl const Foo for T where T: const Specialize {} + | ^^^^^^^^^^^^^^^^ + error: cannot specialize on trait `Specialize` - --> $DIR/spec-effectvar-ice.rs:15:34 + --> $DIR/spec-effectvar-ice.rs:14:34 | LL | impl const Foo for T where T: const Specialize {} | ^^^^^^^^^^^^^^^^ -error: aborting due to 6 previous errors; 1 warning emitted +error: aborting due to 8 previous errors; 1 warning emitted diff --git a/tests/ui/traits/const-traits/ice-123664-unexpected-bound-var.rs b/tests/ui/traits/const-traits/ice-123664-unexpected-bound-var.rs index 64634e7b7ac30..29f40604747b2 100644 --- a/tests/ui/traits/const-traits/ice-123664-unexpected-bound-var.rs +++ b/tests/ui/traits/const-traits/ice-123664-unexpected-bound-var.rs @@ -3,5 +3,6 @@ const fn with_positive() {} //~^ ERROR `~const` can only be applied to `#[const_trait]` traits +//~| ERROR `~const` can only be applied to `#[const_trait]` traits pub fn main() {} diff --git a/tests/ui/traits/const-traits/ice-123664-unexpected-bound-var.stderr b/tests/ui/traits/const-traits/ice-123664-unexpected-bound-var.stderr index c937430a1ca19..03f88be009364 100644 --- a/tests/ui/traits/const-traits/ice-123664-unexpected-bound-var.stderr +++ b/tests/ui/traits/const-traits/ice-123664-unexpected-bound-var.stderr @@ -9,5 +9,13 @@ error: `~const` can only be applied to `#[const_trait]` traits LL | const fn with_positive() {} | ^^^^ -error: aborting due to 2 previous errors +error: `~const` can only be applied to `#[const_trait]` traits + --> $DIR/ice-123664-unexpected-bound-var.rs:4:34 + | +LL | const fn with_positive() {} + | ^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: aborting due to 3 previous errors diff --git a/tests/ui/traits/const-traits/issue-92111.stderr b/tests/ui/traits/const-traits/issue-92111.stderr index ecc994a3fe658..805cc5370149b 100644 --- a/tests/ui/traits/const-traits/issue-92111.stderr +++ b/tests/ui/traits/const-traits/issue-92111.stderr @@ -4,6 +4,14 @@ error: `~const` can only be applied to `#[const_trait]` traits LL | const fn a(t: T) {} | ^^^^^^^^ +error: `~const` can only be applied to `#[const_trait]` traits + --> $DIR/issue-92111.rs:20:22 + | +LL | const fn a(t: T) {} + | ^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + error[E0493]: destructor of `T` cannot be evaluated at compile-time --> $DIR/issue-92111.rs:20:32 | @@ -12,6 +20,6 @@ LL | const fn a(t: T) {} | | | the destructor for this type cannot be evaluated in constant functions -error: aborting due to 2 previous errors +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0493`. diff --git a/tests/ui/traits/const-traits/non-const-op-in-closure-in-const.stderr b/tests/ui/traits/const-traits/non-const-op-in-closure-in-const.stderr index de4783bdb3fe6..2803c37646b14 100644 --- a/tests/ui/traits/const-traits/non-const-op-in-closure-in-const.stderr +++ b/tests/ui/traits/const-traits/non-const-op-in-closure-in-const.stderr @@ -4,14 +4,13 @@ error: `~const` can only be applied to `#[const_trait]` traits LL | impl const Convert for A where B: ~const From { | ^^^^^^^ -error[E0049]: method `to` has 1 const parameter but its trait declaration has 0 const parameters - --> $DIR/non-const-op-in-closure-in-const.rs:5:1 +error: `~const` can only be applied to `#[const_trait]` traits + --> $DIR/non-const-op-in-closure-in-const.rs:10:51 + | +LL | impl const Convert for A where B: ~const From { + | ^^^^^^^ | -LL | #[const_trait] - | ^^^^^^^^^^^^^^ found 1 const parameter -LL | trait Convert { -LL | fn to(self) -> T; - | - expected 0 const parameters + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error[E0015]: cannot call non-const fn `>::from` in constant functions --> $DIR/non-const-op-in-closure-in-const.rs:12:9 @@ -27,5 +26,4 @@ LL + #![feature(effects)] error: aborting due to 3 previous errors -Some errors have detailed explanations: E0015, E0049. -For more information about an error, try `rustc --explain E0015`. +For more information about this error, try `rustc --explain E0015`. diff --git a/tests/ui/traits/const-traits/specialization/const-default-bound-non-const-specialized-bound.stderr b/tests/ui/traits/const-traits/specialization/const-default-bound-non-const-specialized-bound.stderr index 7643697874f25..bffc60c65fcea 100644 --- a/tests/ui/traits/const-traits/specialization/const-default-bound-non-const-specialized-bound.stderr +++ b/tests/ui/traits/const-traits/specialization/const-default-bound-non-const-specialized-bound.stderr @@ -1,12 +1,3 @@ -error[E0049]: associated function `bar` has 1 const parameter but its trait declaration has 0 const parameters - --> $DIR/const-default-bound-non-const-specialized-bound.rs:16:1 - | -LL | #[const_trait] - | ^^^^^^^^^^^^^^ found 1 const parameter -LL | trait Bar { -LL | fn bar(); - | - expected 0 const parameters - error: cannot specialize on const impl with non-const impl --> $DIR/const-default-bound-non-const-specialized-bound.rs:28:1 | @@ -16,26 +7,5 @@ LL | | T: Foo, //FIXME ~ ERROR missing `~const` qualifier LL | | T: Specialize, | |__________________^ -error[E0049]: associated function `baz` has 1 const parameter but its trait declaration has 0 const parameters - --> $DIR/const-default-bound-non-const-specialized-bound.rs:36:1 - | -LL | #[const_trait] - | ^^^^^^^^^^^^^^ found 1 const parameter -LL | trait Baz { -LL | fn baz(); - | - expected 0 const parameters - -error[E0049]: associated function `baz` has 1 const parameter but its trait declaration has 0 const parameters - --> $DIR/const-default-bound-non-const-specialized-bound.rs:36:1 - | -LL | #[const_trait] - | ^^^^^^^^^^^^^^ found 1 const parameter -LL | trait Baz { -LL | fn baz(); - | - expected 0 const parameters - | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error: aborting due to 4 previous errors +error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0049`. diff --git a/tests/ui/traits/const-traits/specialization/const-default-const-specialized.stderr b/tests/ui/traits/const-traits/specialization/const-default-const-specialized.stderr index 9b2ae8d739c88..f127268d2a1c9 100644 --- a/tests/ui/traits/const-traits/specialization/const-default-const-specialized.stderr +++ b/tests/ui/traits/const-traits/specialization/const-default-const-specialized.stderr @@ -1,23 +1,3 @@ -error[E0049]: associated function `value` has 1 const parameter but its trait declaration has 0 const parameters - --> $DIR/const-default-const-specialized.rs:10:1 - | -LL | #[const_trait] - | ^^^^^^^^^^^^^^ found 1 const parameter -LL | trait Value { -LL | fn value() -> u32; - | - expected 0 const parameters - -error[E0049]: associated function `value` has 1 const parameter but its trait declaration has 0 const parameters - --> $DIR/const-default-const-specialized.rs:10:1 - | -LL | #[const_trait] - | ^^^^^^^^^^^^^^ found 1 const parameter -LL | trait Value { -LL | fn value() -> u32; - | - expected 0 const parameters - | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - error[E0015]: cannot call non-const fn `::value` in constant functions --> $DIR/const-default-const-specialized.rs:16:5 | @@ -30,7 +10,6 @@ help: add `#![feature(effects)]` to the crate attributes to enable LL + #![feature(effects)] | -error: aborting due to 3 previous errors +error: aborting due to 1 previous error -Some errors have detailed explanations: E0015, E0049. -For more information about an error, try `rustc --explain E0015`. +For more information about this error, try `rustc --explain E0015`. diff --git a/tests/ui/traits/const-traits/specialization/default-keyword.rs b/tests/ui/traits/const-traits/specialization/default-keyword.rs index d9ffd237dcefd..bc45a70777ca5 100644 --- a/tests/ui/traits/const-traits/specialization/default-keyword.rs +++ b/tests/ui/traits/const-traits/specialization/default-keyword.rs @@ -1,5 +1,4 @@ -//@ known-bug: #110395 -// FIXME check-pass +//@ check-pass #![feature(const_trait_impl)] #![feature(min_specialization)] diff --git a/tests/ui/traits/const-traits/specialization/default-keyword.stderr b/tests/ui/traits/const-traits/specialization/default-keyword.stderr deleted file mode 100644 index 18a25045f4b08..0000000000000 --- a/tests/ui/traits/const-traits/specialization/default-keyword.stderr +++ /dev/null @@ -1,12 +0,0 @@ -error[E0049]: associated function `foo` has 1 const parameter but its trait declaration has 0 const parameters - --> $DIR/default-keyword.rs:7:1 - | -LL | #[const_trait] - | ^^^^^^^^^^^^^^ found 1 const parameter -LL | trait Foo { -LL | fn foo(); - | - expected 0 const parameters - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0049`. diff --git a/tests/ui/traits/const-traits/specialization/issue-95186-specialize-on-tilde-const.rs b/tests/ui/traits/const-traits/specialization/issue-95186-specialize-on-tilde-const.rs index 219e5f3a600c1..d80370aee8209 100644 --- a/tests/ui/traits/const-traits/specialization/issue-95186-specialize-on-tilde-const.rs +++ b/tests/ui/traits/const-traits/specialization/issue-95186-specialize-on-tilde-const.rs @@ -1,7 +1,6 @@ // Tests that `~const` trait bounds can be used to specialize const trait impls. -//@ known-bug: #110395 -// FIXME check-pass +//@ check-pass #![feature(const_trait_impl)] #![feature(rustc_attrs)] diff --git a/tests/ui/traits/const-traits/specialization/issue-95186-specialize-on-tilde-const.stderr b/tests/ui/traits/const-traits/specialization/issue-95186-specialize-on-tilde-const.stderr deleted file mode 100644 index ecdc7b930e609..0000000000000 --- a/tests/ui/traits/const-traits/specialization/issue-95186-specialize-on-tilde-const.stderr +++ /dev/null @@ -1,43 +0,0 @@ -error[E0049]: associated function `foo` has 1 const parameter but its trait declaration has 0 const parameters - --> $DIR/issue-95186-specialize-on-tilde-const.rs:14:1 - | -LL | #[const_trait] - | ^^^^^^^^^^^^^^ found 1 const parameter -LL | trait Foo { -LL | fn foo(); - | - expected 0 const parameters - -error[E0049]: associated function `foo` has 1 const parameter but its trait declaration has 0 const parameters - --> $DIR/issue-95186-specialize-on-tilde-const.rs:14:1 - | -LL | #[const_trait] - | ^^^^^^^^^^^^^^ found 1 const parameter -LL | trait Foo { -LL | fn foo(); - | - expected 0 const parameters - | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error[E0049]: associated function `bar` has 1 const parameter but its trait declaration has 0 const parameters - --> $DIR/issue-95186-specialize-on-tilde-const.rs:30:1 - | -LL | #[const_trait] - | ^^^^^^^^^^^^^^ found 1 const parameter -LL | trait Bar { -LL | fn bar() {} - | - expected 0 const parameters - -error[E0049]: associated function `bar` has 1 const parameter but its trait declaration has 0 const parameters - --> $DIR/issue-95186-specialize-on-tilde-const.rs:30:1 - | -LL | #[const_trait] - | ^^^^^^^^^^^^^^ found 1 const parameter -LL | trait Bar { -LL | fn bar() {} - | - expected 0 const parameters - | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error: aborting due to 4 previous errors - -For more information about this error, try `rustc --explain E0049`. diff --git a/tests/ui/traits/const-traits/specialization/issue-95187-same-trait-bound-different-constness.rs b/tests/ui/traits/const-traits/specialization/issue-95187-same-trait-bound-different-constness.rs index 7514baa2fd554..d97469edaf97f 100644 --- a/tests/ui/traits/const-traits/specialization/issue-95187-same-trait-bound-different-constness.rs +++ b/tests/ui/traits/const-traits/specialization/issue-95187-same-trait-bound-different-constness.rs @@ -2,8 +2,7 @@ // `T: Foo` in the default impl for the purposes of specialization (i.e., it // does not think that the user is attempting to specialize on trait `Foo`). -//@ known-bug: #110395 -// FIXME check-pass +//@ check-pass #![feature(rustc_attrs)] #![feature(min_specialization)] diff --git a/tests/ui/traits/const-traits/specialization/issue-95187-same-trait-bound-different-constness.stderr b/tests/ui/traits/const-traits/specialization/issue-95187-same-trait-bound-different-constness.stderr deleted file mode 100644 index 6679bb4653788..0000000000000 --- a/tests/ui/traits/const-traits/specialization/issue-95187-same-trait-bound-different-constness.stderr +++ /dev/null @@ -1,43 +0,0 @@ -error[E0049]: associated function `bar` has 1 const parameter but its trait declaration has 0 const parameters - --> $DIR/issue-95187-same-trait-bound-different-constness.rs:18:1 - | -LL | #[const_trait] - | ^^^^^^^^^^^^^^ found 1 const parameter -LL | trait Bar { -LL | fn bar(); - | - expected 0 const parameters - -error[E0049]: associated function `bar` has 1 const parameter but its trait declaration has 0 const parameters - --> $DIR/issue-95187-same-trait-bound-different-constness.rs:18:1 - | -LL | #[const_trait] - | ^^^^^^^^^^^^^^ found 1 const parameter -LL | trait Bar { -LL | fn bar(); - | - expected 0 const parameters - | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error[E0049]: associated function `baz` has 1 const parameter but its trait declaration has 0 const parameters - --> $DIR/issue-95187-same-trait-bound-different-constness.rs:38:1 - | -LL | #[const_trait] - | ^^^^^^^^^^^^^^ found 1 const parameter -LL | trait Baz { -LL | fn baz(); - | - expected 0 const parameters - -error[E0049]: associated function `baz` has 1 const parameter but its trait declaration has 0 const parameters - --> $DIR/issue-95187-same-trait-bound-different-constness.rs:38:1 - | -LL | #[const_trait] - | ^^^^^^^^^^^^^^ found 1 const parameter -LL | trait Baz { -LL | fn baz(); - | - expected 0 const parameters - | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error: aborting due to 4 previous errors - -For more information about this error, try `rustc --explain E0049`. diff --git a/tests/ui/traits/const-traits/specialization/non-const-default-const-specialized.stderr b/tests/ui/traits/const-traits/specialization/non-const-default-const-specialized.stderr index 7f363922947fe..a4095d7e8ce56 100644 --- a/tests/ui/traits/const-traits/specialization/non-const-default-const-specialized.stderr +++ b/tests/ui/traits/const-traits/specialization/non-const-default-const-specialized.stderr @@ -1,23 +1,3 @@ -error[E0049]: associated function `value` has 1 const parameter but its trait declaration has 0 const parameters - --> $DIR/non-const-default-const-specialized.rs:9:1 - | -LL | #[const_trait] - | ^^^^^^^^^^^^^^ found 1 const parameter -LL | trait Value { -LL | fn value() -> u32; - | - expected 0 const parameters - -error[E0049]: associated function `value` has 1 const parameter but its trait declaration has 0 const parameters - --> $DIR/non-const-default-const-specialized.rs:9:1 - | -LL | #[const_trait] - | ^^^^^^^^^^^^^^ found 1 const parameter -LL | trait Value { -LL | fn value() -> u32; - | - expected 0 const parameters - | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - error[E0015]: cannot call non-const fn `::value` in constant functions --> $DIR/non-const-default-const-specialized.rs:15:5 | @@ -30,7 +10,6 @@ help: add `#![feature(effects)]` to the crate attributes to enable LL + #![feature(effects)] | -error: aborting due to 3 previous errors +error: aborting due to 1 previous error -Some errors have detailed explanations: E0015, E0049. -For more information about an error, try `rustc --explain E0015`. +For more information about this error, try `rustc --explain E0015`. diff --git a/tests/ui/traits/const-traits/specializing-constness-2.stderr b/tests/ui/traits/const-traits/specializing-constness-2.stderr index bf273f349b4bc..8e6f6945a1b85 100644 --- a/tests/ui/traits/const-traits/specializing-constness-2.stderr +++ b/tests/ui/traits/const-traits/specializing-constness-2.stderr @@ -1,23 +1,3 @@ -error[E0049]: associated function `a` has 1 const parameter but its trait declaration has 0 const parameters - --> $DIR/specializing-constness-2.rs:9:1 - | -LL | #[const_trait] - | ^^^^^^^^^^^^^^ found 1 const parameter -LL | pub trait A { -LL | fn a() -> u32; - | - expected 0 const parameters - -error[E0049]: associated function `a` has 1 const parameter but its trait declaration has 0 const parameters - --> $DIR/specializing-constness-2.rs:9:1 - | -LL | #[const_trait] - | ^^^^^^^^^^^^^^ found 1 const parameter -LL | pub trait A { -LL | fn a() -> u32; - | - expected 0 const parameters - | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - error[E0015]: cannot call non-const fn `::a` in constant functions --> $DIR/specializing-constness-2.rs:27:5 | @@ -30,7 +10,6 @@ help: add `#![feature(effects)]` to the crate attributes to enable LL + #![feature(effects)] | -error: aborting due to 3 previous errors +error: aborting due to 1 previous error -Some errors have detailed explanations: E0015, E0049. -For more information about an error, try `rustc --explain E0015`. +For more information about this error, try `rustc --explain E0015`. diff --git a/tests/ui/traits/const-traits/specializing-constness.rs b/tests/ui/traits/const-traits/specializing-constness.rs index 4501a218ad723..3aabaf137d54c 100644 --- a/tests/ui/traits/const-traits/specializing-constness.rs +++ b/tests/ui/traits/const-traits/specializing-constness.rs @@ -22,8 +22,6 @@ impl const A for T { impl A for T { //~^ ERROR: cannot specialize -//~| ERROR: cannot specialize -//~| ERROR: cannot specialize //FIXME(effects) ~| ERROR: missing `~const` qualifier fn a() -> u32 { 3 diff --git a/tests/ui/traits/const-traits/specializing-constness.stderr b/tests/ui/traits/const-traits/specializing-constness.stderr index 90721af8e5aab..e8c4fb0f0c723 100644 --- a/tests/ui/traits/const-traits/specializing-constness.stderr +++ b/tests/ui/traits/const-traits/specializing-constness.stderr @@ -18,17 +18,5 @@ error: cannot specialize on const impl with non-const impl LL | impl A for T { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: cannot specialize on trait `Compat` - --> $DIR/specializing-constness.rs:23:16 - | -LL | impl A for T { - | ^^^ - -error: cannot specialize on trait `Compat` - --> $DIR/specializing-constness.rs:23:9 - | -LL | impl A for T { - | ^^^^ - -error: aborting due to 4 previous errors; 1 warning emitted +error: aborting due to 2 previous errors; 1 warning emitted diff --git a/tests/ui/traits/const-traits/super-traits-fail-2.ny.stderr b/tests/ui/traits/const-traits/super-traits-fail-2.ny.stderr index 029c3b4bde3ec..a0848fe520e85 100644 --- a/tests/ui/traits/const-traits/super-traits-fail-2.ny.stderr +++ b/tests/ui/traits/const-traits/super-traits-fail-2.ny.stderr @@ -20,5 +20,21 @@ LL | trait Bar: ~const Foo {} | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -error: aborting due to 3 previous errors +error: `~const` can only be applied to `#[const_trait]` traits + --> $DIR/super-traits-fail-2.rs:12:19 + | +LL | trait Bar: ~const Foo {} + | ^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: `~const` can only be applied to `#[const_trait]` traits + --> $DIR/super-traits-fail-2.rs:12:19 + | +LL | trait Bar: ~const Foo {} + | ^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: aborting due to 5 previous errors diff --git a/tests/ui/traits/const-traits/super-traits-fail-2.rs b/tests/ui/traits/const-traits/super-traits-fail-2.rs index 93a6f385e47db..0ea61f4ae2001 100644 --- a/tests/ui/traits/const-traits/super-traits-fail-2.rs +++ b/tests/ui/traits/const-traits/super-traits-fail-2.rs @@ -13,7 +13,9 @@ trait Bar: ~const Foo {} //[ny,nn]~^ ERROR: `~const` can only be applied to `#[const_trait]` //[ny,nn]~| ERROR: `~const` can only be applied to `#[const_trait]` //[ny,nn]~| ERROR: `~const` can only be applied to `#[const_trait]` -//[yn,nn]~^^^^ ERROR: `~const` is not allowed here +//[ny]~| ERROR: `~const` can only be applied to `#[const_trait]` +//[ny]~| ERROR: `~const` can only be applied to `#[const_trait]` +//[yn,nn]~^^^^^^ ERROR: `~const` is not allowed here const fn foo(x: &T) { x.a(); diff --git a/tests/ui/traits/const-traits/super-traits-fail-2.yn.stderr b/tests/ui/traits/const-traits/super-traits-fail-2.yn.stderr index 873c57ec71ffe..ec6ca1072890e 100644 --- a/tests/ui/traits/const-traits/super-traits-fail-2.yn.stderr +++ b/tests/ui/traits/const-traits/super-traits-fail-2.yn.stderr @@ -11,23 +11,10 @@ LL | trait Bar: ~const Foo {} | ^^^^^^^^^^^^^^^^^^^^^^^^ error[E0277]: the trait bound `T: ~const Foo` is not satisfied - --> $DIR/super-traits-fail-2.rs:19:7 + --> $DIR/super-traits-fail-2.rs:21:5 | LL | x.a(); - | ^ the trait `Foo` is not implemented for `T` - | -note: required by a bound in `Foo::a` - --> $DIR/super-traits-fail-2.rs:6:25 - | -LL | #[cfg_attr(any(yy, yn), const_trait)] - | ^^^^^^^^^^^ required by this bound in `Foo::a` -LL | trait Foo { -LL | fn a(&self); - | - required by a bound in this associated function -help: consider further restricting this bound - | -LL | const fn foo(x: &T) { - | +++++ + | ^^^^^ error: aborting due to 2 previous errors diff --git a/tests/ui/traits/const-traits/super-traits-fail-2.yy.stderr b/tests/ui/traits/const-traits/super-traits-fail-2.yy.stderr index bea3aea2f3afb..3fa6256abc349 100644 --- a/tests/ui/traits/const-traits/super-traits-fail-2.yy.stderr +++ b/tests/ui/traits/const-traits/super-traits-fail-2.yy.stderr @@ -1,21 +1,8 @@ error[E0277]: the trait bound `T: ~const Foo` is not satisfied - --> $DIR/super-traits-fail-2.rs:19:7 + --> $DIR/super-traits-fail-2.rs:21:5 | LL | x.a(); - | ^ the trait `Foo` is not implemented for `T` - | -note: required by a bound in `Foo::a` - --> $DIR/super-traits-fail-2.rs:6:25 - | -LL | #[cfg_attr(any(yy, yn), const_trait)] - | ^^^^^^^^^^^ required by this bound in `Foo::a` -LL | trait Foo { -LL | fn a(&self); - | - required by a bound in this associated function -help: consider further restricting this bound - | -LL | const fn foo(x: &T) { - | +++++ + | ^^^^^ error: aborting due to 1 previous error diff --git a/tests/ui/traits/const-traits/super-traits-fail-3.nn.stderr b/tests/ui/traits/const-traits/super-traits-fail-3.nn.stderr index f40583f0ca57f..294545014bf5e 100644 --- a/tests/ui/traits/const-traits/super-traits-fail-3.nn.stderr +++ b/tests/ui/traits/const-traits/super-traits-fail-3.nn.stderr @@ -33,10 +33,18 @@ LL | trait Bar: ~const Foo {} = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: `~const` can only be applied to `#[const_trait]` traits - --> $DIR/super-traits-fail-3.rs:20:24 + --> $DIR/super-traits-fail-3.rs:22:24 | LL | const fn foo(x: &T) { | ^^^ -error: aborting due to 5 previous errors +error: `~const` can only be applied to `#[const_trait]` traits + --> $DIR/super-traits-fail-3.rs:22:24 + | +LL | const fn foo(x: &T) { + | ^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: aborting due to 6 previous errors diff --git a/tests/ui/traits/const-traits/super-traits-fail-3.ny.stderr b/tests/ui/traits/const-traits/super-traits-fail-3.ny.stderr index 3f6dfa7b00896..54bb6c5ca4418 100644 --- a/tests/ui/traits/const-traits/super-traits-fail-3.ny.stderr +++ b/tests/ui/traits/const-traits/super-traits-fail-3.ny.stderr @@ -20,5 +20,21 @@ LL | trait Bar: ~const Foo {} | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -error: aborting due to 3 previous errors +error: `~const` can only be applied to `#[const_trait]` traits + --> $DIR/super-traits-fail-3.rs:14:19 + | +LL | trait Bar: ~const Foo {} + | ^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: `~const` can only be applied to `#[const_trait]` traits + --> $DIR/super-traits-fail-3.rs:14:19 + | +LL | trait Bar: ~const Foo {} + | ^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: aborting due to 5 previous errors diff --git a/tests/ui/traits/const-traits/super-traits-fail-3.rs b/tests/ui/traits/const-traits/super-traits-fail-3.rs index b5643b1170000..a9b08e6edcdc6 100644 --- a/tests/ui/traits/const-traits/super-traits-fail-3.rs +++ b/tests/ui/traits/const-traits/super-traits-fail-3.rs @@ -15,10 +15,13 @@ trait Bar: ~const Foo {} //[ny,nn]~^ ERROR: `~const` can only be applied to `#[const_trait]` //[ny,nn]~| ERROR: `~const` can only be applied to `#[const_trait]` //[ny,nn]~| ERROR: `~const` can only be applied to `#[const_trait]` -//[yn,nn]~^^^^ ERROR: `~const` is not allowed here +//[ny]~| ERROR: `~const` can only be applied to `#[const_trait]` +//[ny]~| ERROR: `~const` can only be applied to `#[const_trait]` +//[yn,nn]~^^^^^^ ERROR: `~const` is not allowed here const fn foo(x: &T) { //[yn,nn]~^ ERROR: `~const` can only be applied to `#[const_trait]` + //[yn,nn]~| ERROR: `~const` can only be applied to `#[const_trait]` x.a(); //[yn]~^ ERROR: the trait bound `T: ~const Foo` is not satisfied } diff --git a/tests/ui/traits/const-traits/super-traits-fail-3.yn.stderr b/tests/ui/traits/const-traits/super-traits-fail-3.yn.stderr index bbc95948a59db..b6747d10e83c9 100644 --- a/tests/ui/traits/const-traits/super-traits-fail-3.yn.stderr +++ b/tests/ui/traits/const-traits/super-traits-fail-3.yn.stderr @@ -11,30 +11,25 @@ LL | trait Bar: ~const Foo {} | ^^^^^^^^^^^^^^^^^^^^^^^^ error: `~const` can only be applied to `#[const_trait]` traits - --> $DIR/super-traits-fail-3.rs:20:24 + --> $DIR/super-traits-fail-3.rs:22:24 | LL | const fn foo(x: &T) { | ^^^ -error[E0277]: the trait bound `T: ~const Foo` is not satisfied - --> $DIR/super-traits-fail-3.rs:22:7 - | -LL | x.a(); - | ^ the trait `Foo` is not implemented for `T` +error: `~const` can only be applied to `#[const_trait]` traits + --> $DIR/super-traits-fail-3.rs:22:24 | -note: required by a bound in `Foo::a` - --> $DIR/super-traits-fail-3.rs:8:25 +LL | const fn foo(x: &T) { + | ^^^ | -LL | #[cfg_attr(any(yy, yn), const_trait)] - | ^^^^^^^^^^^ required by this bound in `Foo::a` -LL | trait Foo { -LL | fn a(&self); - | - required by a bound in this associated function -help: consider further restricting this bound + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error[E0277]: the trait bound `T: ~const Foo` is not satisfied + --> $DIR/super-traits-fail-3.rs:25:5 | -LL | const fn foo(x: &T) { - | +++++ +LL | x.a(); + | ^^^^^ -error: aborting due to 3 previous errors +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/traits/const-traits/super-traits-fail.rs b/tests/ui/traits/const-traits/super-traits-fail.rs index da41d7fcc723a..c07619fbf621c 100644 --- a/tests/ui/traits/const-traits/super-traits-fail.rs +++ b/tests/ui/traits/const-traits/super-traits-fail.rs @@ -1,4 +1,3 @@ -//~ ERROR the trait bound //@ compile-flags: -Znext-solver #![allow(incomplete_features)] diff --git a/tests/ui/traits/const-traits/super-traits-fail.stderr b/tests/ui/traits/const-traits/super-traits-fail.stderr index 3870f0f722f99..7a734a6c9f1ca 100644 --- a/tests/ui/traits/const-traits/super-traits-fail.stderr +++ b/tests/ui/traits/const-traits/super-traits-fail.stderr @@ -1,24 +1,9 @@ -error[E0277]: the trait bound `Bar::{synthetic#0}: TyCompat` is not satisfied - --> $DIR/super-traits-fail.rs:19:12 +error[E0277]: the trait bound `S: ~const Foo` is not satisfied + --> $DIR/super-traits-fail.rs:18:20 | LL | impl const Bar for S {} - | ^^^ the trait `TyCompat` is not implemented for `Bar::{synthetic#0}`, which is required by `S: Bar` - | - = help: the trait `Bar` is implemented for `S` -note: required for `S` to implement `Bar` - --> $DIR/super-traits-fail.rs:12:7 - | -LL | trait Bar: ~const Foo {} - | ^^^ - -error[E0277]: the trait bound `Maybe: TyCompat` is not satisfied - | -note: required by a bound in `Bar::{synthetic#0}` - --> $DIR/super-traits-fail.rs:12:12 - | -LL | trait Bar: ~const Foo {} - | ^^^^^^^^^^ required by this bound in `Bar::{synthetic#0}` + | ^ -error: aborting due to 2 previous errors +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/traits/const-traits/tilde-const-and-const-params.rs b/tests/ui/traits/const-traits/tilde-const-and-const-params.rs index 4b720b534a49e..f6a7c7c174612 100644 --- a/tests/ui/traits/const-traits/tilde-const-and-const-params.rs +++ b/tests/ui/traits/const-traits/tilde-const-and-const-params.rs @@ -8,7 +8,6 @@ struct Foo; impl Foo { fn add(self) -> Foo<{ A::add(N) }> { //~^ ERROR `~const` is not allowed here - //~| ERROR mismatched types Foo } } @@ -26,7 +25,6 @@ impl const Add42 for () { fn bar(_: Foo) -> Foo<{ A::add(N) }> { //~^ ERROR `~const` is not allowed here - //~| ERROR mismatched types Foo } diff --git a/tests/ui/traits/const-traits/tilde-const-and-const-params.stderr b/tests/ui/traits/const-traits/tilde-const-and-const-params.stderr index 73526a26e081e..84a425f6791bd 100644 --- a/tests/ui/traits/const-traits/tilde-const-and-const-params.stderr +++ b/tests/ui/traits/const-traits/tilde-const-and-const-params.stderr @@ -11,13 +11,13 @@ LL | fn add(self) -> Foo<{ A::add(N) }> { | ^^^ error: `~const` is not allowed here - --> $DIR/tilde-const-and-const-params.rs:27:11 + --> $DIR/tilde-const-and-const-params.rs:26:11 | LL | fn bar(_: Foo) -> Foo<{ A::add(N) }> { | ^^^^^^ | note: this function is not `const`, so it cannot have `~const` trait bounds - --> $DIR/tilde-const-and-const-params.rs:27:4 + --> $DIR/tilde-const-and-const-params.rs:26:4 | LL | fn bar(_: Foo) -> Foo<{ A::add(N) }> { | ^^^ @@ -27,24 +27,5 @@ error: using `#![feature(effects)]` without enabling next trait solver globally = note: the next trait solver must be enabled globally for the effects feature to work correctly = help: use `-Znext-solver` to enable -error[E0308]: mismatched types - --> $DIR/tilde-const-and-const-params.rs:27:61 - | -LL | fn bar(_: Foo) -> Foo<{ A::add(N) }> { - | ^^^^^^^^^ expected `false`, found `true` - | - = note: expected constant `false` - found constant `true` - -error[E0308]: mismatched types - --> $DIR/tilde-const-and-const-params.rs:9:44 - | -LL | fn add(self) -> Foo<{ A::add(N) }> { - | ^^^^^^^^^ expected `false`, found `true` - | - = note: expected constant `false` - found constant `true` - -error: aborting due to 5 previous errors +error: aborting due to 3 previous errors -For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/traits/const-traits/trait-where-clause-const.rs b/tests/ui/traits/const-traits/trait-where-clause-const.rs index 8ca9b7cc7aa0a..61e2bc384268a 100644 --- a/tests/ui/traits/const-traits/trait-where-clause-const.rs +++ b/tests/ui/traits/const-traits/trait-where-clause-const.rs @@ -20,11 +20,9 @@ trait Foo { const fn test1() { T::a(); T::b(); - //~^ ERROR mismatched types - //~| ERROR the trait bound + //~^ ERROR the trait bound T::c::(); - //~^ ERROR mismatched types - //~| ERROR the trait bound + //~^ ERROR the trait bound } const fn test2() { diff --git a/tests/ui/traits/const-traits/trait-where-clause-const.stderr b/tests/ui/traits/const-traits/trait-where-clause-const.stderr index eaa981ec74444..30a7ef1fd0d3f 100644 --- a/tests/ui/traits/const-traits/trait-where-clause-const.stderr +++ b/tests/ui/traits/const-traits/trait-where-clause-const.stderr @@ -1,52 +1,15 @@ -error[E0277]: the trait bound `T: Foo` is not satisfied +error[E0277]: the trait bound `T: ~const Bar` is not satisfied --> $DIR/trait-where-clause-const.rs:22:5 | LL | T::b(); - | ^ the trait `Foo` is not implemented for `T` - | -note: required by a bound in `Foo::b` - --> $DIR/trait-where-clause-const.rs:13:1 - | -LL | #[const_trait] - | ^^^^^^^^^^^^^^ required by this bound in `Foo::b` -... -LL | fn b() where Self: ~const Bar; - | - required by a bound in this associated function - -error[E0308]: mismatched types - --> $DIR/trait-where-clause-const.rs:22:5 - | -LL | T::b(); - | ^^^^^^ expected `host`, found `true` - | - = note: expected constant `host` - found constant `true` + | ^^^^^^ -error[E0277]: the trait bound `T: Foo` is not satisfied - --> $DIR/trait-where-clause-const.rs:25:5 +error[E0277]: the trait bound `T: ~const Bar` is not satisfied + --> $DIR/trait-where-clause-const.rs:24:5 | LL | T::c::(); - | ^ the trait `Foo` is not implemented for `T` - | -note: required by a bound in `Foo::c` - --> $DIR/trait-where-clause-const.rs:13:1 - | -LL | #[const_trait] - | ^^^^^^^^^^^^^^ required by this bound in `Foo::c` -... -LL | fn c(); - | - required by a bound in this associated function - -error[E0308]: mismatched types - --> $DIR/trait-where-clause-const.rs:25:5 - | -LL | T::c::(); - | ^^^^^^^^^^^ expected `host`, found `true` - | - = note: expected constant `host` - found constant `true` + | ^^^^^^^^^^^ -error: aborting due to 4 previous errors +error: aborting due to 2 previous errors -Some errors have detailed explanations: E0277, E0308. -For more information about an error, try `rustc --explain E0277`. +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/traits/const-traits/unsatisfied-const-trait-bound.stderr b/tests/ui/traits/const-traits/unsatisfied-const-trait-bound.stderr index 848aa68689b48..e0cf062ad95e8 100644 --- a/tests/ui/traits/const-traits/unsatisfied-const-trait-bound.stderr +++ b/tests/ui/traits/const-traits/unsatisfied-const-trait-bound.stderr @@ -6,41 +6,30 @@ LL | #![feature(const_trait_impl, effects, generic_const_exprs)] | = help: remove one of these features -error[E0308]: mismatched types +error[E0277]: the trait bound `T: const Trait` is not satisfied --> $DIR/unsatisfied-const-trait-bound.rs:29:37 | LL | fn accept0(_: Container<{ T::make() }>) {} - | ^^^^^^^^^ expected `false`, found `true` - | - = note: expected constant `false` - found constant `true` + | ^^^^^^^^^ -error[E0308]: mismatched types +error[E0277]: the trait bound `T: const Trait` is not satisfied --> $DIR/unsatisfied-const-trait-bound.rs:33:50 | LL | const fn accept1(_: Container<{ T::make() }>) {} - | ^^^^^^^^^ expected `false`, found `host` - | - = note: expected constant `false` - found constant `host` + | ^^^^^^^^^ error[E0277]: the trait bound `Ty: const Trait` is not satisfied - --> $DIR/unsatisfied-const-trait-bound.rs:22:15 + --> $DIR/unsatisfied-const-trait-bound.rs:22:5 | LL | require::(); - | ^^ the trait `Trait` is not implemented for `Ty` + | ^^^^^^^^^^^^^^^ | note: required by a bound in `require` --> $DIR/unsatisfied-const-trait-bound.rs:8:15 | LL | fn require() {} | ^^^^^^^^^^^ required by this bound in `require` -help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement - | -LL | fn main() where Ty: Trait { - | +++++++++++++++ error: aborting due to 4 previous errors -Some errors have detailed explanations: E0277, E0308. -For more information about an error, try `rustc --explain E0277`. +For more information about this error, try `rustc --explain E0277`. From 779b3943d32816ce1d77672be78eb2871071322c Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Mon, 21 Oct 2024 19:37:48 +0000 Subject: [PATCH 3/5] Add next-solver to more effects tests --- tests/ui/consts/const-try.rs | 4 +++- tests/ui/consts/const-try.stderr | 9 ++----- .../assoc-type-const-bound-usage-0.rs | 1 + .../assoc-type-const-bound-usage-0.stderr | 16 +++++++++---- .../assoc-type-const-bound-usage-1.rs | 2 +- .../assoc-type-const-bound-usage-1.stderr | 24 +++++++++++++++---- tests/ui/traits/const-traits/assoc-type.rs | 5 ++-- .../ui/traits/const-traits/assoc-type.stderr | 16 +++++++++---- .../const-traits/call-generic-method-chain.rs | 1 + .../call-generic-method-chain.stderr | 19 ++++++--------- .../call-generic-method-dup-bound.rs | 1 + .../call-generic-method-dup-bound.stderr | 19 ++++++--------- .../const-traits/call-generic-method-pass.rs | 1 + .../call-generic-method-pass.stderr | 15 ++++-------- .../const-bound-on-not-const-associated-fn.rs | 2 ++ ...st-bound-on-not-const-associated-fn.stderr | 15 ++++-------- .../const-check-fns-in-const-impl.rs | 2 ++ .../const-check-fns-in-const-impl.stderr | 11 +++------ .../const-impl-requires-const-trait.rs | 7 +++--- .../const-impl-requires-const-trait.stderr | 20 +++------------- .../traits/const-traits/const-impl-trait.rs | 3 +++ .../ui/traits/const-traits/hir-const-check.rs | 2 ++ .../const-traits/hir-const-check.stderr | 11 +++------ 23 files changed, 102 insertions(+), 104 deletions(-) diff --git a/tests/ui/consts/const-try.rs b/tests/ui/consts/const-try.rs index 9089dd70a26a6..2862b6ffb17bf 100644 --- a/tests/ui/consts/const-try.rs +++ b/tests/ui/consts/const-try.rs @@ -1,4 +1,4 @@ -//@ known-bug: #110395 +//@ compile-flags: -Znext-solver // Demonstrates what's needed to make use of `?` in const contexts. @@ -14,12 +14,14 @@ struct TryMe; struct Error; impl const FromResidual for TryMe { + //~^ ERROR const `impl` for trait `FromResidual` which is not marked with `#[const_trait]` fn from_residual(residual: Error) -> Self { TryMe } } impl const Try for TryMe { + //~^ ERROR const `impl` for trait `Try` which is not marked with `#[const_trait]` type Output = (); type Residual = Error; fn from_output(output: Self::Output) -> Self { diff --git a/tests/ui/consts/const-try.stderr b/tests/ui/consts/const-try.stderr index 8afdd4e0d61bf..ba9da2421073f 100644 --- a/tests/ui/consts/const-try.stderr +++ b/tests/ui/consts/const-try.stderr @@ -1,8 +1,3 @@ -error: using `#![feature(effects)]` without enabling next trait solver globally - | - = note: the next trait solver must be enabled globally for the effects feature to work correctly - = help: use `-Znext-solver` to enable - error: const `impl` for trait `FromResidual` which is not marked with `#[const_trait]` --> $DIR/const-try.rs:16:12 | @@ -13,7 +8,7 @@ LL | impl const FromResidual for TryMe { = note: adding a non-const method body in the future would be a breaking change error: const `impl` for trait `Try` which is not marked with `#[const_trait]` - --> $DIR/const-try.rs:22:12 + --> $DIR/const-try.rs:23:12 | LL | impl const Try for TryMe { | ^^^ @@ -21,5 +16,5 @@ LL | impl const Try for TryMe { = 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: aborting due to 3 previous errors +error: aborting due to 2 previous errors diff --git a/tests/ui/traits/const-traits/assoc-type-const-bound-usage-0.rs b/tests/ui/traits/const-traits/assoc-type-const-bound-usage-0.rs index 4399ae2d1be32..5a54e8eec91f2 100644 --- a/tests/ui/traits/const-traits/assoc-type-const-bound-usage-0.rs +++ b/tests/ui/traits/const-traits/assoc-type-const-bound-usage-0.rs @@ -1,3 +1,4 @@ +//@ compile-flags: -Znext-solver //@ known-bug: unknown #![allow(incomplete_features)] diff --git a/tests/ui/traits/const-traits/assoc-type-const-bound-usage-0.stderr b/tests/ui/traits/const-traits/assoc-type-const-bound-usage-0.stderr index 20448f51de22c..35069a5a52fc3 100644 --- a/tests/ui/traits/const-traits/assoc-type-const-bound-usage-0.stderr +++ b/tests/ui/traits/const-traits/assoc-type-const-bound-usage-0.stderr @@ -1,7 +1,15 @@ -error: using `#![feature(effects)]` without enabling next trait solver globally +error[E0271]: type mismatch resolving `::Assoc == T` + --> $DIR/assoc-type-const-bound-usage-0.rs:14:5 | - = note: the next trait solver must be enabled globally for the effects feature to work correctly - = help: use `-Znext-solver` to enable +LL | T::Assoc::func() + | ^^^^^^^^^^^^^^^^ types differ -error: aborting due to 1 previous error +error[E0271]: type mismatch resolving `::Assoc == T` + --> $DIR/assoc-type-const-bound-usage-0.rs:18:5 + | +LL | ::Assoc::func() + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ types differ + +error: aborting due to 2 previous errors +For more information about this error, try `rustc --explain E0271`. diff --git a/tests/ui/traits/const-traits/assoc-type-const-bound-usage-1.rs b/tests/ui/traits/const-traits/assoc-type-const-bound-usage-1.rs index 8a1bf75f87e1a..04ad94556c384 100644 --- a/tests/ui/traits/const-traits/assoc-type-const-bound-usage-1.rs +++ b/tests/ui/traits/const-traits/assoc-type-const-bound-usage-1.rs @@ -1,5 +1,5 @@ +//@ compile-flags: -Znext-solver //@ known-bug: unknown -// FIXME(effects) #![feature(const_trait_impl, effects, generic_const_exprs)] #![allow(incomplete_features)] diff --git a/tests/ui/traits/const-traits/assoc-type-const-bound-usage-1.stderr b/tests/ui/traits/const-traits/assoc-type-const-bound-usage-1.stderr index 20448f51de22c..ed9182c733423 100644 --- a/tests/ui/traits/const-traits/assoc-type-const-bound-usage-1.stderr +++ b/tests/ui/traits/const-traits/assoc-type-const-bound-usage-1.stderr @@ -1,7 +1,23 @@ -error: using `#![feature(effects)]` without enabling next trait solver globally +error: `-Znext-solver=globally` and `generic_const_exprs` are incompatible, using them at the same time is not allowed + --> $DIR/assoc-type-const-bound-usage-1.rs:4:39 | - = note: the next trait solver must be enabled globally for the effects feature to work correctly - = help: use `-Znext-solver` to enable +LL | #![feature(const_trait_impl, effects, generic_const_exprs)] + | ^^^^^^^^^^^^^^^^^^^ + | + = help: remove one of these features + +error[E0271]: type mismatch resolving `::Assoc == T` + --> $DIR/assoc-type-const-bound-usage-1.rs:15:44 + | +LL | fn unqualified() -> Type<{ T::Assoc::func() }> { + | ^^^^^^^^^^^^^^^^ types differ + +error[E0271]: type mismatch resolving `::Assoc == T` + --> $DIR/assoc-type-const-bound-usage-1.rs:19:42 + | +LL | fn qualified() -> Type<{ ::Assoc::func() }> { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ types differ -error: aborting due to 1 previous error +error: aborting due to 3 previous errors +For more information about this error, try `rustc --explain E0271`. diff --git a/tests/ui/traits/const-traits/assoc-type.rs b/tests/ui/traits/const-traits/assoc-type.rs index ea3cbabf3020b..a9394d90ed88a 100644 --- a/tests/ui/traits/const-traits/assoc-type.rs +++ b/tests/ui/traits/const-traits/assoc-type.rs @@ -1,4 +1,5 @@ -// FIXME(effects): Replace `Add` with `std::ops::Add` once the latter a `#[const_trait]` again. +//@ compile-flags: -Znext-solver + #![feature(const_trait_impl, effects)] //~ WARN the feature `effects` is incomplete #[const_trait] @@ -33,7 +34,7 @@ trait Foo { impl const Foo for NonConstAdd { type Bar = NonConstAdd; - // FIXME(effects) ERROR the trait bound `NonConstAdd: ~const Add` is not satisfied + //~^ ERROR the trait bound `NonConstAdd: ~const Add` is not satisfied } #[const_trait] diff --git a/tests/ui/traits/const-traits/assoc-type.stderr b/tests/ui/traits/const-traits/assoc-type.stderr index c20b53c210fe6..5c77754200a6c 100644 --- a/tests/ui/traits/const-traits/assoc-type.stderr +++ b/tests/ui/traits/const-traits/assoc-type.stderr @@ -1,5 +1,5 @@ warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/assoc-type.rs:2:30 + --> $DIR/assoc-type.rs:3:30 | LL | #![feature(const_trait_impl, effects)] | ^^^^^^^ @@ -7,10 +7,18 @@ LL | #![feature(const_trait_impl, effects)] = note: see issue #102090 for more information = note: `#[warn(incomplete_features)]` on by default -error: using `#![feature(effects)]` without enabling next trait solver globally +error[E0277]: the trait bound `NonConstAdd: ~const Add` is not satisfied + --> $DIR/assoc-type.rs:36:16 | - = note: the next trait solver must be enabled globally for the effects feature to work correctly - = help: use `-Znext-solver` to enable +LL | type Bar = NonConstAdd; + | ^^^^^^^^^^^ + | +note: required by a bound in `Foo::Bar` + --> $DIR/assoc-type.rs:32:15 + | +LL | type Bar: ~const Add; + | ^^^^^^^^^^ required by this bound in `Foo::Bar` error: aborting due to 1 previous error; 1 warning emitted +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/traits/const-traits/call-generic-method-chain.rs b/tests/ui/traits/const-traits/call-generic-method-chain.rs index 9df694a02f596..e5baedae818b9 100644 --- a/tests/ui/traits/const-traits/call-generic-method-chain.rs +++ b/tests/ui/traits/const-traits/call-generic-method-chain.rs @@ -1,6 +1,7 @@ //! Basic test for calling methods on generic type parameters in `const fn`. //@ known-bug: #110395 +//@ compile-flags: -Znext-solver // FIXME(effects) check-pass #![feature(const_trait_impl, effects)] diff --git a/tests/ui/traits/const-traits/call-generic-method-chain.stderr b/tests/ui/traits/const-traits/call-generic-method-chain.stderr index dce9f0853904d..62eed0f14f9cb 100644 --- a/tests/ui/traits/const-traits/call-generic-method-chain.stderr +++ b/tests/ui/traits/const-traits/call-generic-method-chain.stderr @@ -1,5 +1,5 @@ warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/call-generic-method-chain.rs:6:30 + --> $DIR/call-generic-method-chain.rs:7:30 | LL | #![feature(const_trait_impl, effects)] | ^^^^^^^ @@ -7,13 +7,8 @@ LL | #![feature(const_trait_impl, effects)] = note: see issue #102090 for more information = note: `#[warn(incomplete_features)]` on by default -error: using `#![feature(effects)]` without enabling next trait solver globally - | - = note: the next trait solver must be enabled globally for the effects feature to work correctly - = help: use `-Znext-solver` to enable - error: const `impl` for trait `PartialEq` which is not marked with `#[const_trait]` - --> $DIR/call-generic-method-chain.rs:10:12 + --> $DIR/call-generic-method-chain.rs:11:12 | LL | impl const PartialEq for S { | ^^^^^^^^^ @@ -22,13 +17,13 @@ LL | impl const PartialEq for S { = note: adding a non-const method body in the future would be a breaking change error: `~const` can only be applied to `#[const_trait]` traits - --> $DIR/call-generic-method-chain.rs:19:32 + --> $DIR/call-generic-method-chain.rs:20:32 | LL | const fn equals_self(t: &T) -> bool { | ^^^^^^^^^ error: `~const` can only be applied to `#[const_trait]` traits - --> $DIR/call-generic-method-chain.rs:19:32 + --> $DIR/call-generic-method-chain.rs:20:32 | LL | const fn equals_self(t: &T) -> bool { | ^^^^^^^^^ @@ -36,18 +31,18 @@ LL | const fn equals_self(t: &T) -> bool { = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: `~const` can only be applied to `#[const_trait]` traits - --> $DIR/call-generic-method-chain.rs:23:40 + --> $DIR/call-generic-method-chain.rs:24:40 | LL | const fn equals_self_wrapper(t: &T) -> bool { | ^^^^^^^^^ error: `~const` can only be applied to `#[const_trait]` traits - --> $DIR/call-generic-method-chain.rs:23:40 + --> $DIR/call-generic-method-chain.rs:24:40 | LL | const fn equals_self_wrapper(t: &T) -> bool { | ^^^^^^^^^ | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -error: aborting due to 6 previous errors; 1 warning emitted +error: aborting due to 5 previous errors; 1 warning emitted diff --git a/tests/ui/traits/const-traits/call-generic-method-dup-bound.rs b/tests/ui/traits/const-traits/call-generic-method-dup-bound.rs index f46a34911f193..83a4bb2543621 100644 --- a/tests/ui/traits/const-traits/call-generic-method-dup-bound.rs +++ b/tests/ui/traits/const-traits/call-generic-method-dup-bound.rs @@ -1,3 +1,4 @@ +//@ compile-flags: -Znext-solver //@ known-bug: #110395 // FIXME(effects) check-pass diff --git a/tests/ui/traits/const-traits/call-generic-method-dup-bound.stderr b/tests/ui/traits/const-traits/call-generic-method-dup-bound.stderr index 5da511a580e21..3f9dce919d05f 100644 --- a/tests/ui/traits/const-traits/call-generic-method-dup-bound.stderr +++ b/tests/ui/traits/const-traits/call-generic-method-dup-bound.stderr @@ -1,5 +1,5 @@ warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/call-generic-method-dup-bound.rs:4:30 + --> $DIR/call-generic-method-dup-bound.rs:5:30 | LL | #![feature(const_trait_impl, effects)] | ^^^^^^^ @@ -7,13 +7,8 @@ LL | #![feature(const_trait_impl, effects)] = note: see issue #102090 for more information = note: `#[warn(incomplete_features)]` on by default -error: using `#![feature(effects)]` without enabling next trait solver globally - | - = note: the next trait solver must be enabled globally for the effects feature to work correctly - = help: use `-Znext-solver` to enable - error: const `impl` for trait `PartialEq` which is not marked with `#[const_trait]` - --> $DIR/call-generic-method-dup-bound.rs:8:12 + --> $DIR/call-generic-method-dup-bound.rs:9:12 | LL | impl const PartialEq for S { | ^^^^^^^^^ @@ -22,13 +17,13 @@ LL | impl const PartialEq for S { = note: adding a non-const method body in the future would be a breaking change error: `~const` can only be applied to `#[const_trait]` traits - --> $DIR/call-generic-method-dup-bound.rs:19:44 + --> $DIR/call-generic-method-dup-bound.rs:20:44 | LL | const fn equals_self(t: &T) -> bool { | ^^^^^^^^^ error: `~const` can only be applied to `#[const_trait]` traits - --> $DIR/call-generic-method-dup-bound.rs:19:44 + --> $DIR/call-generic-method-dup-bound.rs:20:44 | LL | const fn equals_self(t: &T) -> bool { | ^^^^^^^^^ @@ -36,18 +31,18 @@ LL | const fn equals_self(t: &T) -> bool { = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: `~const` can only be applied to `#[const_trait]` traits - --> $DIR/call-generic-method-dup-bound.rs:26:37 + --> $DIR/call-generic-method-dup-bound.rs:27:37 | LL | const fn equals_self2(t: &T) -> bool { | ^^^^^^^^^ error: `~const` can only be applied to `#[const_trait]` traits - --> $DIR/call-generic-method-dup-bound.rs:26:37 + --> $DIR/call-generic-method-dup-bound.rs:27:37 | LL | const fn equals_self2(t: &T) -> bool { | ^^^^^^^^^ | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -error: aborting due to 6 previous errors; 1 warning emitted +error: aborting due to 5 previous errors; 1 warning emitted diff --git a/tests/ui/traits/const-traits/call-generic-method-pass.rs b/tests/ui/traits/const-traits/call-generic-method-pass.rs index 413685d8b3443..cbeeb2567dd5b 100644 --- a/tests/ui/traits/const-traits/call-generic-method-pass.rs +++ b/tests/ui/traits/const-traits/call-generic-method-pass.rs @@ -1,5 +1,6 @@ //! Basic test for calling methods on generic type parameters in `const fn`. +//@ compile-flags: -Znext-solver //@ known-bug: #110395 // FIXME(effects) check-pass diff --git a/tests/ui/traits/const-traits/call-generic-method-pass.stderr b/tests/ui/traits/const-traits/call-generic-method-pass.stderr index 52579813b691b..e35de48ed6062 100644 --- a/tests/ui/traits/const-traits/call-generic-method-pass.stderr +++ b/tests/ui/traits/const-traits/call-generic-method-pass.stderr @@ -1,5 +1,5 @@ warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/call-generic-method-pass.rs:6:30 + --> $DIR/call-generic-method-pass.rs:7:30 | LL | #![feature(const_trait_impl, effects)] | ^^^^^^^ @@ -7,13 +7,8 @@ LL | #![feature(const_trait_impl, effects)] = note: see issue #102090 for more information = note: `#[warn(incomplete_features)]` on by default -error: using `#![feature(effects)]` without enabling next trait solver globally - | - = note: the next trait solver must be enabled globally for the effects feature to work correctly - = help: use `-Znext-solver` to enable - error: const `impl` for trait `PartialEq` which is not marked with `#[const_trait]` - --> $DIR/call-generic-method-pass.rs:10:12 + --> $DIR/call-generic-method-pass.rs:11:12 | LL | impl const PartialEq for S { | ^^^^^^^^^ @@ -22,18 +17,18 @@ LL | impl const PartialEq for S { = note: adding a non-const method body in the future would be a breaking change error: `~const` can only be applied to `#[const_trait]` traits - --> $DIR/call-generic-method-pass.rs:19:32 + --> $DIR/call-generic-method-pass.rs:20:32 | LL | const fn equals_self(t: &T) -> bool { | ^^^^^^^^^ error: `~const` can only be applied to `#[const_trait]` traits - --> $DIR/call-generic-method-pass.rs:19:32 + --> $DIR/call-generic-method-pass.rs:20:32 | LL | const fn equals_self(t: &T) -> bool { | ^^^^^^^^^ | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -error: aborting due to 4 previous errors; 1 warning emitted +error: aborting due to 3 previous errors; 1 warning emitted diff --git a/tests/ui/traits/const-traits/const-bound-on-not-const-associated-fn.rs b/tests/ui/traits/const-traits/const-bound-on-not-const-associated-fn.rs index 099cf0b00d3f7..7c3e2af17977c 100644 --- a/tests/ui/traits/const-traits/const-bound-on-not-const-associated-fn.rs +++ b/tests/ui/traits/const-traits/const-bound-on-not-const-associated-fn.rs @@ -1,3 +1,5 @@ +//@ compile-flags: -Znext-solver + #![allow(incomplete_features)] #![feature(const_trait_impl, effects)] diff --git a/tests/ui/traits/const-traits/const-bound-on-not-const-associated-fn.stderr b/tests/ui/traits/const-traits/const-bound-on-not-const-associated-fn.stderr index b5d9b1fff8a1c..ae1260ffab79a 100644 --- a/tests/ui/traits/const-traits/const-bound-on-not-const-associated-fn.stderr +++ b/tests/ui/traits/const-traits/const-bound-on-not-const-associated-fn.stderr @@ -1,31 +1,26 @@ error: `~const` is not allowed here - --> $DIR/const-bound-on-not-const-associated-fn.rs:10:40 + --> $DIR/const-bound-on-not-const-associated-fn.rs:12:40 | LL | fn do_something_else() where Self: ~const MyTrait; | ^^^^^^ | note: this function is not `const`, so it cannot have `~const` trait bounds - --> $DIR/const-bound-on-not-const-associated-fn.rs:10:8 + --> $DIR/const-bound-on-not-const-associated-fn.rs:12:8 | LL | fn do_something_else() where Self: ~const MyTrait; | ^^^^^^^^^^^^^^^^^ error: `~const` is not allowed here - --> $DIR/const-bound-on-not-const-associated-fn.rs:21:32 + --> $DIR/const-bound-on-not-const-associated-fn.rs:23:32 | LL | pub fn foo(&self) where T: ~const MyTrait { | ^^^^^^ | note: this function is not `const`, so it cannot have `~const` trait bounds - --> $DIR/const-bound-on-not-const-associated-fn.rs:21:12 + --> $DIR/const-bound-on-not-const-associated-fn.rs:23:12 | LL | pub fn foo(&self) where T: ~const MyTrait { | ^^^ -error: using `#![feature(effects)]` without enabling next trait solver globally - | - = note: the next trait solver must be enabled globally for the effects feature to work correctly - = help: use `-Znext-solver` to enable - -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors diff --git a/tests/ui/traits/const-traits/const-check-fns-in-const-impl.rs b/tests/ui/traits/const-traits/const-check-fns-in-const-impl.rs index a1710e6525292..7f9b38b820764 100644 --- a/tests/ui/traits/const-traits/const-check-fns-in-const-impl.rs +++ b/tests/ui/traits/const-traits/const-check-fns-in-const-impl.rs @@ -1,3 +1,5 @@ +//@ compile-flags: -Znext-solver + #![feature(const_trait_impl, effects)] //~ WARN the feature `effects` is incomplete struct S; diff --git a/tests/ui/traits/const-traits/const-check-fns-in-const-impl.stderr b/tests/ui/traits/const-traits/const-check-fns-in-const-impl.stderr index 49cd1725c8cf3..ba12854987e24 100644 --- a/tests/ui/traits/const-traits/const-check-fns-in-const-impl.stderr +++ b/tests/ui/traits/const-traits/const-check-fns-in-const-impl.stderr @@ -1,5 +1,5 @@ warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/const-check-fns-in-const-impl.rs:1:30 + --> $DIR/const-check-fns-in-const-impl.rs:3:30 | LL | #![feature(const_trait_impl, effects)] | ^^^^^^^ @@ -7,19 +7,14 @@ LL | #![feature(const_trait_impl, effects)] = note: see issue #102090 for more information = note: `#[warn(incomplete_features)]` on by default -error: using `#![feature(effects)]` without enabling next trait solver globally - | - = note: the next trait solver must be enabled globally for the effects feature to work correctly - = help: use `-Znext-solver` to enable - error[E0015]: cannot call non-const fn `non_const` in constant functions - --> $DIR/const-check-fns-in-const-impl.rs:12:16 + --> $DIR/const-check-fns-in-const-impl.rs:14:16 | LL | fn foo() { non_const() } | ^^^^^^^^^^^ | = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants -error: aborting due to 2 previous errors; 1 warning emitted +error: aborting due to 1 previous error; 1 warning emitted For more information about this error, try `rustc --explain E0015`. diff --git a/tests/ui/traits/const-traits/const-impl-requires-const-trait.rs b/tests/ui/traits/const-traits/const-impl-requires-const-trait.rs index bd6f476f8792a..e49e9090eb433 100644 --- a/tests/ui/traits/const-traits/const-impl-requires-const-trait.rs +++ b/tests/ui/traits/const-traits/const-impl-requires-const-trait.rs @@ -1,11 +1,10 @@ -//@ known-bug: #110395 - +//@ compile-flags: -Znext-solver #![feature(const_trait_impl, effects)] +#![allow(incomplete_features)] pub trait A {} -// FIXME ~^ HELP: mark `A` as const impl const A for () {} -// FIXME ~^ ERROR: const `impl` for trait `A` which is not marked with `#[const_trait]` +//~^ ERROR: const `impl` for trait `A` which is not marked with `#[const_trait]` fn main() {} diff --git a/tests/ui/traits/const-traits/const-impl-requires-const-trait.stderr b/tests/ui/traits/const-traits/const-impl-requires-const-trait.stderr index 2a030369093d6..828e2174f0007 100644 --- a/tests/ui/traits/const-traits/const-impl-requires-const-trait.stderr +++ b/tests/ui/traits/const-traits/const-impl-requires-const-trait.stderr @@ -1,28 +1,14 @@ -warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/const-impl-requires-const-trait.rs:3:30 - | -LL | #![feature(const_trait_impl, effects)] - | ^^^^^^^ - | - = note: see issue #102090 for more information - = note: `#[warn(incomplete_features)]` on by default - -error: using `#![feature(effects)]` without enabling next trait solver globally - | - = note: the next trait solver must be enabled globally for the effects feature to work correctly - = help: use `-Znext-solver` to enable - error: const `impl` for trait `A` which is not marked with `#[const_trait]` - --> $DIR/const-impl-requires-const-trait.rs:8:12 + --> $DIR/const-impl-requires-const-trait.rs:7:12 | LL | pub trait A {} | - help: mark `A` as const: `#[const_trait]` -... +LL | LL | impl const A for () {} | ^ | = 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: aborting due to 2 previous errors; 1 warning emitted +error: aborting due to 1 previous error diff --git a/tests/ui/traits/const-traits/const-impl-trait.rs b/tests/ui/traits/const-traits/const-impl-trait.rs index 51dfe29b8290a..61b8c9a5bff83 100644 --- a/tests/ui/traits/const-traits/const-impl-trait.rs +++ b/tests/ui/traits/const-traits/const-impl-trait.rs @@ -1,4 +1,7 @@ +//@ compile-flags: -Znext-solver //@ known-bug: #110395 +//@ failure-status: 101 +//@ dont-check-compiler-stderr // Broken until we have `&T: const Deref` impl in stdlib #![allow(incomplete_features)] diff --git a/tests/ui/traits/const-traits/hir-const-check.rs b/tests/ui/traits/const-traits/hir-const-check.rs index f5fb0fd516a71..b3df6495afc97 100644 --- a/tests/ui/traits/const-traits/hir-const-check.rs +++ b/tests/ui/traits/const-traits/hir-const-check.rs @@ -1,3 +1,5 @@ +//@ compile-flags: -Znext-solver + // Regression test for #69615. #![feature(const_trait_impl, effects)] //~ WARN the feature `effects` is incomplete diff --git a/tests/ui/traits/const-traits/hir-const-check.stderr b/tests/ui/traits/const-traits/hir-const-check.stderr index 598129d8694e0..19ea734efb777 100644 --- a/tests/ui/traits/const-traits/hir-const-check.stderr +++ b/tests/ui/traits/const-traits/hir-const-check.stderr @@ -1,5 +1,5 @@ warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/hir-const-check.rs:3:30 + --> $DIR/hir-const-check.rs:5:30 | LL | #![feature(const_trait_impl, effects)] | ^^^^^^^ @@ -8,7 +8,7 @@ LL | #![feature(const_trait_impl, effects)] = note: `#[warn(incomplete_features)]` on by default error[E0658]: `?` is not allowed in a `const fn` - --> $DIR/hir-const-check.rs:12:9 + --> $DIR/hir-const-check.rs:14:9 | LL | Some(())?; | ^^^^^^^^^ @@ -17,11 +17,6 @@ LL | Some(())?; = help: add `#![feature(const_try)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date -error: using `#![feature(effects)]` without enabling next trait solver globally - | - = note: the next trait solver must be enabled globally for the effects feature to work correctly - = help: use `-Znext-solver` to enable - -error: aborting due to 2 previous errors; 1 warning emitted +error: aborting due to 1 previous error; 1 warning emitted For more information about this error, try `rustc --explain E0658`. From 25c9253379fa89ae2b45bb6359ef4243ee77345b Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Mon, 21 Oct 2024 20:16:33 +0000 Subject: [PATCH 4/5] Add tests --- .../traits/const-traits/call-const-closure.rs | 22 +++++++ .../const-traits/call-const-closure.stderr | 9 +++ .../const-traits/call-const-in-tilde-const.rs | 14 ++++ .../call-const-in-tilde-const.stderr | 18 +++++ .../const-traits/const-bound-in-host.rs | 15 +++++ .../const-traits/const-bound-in-host.stderr | 11 ++++ .../traits/const-traits/const-in-closure.rs | 25 +++++++ .../const-traits/const-in-closure.stderr | 11 ++++ .../const-traits/dont-observe-host-opaque.rs | 12 ++++ .../dont-observe-host-opaque.stderr | 11 ++++ .../traits/const-traits/dont-observe-host.rs | 23 +++++++ .../const-traits/dont-observe-host.stderr | 11 ++++ tests/ui/traits/const-traits/fn-ptr-lub.rs | 20 ++++++ .../ui/traits/const-traits/fn-ptr-lub.stderr | 11 ++++ .../item-bound-entailment-fails.rs | 31 +++++++++ .../item-bound-entailment-fails.stderr | 36 ++++++++++ .../const-traits/item-bound-entailment.rs | 31 +++++++++ .../const-traits/item-bound-entailment.stderr | 11 ++++ .../predicate-entailment-fails.rs | 43 ++++++++++++ .../predicate-entailment-fails.stderr | 66 +++++++++++++++++++ .../predicate-entailment-passes.rs | 39 +++++++++++ .../predicate-entailment-passes.stderr | 11 ++++ .../tilde-const-in-struct-args.rs | 21 ++++++ .../tilde-const-in-struct-args.stderr | 11 ++++ 24 files changed, 513 insertions(+) create mode 100644 tests/ui/traits/const-traits/call-const-closure.rs create mode 100644 tests/ui/traits/const-traits/call-const-closure.stderr create mode 100644 tests/ui/traits/const-traits/call-const-in-tilde-const.rs create mode 100644 tests/ui/traits/const-traits/call-const-in-tilde-const.stderr create mode 100644 tests/ui/traits/const-traits/const-bound-in-host.rs create mode 100644 tests/ui/traits/const-traits/const-bound-in-host.stderr create mode 100644 tests/ui/traits/const-traits/const-in-closure.rs create mode 100644 tests/ui/traits/const-traits/const-in-closure.stderr create mode 100644 tests/ui/traits/const-traits/dont-observe-host-opaque.rs create mode 100644 tests/ui/traits/const-traits/dont-observe-host-opaque.stderr create mode 100644 tests/ui/traits/const-traits/dont-observe-host.rs create mode 100644 tests/ui/traits/const-traits/dont-observe-host.stderr create mode 100644 tests/ui/traits/const-traits/fn-ptr-lub.rs create mode 100644 tests/ui/traits/const-traits/fn-ptr-lub.stderr create mode 100644 tests/ui/traits/const-traits/item-bound-entailment-fails.rs create mode 100644 tests/ui/traits/const-traits/item-bound-entailment-fails.stderr create mode 100644 tests/ui/traits/const-traits/item-bound-entailment.rs create mode 100644 tests/ui/traits/const-traits/item-bound-entailment.stderr create mode 100644 tests/ui/traits/const-traits/predicate-entailment-fails.rs create mode 100644 tests/ui/traits/const-traits/predicate-entailment-fails.stderr create mode 100644 tests/ui/traits/const-traits/predicate-entailment-passes.rs create mode 100644 tests/ui/traits/const-traits/predicate-entailment-passes.stderr create mode 100644 tests/ui/traits/const-traits/tilde-const-in-struct-args.rs create mode 100644 tests/ui/traits/const-traits/tilde-const-in-struct-args.stderr diff --git a/tests/ui/traits/const-traits/call-const-closure.rs b/tests/ui/traits/const-traits/call-const-closure.rs new file mode 100644 index 0000000000000..cbf3e6c3ac40a --- /dev/null +++ b/tests/ui/traits/const-traits/call-const-closure.rs @@ -0,0 +1,22 @@ +//@ compile-flags: -Znext-solver +//@ edition:2021 + +#![feature(const_trait_impl, effects, const_closures)] +#![allow(incomplete_features)] + +#[const_trait] +trait Bar { + fn foo(&self); +} + +impl Bar for () { + fn foo(&self) {} +} + +const FOO: () = { + (const || ().foo())(); + //~^ ERROR the trait bound `(): ~const Bar` is not satisfied + // FIXME(effects): The constness environment for const closures is wrong. +}; + +fn main() {} diff --git a/tests/ui/traits/const-traits/call-const-closure.stderr b/tests/ui/traits/const-traits/call-const-closure.stderr new file mode 100644 index 0000000000000..3fed67f5d0884 --- /dev/null +++ b/tests/ui/traits/const-traits/call-const-closure.stderr @@ -0,0 +1,9 @@ +error[E0277]: the trait bound `(): ~const Bar` is not satisfied + --> $DIR/call-const-closure.rs:17:15 + | +LL | (const || ().foo())(); + | ^^^^^^^^ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/traits/const-traits/call-const-in-tilde-const.rs b/tests/ui/traits/const-traits/call-const-in-tilde-const.rs new file mode 100644 index 0000000000000..970ee93fd49a3 --- /dev/null +++ b/tests/ui/traits/const-traits/call-const-in-tilde-const.rs @@ -0,0 +1,14 @@ +//@ compile-flags: -Znext-solver +#![feature(const_trait_impl, effects)] +//~^ WARN the feature `effects` is incomplete + +#[const_trait] trait Foo { + fn foo(); +} + +const fn foo() { + const { T::foo() } + //~^ ERROR the trait bound `T: const Foo` is not satisfied +} + +fn main() {} diff --git a/tests/ui/traits/const-traits/call-const-in-tilde-const.stderr b/tests/ui/traits/const-traits/call-const-in-tilde-const.stderr new file mode 100644 index 0000000000000..49c310f1f7513 --- /dev/null +++ b/tests/ui/traits/const-traits/call-const-in-tilde-const.stderr @@ -0,0 +1,18 @@ +warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/call-const-in-tilde-const.rs:2:30 + | +LL | #![feature(const_trait_impl, effects)] + | ^^^^^^^ + | + = note: see issue #102090 for more information + = note: `#[warn(incomplete_features)]` on by default + +error[E0277]: the trait bound `T: const Foo` is not satisfied + --> $DIR/call-const-in-tilde-const.rs:10:13 + | +LL | const { T::foo() } + | ^^^^^^^^ + +error: aborting due to 1 previous error; 1 warning emitted + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/traits/const-traits/const-bound-in-host.rs b/tests/ui/traits/const-traits/const-bound-in-host.rs new file mode 100644 index 0000000000000..6fbc21074b685 --- /dev/null +++ b/tests/ui/traits/const-traits/const-bound-in-host.rs @@ -0,0 +1,15 @@ +//@ compile-flags: -Znext-solver +//@ check-pass + +#![feature(const_trait_impl, effects)] +//~^ WARN the feature `effects` is incomplete + +#[const_trait] trait Foo { + fn foo(); +} + +fn foo() { + const { T::foo() } +} + +fn main() {} diff --git a/tests/ui/traits/const-traits/const-bound-in-host.stderr b/tests/ui/traits/const-traits/const-bound-in-host.stderr new file mode 100644 index 0000000000000..b815f745ee8fc --- /dev/null +++ b/tests/ui/traits/const-traits/const-bound-in-host.stderr @@ -0,0 +1,11 @@ +warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/const-bound-in-host.rs:4:30 + | +LL | #![feature(const_trait_impl, effects)] + | ^^^^^^^ + | + = note: see issue #102090 for more information + = note: `#[warn(incomplete_features)]` on by default + +warning: 1 warning emitted + diff --git a/tests/ui/traits/const-traits/const-in-closure.rs b/tests/ui/traits/const-traits/const-in-closure.rs new file mode 100644 index 0000000000000..51b22c530361a --- /dev/null +++ b/tests/ui/traits/const-traits/const-in-closure.rs @@ -0,0 +1,25 @@ +//@ compile-flags: -Znext-solver +//@ check-pass + +#![feature(const_trait_impl, effects)] +//~^ WARN the feature `effects` is incomplete + +#[const_trait] trait Trait { + fn method(); +} + +const fn foo() { + let _ = || { + // Make sure this doesn't enforce `T: ~const Trait` + T::method(); + }; +} + +fn bar() { + let _ = || { + // Make sure unconditionally const bounds propagate from parent. + const { T::method(); }; + }; +} + +fn main() {} diff --git a/tests/ui/traits/const-traits/const-in-closure.stderr b/tests/ui/traits/const-traits/const-in-closure.stderr new file mode 100644 index 0000000000000..f4b03b9ed2017 --- /dev/null +++ b/tests/ui/traits/const-traits/const-in-closure.stderr @@ -0,0 +1,11 @@ +warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/const-in-closure.rs:4:30 + | +LL | #![feature(const_trait_impl, effects)] + | ^^^^^^^ + | + = note: see issue #102090 for more information + = note: `#[warn(incomplete_features)]` on by default + +warning: 1 warning emitted + diff --git a/tests/ui/traits/const-traits/dont-observe-host-opaque.rs b/tests/ui/traits/const-traits/dont-observe-host-opaque.rs new file mode 100644 index 0000000000000..4a5ae346e3961 --- /dev/null +++ b/tests/ui/traits/const-traits/dont-observe-host-opaque.rs @@ -0,0 +1,12 @@ +//@ compile-flags: -Znext-solver +//@ check-pass + +#![feature(const_trait_impl, effects)] +//~^ WARN the feature `effects` is incomplete + +const fn opaque() -> impl Sized {} + +fn main() { + let mut x = const { opaque() }; + x = opaque(); +} diff --git a/tests/ui/traits/const-traits/dont-observe-host-opaque.stderr b/tests/ui/traits/const-traits/dont-observe-host-opaque.stderr new file mode 100644 index 0000000000000..1b457ab764327 --- /dev/null +++ b/tests/ui/traits/const-traits/dont-observe-host-opaque.stderr @@ -0,0 +1,11 @@ +warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/dont-observe-host-opaque.rs:4:30 + | +LL | #![feature(const_trait_impl, effects)] + | ^^^^^^^ + | + = note: see issue #102090 for more information + = note: `#[warn(incomplete_features)]` on by default + +warning: 1 warning emitted + diff --git a/tests/ui/traits/const-traits/dont-observe-host.rs b/tests/ui/traits/const-traits/dont-observe-host.rs new file mode 100644 index 0000000000000..d027d578c42f3 --- /dev/null +++ b/tests/ui/traits/const-traits/dont-observe-host.rs @@ -0,0 +1,23 @@ +//@ compile-flags: -Znext-solver +//@ check-pass + +#![feature(const_trait_impl, effects)] +//~^ WARN the feature `effects` is incomplete + +#[const_trait] +trait Trait { + fn method() {} +} + +impl const Trait for () {} + +fn main() { + let mut x = const { + let x = <()>::method; + x(); + x + }; + let y = <()>::method; + y(); + x = y; +} diff --git a/tests/ui/traits/const-traits/dont-observe-host.stderr b/tests/ui/traits/const-traits/dont-observe-host.stderr new file mode 100644 index 0000000000000..64ef611f011c0 --- /dev/null +++ b/tests/ui/traits/const-traits/dont-observe-host.stderr @@ -0,0 +1,11 @@ +warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/dont-observe-host.rs:4:30 + | +LL | #![feature(const_trait_impl, effects)] + | ^^^^^^^ + | + = note: see issue #102090 for more information + = note: `#[warn(incomplete_features)]` on by default + +warning: 1 warning emitted + diff --git a/tests/ui/traits/const-traits/fn-ptr-lub.rs b/tests/ui/traits/const-traits/fn-ptr-lub.rs new file mode 100644 index 0000000000000..0fc326788270d --- /dev/null +++ b/tests/ui/traits/const-traits/fn-ptr-lub.rs @@ -0,0 +1,20 @@ +//@ compile-flags: -Znext-solver +//@ check-pass + +#![feature(const_trait_impl, effects)] +//~^ WARN the feature `effects` is incomplete + +const fn foo() {} +const fn bar() {} +fn baz() {} + +const fn caller(branch: bool) { + let mut x = if branch { + foo + } else { + bar + }; + x = baz; +} + +fn main() {} diff --git a/tests/ui/traits/const-traits/fn-ptr-lub.stderr b/tests/ui/traits/const-traits/fn-ptr-lub.stderr new file mode 100644 index 0000000000000..b333311b660e7 --- /dev/null +++ b/tests/ui/traits/const-traits/fn-ptr-lub.stderr @@ -0,0 +1,11 @@ +warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/fn-ptr-lub.rs:4:30 + | +LL | #![feature(const_trait_impl, effects)] + | ^^^^^^^ + | + = note: see issue #102090 for more information + = note: `#[warn(incomplete_features)]` on by default + +warning: 1 warning emitted + diff --git a/tests/ui/traits/const-traits/item-bound-entailment-fails.rs b/tests/ui/traits/const-traits/item-bound-entailment-fails.rs new file mode 100644 index 0000000000000..42799e3700ca4 --- /dev/null +++ b/tests/ui/traits/const-traits/item-bound-entailment-fails.rs @@ -0,0 +1,31 @@ +//@ compile-flags: -Znext-solver +#![feature(const_trait_impl, effects)] +//~^ WARN the feature `effects` is incomplete + +#[const_trait] trait Foo { + type Assoc: ~const Bar + where + T: ~const Bar; +} + +#[const_trait] trait Bar {} +struct N(T); +impl Bar for N where T: Bar {} +struct C(T); +impl const Bar for C where T: ~const Bar {} + +impl const Foo for u32 { + type Assoc = N + //~^ ERROR the trait bound `N: ~const Bar` is not satisfied + where + T: ~const Bar; +} + +impl const Foo for i32 { + type Assoc = C + //~^ ERROR the trait bound `T: ~const Bar` is not satisfied + where + T: Bar; +} + +fn main() {} diff --git a/tests/ui/traits/const-traits/item-bound-entailment-fails.stderr b/tests/ui/traits/const-traits/item-bound-entailment-fails.stderr new file mode 100644 index 0000000000000..3b3868c4bc845 --- /dev/null +++ b/tests/ui/traits/const-traits/item-bound-entailment-fails.stderr @@ -0,0 +1,36 @@ +warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/item-bound-entailment-fails.rs:2:30 + | +LL | #![feature(const_trait_impl, effects)] + | ^^^^^^^ + | + = note: see issue #102090 for more information + = note: `#[warn(incomplete_features)]` on by default + +error[E0277]: the trait bound `N: ~const Bar` is not satisfied + --> $DIR/item-bound-entailment-fails.rs:18:21 + | +LL | type Assoc = N + | ^^^^ + | +note: required by a bound in `Foo::Assoc` + --> $DIR/item-bound-entailment-fails.rs:6:20 + | +LL | type Assoc: ~const Bar + | ^^^^^^^^^^ required by this bound in `Foo::Assoc` + +error[E0277]: the trait bound `T: ~const Bar` is not satisfied + --> $DIR/item-bound-entailment-fails.rs:25:21 + | +LL | type Assoc = C + | ^^^^ + | +note: required by a bound in `Foo::Assoc` + --> $DIR/item-bound-entailment-fails.rs:6:20 + | +LL | type Assoc: ~const Bar + | ^^^^^^^^^^ required by this bound in `Foo::Assoc` + +error: aborting due to 2 previous errors; 1 warning emitted + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/traits/const-traits/item-bound-entailment.rs b/tests/ui/traits/const-traits/item-bound-entailment.rs new file mode 100644 index 0000000000000..3670eabd66c0f --- /dev/null +++ b/tests/ui/traits/const-traits/item-bound-entailment.rs @@ -0,0 +1,31 @@ +//@ compile-flags: -Znext-solver +//@ check-pass + +#![feature(const_trait_impl, effects)] +//~^ WARN the feature `effects` is incomplete + +#[const_trait] trait Foo { + type Assoc: ~const Bar + where + T: ~const Bar; +} + +#[const_trait] trait Bar {} +struct N(T); +impl Bar for N where T: Bar {} +struct C(T); +impl const Bar for C where T: ~const Bar {} + +impl Foo for u32 { + type Assoc = N + where + T: Bar; +} + +impl const Foo for i32 { + type Assoc = C + where + T: ~const Bar; +} + +fn main() {} diff --git a/tests/ui/traits/const-traits/item-bound-entailment.stderr b/tests/ui/traits/const-traits/item-bound-entailment.stderr new file mode 100644 index 0000000000000..b4a4ebdbee274 --- /dev/null +++ b/tests/ui/traits/const-traits/item-bound-entailment.stderr @@ -0,0 +1,11 @@ +warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/item-bound-entailment.rs:4:30 + | +LL | #![feature(const_trait_impl, effects)] + | ^^^^^^^ + | + = note: see issue #102090 for more information + = note: `#[warn(incomplete_features)]` on by default + +warning: 1 warning emitted + diff --git a/tests/ui/traits/const-traits/predicate-entailment-fails.rs b/tests/ui/traits/const-traits/predicate-entailment-fails.rs new file mode 100644 index 0000000000000..5d6109bfad3a0 --- /dev/null +++ b/tests/ui/traits/const-traits/predicate-entailment-fails.rs @@ -0,0 +1,43 @@ +//@ compile-flags: -Znext-solver +#![feature(const_trait_impl, effects)] +//~^ WARN the feature `effects` is incomplete + +#[const_trait] trait Bar {} +impl const Bar for () {} + + +#[const_trait] trait TildeConst { + type Bar where T: ~const Bar; + + fn foo() where T: ~const Bar; +} +impl TildeConst for () { + type Bar = () where T: const Bar; + //~^ ERROR impl has stricter requirements than trait + + fn foo() where T: const Bar {} + //~^ ERROR impl has stricter requirements than trait +} + + +#[const_trait] trait NeverConst { + type Bar where T: Bar; + + fn foo() where T: Bar; +} +impl NeverConst for i32 { + type Bar = () where T: const Bar; + //~^ ERROR impl has stricter requirements than trait + + fn foo() where T: const Bar {} + //~^ ERROR impl has stricter requirements than trait +} +impl const NeverConst for u32 { + type Bar = () where T: ~const Bar; + //~^ ERROR impl has stricter requirements than trait + + fn foo() where T: ~const Bar {} + //~^ ERROR impl has stricter requirements than trait +} + +fn main() {} diff --git a/tests/ui/traits/const-traits/predicate-entailment-fails.stderr b/tests/ui/traits/const-traits/predicate-entailment-fails.stderr new file mode 100644 index 0000000000000..7cd48ef1d4883 --- /dev/null +++ b/tests/ui/traits/const-traits/predicate-entailment-fails.stderr @@ -0,0 +1,66 @@ +warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/predicate-entailment-fails.rs:2:30 + | +LL | #![feature(const_trait_impl, effects)] + | ^^^^^^^ + | + = note: see issue #102090 for more information + = note: `#[warn(incomplete_features)]` on by default + +error[E0276]: impl has stricter requirements than trait + --> $DIR/predicate-entailment-fails.rs:15:31 + | +LL | type Bar where T: ~const Bar; + | ----------- definition of `Bar` from trait +... +LL | type Bar = () where T: const Bar; + | ^^^^^^^^^ impl has extra requirement `T: const Bar` + +error[E0276]: impl has stricter requirements than trait + --> $DIR/predicate-entailment-fails.rs:18:26 + | +LL | fn foo() where T: ~const Bar; + | -------------------------------- definition of `foo` from trait +... +LL | fn foo() where T: const Bar {} + | ^^^^^^^^^ impl has extra requirement `T: const Bar` + +error[E0276]: impl has stricter requirements than trait + --> $DIR/predicate-entailment-fails.rs:29:31 + | +LL | type Bar where T: Bar; + | ----------- definition of `Bar` from trait +... +LL | type Bar = () where T: const Bar; + | ^^^^^^^^^ impl has extra requirement `T: const Bar` + +error[E0276]: impl has stricter requirements than trait + --> $DIR/predicate-entailment-fails.rs:32:26 + | +LL | fn foo() where T: Bar; + | ------------------------- definition of `foo` from trait +... +LL | fn foo() where T: const Bar {} + | ^^^^^^^^^ impl has extra requirement `T: const Bar` + +error[E0276]: impl has stricter requirements than trait + --> $DIR/predicate-entailment-fails.rs:36:31 + | +LL | type Bar where T: Bar; + | ----------- definition of `Bar` from trait +... +LL | type Bar = () where T: ~const Bar; + | ^^^^^^^^^^ impl has extra requirement `T: ~const Bar` + +error[E0276]: impl has stricter requirements than trait + --> $DIR/predicate-entailment-fails.rs:39:26 + | +LL | fn foo() where T: Bar; + | ------------------------- definition of `foo` from trait +... +LL | fn foo() where T: ~const Bar {} + | ^^^^^^^^^^ impl has extra requirement `T: ~const Bar` + +error: aborting due to 6 previous errors; 1 warning emitted + +For more information about this error, try `rustc --explain E0276`. diff --git a/tests/ui/traits/const-traits/predicate-entailment-passes.rs b/tests/ui/traits/const-traits/predicate-entailment-passes.rs new file mode 100644 index 0000000000000..b660329151bec --- /dev/null +++ b/tests/ui/traits/const-traits/predicate-entailment-passes.rs @@ -0,0 +1,39 @@ +//@ compile-flags: -Znext-solver +//@ check-pass + +#![feature(const_trait_impl, effects)] +//~^ WARN the feature `effects` is incomplete + +#[const_trait] trait Bar {} +impl const Bar for () {} + + +#[const_trait] trait TildeConst { + type Bar where T: ~const Bar; + + fn foo() where T: ~const Bar; +} +impl TildeConst for () { + type Bar = () where T: Bar; + + fn foo() where T: Bar {} +} + + +#[const_trait] trait AlwaysConst { + type Bar where T: const Bar; + + fn foo() where T: const Bar; +} +impl AlwaysConst for i32 { + type Bar = () where T: Bar; + + fn foo() where T: Bar {} +} +impl const AlwaysConst for u32 { + type Bar = () where T: ~const Bar; + + fn foo() where T: ~const Bar {} +} + +fn main() {} diff --git a/tests/ui/traits/const-traits/predicate-entailment-passes.stderr b/tests/ui/traits/const-traits/predicate-entailment-passes.stderr new file mode 100644 index 0000000000000..dcaeea73b580d --- /dev/null +++ b/tests/ui/traits/const-traits/predicate-entailment-passes.stderr @@ -0,0 +1,11 @@ +warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/predicate-entailment-passes.rs:4:30 + | +LL | #![feature(const_trait_impl, effects)] + | ^^^^^^^ + | + = note: see issue #102090 for more information + = note: `#[warn(incomplete_features)]` on by default + +warning: 1 warning emitted + diff --git a/tests/ui/traits/const-traits/tilde-const-in-struct-args.rs b/tests/ui/traits/const-traits/tilde-const-in-struct-args.rs new file mode 100644 index 0000000000000..4722be955e9e5 --- /dev/null +++ b/tests/ui/traits/const-traits/tilde-const-in-struct-args.rs @@ -0,0 +1,21 @@ +//@ compile-flags: -Znext-solver +//@ known-bug: #132067 +//@ check-pass + +#![feature(const_trait_impl, effects)] + +struct S; +#[const_trait] +trait Trait {} + +const fn f< + T: Trait< + { + struct I>(U); + 0 + }, + >, +>() { +} + +pub fn main() {} diff --git a/tests/ui/traits/const-traits/tilde-const-in-struct-args.stderr b/tests/ui/traits/const-traits/tilde-const-in-struct-args.stderr new file mode 100644 index 0000000000000..a9759f10d06b6 --- /dev/null +++ b/tests/ui/traits/const-traits/tilde-const-in-struct-args.stderr @@ -0,0 +1,11 @@ +warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/tilde-const-in-struct-args.rs:5:30 + | +LL | #![feature(const_trait_impl, effects)] + | ^^^^^^^ + | + = note: see issue #102090 for more information + = note: `#[warn(incomplete_features)]` on by default + +warning: 1 warning emitted + From 0f5a47d0884d9d3966f0f4a54e9e9a02cb5f482d Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 23 Oct 2024 16:53:59 +0000 Subject: [PATCH 5/5] Be better at enforcing that const_conditions is only called on const items --- compiler/rustc_hir_analysis/src/bounds.rs | 6 +- .../src/check/compare_impl_item.rs | 21 ++--- .../rustc_hir_analysis/src/check/wfcheck.rs | 2 +- .../src/collect/predicates_of.rs | 80 +++++-------------- compiler/rustc_hir_typeck/src/callee.rs | 7 +- compiler/rustc_metadata/src/rmeta/encoder.rs | 18 +++-- compiler/rustc_middle/src/ty/context.rs | 3 +- compiler/rustc_middle/src/ty/mod.rs | 67 +++++++++++++++- compiler/rustc_ty_utils/src/ty.rs | 13 +-- .../derive-const-with-params.stderr | 11 +-- .../effects/spec-effectvar-ice.rs | 2 - .../effects/spec-effectvar-ice.stderr | 16 +--- 12 files changed, 126 insertions(+), 120 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/bounds.rs b/compiler/rustc_hir_analysis/src/bounds.rs index 7a919bb250059..1121ca5324019 100644 --- a/compiler/rustc_hir_analysis/src/bounds.rs +++ b/compiler/rustc_hir_analysis/src/bounds.rs @@ -89,7 +89,11 @@ impl<'tcx> Bounds<'tcx> { host: ty::HostPolarity, span: Span, ) { - self.clauses.push((bound_trait_ref.to_host_effect_clause(tcx, host), span)); + if tcx.is_const_trait(bound_trait_ref.def_id()) { + self.clauses.push((bound_trait_ref.to_host_effect_clause(tcx, host), span)); + } else { + tcx.dcx().span_delayed_bug(span, "tried to lower {host:?} bound for non-const trait"); + } } pub(crate) fn clauses( diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs index 439e6d7842839..02cf1a502f16e 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs @@ -206,8 +206,8 @@ fn compare_method_predicate_entailment<'tcx>( ); // FIXME(effects): This should be replaced with a more dedicated method. - let check_const_if_const = tcx.constness(impl_def_id) == hir::Constness::Const; - if check_const_if_const { + let is_conditionally_const = tcx.is_conditionally_const(impl_def_id); + if is_conditionally_const { // Augment the hybrid param-env with the const conditions // of the impl header and the trait method. hybrid_preds.extend( @@ -255,7 +255,7 @@ fn compare_method_predicate_entailment<'tcx>( // This registers the `~const` bounds of the impl method, which we will prove // using the hybrid param-env that we earlier augmented with the const conditions // from the impl header and trait method declaration. - if check_const_if_const { + if is_conditionally_const { for (const_condition, span) in tcx.const_conditions(impl_m.def_id).instantiate_own_identity() { @@ -1904,9 +1904,8 @@ fn compare_type_predicate_entailment<'tcx>( let trait_ty_predicates = tcx.predicates_of(trait_ty.def_id); let impl_ty_own_bounds = impl_ty_predicates.instantiate_own_identity(); - let impl_ty_own_const_conditions = - tcx.const_conditions(impl_ty.def_id).instantiate_own_identity(); - if impl_ty_own_bounds.len() == 0 && impl_ty_own_const_conditions.len() == 0 { + // If there are no bounds, then there are no const conditions, so no need to check that here. + if impl_ty_own_bounds.len() == 0 { // Nothing to check. return Ok(()); } @@ -1931,8 +1930,8 @@ fn compare_type_predicate_entailment<'tcx>( let impl_ty_span = tcx.def_span(impl_ty_def_id); let normalize_cause = ObligationCause::misc(impl_ty_span, impl_ty_def_id); - let check_const_if_const = tcx.constness(impl_def_id) == hir::Constness::Const; - if check_const_if_const { + let is_conditionally_const = tcx.is_conditionally_const(impl_ty.def_id); + if is_conditionally_const { // Augment the hybrid param-env with the const conditions // of the impl header and the trait assoc type. hybrid_preds.extend( @@ -1968,8 +1967,10 @@ fn compare_type_predicate_entailment<'tcx>( ocx.register_obligation(traits::Obligation::new(tcx, cause, param_env, predicate)); } - if check_const_if_const { + if is_conditionally_const { // Validate the const conditions of the impl associated type. + let impl_ty_own_const_conditions = + tcx.const_conditions(impl_ty.def_id).instantiate_own_identity(); for (const_condition, span) in impl_ty_own_const_conditions { let normalize_cause = traits::ObligationCause::misc(span, impl_ty_def_id); let const_condition = ocx.normalize(&normalize_cause, param_env, const_condition); @@ -2081,7 +2082,7 @@ pub(super) fn check_type_bounds<'tcx>( .collect(); // Only in a const implementation do we need to check that the `~const` item bounds hold. - if tcx.constness(container_id) == hir::Constness::Const { + if tcx.is_conditionally_const(impl_ty_def_id) { obligations.extend( tcx.implied_const_bounds(trait_ty.def_id) .iter_instantiated_copied(tcx, rebased_args) diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index f0041a577424f..499e42d31c97f 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -1372,7 +1372,7 @@ fn check_impl<'tcx>( } // Ensure that the `~const` where clauses of the trait hold for the impl. - if tcx.constness(item.owner_id.def_id) == hir::Constness::Const { + if tcx.is_conditionally_const(item.owner_id.def_id) { for (bound, _) in tcx.const_conditions(trait_ref.def_id).instantiate(tcx, trait_ref.args) { diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs index ec5773d174f82..61dc4b1677c63 100644 --- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs @@ -888,48 +888,8 @@ pub(super) fn const_conditions<'tcx>( tcx: TyCtxt<'tcx>, def_id: LocalDefId, ) -> ty::ConstConditions<'tcx> { - // This logic is spaghetti, and should be cleaned up. The current methods that are - // defined to deal with constness are very unintuitive. - if tcx.is_const_fn_raw(def_id.to_def_id()) { - // Ok, const fn or method in const trait. - } else { - match tcx.def_kind(def_id) { - DefKind::Trait => { - if !tcx.is_const_trait(def_id.to_def_id()) { - return Default::default(); - } - } - DefKind::Impl { .. } => { - // FIXME(effects): Should be using a dedicated function to - // test if this is a const trait impl. - if tcx.constness(def_id) != hir::Constness::Const { - return Default::default(); - } - } - DefKind::AssocTy | DefKind::AssocFn => { - let parent_def_id = tcx.local_parent(def_id).to_def_id(); - match tcx.associated_item(def_id).container { - ty::AssocItemContainer::TraitContainer => { - if !tcx.is_const_trait(parent_def_id) { - return Default::default(); - } - } - ty::AssocItemContainer::ImplContainer => { - // FIXME(effects): Should be using a dedicated function to - // test if this is a const trait impl. - if tcx.constness(parent_def_id) != hir::Constness::Const { - return Default::default(); - } - } - } - } - DefKind::Closure | DefKind::OpaqueTy => { - // Closures and RPITs will eventually have const conditions - // for `~const` bounds. - return Default::default(); - } - _ => return Default::default(), - } + if !tcx.is_conditionally_const(def_id) { + bug!("const_conditions invoked for item that is not conditionally const: {def_id:?}"); } let (generics, trait_def_id_and_supertraits, has_parent) = match tcx.hir_node_by_def_id(def_id) @@ -940,7 +900,7 @@ pub(super) fn const_conditions<'tcx>( hir::ItemKind::Trait(_, _, generics, supertraits, _) => { (generics, Some((item.owner_id.def_id, supertraits)), false) } - _ => return Default::default(), + _ => bug!("const_conditions called on wrong item: {def_id:?}"), }, // While associated types are not really const, we do allow them to have `~const` // bounds and where clauses. `const_conditions` is responsible for gathering @@ -950,13 +910,21 @@ pub(super) fn const_conditions<'tcx>( hir::TraitItemKind::Fn(_, _) | hir::TraitItemKind::Type(_, _) => { (item.generics, None, true) } - _ => return Default::default(), + _ => bug!("const_conditions called on wrong item: {def_id:?}"), }, Node::ImplItem(item) => match item.kind { - hir::ImplItemKind::Fn(_, _) | hir::ImplItemKind::Type(_) => (item.generics, None, true), - _ => return Default::default(), + hir::ImplItemKind::Fn(_, _) | hir::ImplItemKind::Type(_) => { + (item.generics, None, tcx.is_conditionally_const(tcx.local_parent(def_id))) + } + _ => bug!("const_conditions called on wrong item: {def_id:?}"), }, - _ => return Default::default(), + Node::ForeignItem(item) => match item.kind { + hir::ForeignItemKind::Fn(_, _, generics) => (generics, None, false), + _ => bug!("const_conditions called on wrong item: {def_id:?}"), + }, + // N.B. Tuple ctors are unconditionally constant. + Node::Ctor(hir::VariantData::Tuple { .. }) => return Default::default(), + _ => bug!("const_conditions called on wrong item: {def_id:?}"), }; let icx = ItemCtxt::new(tcx, def_id); @@ -1017,12 +985,12 @@ pub(super) fn implied_const_bounds<'tcx>( tcx: TyCtxt<'tcx>, def_id: LocalDefId, ) -> ty::EarlyBinder<'tcx, &'tcx [(ty::PolyTraitRef<'tcx>, Span)]> { + if !tcx.is_conditionally_const(def_id) { + bug!("const_conditions invoked for item that is not conditionally const: {def_id:?}"); + } + let bounds = match tcx.hir_node_by_def_id(def_id) { Node::Item(hir::Item { kind: hir::ItemKind::Trait(..), .. }) => { - if !tcx.is_const_trait(def_id.to_def_id()) { - return ty::EarlyBinder::bind(&[]); - } - implied_predicates_with_filter( tcx, def_id.to_def_id(), @@ -1030,17 +998,9 @@ pub(super) fn implied_const_bounds<'tcx>( ) } Node::TraitItem(hir::TraitItem { kind: hir::TraitItemKind::Type(..), .. }) => { - if !tcx.is_const_trait(tcx.local_parent(def_id).to_def_id()) { - return ty::EarlyBinder::bind(&[]); - } - explicit_item_bounds_with_filter(tcx, def_id, PredicateFilter::ConstIfConst) } - Node::OpaqueTy(..) => { - // We should eventually collect the `~const` bounds on opaques. - return ty::EarlyBinder::bind(&[]); - } - _ => return ty::EarlyBinder::bind(&[]), + _ => bug!("implied_const_bounds called on wrong item: {def_id:?}"), }; bounds.map_bound(|bounds| { diff --git a/compiler/rustc_hir_typeck/src/callee.rs b/compiler/rustc_hir_typeck/src/callee.rs index 081cb8c18e65d..190e405282c12 100644 --- a/compiler/rustc_hir_typeck/src/callee.rs +++ b/compiler/rustc_hir_typeck/src/callee.rs @@ -861,12 +861,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // FIXME(effects): Should this be `is_const_fn_raw`? It depends on if we move // const stability checking here too, I guess. - if self.tcx.is_const_fn(callee_did) - || self - .tcx - .trait_of_item(callee_did) - .is_some_and(|def_id| self.tcx.is_const_trait(def_id)) - { + if self.tcx.is_conditionally_const(callee_did) { let q = self.tcx.const_conditions(callee_did); // FIXME(effects): Use this span with a better cause code. for (cond, _) in q.instantiate(self.tcx, callee_args) { diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index a71d1993c6c16..e06c86ae4c03e 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -1423,7 +1423,6 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { let g = tcx.generics_of(def_id); record!(self.tables.generics_of[def_id] <- g); record!(self.tables.explicit_predicates_of[def_id] <- self.tcx.explicit_predicates_of(def_id)); - record!(self.tables.const_conditions[def_id] <- self.tcx.const_conditions(def_id)); let inferred_outlives = self.tcx.inferred_outlives_of(def_id); record_defaulted_array!(self.tables.inferred_outlives_of[def_id] <- inferred_outlives); @@ -1434,6 +1433,9 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { } } } + if tcx.is_conditionally_const(def_id) { + record!(self.tables.const_conditions[def_id] <- self.tcx.const_conditions(def_id)); + } if should_encode_type(tcx, local_id, def_kind) { record!(self.tables.type_of[def_id] <- self.tcx.type_of(def_id)); } @@ -1457,11 +1459,13 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { self.tcx.explicit_super_predicates_of(def_id).skip_binder()); record_defaulted_array!(self.tables.explicit_implied_predicates_of[def_id] <- self.tcx.explicit_implied_predicates_of(def_id).skip_binder()); - record_defaulted_array!(self.tables.implied_const_bounds[def_id] - <- self.tcx.implied_const_bounds(def_id).skip_binder()); let module_children = self.tcx.module_children_local(local_id); record_array!(self.tables.module_children_non_reexports[def_id] <- module_children.iter().map(|child| child.res.def_id().index)); + if self.tcx.is_const_trait(def_id) { + record_defaulted_array!(self.tables.implied_const_bounds[def_id] + <- self.tcx.implied_const_bounds(def_id).skip_binder()); + } } if let DefKind::TraitAlias = def_kind { record!(self.tables.trait_def[def_id] <- self.tcx.trait_def(def_id)); @@ -1469,8 +1473,6 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { self.tcx.explicit_super_predicates_of(def_id).skip_binder()); record_defaulted_array!(self.tables.explicit_implied_predicates_of[def_id] <- self.tcx.explicit_implied_predicates_of(def_id).skip_binder()); - record_defaulted_array!(self.tables.implied_const_bounds[def_id] - <- self.tcx.implied_const_bounds(def_id).skip_binder()); } if let DefKind::Trait | DefKind::Impl { .. } = def_kind { let associated_item_def_ids = self.tcx.associated_item_def_ids(def_id); @@ -1653,8 +1655,10 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { if let ty::AssocKind::Type = item.kind { self.encode_explicit_item_bounds(def_id); self.encode_explicit_item_super_predicates(def_id); - record_defaulted_array!(self.tables.implied_const_bounds[def_id] - <- self.tcx.implied_const_bounds(def_id).skip_binder()); + if tcx.is_conditionally_const(def_id) { + record_defaulted_array!(self.tables.implied_const_bounds[def_id] + <- self.tcx.implied_const_bounds(def_id).skip_binder()); + } } } AssocItemContainer::ImplContainer => { diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index c8fe6cbf4c657..eab106a44039b 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -384,7 +384,7 @@ impl<'tcx> Interner for TyCtxt<'tcx> { } fn is_const_impl(self, def_id: DefId) -> bool { - self.constness(def_id) == hir::Constness::Const + self.is_conditionally_const(def_id) } fn const_conditions( @@ -3140,6 +3140,7 @@ impl<'tcx> TyCtxt<'tcx> { } } + // FIXME(effects): Please remove this. It's a footgun. /// Whether the trait impl is marked const. This does not consider stability or feature gates. pub fn is_const_trait_impl_raw(self, def_id: DefId) -> bool { let Some(local_def_id) = def_id.as_local() else { return false }; diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 84e1897019e7e..854147648178f 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -1999,10 +1999,75 @@ impl<'tcx> TyCtxt<'tcx> { pub fn is_const_fn_raw(self, def_id: DefId) -> bool { matches!( self.def_kind(def_id), - DefKind::Fn | DefKind::AssocFn | DefKind::Ctor(..) | DefKind::Closure + DefKind::Fn | DefKind::AssocFn | DefKind::Ctor(_, CtorKind::Fn) | DefKind::Closure ) && self.constness(def_id) == hir::Constness::Const } + /// Whether this item is conditionally constant for the purposes of the + /// effects implementation. + /// + /// This roughly corresponds to all const functions and other callable + /// items, along with const impls and traits, and associated types within + /// those impls and traits. + pub fn is_conditionally_const(self, def_id: impl Into) -> bool { + let def_id: DefId = def_id.into(); + match self.def_kind(def_id) { + DefKind::Impl { of_trait: true } => { + self.constness(def_id) == hir::Constness::Const + && self.is_const_trait( + self.trait_id_of_impl(def_id) + .expect("expected trait for trait implementation"), + ) + } + DefKind::Fn | DefKind::Ctor(_, CtorKind::Fn) => { + self.constness(def_id) == hir::Constness::Const + } + DefKind::Trait => self.is_const_trait(def_id), + DefKind::AssocTy | DefKind::AssocFn => { + let parent_def_id = self.parent(def_id); + match self.def_kind(parent_def_id) { + DefKind::Impl { of_trait: false } => { + self.constness(def_id) == hir::Constness::Const + } + DefKind::Impl { of_trait: true } | DefKind::Trait => { + self.is_conditionally_const(parent_def_id) + } + _ => bug!("unexpected parent item of associated item: {parent_def_id:?}"), + } + } + DefKind::Closure | DefKind::OpaqueTy => { + // Closures and RPITs will eventually have const conditions + // for `~const` bounds. + false + } + DefKind::Ctor(_, CtorKind::Const) + | DefKind::Impl { of_trait: false } + | DefKind::Mod + | DefKind::Struct + | DefKind::Union + | DefKind::Enum + | DefKind::Variant + | DefKind::TyAlias + | DefKind::ForeignTy + | DefKind::TraitAlias + | DefKind::TyParam + | DefKind::Const + | DefKind::ConstParam + | DefKind::Static { .. } + | DefKind::AssocConst + | DefKind::Macro(_) + | DefKind::ExternCrate + | DefKind::Use + | DefKind::ForeignMod + | DefKind::AnonConst + | DefKind::InlineConst + | DefKind::Field + | DefKind::LifetimeParam + | DefKind::GlobalAsm + | DefKind::SyntheticCoroutineBody => false, + } + } + #[inline] pub fn is_const_trait(self, def_id: DefId) -> bool { self.trait_def(def_id).constness == hir::Constness::Const diff --git a/compiler/rustc_ty_utils/src/ty.rs b/compiler/rustc_ty_utils/src/ty.rs index ac2708a29f4a3..aa499995bcb9d 100644 --- a/compiler/rustc_ty_utils/src/ty.rs +++ b/compiler/rustc_ty_utils/src/ty.rs @@ -152,12 +152,13 @@ fn param_env(tcx: TyCtxt<'_>, def_id: DefId) -> ty::ParamEnv<'_> { // We extend the param-env of our item with the const conditions of the item, // since we're allowed to assume `~const` bounds hold within the item itself. - predicates.extend( - tcx.const_conditions(def_id) - .instantiate_identity(tcx) - .into_iter() - .map(|(trait_ref, _)| trait_ref.to_host_effect_clause(tcx, ty::HostPolarity::Maybe)), - ); + if tcx.is_conditionally_const(def_id) { + predicates.extend( + tcx.const_conditions(def_id).instantiate_identity(tcx).into_iter().map( + |(trait_ref, _)| trait_ref.to_host_effect_clause(tcx, ty::HostPolarity::Maybe), + ), + ); + } let local_did = def_id.as_local(); diff --git a/tests/ui/traits/const-traits/const_derives/derive-const-with-params.stderr b/tests/ui/traits/const-traits/const_derives/derive-const-with-params.stderr index 3388ee30a5d33..addce8dcd6c75 100644 --- a/tests/ui/traits/const-traits/const_derives/derive-const-with-params.stderr +++ b/tests/ui/traits/const-traits/const_derives/derive-const-with-params.stderr @@ -30,14 +30,5 @@ 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: `~const` can only be applied to `#[const_trait]` traits - --> $DIR/derive-const-with-params.rs:7:16 - | -LL | #[derive_const(PartialEq)] - | ^^^^^^^^^ - | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - = note: this error originates in the derive macro `PartialEq` (in Nightly builds, run with -Z macro-backtrace for more info) - -error: aborting due to 4 previous errors; 1 warning emitted +error: aborting due to 3 previous errors; 1 warning emitted diff --git a/tests/ui/traits/const-traits/effects/spec-effectvar-ice.rs b/tests/ui/traits/const-traits/effects/spec-effectvar-ice.rs index 73d3e883aad9c..d29cd93d3fb72 100644 --- a/tests/ui/traits/const-traits/effects/spec-effectvar-ice.rs +++ b/tests/ui/traits/const-traits/effects/spec-effectvar-ice.rs @@ -14,9 +14,7 @@ impl const Foo for T {} impl const Foo for T where T: const Specialize {} //~^ error: const `impl` for trait `Foo` which is not marked with `#[const_trait]` //~| error: `const` can only be applied to `#[const_trait]` traits -//~| error: `const` can only be applied to `#[const_trait]` traits //~| error: specialization impl does not specialize any associated items //~| error: cannot specialize on trait `Specialize` -//~| ERROR cannot specialize on predicate fn main() {} diff --git a/tests/ui/traits/const-traits/effects/spec-effectvar-ice.stderr b/tests/ui/traits/const-traits/effects/spec-effectvar-ice.stderr index 2556903150b47..d9655c4995fa3 100644 --- a/tests/ui/traits/const-traits/effects/spec-effectvar-ice.stderr +++ b/tests/ui/traits/const-traits/effects/spec-effectvar-ice.stderr @@ -42,14 +42,6 @@ error: `const` can only be applied to `#[const_trait]` traits LL | impl const Foo for T where T: const Specialize {} | ^^^^^^^^^^ -error: `const` can only be applied to `#[const_trait]` traits - --> $DIR/spec-effectvar-ice.rs:14:40 - | -LL | impl const Foo for T where T: const Specialize {} - | ^^^^^^^^^^ - | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - error: specialization impl does not specialize any associated items --> $DIR/spec-effectvar-ice.rs:14:1 | @@ -62,17 +54,11 @@ note: impl is a specialization of this impl LL | impl const Foo for T {} | ^^^^^^^^^^^^^^^^^^^^^^^ -error: cannot specialize on predicate `T: const Specialize` - --> $DIR/spec-effectvar-ice.rs:14:34 - | -LL | impl const Foo for T where T: const Specialize {} - | ^^^^^^^^^^^^^^^^ - error: cannot specialize on trait `Specialize` --> $DIR/spec-effectvar-ice.rs:14:34 | LL | impl const Foo for T where T: const Specialize {} | ^^^^^^^^^^^^^^^^ -error: aborting due to 8 previous errors; 1 warning emitted +error: aborting due to 6 previous errors; 1 warning emitted