From 72e8244e64b284f8f93a778e804b59c10305fc59 Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Fri, 14 Jun 2024 12:16:15 +0000 Subject: [PATCH 01/10] implement new effects desugaring --- compiler/rustc_ast_lowering/src/expr.rs | 1 - compiler/rustc_ast_lowering/src/item.rs | 111 ++++++++---- compiler/rustc_ast_lowering/src/lib.rs | 91 ++-------- compiler/rustc_ast_lowering/src/path.rs | 9 - .../src/const_eval/fn_queries.rs | 5 +- compiler/rustc_feature/src/builtin_attrs.rs | 4 + compiler/rustc_hir/src/hir.rs | 2 + compiler/rustc_hir/src/intravisit.rs | 3 +- compiler/rustc_hir/src/lang_items.rs | 8 + compiler/rustc_hir_analysis/src/bounds.rs | 102 ++++++++++- .../rustc_hir_analysis/src/check/check.rs | 2 +- .../src/check/compare_impl_item.rs | 8 +- .../rustc_hir_analysis/src/check/wfcheck.rs | 7 +- compiler/rustc_hir_analysis/src/collect.rs | 49 ++--- .../src/collect/generics_of.rs | 6 +- .../src/collect/item_bounds.rs | 4 +- .../src/collect/predicates_of.rs | 65 +++++-- .../src/collect/resolve_bound_vars.rs | 2 +- .../src/hir_ty_lowering/generics.rs | 3 +- .../src/hir_ty_lowering/mod.rs | 9 +- .../src/hir_ty_lowering/object_safety.rs | 6 +- compiler/rustc_hir_pretty/src/lib.rs | 7 +- .../rustc_hir_typeck/src/fn_ctxt/_impl.rs | 4 +- compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs | 1 + compiler/rustc_hir_typeck/src/method/mod.rs | 15 +- compiler/rustc_hir_typeck/src/method/probe.rs | 1 + compiler/rustc_metadata/src/rmeta/decoder.rs | 5 +- .../src/rmeta/decoder/cstore_impl.rs | 3 + compiler/rustc_metadata/src/rmeta/encoder.rs | 6 + compiler/rustc_metadata/src/rmeta/mod.rs | 2 + compiler/rustc_middle/src/query/mod.rs | 8 + compiler/rustc_middle/src/ty/assoc.rs | 2 + compiler/rustc_middle/src/ty/context.rs | 4 +- compiler/rustc_middle/src/ty/generics.rs | 3 +- compiler/rustc_middle/src/ty/mod.rs | 12 +- compiler/rustc_smir/src/rustc_smir/context.rs | 6 +- .../rustc_smir/src/rustc_smir/convert/ty.rs | 2 +- compiler/rustc_span/src/symbol.rs | 9 + .../src/traits/error_reporting/suggestions.rs | 6 + compiler/rustc_ty_utils/src/assoc.rs | 168 +++++++++++++++++- library/core/src/lib.rs | 1 + library/core/src/marker.rs | 38 ++++ src/librustdoc/clean/mod.rs | 14 +- src/librustdoc/clean/types.rs | 4 +- src/librustdoc/json/conversions.rs | 16 +- .../const_trait_fn-issue-88433.rs | 1 + .../effects/group-traits.rs | 14 ++ .../issue-92230-wf-super-trait-env.rs | 3 +- .../tilde-const-invalid-places.stderr | 11 +- .../unsatisfied-const-trait-bound.rs | 1 + 50 files changed, 636 insertions(+), 228 deletions(-) create mode 100644 tests/ui/rfcs/rfc-2632-const-trait-impl/effects/group-traits.rs diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs index 624bca525b9f3..218fa9740229d 100644 --- a/compiler/rustc_ast_lowering/src/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs @@ -103,7 +103,6 @@ impl<'hir> LoweringContext<'_, 'hir> { ParamMode::Optional, ParenthesizedGenericArgs::Err, ImplTraitContext::Disallowed(ImplTraitPosition::Path), - None, // Method calls can't have bound modifiers None, )); diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index 74e04eff4f3e0..d59ac5766298d 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -56,7 +56,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); + let mut lctx = LoweringContext::new(self.tcx, self.resolver, self.ast_index); lctx.with_hir_id_owner(owner, |lctx| f(lctx)); for (def_id, info) in lctx.children { @@ -190,6 +190,7 @@ impl<'hir> LoweringContext<'_, 'hir> { let (generics, (ty, body_id)) = self.lower_generics( generics, Const::No, + false, id, ImplTraitContext::Disallowed(ImplTraitPosition::Generic), |this| { @@ -221,7 +222,7 @@ impl<'hir> LoweringContext<'_, 'hir> { let itctx = ImplTraitContext::Universal; let (generics, decl) = - this.lower_generics(generics, header.constness, id, itctx, |this| { + this.lower_generics(generics, header.constness, false, id, itctx, |this| { this.lower_fn_decl( decl, id, @@ -265,6 +266,7 @@ impl<'hir> LoweringContext<'_, 'hir> { let (generics, ty) = self.lower_generics( &generics, Const::No, + false, id, ImplTraitContext::Disallowed(ImplTraitPosition::Generic), |this| match ty { @@ -293,6 +295,7 @@ impl<'hir> LoweringContext<'_, 'hir> { let (generics, variants) = self.lower_generics( generics, Const::No, + false, id, ImplTraitContext::Disallowed(ImplTraitPosition::Generic), |this| { @@ -307,6 +310,7 @@ impl<'hir> LoweringContext<'_, 'hir> { 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), @@ -317,6 +321,7 @@ impl<'hir> LoweringContext<'_, 'hir> { let (generics, vdata) = self.lower_generics( generics, Const::No, + false, id, ImplTraitContext::Disallowed(ImplTraitPosition::Generic), |this| this.lower_variant_data(hir_id, vdata), @@ -348,12 +353,9 @@ impl<'hir> LoweringContext<'_, 'hir> { // parent lifetime. let itctx = ImplTraitContext::Universal; let (generics, (trait_ref, lowered_ty)) = - self.lower_generics(ast_generics, *constness, id, itctx, |this| { + self.lower_generics(ast_generics, Const::No, false, id, itctx, |this| { let modifiers = TraitBoundModifiers { - constness: match *constness { - Const::Yes(span) => BoundConstness::Maybe(span), - Const::No => BoundConstness::Never, - }, + constness: BoundConstness::Never, asyncness: BoundAsyncness::Normal, // we don't use this in bound lowering polarity: BoundPolarity::Positive, @@ -389,6 +391,7 @@ impl<'hir> LoweringContext<'_, 'hir> { ImplPolarity::Negative(s) => ImplPolarity::Negative(self.lower_span(*s)), }; hir::ItemKind::Impl(self.arena.alloc(hir::Impl { + constness: self.lower_constness(*constness), safety: self.lower_safety(*safety, hir::Safety::Safe), polarity, defaultness, @@ -400,15 +403,10 @@ impl<'hir> LoweringContext<'_, 'hir> { })) } ItemKind::Trait(box Trait { is_auto, safety, generics, bounds, items }) => { - // FIXME(const_trait_impl, effects, fee1-dead) this should be simplified if possible - let constness = attrs - .unwrap_or(&[]) - .iter() - .find(|x| x.has_name(sym::const_trait)) - .map_or(Const::No, |x| Const::Yes(x.span)); let (generics, (safety, items, bounds)) = self.lower_generics( generics, - constness, + Const::No, + false, id, ImplTraitContext::Disallowed(ImplTraitPosition::Generic), |this| { @@ -429,6 +427,7 @@ impl<'hir> LoweringContext<'_, 'hir> { let (generics, bounds) = self.lower_generics( generics, Const::No, + false, id, ImplTraitContext::Disallowed(ImplTraitPosition::Generic), |this| { @@ -609,30 +608,45 @@ impl<'hir> LoweringContext<'_, 'hir> { // This is used to track which lifetimes have already been defined, // and which need to be replicated when lowering an async fn. - let generics = match parent_hir.node().expect_item().kind { + let parent_item = parent_hir.node().expect_item(); + let constness = match parent_item.kind { hir::ItemKind::Impl(impl_) => { self.is_in_trait_impl = impl_.of_trait.is_some(); - &impl_.generics + // 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 { + self.tcx + .get_attr(def_id, sym::const_trait) + .map_or(Const::No, |attr| Const::Yes(attr.span)) + } + } else { + Const::No + } } - hir::ItemKind::Trait(_, _, generics, _, _) => generics, + 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)), kind => { span_bug!(item.span, "assoc item has unexpected kind of parent: {}", kind.descr()) } }; - if self.tcx.features().effects { - self.host_param_id = generics - .params - .iter() - .find(|param| { - matches!(param.kind, hir::GenericParamKind::Const { is_host_effect: true, .. }) - }) - .map(|param| param.def_id); - } - match ctxt { - AssocCtxt::Trait => hir::OwnerNode::TraitItem(self.lower_trait_item(item)), - AssocCtxt::Impl => hir::OwnerNode::ImplItem(self.lower_impl_item(item)), + AssocCtxt::Trait => hir::OwnerNode::TraitItem(self.lower_trait_item(item, constness)), + AssocCtxt::Impl => hir::OwnerNode::ImplItem(self.lower_impl_item(item, constness)), } } @@ -648,7 +662,7 @@ impl<'hir> LoweringContext<'_, 'hir> { let fdec = &sig.decl; let itctx = ImplTraitContext::Universal; let (generics, (fn_dec, fn_args)) = - self.lower_generics(generics, Const::No, i.id, itctx, |this| { + self.lower_generics(generics, Const::No, false, i.id, itctx, |this| { ( // Disallow `impl Trait` in foreign items. this.lower_fn_decl( @@ -765,7 +779,11 @@ impl<'hir> LoweringContext<'_, 'hir> { } } - fn lower_trait_item(&mut self, i: &AssocItem) -> &'hir hir::TraitItem<'hir> { + fn lower_trait_item( + &mut self, + i: &AssocItem, + trait_constness: Const, + ) -> &'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(); @@ -775,6 +793,7 @@ impl<'hir> LoweringContext<'_, 'hir> { let (generics, kind) = self.lower_generics( generics, Const::No, + false, i.id, ImplTraitContext::Disallowed(ImplTraitPosition::Generic), |this| { @@ -795,6 +814,7 @@ impl<'hir> LoweringContext<'_, 'hir> { i.id, FnDeclKind::Trait, sig.header.coroutine_kind, + trait_constness, ); (generics, hir::TraitItemKind::Fn(sig, hir::TraitFn::Required(names)), false) } @@ -813,6 +833,7 @@ 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) } @@ -822,6 +843,7 @@ impl<'hir> LoweringContext<'_, 'hir> { let (generics, kind) = self.lower_generics( &generics, Const::No, + false, i.id, ImplTraitContext::Disallowed(ImplTraitPosition::Generic), |this| { @@ -894,7 +916,11 @@ impl<'hir> LoweringContext<'_, 'hir> { self.expr(span, hir::ExprKind::Err(guar)) } - fn lower_impl_item(&mut self, i: &AssocItem) -> &'hir hir::ImplItem<'hir> { + fn lower_impl_item( + &mut self, + i: &AssocItem, + constness_of_trait: Const, + ) -> &'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); @@ -905,6 +931,7 @@ impl<'hir> LoweringContext<'_, 'hir> { AssocItemKind::Const(box ConstItem { generics, ty, expr, .. }) => self.lower_generics( generics, Const::No, + false, i.id, ImplTraitContext::Disallowed(ImplTraitPosition::Generic), |this| { @@ -930,6 +957,7 @@ 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)) @@ -940,6 +968,7 @@ impl<'hir> LoweringContext<'_, 'hir> { self.lower_generics( &generics, Const::No, + false, i.id, ImplTraitContext::Disallowed(ImplTraitPosition::Generic), |this| match ty { @@ -1352,15 +1381,18 @@ 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); // 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 { Const::No }; + let constness = + if kind == FnDeclKind::Inherent { sig.header.constness } else { parent_constness }; let itctx = ImplTraitContext::Universal; - let (generics, decl) = self.lower_generics(generics, constness, id, itctx, |this| { - this.lower_fn_decl(&sig.decl, id, sig.span, kind, coroutine_kind) - }); + 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) + }); (generics, hir::FnSig { header, decl, span: self.lower_span(sig.span) }) } @@ -1436,6 +1468,7 @@ impl<'hir> LoweringContext<'_, 'hir> { &mut self, generics: &Generics, constness: Const, + force_append_constness: bool, parent_node_id: NodeId, itctx: ImplTraitContext, f: impl FnOnce(&mut Self) -> T, @@ -1496,7 +1529,9 @@ impl<'hir> LoweringContext<'_, 'hir> { // 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 - && self.tcx.features().effects + // 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(); @@ -1609,6 +1644,7 @@ impl<'hir> LoweringContext<'_, 'hir> { }), )), )), + // FIXME(effects) we might not need a default. default: Some(self.arena.alloc(hir::AnonConst { def_id: anon_const, hir_id: const_id, @@ -1616,6 +1652,7 @@ impl<'hir> LoweringContext<'_, 'hir> { span, })), is_host_effect: true, + synthetic: true, }, colon_span: None, pure_wrt_drop: false, diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 0a06304fcecfa..8fba46625ab9a 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -142,14 +142,19 @@ struct LoweringContext<'a, 'hir> { 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) -> Self { + fn new( + tcx: TyCtxt<'hir>, + resolver: &'a mut ResolverAstLowering, + ast_index: &'a IndexSlice>, + ) -> Self { Self { // Pseudo-globals. tcx, - resolver: resolver, + resolver, arena: tcx.hir_arena, // HirId handling. @@ -185,6 +190,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { allow_async_iterator: [sym::gen_future, sym::async_iterator].into(), generics_def_id_map: Default::default(), host_param_id: None, + ast_index, } } @@ -2135,7 +2141,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { param: &GenericParam, source: hir::GenericParamSource, ) -> hir::GenericParam<'hir> { - let (name, kind) = self.lower_generic_param_kind(param, source); + let (name, kind) = self.lower_generic_param_kind( + param, + source, + attr::contains_name(¶m.attrs, sym::rustc_runtime), + ); let hir_id = self.lower_node_id(param.id); self.lower_attrs(hir_id, ¶m.attrs); @@ -2155,6 +2165,7 @@ 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 => { @@ -2220,7 +2231,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { ( hir::ParamName::Plain(self.lower_ident(param.ident)), - hir::GenericParamKind::Const { ty, default, is_host_effect: false }, + hir::GenericParamKind::Const { ty, default, is_host_effect, synthetic: false }, ) } } @@ -2607,78 +2618,6 @@ struct GenericArgsCtor<'hir> { } impl<'hir> GenericArgsCtor<'hir> { - fn push_constness( - &mut self, - lcx: &mut LoweringContext<'_, 'hir>, - constness: ast::BoundConstness, - ) { - if !lcx.tcx.features().effects { - return; - } - - let (span, body) = match constness { - BoundConstness::Never => return, - BoundConstness::Always(span) => { - let span = lcx.lower_span(span); - - let body = hir::ExprKind::Lit( - lcx.arena.alloc(hir::Lit { node: LitKind::Bool(false), span }), - ); - - (span, body) - } - BoundConstness::Maybe(span) => { - let span = lcx.lower_span(span); - - let Some(host_param_id) = lcx.host_param_id else { - lcx.dcx().span_delayed_bug( - span, - "no host param id for call in const yet no errors reported", - ); - return; - }; - - let hir_id = lcx.next_id(); - let res = Res::Def(DefKind::ConstParam, host_param_id.to_def_id()); - let body = hir::ExprKind::Path(hir::QPath::Resolved( - None, - lcx.arena.alloc(hir::Path { - span, - res, - segments: arena_vec![ - lcx; - hir::PathSegment::new( - Ident { name: sym::host, span }, - hir_id, - res - ) - ], - }), - )); - - (span, body) - } - }; - let body = lcx.lower_body(|lcx| (&[], lcx.expr(span, body))); - - let id = lcx.next_node_id(); - let hir_id = lcx.next_id(); - - let def_id = lcx.create_def( - lcx.current_hir_id_owner.def_id, - id, - kw::Empty, - DefKind::AnonConst, - span, - ); - - lcx.children.push((def_id, hir::MaybeOwner::NonOwner(hir_id))); - self.args.push(hir::GenericArg::Const(hir::ConstArg { - value: lcx.arena.alloc(hir::AnonConst { def_id, hir_id, body, span }), - is_desugared_from_effects: true, - })) - } - fn is_empty(&self) -> bool { self.args.is_empty() && self.constraints.is_empty() diff --git a/compiler/rustc_ast_lowering/src/path.rs b/compiler/rustc_ast_lowering/src/path.rs index 9d38e1e678471..9a1ca703699a8 100644 --- a/compiler/rustc_ast_lowering/src/path.rs +++ b/compiler/rustc_ast_lowering/src/path.rs @@ -107,8 +107,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { param_mode, parenthesized_generic_args, itctx, - // if this is the last segment, add constness to the trait path - if i == proj_start - 1 { modifiers.map(|m| m.constness) } else { None }, bound_modifier_allowed_features.clone(), ) }, @@ -165,7 +163,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { ParenthesizedGenericArgs::Err, itctx, None, - None, )); let qpath = hir::QPath::TypeRelative(ty, hir_segment); @@ -208,7 +205,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { ParenthesizedGenericArgs::Err, ImplTraitContext::Disallowed(ImplTraitPosition::Path), None, - None, ) })), span: self.lower_span(p.span), @@ -222,7 +218,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { param_mode: ParamMode, parenthesized_generic_args: ParenthesizedGenericArgs, itctx: ImplTraitContext, - constness: Option, // Additional features ungated with a bound modifier like `async`. // This is passed down to the implicit associated type binding in // parenthesized bounds. @@ -289,10 +284,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { ) }; - if let Some(constness) = constness { - generic_args.push_constness(self, constness); - } - let has_lifetimes = generic_args.args.iter().any(|arg| matches!(arg, GenericArg::Lifetime(_))); diff --git a/compiler/rustc_const_eval/src/const_eval/fn_queries.rs b/compiler/rustc_const_eval/src/const_eval/fn_queries.rs index 8c66888d1007e..7acd08e0cceb6 100644 --- a/compiler/rustc_const_eval/src/const_eval/fn_queries.rs +++ b/compiler/rustc_const_eval/src/const_eval/fn_queries.rs @@ -42,10 +42,7 @@ fn constness(tcx: TyCtxt<'_>, def_id: LocalDefId) -> hir::Constness { | hir::Node::ImplItem(hir::ImplItem { kind: hir::ImplItemKind::Const(..), .. }) => { hir::Constness::Const } - hir::Node::Item(hir::Item { kind: hir::ItemKind::Impl(_), .. }) => tcx - .generics_of(def_id) - .host_effect_index - .map_or(hir::Constness::NotConst, |_| hir::Constness::Const), + hir::Node::Item(hir::Item { kind: hir::ItemKind::Impl(impl_), .. }) => impl_.constness, hir::Node::ForeignItem(hir::ForeignItem { kind: hir::ForeignItemKind::Fn(..), .. }) => { // Intrinsics use `rustc_const_{un,}stable` attributes to indicate constness. All other // foreign items cannot be evaluated at compile-time. diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs index f884f99692779..a4245f0908e33 100644 --- a/compiler/rustc_feature/src/builtin_attrs.rs +++ b/compiler/rustc_feature/src/builtin_attrs.rs @@ -833,6 +833,10 @@ 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 22a6c06bba323..6cccdec94c0b5 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -526,6 +526,7 @@ pub enum GenericParamKind<'hir> { /// Optional default value for the const generic param default: Option<&'hir AnonConst>, is_host_effect: bool, + synthetic: bool, }, } @@ -3364,6 +3365,7 @@ pub enum ItemKind<'hir> { /// Refer to [`ImplItem`] for an associated item within an impl block. #[derive(Debug, Clone, Copy, HashStable_Generic)] pub struct Impl<'hir> { + pub constness: Constness, pub safety: Safety, pub polarity: ImplPolarity, pub defaultness: Defaultness, diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs index 065ecc5d7b7ba..9bb3245ae05af 100644 --- a/compiler/rustc_hir/src/intravisit.rs +++ b/compiler/rustc_hir/src/intravisit.rs @@ -543,6 +543,7 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item<'v>) -> V:: try_visit!(visitor.visit_enum_def(enum_definition, item.hir_id())); } ItemKind::Impl(Impl { + constness: _, safety: _, defaultness: _, polarity: _, @@ -915,7 +916,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: _ } => { + GenericParamKind::Const { ref ty, ref default, is_host_effect: _, 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 69461957f804d..d49eb4ece99f8 100644 --- a/compiler/rustc_hir/src/lang_items.rs +++ b/compiler/rustc_hir/src/lang_items.rs @@ -393,6 +393,14 @@ 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; + EffectsMin, sym::EffectsMin, effects_min, Target::Trait, GenericRequirement::None; + EffectsMinOutput, sym::EffectsMinOutput, effects_min_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 7f0d72b3a8d4d..18a29c10b61a3 100644 --- a/compiler/rustc_hir_analysis/src/bounds.rs +++ b/compiler/rustc_hir_analysis/src/bounds.rs @@ -1,9 +1,13 @@ //! Bounds are restrictions applied to some types after they've been lowered from the HIR to the //! [`rustc_middle::ty`] form. +use rustc_data_structures::fx::FxIndexMap; +use rustc_hir::def::DefKind; use rustc_hir::LangItem; +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 rustc_span::{sym, Span}; /// Collects together a list of type bounds. These lists of bounds occur in many places /// in Rust's syntax: @@ -24,6 +28,7 @@ use rustc_span::Span; #[derive(Default, PartialEq, Eq, Clone, Debug)] pub struct Bounds<'tcx> { clauses: Vec<(ty::Clause<'tcx>, Span)>, + effects_min_tys: FxIndexMap, Span>, } impl<'tcx> Bounds<'tcx> { @@ -40,12 +45,14 @@ impl<'tcx> Bounds<'tcx> { pub fn push_trait_bound( &mut self, tcx: TyCtxt<'tcx>, - trait_ref: ty::PolyTraitRef<'tcx>, + defining_def_id: DefId, + bound_trait_ref: ty::PolyTraitRef<'tcx>, span: Span, polarity: ty::PredicatePolarity, + constness: ty::BoundConstness, ) { let clause = ( - trait_ref + bound_trait_ref .map_bound(|trait_ref| { ty::ClauseKind::Trait(ty::TraitPredicate { trait_ref, polarity }) }) @@ -53,11 +60,88 @@ impl<'tcx> Bounds<'tcx> { span, ); // FIXME(-Znext-solver): We can likely remove this hack once the new trait solver lands. - if tcx.is_lang_item(trait_ref.def_id(), LangItem::Sized) { + if tcx.is_lang_item(bound_trait_ref.def_id(), LangItem::Sized) { self.clauses.insert(0, clause); } else { self.clauses.push(clause); } + // 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. + if let Some(compat_val) = match (tcx.def_kind(defining_def_id), constness) { + // TODO: do we need `T: const Trait` anymore? + (_, ty::BoundConstness::Const) => Some(tcx.consts.false_), + // body owners that can have trait bounds + (DefKind::Const | DefKind::Fn | DefKind::AssocFn, ty::BoundConstness::ConstIfConst) => { + Some(tcx.expected_host_effect_param_for_body(defining_def_id)) + } + + (_, ty::BoundConstness::NotConst) => { + tcx.has_attr(bound_trait_ref.def_id(), sym::const_trait).then_some(tcx.consts.true_) + } + + ( + DefKind::Trait | DefKind::Impl { of_trait: true }, + ty::BoundConstness::ConstIfConst, + ) => { + // this is either a where clause on an impl/trait header or on a trait. + // 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)); + + // Replace the binder with dummy types/lifetimes. This should work for any + // binder as long as they don't have any bounds e.g. `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, ty::BoundConstness::ConstIfConst) => { + // TODO write the actual impl + return; + } + // probably illegal in this position. + (_, 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 fn push_projection_bound( @@ -79,7 +163,15 @@ impl<'tcx> Bounds<'tcx> { self.clauses.insert(0, (trait_ref.upcast(tcx), span)); } - pub fn clauses(&self) -> impl Iterator, Span)> + '_ { + pub fn clauses( + &self, + // TODO remove tcx + _tcx: TyCtxt<'tcx>, + ) -> impl Iterator, Span)> + '_ { self.clauses.iter().cloned() } + + pub fn effects_min_tys(&self) -> impl Iterator> + '_ { + self.effects_min_tys.keys().copied() + } } diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index e13ea1a1935b4..e1813029778ee 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -879,7 +879,7 @@ pub(super) fn check_specialization_validity<'tcx>( let result = opt_result.unwrap_or(Ok(())); if let Err(parent_impl) = result { - if !tcx.is_impl_trait_in_trait(impl_item) { + if !tcx.is_impl_trait_in_trait(impl_item) && !tcx.is_effects_desugared_assoc_ty(impl_item) { report_forbidden_specialization(tcx, impl_item, parent_impl); } else { tcx.dcx().delayed_bug(format!("parent item: {parent_impl:?} not marked as default")); 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 7fa5c96bc9ab4..b5b68471b9d16 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs @@ -1985,10 +1985,10 @@ pub(super) fn check_type_bounds<'tcx>( let infcx = tcx.infer_ctxt().build(); let ocx = ObligationCtxt::new_with_diagnostics(&infcx); - // A synthetic impl Trait for RPITIT desugaring has no HIR, which we currently use to get the - // span for an impl's associated type. Instead, for these, use the def_span for the synthesized - // associated type. - let impl_ty_span = if impl_ty.is_impl_trait_in_trait() { + // A synthetic impl Trait for RPITIT desugaring or assoc type for effects desugaring has no HIR, + // which we currently use to get the span for an impl's associated type. Instead, for these, + // use the def_span for the synthesized associated type. + let impl_ty_span = if impl_ty.is_impl_trait_in_trait() || impl_ty.is_effects_desugaring { tcx.def_span(impl_ty_def_id) } else { match tcx.hir_node_by_def_id(impl_ty_def_id) { diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index a188c1b12aeb6..2230528a5ae11 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -913,7 +913,12 @@ 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: _ } => { + hir::GenericParamKind::Const { + ty: hir_ty, + default: _, + is_host_effect: _, + synthetic: _, + } => { let ty = tcx.type_of(param.def_id).instantiate_identity(); if tcx.features().adt_const_params { diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index e7892f1766067..f453dcfe90d1b 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -1638,44 +1638,19 @@ fn impl_trait_header(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option, def_id: LocalDefId) -> ty::Generics { kind, }) } - GenericParamKind::Const { ty: _, default, is_host_effect } => { + 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. @@ -388,6 +388,7 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics { kind: ty::GenericParamDefKind::Const { has_default: default.is_some(), is_host_effect, + synthetic, }, }) } @@ -541,7 +542,8 @@ struct AnonConstInParamTyDetector { impl<'v> Visitor<'v> for AnonConstInParamTyDetector { fn visit_generic_param(&mut self, p: &'v hir::GenericParam<'v>) { - if let GenericParamKind::Const { ty, default: _, is_host_effect: _ } = p.kind { + if let GenericParamKind::Const { ty, default: _, is_host_effect: _, synthetic: _ } = p.kind + { let prev = self.in_param_ty; self.in_param_ty = true; self.visit_ty(ty); diff --git a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs index d084d3aefeb17..57142414b9d81 100644 --- a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs +++ b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs @@ -46,7 +46,7 @@ fn associated_type_bounds<'tcx>( } }); - let all_bounds = tcx.arena.alloc_from_iter(bounds.clauses().chain(bounds_from_parent)); + let all_bounds = tcx.arena.alloc_from_iter(bounds.clauses(tcx).chain(bounds_from_parent)); debug!( "associated_type_bounds({}) = {:?}", tcx.def_path_str(assoc_item_def_id.to_def_id()), @@ -75,7 +75,7 @@ fn opaque_type_bounds<'tcx>( icx.lowerer().add_sized_bound(&mut bounds, item_ty, hir_bounds, None, span); debug!(?bounds); - tcx.arena.alloc_from_iter(bounds.clauses()) + 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 3421c8da4e9f3..087e02a030511 100644 --- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs @@ -57,6 +57,7 @@ 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; // to override hir::Ty match tcx.opt_rpitit_info(def_id.to_def_id()) { Some(ImplTraitInTraitData::Trait { fn_def_id, .. }) => { @@ -84,6 +85,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen return ty::GenericPredicates { parent: Some(tcx.parent(def_id.to_def_id())), predicates: tcx.arena.alloc_from_iter(predicates), + effects_min_tys: ty::List::empty(), }; } @@ -105,12 +107,43 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen return ty::GenericPredicates { parent: Some(impl_def_id), predicates: tcx.arena.alloc_from_iter(impl_predicates), + effects_min_tys: ty::List::empty(), }; } None => {} } + if tcx.is_effects_desugared_assoc_ty(def_id.to_def_id()) { + let mut predicates = Vec::new(); + + // Inherit predicates of parent (impl or trait) + let parent = tcx.local_parent(def_id); + + let identity_args = ty::GenericArgs::identity_for_item(tcx, def_id); + let preds = tcx.explicit_predicates_of(parent); + predicates.extend(preds.instantiate_own(tcx, identity_args)); + if let ty::AssocItemContainer::TraitContainer = tcx.associated_item(def_id).container { + // for traits, emit `type Effects: TyCompat<<(T1::Effects, ..) as Min>::Output>` + // TODO do the same for impls + let tup = Ty::new(tcx, ty::Tuple(preds.effects_min_tys)); + // TODO span + let span = tcx.def_span(def_id); + let assoc = tcx.require_lang_item(LangItem::EffectsMinOutput, Some(span)); + let proj = Ty::new_projection(tcx, assoc, [tup]); + // TODO this is bad + let self_proj = Ty::new_projection(tcx, def_id.to_def_id(), identity_args); + let trait_ = tcx.require_lang_item(LangItem::EffectsTyCompat, Some(span)); + let trait_ref = ty::TraitRef::new(tcx, trait_, [self_proj, proj]); + predicates.push((ty::Binder::dummy(trait_ref).upcast(tcx), span)); + } + return ty::GenericPredicates { + parent: Some(parent.to_def_id()), + predicates: tcx.arena.alloc_from_iter(predicates), + effects_min_tys: ty::List::empty(), + }; + } + let hir_id = tcx.local_def_id_to_hir_id(def_id); let node = tcx.hir_node(hir_id); @@ -124,6 +157,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen // We use an `IndexSet` to preserve order of insertion. // Preserving the order of insertion is important here so as not to break UI tests. let mut predicates: FxIndexSet<(ty::Clause<'_>, Span)> = FxIndexSet::default(); + let mut effects_min_tys = Vec::new(); let hir_generics = node.generics().unwrap_or(NO_GENERICS); if let Node::Item(item) = node { @@ -150,11 +184,13 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen // on a trait we must also consider the bounds that follow the trait's name, // like `trait Foo: A + B + C`. if let Some(self_bounds) = is_trait { - predicates.extend( - icx.lowerer() - .lower_mono_bounds(tcx.types.self_param, self_bounds, PredicateFilter::All) - .clauses(), + let bounds = icx.lowerer().lower_mono_bounds( + tcx.types.self_param, + self_bounds, + PredicateFilter::All, ); + predicates.extend(bounds.clauses(tcx)); + effects_min_tys.extend(bounds.effects_min_tys()); } // In default impls, we can assume that the self type implements @@ -187,7 +223,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen param.span, ); trace!(?bounds); - predicates.extend(bounds.clauses()); + predicates.extend(bounds.clauses(tcx)); trace!(?predicates); } hir::GenericParamKind::Const { .. } => { @@ -238,7 +274,8 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen bound_vars, OnlySelfBounds(false), ); - predicates.extend(bounds.clauses()); + predicates.extend(bounds.clauses(tcx)); + effects_min_tys.extend(bounds.effects_min_tys()); } hir::WherePredicate::RegionPredicate(region_pred) => { @@ -297,7 +334,8 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen // and the duplicated parameter, to ensure that they do not get out of sync. if let Node::Item(&Item { kind: ItemKind::OpaqueTy(..), .. }) = node { let opaque_ty_node = tcx.parent_hir_node(hir_id); - let Node::Ty(&Ty { kind: TyKind::OpaqueDef(_, lifetimes, _), .. }) = opaque_ty_node else { + let Node::Ty(&hir::Ty { kind: TyKind::OpaqueDef(_, lifetimes, _), .. }) = opaque_ty_node + else { bug!("unexpected {opaque_ty_node:?}") }; debug!(?lifetimes); @@ -309,6 +347,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen ty::GenericPredicates { parent: generics.parent, predicates: tcx.arena.alloc_from_iter(predicates), + effects_min_tys: tcx.mk_type_list(&effects_min_tys), } } @@ -459,6 +498,7 @@ pub(super) fn explicit_predicates_of<'tcx>( ty::GenericPredicates { parent: predicates_and_bounds.parent, predicates: tcx.arena.alloc_slice(&predicates), + effects_min_tys: predicates_and_bounds.effects_min_tys, } } } else { @@ -510,6 +550,7 @@ pub(super) fn explicit_predicates_of<'tcx>( return GenericPredicates { parent: parent_preds.parent, predicates: { tcx.arena.alloc_from_iter(filtered_predicates) }, + effects_min_tys: parent_preds.effects_min_tys, }; } gather_explicit_predicates_of(tcx, def_id) @@ -587,7 +628,7 @@ pub(super) fn implied_predicates_with_filter( // Combine the two lists to form the complete set of superbounds: let implied_bounds = - &*tcx.arena.alloc_from_iter(superbounds.clauses().chain(where_bounds_that_match)); + &*tcx.arena.alloc_from_iter(superbounds.clauses(tcx).chain(where_bounds_that_match)); debug!(?implied_bounds); // Now require that immediate supertraits are lowered, which will, in @@ -618,7 +659,11 @@ pub(super) fn implied_predicates_with_filter( _ => {} } - ty::GenericPredicates { parent: None, predicates: implied_bounds } + ty::GenericPredicates { + parent: None, + predicates: implied_bounds, + effects_min_tys: ty::List::empty(), + } } /// Returns the predicates defined on `item_def_id` of the form @@ -744,7 +789,7 @@ impl<'tcx> ItemCtxt<'tcx> { ); } - bounds.clauses().collect() + bounds.clauses(self.tcx).collect() } #[instrument(level = "trace", skip(self))] diff --git a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs index abc3bb838db3e..5c54c9d8e53d2 100644 --- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs +++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs @@ -951,7 +951,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> { self.visit_ty(ty); } } - GenericParamKind::Const { ty, default, is_host_effect: _ } => { + GenericParamKind::Const { ty, default, .. } => { self.visit_ty(ty); if let Some(default) = default { self.visit_body(self.tcx.hir().body(default.body)); diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs index 3f888c4e2722b..67046b5ac0e40 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs @@ -256,6 +256,7 @@ pub fn lower_generic_args<'tcx: 'a, 'a>( | GenericParamDefKind::Lifetime, _, ) => { + // TODO: this should be removed // SPECIAL CASE FOR DESUGARED EFFECT PARAMS // This comes from the following example: // @@ -445,7 +446,7 @@ pub(crate) fn check_generic_arg_count( .own_params .iter() .filter(|param| { - matches!(param.kind, ty::GenericParamDefKind::Const { is_host_effect: true, .. }) + matches!(param.kind, ty::GenericParamDefKind::Const { synthetic: true, .. }) }) .count(); let named_const_param_count = param_counts.consts - synth_const_param_count; 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 24ea328889c6b..2a68d3915bbbc 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -698,7 +698,14 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { ); debug!(?poly_trait_ref); - bounds.push_trait_bound(tcx, poly_trait_ref, span, polarity); + bounds.push_trait_bound( + tcx, + self.item_def_id().to_def_id(), + poly_trait_ref, + span, + polarity, + constness, + ); let mut dup_constraints = FxIndexMap::default(); for constraint in trait_segment.args().constraints { diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/object_safety.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/object_safety.rs index 34924f09d09ed..df69c1938dd75 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/object_safety.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/object_safety.rs @@ -59,7 +59,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { let mut trait_bounds = vec![]; let mut projection_bounds = vec![]; - for (pred, span) in bounds.clauses() { + for (pred, span) in bounds.clauses(tcx) { let bound_pred = pred.kind(); match bound_pred.skip_binder() { ty::ClauseKind::Trait(trait_pred) => { @@ -133,7 +133,9 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { tcx.associated_items(pred.def_id()) .in_definition_order() .filter(|item| item.kind == ty::AssocKind::Type) - .filter(|item| !item.is_impl_trait_in_trait()) + .filter(|item| { + !item.is_impl_trait_in_trait() && !item.is_effects_desugaring + }) .map(|item| item.def_id), ); } diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs index 25b0cbdc026af..5105d60ae188c 100644 --- a/compiler/rustc_hir_pretty/src/lib.rs +++ b/compiler/rustc_hir_pretty/src/lib.rs @@ -585,6 +585,7 @@ impl<'a> State<'a> { self.print_struct(struct_def, generics, item.ident.name, item.span, true); } hir::ItemKind::Impl(&hir::Impl { + constness, safety, polarity, defaultness, @@ -599,6 +600,10 @@ impl<'a> State<'a> { self.print_safety(safety); self.word_nbsp("impl"); + if let hir::Constness::Const = constness { + self.word_nbsp("const"); + } + if !generics.params.is_empty() { self.print_generic_params(generics.params); self.space(); @@ -2144,7 +2149,7 @@ impl<'a> State<'a> { self.print_type(default); } } - GenericParamKind::Const { ty, ref default, is_host_effect: _ } => { + GenericParamKind::Const { ty, ref default, is_host_effect: _, synthetic: _ } => { self.word_space(":"); self.print_type(ty); if let Some(default) = default { diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index 061afd0306230..f6e21262b6ac7 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -1304,7 +1304,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.fcx.ty_infer(Some(param), inf.span).into() } ( - &GenericParamDefKind::Const { has_default, is_host_effect }, + &GenericParamDefKind::Const { has_default, is_host_effect, .. }, GenericArg::Infer(inf), ) => { if has_default && is_host_effect { @@ -1346,7 +1346,7 @@ 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, is_host_effect, .. } => { 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` diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs index c0d604779677b..ed3cbb0663efa 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs @@ -274,6 +274,7 @@ impl<'tcx> HirTyLowerer<'tcx> for FnCtxt<'_, 'tcx> { } }), ), + effects_min_tys: ty::List::empty(), } } diff --git a/compiler/rustc_hir_typeck/src/method/mod.rs b/compiler/rustc_hir_typeck/src/method/mod.rs index e1223307b53e3..dad909fc4e102 100644 --- a/compiler/rustc_hir_typeck/src/method/mod.rs +++ b/compiler/rustc_hir_typeck/src/method/mod.rs @@ -21,7 +21,7 @@ use rustc_middle::ty::{self, GenericParamDefKind, Ty, TypeVisitableExt}; use rustc_middle::ty::{GenericArgs, GenericArgsRef}; use rustc_middle::{bug, span_bug}; use rustc_span::symbol::Ident; -use rustc_span::Span; +use rustc_span::{sym, Span}; use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt; use rustc_trait_selection::traits::{self, NormalizeExt}; @@ -356,6 +356,17 @@ 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.has_attr(trait_def_id, sym::const_trait) { + 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) } @@ -393,6 +404,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { debug!("lookup_in_trait_adjusted: method_item={:?}", method_item); let mut obligations = vec![]; + // TODO there is something wrong here because now methods for binops may get `const host: bool` + // Instantiate late-bound regions and instantiate the trait // parameters into the method type to get the actual method type. // diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs index 9747a91ccbfad..63b30d79aba14 100644 --- a/compiler/rustc_hir_typeck/src/method/probe.rs +++ b/compiler/rustc_hir_typeck/src/method/probe.rs @@ -1279,6 +1279,7 @@ impl<'tcx> Pick<'tcx> { trait_item_def_id: _, fn_has_self_parameter: _, opt_rpitit_info: _, + is_effects_desugaring: _, }, kind: _, import_ids: _, diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs index ea7037740f17e..83b41e0540edf 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder.rs @@ -1348,7 +1348,9 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { } fn get_associated_item(self, id: DefIndex, sess: &'a Session) -> ty::AssocItem { - let name = if self.root.tables.opt_rpitit_info.get(self, id).is_some() { + let name = if self.root.tables.opt_rpitit_info.get(self, id).is_some() + || self.root.tables.is_effects_desugaring.get(self, id) + { kw::Empty } else { self.item_name(id) @@ -1371,6 +1373,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { container, fn_has_self_parameter: has_self, opt_rpitit_info, + is_effects_desugaring: self.root.tables.is_effects_desugaring.get(self, id), } } diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs index c9450142cd3be..f696be08cb228 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs @@ -279,6 +279,9 @@ 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 4bd2ec09a6e6f..f985c55eeec50 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -1454,6 +1454,9 @@ 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 def_kind == DefKind::Closure && let Some(coroutine_kind) = self.tcx.coroutine_kind(def_id) @@ -1634,6 +1637,9 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { ); } } + if item.is_effects_desugaring { + self.tables.is_effects_desugaring.set(def_id.index, true); + } } fn encode_mir(&mut self) { diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs index 87900c23d8daf..cb5f3d20d99a8 100644 --- a/compiler/rustc_metadata/src/rmeta/mod.rs +++ b/compiler/rustc_metadata/src/rmeta/mod.rs @@ -391,7 +391,9 @@ define_tables! { inferred_outlives_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, // Reexported names are not associated with individual `DefId`s, // e.g. a glob import can introduce a lot of names, all with the same `DefId`. diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 230a44bcf2452..d94f12af448e2 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -368,6 +368,7 @@ rustc_queries! { desc { |tcx| "finding item bounds for `{}`", tcx.def_path_str(key) } cache_on_disk_if { key.is_local() } separate_provide_extern + feedable } /// The set of item bounds (see [`TyCtxt::explicit_item_bounds`]) that @@ -378,6 +379,7 @@ rustc_queries! { desc { |tcx| "finding item bounds for `{}`", tcx.def_path_str(key) } cache_on_disk_if { key.is_local() } separate_provide_extern + feedable } /// Elaborated version of the predicates from `explicit_item_bounds`. @@ -847,6 +849,12 @@ 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/assoc.rs b/compiler/rustc_middle/src/ty/assoc.rs index 1cdde3f057c67..820f5e950a9d9 100644 --- a/compiler/rustc_middle/src/ty/assoc.rs +++ b/compiler/rustc_middle/src/ty/assoc.rs @@ -34,6 +34,8 @@ pub struct AssocItem { /// return-position `impl Trait` in trait desugaring. The `ImplTraitInTraitData` /// provides additional information about its source. pub opt_rpitit_info: Option, + + pub is_effects_desugaring: bool, } impl AssocItem { diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 4bac9396e59a9..656aba67112cc 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -3095,9 +3095,9 @@ impl<'tcx> TyCtxt<'tcx> { matches!( node, hir::Node::Item(hir::Item { - kind: hir::ItemKind::Impl(hir::Impl { generics, .. }), + kind: hir::ItemKind::Impl(hir::Impl { constness, .. }), .. - }) if generics.params.iter().any(|p| matches!(p.kind, hir::GenericParamKind::Const { is_host_effect: true, .. })) + }) if matches!(constness, hir::Constness::Const) ) } diff --git a/compiler/rustc_middle/src/ty/generics.rs b/compiler/rustc_middle/src/ty/generics.rs index 6467689a8aa15..844023df1e315 100644 --- a/compiler/rustc_middle/src/ty/generics.rs +++ b/compiler/rustc_middle/src/ty/generics.rs @@ -14,7 +14,7 @@ use super::{Clause, InstantiatedPredicates, ParamConst, ParamTy, Ty, TyCtxt}; pub enum GenericParamDefKind { Lifetime, Type { has_default: bool, synthetic: bool }, - Const { has_default: bool, is_host_effect: bool }, + Const { has_default: bool, is_host_effect: bool, synthetic: bool }, } impl GenericParamDefKind { @@ -371,6 +371,7 @@ impl<'tcx> Generics { pub struct GenericPredicates<'tcx> { pub parent: Option, pub predicates: &'tcx [(Clause<'tcx>, Span)], + pub effects_min_tys: &'tcx ty::List>, } impl<'tcx> GenericPredicates<'tcx> { diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 9c2bfc12a18a1..7d57d88f40f4a 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -1608,7 +1608,7 @@ impl<'tcx> TyCtxt<'tcx> { } } - /// If the def-id is an associated type that was desugared from a + /// If the `def_id` is an associated type that was desugared from a /// return-position `impl Trait` from a trait, then provide the source info /// about where that RPITIT came from. pub fn opt_rpitit_info(self, def_id: DefId) -> Option { @@ -1619,6 +1619,16 @@ impl<'tcx> TyCtxt<'tcx> { } } + /// Whether the `def_id` is an associated type that was desugared from a + /// `#[const_trait]` or `impl_const`. + pub fn is_effects_desugared_assoc_ty(self, def_id: DefId) -> bool { + if let DefKind::AssocTy = self.def_kind(def_id) { + self.associated_item(def_id).is_effects_desugaring + } else { + false + } + } + pub fn find_field_index(self, ident: Ident, variant: &VariantDef) -> Option { variant.fields.iter_enumerated().find_map(|(i, field)| { self.hygienic_eq(ident, field.ident(self), variant.def_id).then_some(i) diff --git a/compiler/rustc_smir/src/rustc_smir/context.rs b/compiler/rustc_smir/src/rustc_smir/context.rs index e23f4289e981a..4eefd0eb17c40 100644 --- a/compiler/rustc_smir/src/rustc_smir/context.rs +++ b/compiler/rustc_smir/src/rustc_smir/context.rs @@ -160,7 +160,8 @@ impl<'tcx> Context for TablesWrapper<'tcx> { fn predicates_of(&self, def_id: stable_mir::DefId) -> stable_mir::ty::GenericPredicates { let mut tables = self.0.borrow_mut(); let def_id = tables[def_id]; - let GenericPredicates { parent, predicates } = tables.tcx.predicates_of(def_id); + let GenericPredicates { parent, predicates, effects_min_tys: _ } = + tables.tcx.predicates_of(def_id); stable_mir::ty::GenericPredicates { parent: parent.map(|did| tables.trait_def(did)), predicates: predicates @@ -181,7 +182,8 @@ impl<'tcx> Context for TablesWrapper<'tcx> { ) -> stable_mir::ty::GenericPredicates { let mut tables = self.0.borrow_mut(); let def_id = tables[def_id]; - let GenericPredicates { parent, predicates } = tables.tcx.explicit_predicates_of(def_id); + let GenericPredicates { parent, predicates, effects_min_tys: _ } = + tables.tcx.explicit_predicates_of(def_id); stable_mir::ty::GenericPredicates { parent: parent.map(|did| tables.trait_def(did)), predicates: predicates diff --git a/compiler/rustc_smir/src/rustc_smir/convert/ty.rs b/compiler/rustc_smir/src/rustc_smir/convert/ty.rs index 74c3fcc9b9ea9..9382460d6d403 100644 --- a/compiler/rustc_smir/src/rustc_smir/convert/ty.rs +++ b/compiler/rustc_smir/src/rustc_smir/convert/ty.rs @@ -600,7 +600,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: _ } => { + ty::GenericParamDefKind::Const { has_default, is_host_effect: _, synthetic: _ } => { GenericParamDefKind::Const { has_default: *has_default } } } diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 3b6147c4c0f64..4a26e8ae09734 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -194,6 +194,14 @@ symbols! { Display, DoubleEndedIterator, Duration, + EffectsCompat, + EffectsMaybe, + EffectsMin, + EffectsMinOutput, + EffectsNoRuntime, + EffectsRuntime, + EffectsTyCompat, + Effects__, Encodable, Encoder, Enumerate, @@ -1658,6 +1666,7 @@ 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/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index f4a026c0367f4..599a95f2300b9 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -4995,6 +4995,12 @@ fn point_at_assoc_type_restriction( let ty::ClauseKind::Projection(proj) = clause else { return; }; + // avoid ICEing since effects desugared associated types don't have names. + // this path should only be hit for `~const` on invalid places, so they + // will have an informative error already. + if tcx.is_effects_desugared_assoc_ty(proj.projection_term.def_id) { + return; + } let name = tcx.item_name(proj.projection_term.def_id); let mut predicates = generics.predicates.iter().peekable(); let mut prev: Option<&hir::WhereBoundPredicate<'_>> = None; diff --git a/compiler/rustc_ty_utils/src/assoc.rs b/compiler/rustc_ty_utils/src/assoc.rs index 4395eb57cd6d2..df6c54ab289ae 100644 --- a/compiler/rustc_ty_utils/src/assoc.rs +++ b/compiler/rustc_ty_utils/src/assoc.rs @@ -4,8 +4,9 @@ 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, TyCtxt}; +use rustc_middle::ty::{self, ImplTraitInTraitData, Ty, TyCtxt}; use rustc_middle::{bug, span_bug}; +use rustc_span::sym; use rustc_span::symbol::kw; pub(crate) fn provide(providers: &mut Providers) { @@ -14,6 +15,7 @@ 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 @@ -44,7 +46,8 @@ fn associated_item_def_ids(tcx: TyCtxt<'_>, def_id: LocalDefId) -> &[DefId] { ) }) .copied(), - ), + ) + .chain(tcx.associated_type_for_effects(def_id)), ) } hir::ItemKind::Impl(impl_) => { @@ -70,7 +73,8 @@ 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"), @@ -143,6 +147,7 @@ fn associated_item_from_trait_item_ref(trait_item_ref: &hir::TraitItemRef) -> ty container: ty::TraitContainer, fn_has_self_parameter: has_self, opt_rpitit_info: None, + is_effects_desugaring: false, } } @@ -162,6 +167,161 @@ fn associated_item_from_impl_item_ref(impl_item_ref: &hir::ImplItemRef) -> ty::A container: ty::ImplContainer, fn_has_self_parameter: has_self, opt_rpitit_info: None, + is_effects_desugaring: false, + } +} + +/// 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 { + match tcx.def_kind(def_id) { + DefKind::Trait => { + let trait_def_id = def_id; + let Some(attr) = tcx.get_attr(def_id, sym::const_trait) else { + return None; + }; + + 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(); + + trait_assoc_ty.feed_hir(); + + // 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, + }); + + // visibility is public. + trait_assoc_ty.visibility(ty::Visibility::Public); + + // No default type + trait_assoc_ty.defaultness(hir::Defaultness::Default { has_value: false }); + + trait_assoc_ty.is_type_alias_impl_trait(false); + + // Copy generics_of of the trait, making the trait as parent. + trait_assoc_ty.generics_of({ + let parent_generics = tcx.generics_of(trait_def_id); + let parent_count = parent_generics.parent_count + parent_generics.own_params.len(); + + ty::Generics { + parent: Some(trait_def_id.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, + } + }); + + trait_assoc_ty.explicit_item_bounds(ty::EarlyBinder::bind(&[])); + trait_assoc_ty.explicit_item_super_predicates(ty::EarlyBinder::bind(&[])); + + // There are no inferred outlives for the synthesized associated type. + trait_assoc_ty.inferred_outlives_of(&[]); + + Some(def_id) + } + DefKind::Impl { .. } => { + let impl_def_id = def_id; + let Some(trait_id) = tcx.trait_id_of_impl(def_id.to_def_id()) else { return None }; + + // 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 Some(trait_assoc_id) = tcx.associated_type_for_effects(trait_id) else { + return None; + }; + + // TODO span is bad + 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.feed_hir(); + + 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, + }); + + // visibility is public. + impl_assoc_ty.visibility(ty::Visibility::Public); + + // 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)) + }; + // TODO this is wrong + impl_assoc_ty.type_of(ty::EarlyBinder::bind(Ty::new_adt( + tcx, + tcx.adt_def(type_def_id), + ty::GenericArgs::empty(), + ))); + + // Copy generics_of of the impl, making the impl as parent. + impl_assoc_ty.generics_of({ + let parent_generics = tcx.generics_of(impl_def_id); + let parent_count = parent_generics.parent_count + parent_generics.own_params.len(); + + ty::Generics { + parent: Some(impl_def_id.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, + } + }); + + impl_assoc_ty.explicit_item_bounds(ty::EarlyBinder::bind(&[])); + impl_assoc_ty.explicit_item_super_predicates(ty::EarlyBinder::bind(&[])); + + // There are no inferred outlives for the synthesized associated type. + impl_assoc_ty.inferred_outlives_of(&[]); + + Some(def_id) + } + def_kind => bug!( + "associated_type_for_effects: {:?} should be Trait or Impl but is {:?}", + def_id, + def_kind + ), } } @@ -275,6 +435,7 @@ fn associated_type_for_impl_trait_in_trait( fn_def_id: fn_def_id.to_def_id(), opaque_def_id: opaque_ty_def_id.to_def_id(), }), + is_effects_desugaring: false, }); // Copy visility of the containing function. @@ -326,6 +487,7 @@ fn associated_type_for_impl_trait_in_impl( container: ty::ImplContainer, fn_has_self_parameter: false, opt_rpitit_info: Some(ImplTraitInTraitData::Impl { fn_def_id: impl_fn_def_id.to_def_id() }), + is_effects_desugaring: false, }); // Copy visility of the containing function. diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index d1692729a31b4..cfadfb0233ea7 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -231,6 +231,7 @@ #![feature(let_chains)] #![feature(link_llvm_intrinsics)] #![feature(macro_metavar_expr)] +#![feature(marker_trait_attr)] #![feature(min_exhaustive_patterns)] #![feature(min_specialization)] #![feature(multiple_supertrait_upcastable)] diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs index 0fedb8835d1ae..b3f3cc021261f 100644 --- a/library/core/src/marker.rs +++ b/library/core/src/marker.rs @@ -1027,3 +1027,41 @@ pub trait FnPtr: Copy + Clone { pub macro SmartPointer($item:item) { /* compiler built-in */ } + +#[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. +#[cfg(not(bootstrap))] +// TODO docs +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 Maybe {} + + #[lang = "EffectsMin"] + pub trait Min { + #[lang = "EffectsMinOutput"] + type Output; + } +} diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 22565ea402803..b5660cd849246 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -549,7 +549,7 @@ fn clean_generic_param_def<'tcx>( }, ) } - ty::GenericParamDefKind::Const { has_default, is_host_effect } => ( + ty::GenericParamDefKind::Const { has_default, synthetic, is_host_effect: _ } => ( def.name, GenericParamDefKind::Const { ty: Box::new(clean_middle_ty( @@ -572,7 +572,7 @@ fn clean_generic_param_def<'tcx>( } else { None }, - is_host_effect, + synthetic, }, ), }; @@ -628,13 +628,13 @@ fn clean_generic_param<'tcx>( }, ) } - hir::GenericParamKind::Const { ty, default, is_host_effect } => ( + hir::GenericParamKind::Const { ty, default, synthetic, is_host_effect: _ } => ( param.name.ident().name, GenericParamDefKind::Const { ty: Box::new(clean_ty(ty, cx)), default: default .map(|ct| Box::new(ty::Const::from_anon_const(cx.tcx, ct.def_id).to_string())), - is_host_effect, + synthetic, }, ), }; @@ -1411,7 +1411,11 @@ pub(crate) fn clean_middle_assoc_item<'tcx>( let mut generics = clean_ty_generics( cx, tcx.generics_of(assoc_item.def_id), - ty::GenericPredicates { parent: None, predicates }, + ty::GenericPredicates { + parent: None, + predicates, + effects_min_tys: ty::List::empty(), + }, ); simplify::move_bounds_to_generic_parameters(&mut generics); diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index c4020f2a450bc..9050a1c12078b 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -1321,7 +1321,7 @@ pub(crate) enum GenericParamDefKind { Lifetime { outlives: ThinVec }, Type { bounds: ThinVec, default: Option>, synthetic: bool }, // Option> makes this type smaller than `Option` would. - Const { ty: Box, default: Option>, is_host_effect: bool }, + Const { ty: Box, default: Option>, synthetic: bool }, } impl GenericParamDefKind { @@ -1345,7 +1345,7 @@ impl GenericParamDef { pub(crate) fn is_synthetic_param(&self) -> bool { match self.kind { GenericParamDefKind::Lifetime { .. } => false, - GenericParamDefKind::Const { is_host_effect, .. } => is_host_effect, + GenericParamDefKind::Const { synthetic: is_host_effect, .. } => is_host_effect, GenericParamDefKind::Type { synthetic, .. } => synthetic, } } diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs index d099a97f1cba2..b965ab019cc4f 100644 --- a/src/librustdoc/json/conversions.rs +++ b/src/librustdoc/json/conversions.rs @@ -466,7 +466,7 @@ impl FromWithTcx for GenericParamDefKind { default: default.map(|x| (*x).into_tcx(tcx)), synthetic, }, - Const { ty, default, is_host_effect: _ } => GenericParamDefKind::Const { + Const { ty, default, synthetic: _ } => GenericParamDefKind::Const { type_: (*ty).into_tcx(tcx), default: default.map(|x| *x), }, @@ -501,14 +501,12 @@ impl FromWithTcx for WherePredicate { synthetic, } } - clean::GenericParamDefKind::Const { - ty, - default, - is_host_effect: _, - } => GenericParamDefKind::Const { - type_: (*ty).into_tcx(tcx), - default: default.map(|d| *d), - }, + clean::GenericParamDefKind::Const { ty, default, synthetic: _ } => { + GenericParamDefKind::Const { + type_: (*ty).into_tcx(tcx), + default: default.map(|d| *d), + } + } }; GenericParamDef { name, kind } }) diff --git a/tests/ui/const-generics/const_trait_fn-issue-88433.rs b/tests/ui/const-generics/const_trait_fn-issue-88433.rs index cd008aa2c9f2d..f3271f833cc64 100644 --- a/tests/ui/const-generics/const_trait_fn-issue-88433.rs +++ b/tests/ui/const-generics/const_trait_fn-issue-88433.rs @@ -1,4 +1,5 @@ //@ build-pass +//@ compile-flags: -Znext-solver #![feature(const_trait_impl, effects)] //~ WARN the feature `effects` is incomplete diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/group-traits.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/group-traits.rs new file mode 100644 index 0000000000000..2c5b6cc40e638 --- /dev/null +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/group-traits.rs @@ -0,0 +1,14 @@ +//@ check-pass +use std::ops::Add; + +pub trait GroupOpsOwned: for<'r> Add<&'r Rhs, Output = Output> {} + +pub trait Curve: Sized + GroupOpsOwned { + type AffineRepr; +} + +pub trait CofactorCurve: Curve::Affine> { + type Affine; +} + +fn main() {} diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-92230-wf-super-trait-env.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-92230-wf-super-trait-env.rs index 825ddb6a5cdb9..a587de9f17963 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-92230-wf-super-trait-env.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-92230-wf-super-trait-env.rs @@ -1,8 +1,9 @@ // Regression test for #92230. // //@ check-pass +//@ compile-flags: -Znext-solver -#![feature(const_trait_impl)] +#![feature(const_trait_impl, effects)] #[const_trait] pub trait Super {} diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-invalid-places.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-invalid-places.stderr index 8151b9aaa23de..3b320f1c5424a 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-invalid-places.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-invalid-places.stderr @@ -282,12 +282,21 @@ help: wrap the field type in `ManuallyDrop<...>` LL | union Union { field: std::mem::ManuallyDrop } | +++++++++++++++++++++++ + -error[E0275]: overflow evaluating the requirement `(): Trait` +error[E0275]: overflow evaluating the requirement `Trait::{opaque#0} == _` --> $DIR/tilde-const-invalid-places.rs:34:34 | LL | type Type = (); | ^^ | +note: required for `()` to implement `Trait` + --> $DIR/tilde-const-invalid-places.rs:56:23 + | +LL | impl Trait for T {} + | ------------ ^^^^^ ^ + | | + | unsatisfied trait bound introduced here + = note: 1 redundant requirement hidden + = note: required for `()` to implement `Trait` note: required by a bound in `NonConstTrait::Type` --> $DIR/tilde-const-invalid-places.rs:25:33 | diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/unsatisfied-const-trait-bound.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/unsatisfied-const-trait-bound.rs index 8f441410c1784..3a8c6d5b1a4fa 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/unsatisfied-const-trait-bound.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/unsatisfied-const-trait-bound.rs @@ -1,4 +1,5 @@ // Ensure that we print unsatisfied always-const trait bounds as `const Trait` in diagnostics. +//@ compile-flags: -Znext-solver #![feature(const_trait_impl, effects, generic_const_exprs)] #![allow(incomplete_features)] From c7d27a15d0a28d66d9a6b279e6005b6fcd861ae2 Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Mon, 24 Jun 2024 16:25:17 +0000 Subject: [PATCH 02/10] Implement `Min` trait in new solver --- .../src/collect/predicates_of.rs | 2 +- compiler/rustc_middle/src/ty/context.rs | 5 ++ .../src/solve/assembly/mod.rs | 7 +++ .../src/solve/normalizes_to/mod.rs | 59 +++++++++++++++++++ .../src/solve/trait_goals.rs | 41 +++++++++++++ compiler/rustc_type_ir/src/effects.rs | 56 ++++++++++++++++++ compiler/rustc_type_ir/src/lang_items.rs | 5 ++ compiler/rustc_type_ir/src/lib.rs | 2 + library/core/src/marker.rs | 9 +-- .../trait-where-clause-run.rs | 1 + 10 files changed, 182 insertions(+), 5 deletions(-) create mode 100644 compiler/rustc_type_ir/src/effects.rs diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs index 087e02a030511..e3d1e1c423e4c 100644 --- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs @@ -122,7 +122,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen let identity_args = ty::GenericArgs::identity_for_item(tcx, def_id); let preds = tcx.explicit_predicates_of(parent); - predicates.extend(preds.instantiate_own(tcx, identity_args)); + if let ty::AssocItemContainer::TraitContainer = tcx.associated_item(def_id).container { // for traits, emit `type Effects: TyCompat<<(T1::Effects, ..) as Min>::Output>` // TODO do the same for impls diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 656aba67112cc..c0ebad9616df3 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -598,6 +598,11 @@ fn trait_lang_item_to_lang_item(lang_item: TraitSolverLangItem) -> LangItem { TraitSolverLangItem::Destruct => LangItem::Destruct, TraitSolverLangItem::DiscriminantKind => LangItem::DiscriminantKind, TraitSolverLangItem::DynMetadata => LangItem::DynMetadata, + TraitSolverLangItem::EffectsMaybe => LangItem::EffectsMaybe, + TraitSolverLangItem::EffectsMin => LangItem::EffectsMin, + TraitSolverLangItem::EffectsMinOutput => LangItem::EffectsMinOutput, + TraitSolverLangItem::EffectsNoRuntime => LangItem::EffectsNoRuntime, + TraitSolverLangItem::EffectsRuntime => LangItem::EffectsRuntime, TraitSolverLangItem::FnPtrTrait => LangItem::FnPtrTrait, TraitSolverLangItem::FusedIterator => LangItem::FusedIterator, TraitSolverLangItem::Future => LangItem::Future, 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 21439530c08f6..8d57c3d9af004 100644 --- a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs @@ -269,6 +269,11 @@ where ecx: &mut EvalCtxt<'_, D>, goal: Goal, ) -> Vec>; + + fn consider_builtin_effects_min_candidate( + ecx: &mut EvalCtxt<'_, D>, + goal: Goal, + ) -> Result, NoSolution>; } impl EvalCtxt<'_, D> @@ -420,6 +425,8 @@ where G::consider_builtin_destruct_candidate(self, goal) } else if cx.is_lang_item(trait_def_id, TraitSolverLangItem::TransmuteTrait) { G::consider_builtin_transmute_candidate(self, goal) + } else if tcx.is_lang_item(trait_def_id, TraitSolverLangItem::EffectsMin) { + G::consider_builtin_effects_min_candidate(self, goal) } else { Err(NoSolution) }; 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 4e8cb4384f462..f75c30eda9949 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 @@ -864,6 +864,65 @@ where ) -> Result, NoSolution> { panic!("`BikeshedIntrinsicFrom` does not have an associated type: {:?}", goal) } + + fn consider_builtin_effects_min_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 { + 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 { + let Some(kind) = ty::EffectKind::try_from_ty(cx, ty) else { + return Err(NoSolution); + }; + + let Some(result) = ty::EffectKind::min(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 2bc9d35c2b020..8c6e5eb5a4d9d 100644 --- a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs +++ b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs @@ -702,6 +702,47 @@ where } }) } + + fn consider_builtin_effects_min_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 + .into_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 { + let Some(kind) = ty::EffectKind::try_from_ty(ecx.cx(), ty) else { + return Err(NoSolution); + }; + + let Some(result) = ty::EffectKind::min(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_type_ir/src/effects.rs b/compiler/rustc_type_ir/src/effects.rs new file mode 100644 index 0000000000000..259072de6e77d --- /dev/null +++ b/compiler/rustc_type_ir/src/effects.rs @@ -0,0 +1,56 @@ +use crate::lang_items::TraitSolverLangItem::{EffectsMaybe, EffectsRuntime, EffectsNoRuntime}; +use crate::Interner; +use crate::inherent::{AdtDef, IntoKind, Ty}; + +#[derive(Clone, Copy, PartialEq, Eq)] +pub enum EffectKind { + Maybe, + Runtime, + NoRuntime, +} + +impl EffectKind { + pub fn try_from_def_id(tcx: I, def_id: I::DefId) -> Option { + if tcx.is_lang_item(def_id, EffectsMaybe) { + Some(EffectKind::Maybe) + } else if tcx.is_lang_item(def_id, EffectsRuntime) { + Some(EffectKind::Runtime) + } else if tcx.is_lang_item(def_id, EffectsNoRuntime) { + Some(EffectKind::NoRuntime) + } else { + None + } + } + + pub fn to_def_id(self, tcx: I) -> I::DefId { + let lang_item = match self { + EffectKind::Maybe => EffectsMaybe, + EffectKind::NoRuntime => EffectsNoRuntime, + EffectKind::Runtime => EffectsRuntime, + }; + + tcx.require_lang_item(lang_item) + } + + pub fn try_from_ty(tcx: I, ty: I::Ty) -> Option { + if let crate::Adt(def, _) = ty.kind() { + Self::try_from_def_id(tcx, def.def_id()) + } else { + None + } + } + + pub fn to_ty(self, tcx: I) -> I::Ty { + I::Ty::new_adt(tcx, tcx.adt_def(self.to_def_id(tcx)), Default::default()) + } + + pub fn min(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, + } + } +} \ No newline at end of file diff --git a/compiler/rustc_type_ir/src/lang_items.rs b/compiler/rustc_type_ir/src/lang_items.rs index cf5ec1ab3febc..55b9709b66876 100644 --- a/compiler/rustc_type_ir/src/lang_items.rs +++ b/compiler/rustc_type_ir/src/lang_items.rs @@ -17,6 +17,11 @@ pub enum TraitSolverLangItem { Destruct, DiscriminantKind, DynMetadata, + EffectsMaybe, + EffectsMin, + EffectsMinOutput, + EffectsNoRuntime, + EffectsRuntime, FnPtrTrait, FusedIterator, Future, diff --git a/compiler/rustc_type_ir/src/lib.rs b/compiler/rustc_type_ir/src/lib.rs index 9b8ca5efdda82..d7442e7c89c4a 100644 --- a/compiler/rustc_type_ir/src/lib.rs +++ b/compiler/rustc_type_ir/src/lib.rs @@ -35,6 +35,7 @@ mod macros; mod binder; mod canonical; mod const_kind; +mod effects; mod flags; mod generic_arg; mod interner; @@ -51,6 +52,7 @@ 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 interner::*; diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs index b3f3cc021261f..b71bedaa1948f 100644 --- a/library/core/src/marker.rs +++ b/library/core/src/marker.rs @@ -1054,14 +1054,15 @@ pub mod effects { #[lang = "EffectsTyCompat"] #[marker] - pub trait TyCompat {} + pub trait TyCompat {} - impl TyCompat for T {} - impl TyCompat for Maybe {} + impl TyCompat for T {} + impl TyCompat for Maybe {} + impl TyCompat for T {} #[lang = "EffectsMin"] pub trait Min { #[lang = "EffectsMinOutput"] - type Output; + type Output: ?Sized; } } diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-run.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-run.rs index afc5b1c836993..ddb26505202f4 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-run.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-run.rs @@ -1,4 +1,5 @@ //@ run-pass +//@ compile-flags: -Znext-solver #![feature(const_trait_impl, effects)] //~ WARN the feature `effects` is incomplete From 3637b153f7cb8de14588ea82a15a28499bcb3b3f Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Tue, 25 Jun 2024 07:51:44 +0000 Subject: [PATCH 03/10] move desugaring to item bounds --- .../src/collect/item_bounds.rs | 26 ++++++++++++++++ .../src/collect/predicates_of.rs | 31 ------------------- 2 files changed, 26 insertions(+), 31 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs index 57142414b9d81..707a3f2d3c715 100644 --- a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs +++ b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs @@ -8,6 +8,7 @@ use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFold use rustc_middle::{bug, span_bug}; use rustc_span::def_id::{DefId, LocalDefId}; use rustc_span::Span; +use rustc_type_ir::Upcast; /// For associated types we include both bounds written on the type /// (`type X: Trait`) and predicates from the trait: `where Self::X: Trait`. @@ -124,6 +125,31 @@ pub(super) fn explicit_item_bounds_with_filter( None => {} } + if tcx.is_effects_desugared_assoc_ty(def_id.to_def_id()) { + let mut predicates = Vec::new(); + + let parent = tcx.local_parent(def_id); + + let identity_args = ty::GenericArgs::identity_for_item(tcx, def_id); + let preds = tcx.explicit_predicates_of(parent); + + if let ty::AssocItemContainer::TraitContainer = tcx.associated_item(def_id).container { + // for traits, emit `type Effects: TyCompat<<(T1::Effects, ..) as Min>::Output>` + // TODO do the same for impls + let tup = Ty::new(tcx, ty::Tuple(preds.effects_min_tys)); + // TODO span + let span = tcx.def_span(def_id); + let assoc = tcx.require_lang_item(hir::LangItem::EffectsMinOutput, Some(span)); + let proj = Ty::new_projection(tcx, assoc, [tup]); + // TODO this is bad + let self_proj = Ty::new_projection(tcx, def_id.to_def_id(), identity_args); + let trait_ = tcx.require_lang_item(hir::LangItem::EffectsTyCompat, Some(span)); + let trait_ref = ty::TraitRef::new(tcx, trait_, [self_proj, proj]); + predicates.push((ty::Binder::dummy(trait_ref).upcast(tcx), span)); + } + return ty::EarlyBinder::bind(tcx.arena.alloc_from_iter(predicates)); + } + let bounds = match tcx.hir_node_by_def_id(def_id) { hir::Node::TraitItem(hir::TraitItem { kind: hir::TraitItemKind::Type(bounds, _), diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs index e3d1e1c423e4c..9a5feaf3d3c65 100644 --- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs @@ -57,7 +57,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; // to override hir::Ty match tcx.opt_rpitit_info(def_id.to_def_id()) { Some(ImplTraitInTraitData::Trait { fn_def_id, .. }) => { @@ -114,36 +113,6 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen None => {} } - if tcx.is_effects_desugared_assoc_ty(def_id.to_def_id()) { - let mut predicates = Vec::new(); - - // Inherit predicates of parent (impl or trait) - let parent = tcx.local_parent(def_id); - - let identity_args = ty::GenericArgs::identity_for_item(tcx, def_id); - let preds = tcx.explicit_predicates_of(parent); - - if let ty::AssocItemContainer::TraitContainer = tcx.associated_item(def_id).container { - // for traits, emit `type Effects: TyCompat<<(T1::Effects, ..) as Min>::Output>` - // TODO do the same for impls - let tup = Ty::new(tcx, ty::Tuple(preds.effects_min_tys)); - // TODO span - let span = tcx.def_span(def_id); - let assoc = tcx.require_lang_item(LangItem::EffectsMinOutput, Some(span)); - let proj = Ty::new_projection(tcx, assoc, [tup]); - // TODO this is bad - let self_proj = Ty::new_projection(tcx, def_id.to_def_id(), identity_args); - let trait_ = tcx.require_lang_item(LangItem::EffectsTyCompat, Some(span)); - let trait_ref = ty::TraitRef::new(tcx, trait_, [self_proj, proj]); - predicates.push((ty::Binder::dummy(trait_ref).upcast(tcx), span)); - } - return ty::GenericPredicates { - parent: Some(parent.to_def_id()), - predicates: tcx.arena.alloc_from_iter(predicates), - effects_min_tys: ty::List::empty(), - }; - } - let hir_id = tcx.local_def_id_to_hir_id(def_id); let node = tcx.hir_node(hir_id); From 74e7b5bd762ac9be7d84689271324826d2056a7f Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Tue, 25 Jun 2024 07:52:44 +0000 Subject: [PATCH 04/10] temporarily disable effects on specialization tests --- .../rustc_hir_analysis/src/check/check.rs | 1 + compiler/rustc_ty_utils/src/assoc.rs | 7 ++- .../const-trait-bounds-trait-objects.rs | 3 +- .../const-trait-bounds-trait-objects.stderr | 19 ++------ .../specializing-constness-2.rs | 2 +- .../specializing-constness-2.stderr | 47 ++++++++++--------- .../trait-where-clause-run.rs | 3 +- .../trait-where-clause-run.stderr | 11 ----- 8 files changed, 43 insertions(+), 50 deletions(-) delete mode 100644 tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-run.stderr diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index e1813029778ee..f93777eda529e 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -879,6 +879,7 @@ pub(super) fn check_specialization_validity<'tcx>( let result = opt_result.unwrap_or(Ok(())); if let Err(parent_impl) = result { + // FIXME(effects) the associated type from effects could be specialized if !tcx.is_impl_trait_in_trait(impl_item) && !tcx.is_effects_desugared_assoc_ty(impl_item) { report_forbidden_specialization(tcx, impl_item, parent_impl); } else { diff --git a/compiler/rustc_ty_utils/src/assoc.rs b/compiler/rustc_ty_utils/src/assoc.rs index df6c54ab289ae..681f089e84fb7 100644 --- a/compiler/rustc_ty_utils/src/assoc.rs +++ b/compiler/rustc_ty_utils/src/assoc.rs @@ -179,6 +179,11 @@ fn associated_item_from_impl_item_ref(impl_item_ref: &hir::ImplItemRef) -> ty::A /// 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; + } match tcx.def_kind(def_id) { DefKind::Trait => { let trait_def_id = def_id; @@ -309,7 +314,7 @@ fn associated_type_for_effects(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option $DIR/const-trait-bounds-trait-objects.rs:8:17 + --> $DIR/const-trait-bounds-trait-objects.rs:9:17 | LL | let _: &dyn const Trait; | ^^^^^^^^^^^ error: `~const` is not allowed here - --> $DIR/const-trait-bounds-trait-objects.rs:9:17 + --> $DIR/const-trait-bounds-trait-objects.rs:10:17 | LL | let _: &dyn ~const Trait; | ^^^^^^ @@ -13,27 +13,18 @@ LL | let _: &dyn ~const Trait; = note: trait objects cannot have `~const` trait bounds error: const trait bounds are not allowed in trait object types - --> $DIR/const-trait-bounds-trait-objects.rs:14:25 + --> $DIR/const-trait-bounds-trait-objects.rs:15:25 | LL | const fn handle(_: &dyn const NonConst) {} | ^^^^^^^^^^^^^^ error: `~const` is not allowed here - --> $DIR/const-trait-bounds-trait-objects.rs:16:23 + --> $DIR/const-trait-bounds-trait-objects.rs:17:23 | LL | const fn take(_: &dyn ~const NonConst) {} | ^^^^^^ | = note: trait objects cannot have `~const` trait bounds -warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/const-trait-bounds-trait-objects.rs:1:30 - | -LL | #![feature(const_trait_impl, effects)] - | ^^^^^^^ - | - = note: see issue #102090 for more information - = note: `#[warn(incomplete_features)]` on by default - -error: aborting due to 4 previous errors; 1 warning emitted +error: aborting due to 4 previous errors diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/specializing-constness-2.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/specializing-constness-2.rs index 5218ea925661e..c1fe42b975127 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/specializing-constness-2.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/specializing-constness-2.rs @@ -1,4 +1,4 @@ -#![feature(const_trait_impl, effects, min_specialization, rustc_attrs)] +#![feature(const_trait_impl, min_specialization, rustc_attrs)] //@ known-bug: #110395 #[rustc_specialization_trait] #[const_trait] diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/specializing-constness-2.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/specializing-constness-2.stderr index 7404b6a8b11f2..d082cd6de6097 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/specializing-constness-2.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/specializing-constness-2.stderr @@ -1,31 +1,36 @@ -warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/specializing-constness-2.rs:1:30 +error[E0049]: method `a` has 1 const parameter but its trait declaration has 0 const parameters + --> $DIR/specializing-constness-2.rs:9:1 | -LL | #![feature(const_trait_impl, effects, min_specialization, rustc_attrs)] - | ^^^^^^^ - | - = note: see issue #102090 for more information - = note: `#[warn(incomplete_features)]` on by default +LL | #[const_trait] + | ^^^^^^^^^^^^^^ found 1 const parameter +LL | pub trait A { +LL | fn a() -> u32; + | - expected 0 const parameters -error[E0119]: conflicting implementations of trait `A` - --> $DIR/specializing-constness-2.rs:20:1 +error[E0049]: method `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 | -LL | impl A for T { - | ------------------------ first implementation here -... -LL | impl const A for T { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -error[E0308]: mismatched types +error[E0015]: cannot call non-const fn `::a` in constant functions --> $DIR/specializing-constness-2.rs:27:5 | LL | ::a(); - | ^^^^^^^^^^^^^ expected `host`, found `true` + | ^^^^^^^^^^^^^ + | + = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants +help: add `#![feature(effects)]` to the crate attributes to enable + | +LL + #![feature(effects)] | - = note: expected constant `host` - found constant `true` -error: aborting due to 2 previous errors; 1 warning emitted +error: aborting due to 3 previous errors -Some errors have detailed explanations: E0119, E0308. -For more information about an error, try `rustc --explain E0119`. +Some errors have detailed explanations: E0015, E0049. +For more information about an error, try `rustc --explain E0015`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-run.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-run.rs index ddb26505202f4..2837c83542999 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-run.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-run.rs @@ -1,7 +1,8 @@ //@ run-pass //@ compile-flags: -Znext-solver -#![feature(const_trait_impl, effects)] //~ WARN the feature `effects` is incomplete +#![feature(const_trait_impl, effects)] +#![allow(incomplete_features)] #[const_trait] trait Bar { diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-run.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-run.stderr deleted file mode 100644 index aef4f569d5e11..0000000000000 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-run.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/trait-where-clause-run.rs:3: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 b9886c6872b1fc7fe8d67c7eea8a20eb9a666200 Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Tue, 25 Jun 2024 08:36:40 +0000 Subject: [PATCH 05/10] bless tests part 1 --- compiler/rustc_hir_analysis/src/bounds.rs | 4 + .../const_trait_fn-issue-88433.rs | 3 +- .../const_trait_fn-issue-88433.stderr | 11 - .../unify-op-with-fn-call.rs | 2 +- .../unify-op-with-fn-call.stderr | 55 +---- tests/ui/const-generics/issues/issue-88119.rs | 2 +- tests/ui/consts/const-float-classify.rs | 1 + tests/ui/consts/const-float-classify.stderr | 216 +----------------- tests/ui/consts/const-try.rs | 3 +- tests/ui/consts/const-try.stderr | 41 +--- .../constifconst-call-in-const-position.rs | 3 +- ...constifconst-call-in-const-position.stderr | 37 +-- tests/ui/consts/promoted-const-drop.rs | 1 + tests/ui/consts/promoted-const-drop.stderr | 15 +- tests/ui/consts/promoted_const_call.stderr | 34 ++- .../consts/rustc-impl-const-stability.stderr | 12 +- .../auxiliary/cross-crate.rs | 3 +- ...fault-bound-non-const-specialized-bound.rs | 2 +- ...t-bound-non-const-specialized-bound.stderr | 41 ++++ .../const-default-const-specialized.rs | 5 +- .../const-default-const-specialized.stderr | 39 +++- .../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.rs | 4 +- ...non-const-default-const-specialized.stderr | 45 ++-- .../trait-where-clause-const.rs | 6 +- .../ui/specialization/const_trait_impl.stderr | 68 +++++- 31 files changed, 368 insertions(+), 392 deletions(-) delete mode 100644 tests/ui/const-generics/const_trait_fn-issue-88433.stderr create mode 100644 tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/const-default-bound-non-const-specialized-bound.stderr create mode 100644 tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/default-keyword.stderr create mode 100644 tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/issue-95186-specialize-on-tilde-const.stderr create mode 100644 tests/ui/rfcs/rfc-2632-const-trait-impl/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 18a29c10b61a3..0b03eeaced1be 100644 --- a/compiler/rustc_hir_analysis/src/bounds.rs +++ b/compiler/rustc_hir_analysis/src/bounds.rs @@ -65,6 +65,10 @@ impl<'tcx> Bounds<'tcx> { } else { self.clauses.push(clause); } + + if !tcx.features().effects { + return; + } // 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. if let Some(compat_val) = match (tcx.def_kind(defining_def_id), constness) { diff --git a/tests/ui/const-generics/const_trait_fn-issue-88433.rs b/tests/ui/const-generics/const_trait_fn-issue-88433.rs index f3271f833cc64..5e0ea6fc168ef 100644 --- a/tests/ui/const-generics/const_trait_fn-issue-88433.rs +++ b/tests/ui/const-generics/const_trait_fn-issue-88433.rs @@ -1,7 +1,8 @@ //@ build-pass //@ compile-flags: -Znext-solver -#![feature(const_trait_impl, effects)] //~ WARN the feature `effects` is incomplete +#![allow(incomplete_features)] +#![feature(const_trait_impl, effects)] #[const_trait] trait Func { diff --git a/tests/ui/const-generics/const_trait_fn-issue-88433.stderr b/tests/ui/const-generics/const_trait_fn-issue-88433.stderr deleted file mode 100644 index 4e0d6370fbd50..0000000000000 --- a/tests/ui/const-generics/const_trait_fn-issue-88433.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/const_trait_fn-issue-88433.rs:3: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/const-generics/generic_const_exprs/unify-op-with-fn-call.rs b/tests/ui/const-generics/generic_const_exprs/unify-op-with-fn-call.rs index 2f903ea419efa..bd9c08e5ad895 100644 --- a/tests/ui/const-generics/generic_const_exprs/unify-op-with-fn-call.rs +++ b/tests/ui/const-generics/generic_const_exprs/unify-op-with-fn-call.rs @@ -1,6 +1,6 @@ //@ known-bug: #110395 -#![feature(generic_const_exprs, adt_const_params, const_trait_impl)] +#![feature(generic_const_exprs, adt_const_params, const_trait_impl, effects)] #![allow(incomplete_features)] // test `N + N` unifies with explicit function calls for non-builtin-types diff --git a/tests/ui/const-generics/generic_const_exprs/unify-op-with-fn-call.stderr b/tests/ui/const-generics/generic_const_exprs/unify-op-with-fn-call.stderr index 335130c958f0e..cf03bb9ad7612 100644 --- a/tests/ui/const-generics/generic_const_exprs/unify-op-with-fn-call.stderr +++ b/tests/ui/const-generics/generic_const_exprs/unify-op-with-fn-call.stderr @@ -1,3 +1,12 @@ +error: const `impl` for trait `Add` which is not marked with `#[const_trait]` + --> $DIR/unify-op-with-fn-call.rs:10:12 + | +LL | impl const std::ops::Add for Foo { + | ^^^^^^^^^^^^^ + | + = 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[E0741]: `Foo` must implement `ConstParamTy` to be used as the type of a const generic parameter --> $DIR/unify-op-with-fn-call.rs:18:29 | @@ -45,48 +54,6 @@ help: try adding a `where` bound LL | fn foo2(a: Evaluatable2<{ N + N }>) where [(); { std::ops::Add::add(N, N) }]: { | +++++++++++++++++++++++++++++++++++++++++ -error[E0015]: cannot call non-const operator in constants - --> $DIR/unify-op-with-fn-call.rs:20:39 - | -LL | fn foo(a: Evaluatable<{ N + N }>) { - | ^^^^^ - | -note: impl defined here, but it is not `const` - --> $DIR/unify-op-with-fn-call.rs:10:1 - | -LL | impl const std::ops::Add for Foo { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: calls in constants are limited to constant functions, tuple structs and tuple variants -help: add `#![feature(effects)]` to the crate attributes to enable - | -LL + #![feature(effects)] - | - -error[E0015]: cannot call non-const fn `::add` in constants - --> $DIR/unify-op-with-fn-call.rs:21:13 - | -LL | bar::<{ std::ops::Add::add(N, N) }>(); - | ^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: calls in constants are limited to constant functions, tuple structs and tuple variants -help: add `#![feature(effects)]` to the crate attributes to enable - | -LL + #![feature(effects)] - | - -error[E0015]: cannot call non-const fn `::add` in constants - --> $DIR/unify-op-with-fn-call.rs:30:14 - | -LL | bar2::<{ std::ops::Add::add(N, N) }>(); - | ^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: calls in constants are limited to constant functions, tuple structs and tuple variants -help: add `#![feature(effects)]` to the crate attributes to enable - | -LL + #![feature(effects)] - | - -error: aborting due to 7 previous errors +error: aborting due to 5 previous errors -Some errors have detailed explanations: E0015, E0741. -For more information about an error, try `rustc --explain E0015`. +For more information about this error, try `rustc --explain E0741`. diff --git a/tests/ui/const-generics/issues/issue-88119.rs b/tests/ui/const-generics/issues/issue-88119.rs index bcbb26f0d8e68..128e0b64a2bfa 100644 --- a/tests/ui/const-generics/issues/issue-88119.rs +++ b/tests/ui/const-generics/issues/issue-88119.rs @@ -1,7 +1,7 @@ //@ check-pass #![allow(incomplete_features)] -#![feature(const_trait_impl, generic_const_exprs)] +#![feature(const_trait_impl, effects, generic_const_exprs)] #[const_trait] trait ConstName { diff --git a/tests/ui/consts/const-float-classify.rs b/tests/ui/consts/const-float-classify.rs index ae094003c89e2..acc8d00f83e60 100644 --- a/tests/ui/consts/const-float-classify.rs +++ b/tests/ui/consts/const-float-classify.rs @@ -5,6 +5,7 @@ #![feature(const_float_bits_conv)] #![feature(const_float_classify)] #![feature(const_trait_impl, effects)] +#![allow(incomplete_features)] // Don't promote const fn nop(x: T) -> T { x } diff --git a/tests/ui/consts/const-float-classify.stderr b/tests/ui/consts/const-float-classify.stderr index 1de27a072cf73..38acb8a228104 100644 --- a/tests/ui/consts/const-float-classify.stderr +++ b/tests/ui/consts/const-float-classify.stderr @@ -1,14 +1,5 @@ -warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/const-float-classify.rs:7:30 - | -LL | #![feature(const_trait_impl, effects)] - | ^^^^^^^ - | - = note: see issue #102090 for more information - = note: `#[warn(incomplete_features)]` on by default - error: const `impl` for trait `PartialEq` which is not marked with `#[const_trait]` - --> $DIR/const-float-classify.rs:12:12 + --> $DIR/const-float-classify.rs:13:12 | LL | impl const PartialEq for bool { | ^^^^^^^^^^^^^^^^^ @@ -16,208 +7,5 @@ LL | impl const PartialEq for bool { = 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[E0207]: the const parameter `host` is not constrained by the impl trait, self type, or predicates - --> $DIR/const-float-classify.rs:12:6 - | -LL | impl const PartialEq for bool { - | ^^^^^ unconstrained const parameter - | - = note: expressions using a const parameter must map each value to a distinct output value - = note: proving the result of expressions other than the parameter are unique is not supported - -error[E0284]: type annotations needed - --> $DIR/const-float-classify.rs:21:35 - | -LL | const _: () = assert!($a == $b); - | ^^ cannot infer the value of the constant `_` -... -LL | / suite! { -LL | | [is_nan, is_infinite, is_finite, is_normal, is_sign_positive, is_sign_negative] -LL | | -0.0 / 0.0 => [ true, false, false, false, NonDet, NonDet] -LL | | 0.0 / 0.0 => [ true, false, false, false, NonDet, NonDet] -... | -LL | | -1.0 / 0.0 => [ false, true, false, false, false, true] -LL | | } - | |_- in this macro invocation - | -note: required for `bool` to implement `PartialEq` - --> $DIR/const-float-classify.rs:12:12 - | -LL | impl const PartialEq for bool { - | ----- ^^^^^^^^^^^^^^^^^ ^^^^ - | | - | unsatisfied trait bound introduced here - = note: this error originates in the macro `const_assert` which comes from the expansion of the macro `suite` (in Nightly builds, run with -Z macro-backtrace for more info) - -error[E0284]: type annotations needed - --> $DIR/const-float-classify.rs:21:35 - | -LL | const _: () = assert!($a == $b); - | ^^ cannot infer the value of the constant `_` -... -LL | / suite! { -LL | | [is_nan, is_infinite, is_finite, is_normal, is_sign_positive, is_sign_negative] -LL | | -0.0 / 0.0 => [ true, false, false, false, NonDet, NonDet] -LL | | 0.0 / 0.0 => [ true, false, false, false, NonDet, NonDet] -... | -LL | | -1.0 / 0.0 => [ false, true, false, false, false, true] -LL | | } - | |_- in this macro invocation - | -note: required for `bool` to implement `PartialEq` - --> $DIR/const-float-classify.rs:12:12 - | -LL | impl const PartialEq for bool { - | ----- ^^^^^^^^^^^^^^^^^ ^^^^ - | | - | unsatisfied trait bound introduced here - = note: this error originates in the macro `const_assert` which comes from the expansion of the macro `suite` (in Nightly builds, run with -Z macro-backtrace for more info) - -error[E0284]: type annotations needed - --> $DIR/const-float-classify.rs:21:35 - | -LL | const _: () = assert!($a == $b); - | ^^ cannot infer the value of the constant `_` -... -LL | / suite! { -LL | | [is_nan, is_infinite, is_finite, is_normal, is_sign_positive, is_sign_negative] -LL | | -0.0 / 0.0 => [ true, false, false, false, NonDet, NonDet] -LL | | 0.0 / 0.0 => [ true, false, false, false, NonDet, NonDet] -... | -LL | | -1.0 / 0.0 => [ false, true, false, false, false, true] -LL | | } - | |_- in this macro invocation - | -note: required for `bool` to implement `PartialEq` - --> $DIR/const-float-classify.rs:12:12 - | -LL | impl const PartialEq for bool { - | ----- ^^^^^^^^^^^^^^^^^ ^^^^ - | | - | unsatisfied trait bound introduced here - = note: this error originates in the macro `const_assert` which comes from the expansion of the macro `suite` (in Nightly builds, run with -Z macro-backtrace for more info) - -error[E0284]: type annotations needed - --> $DIR/const-float-classify.rs:21:35 - | -LL | const _: () = assert!($a == $b); - | ^^ cannot infer the value of the constant `_` -... -LL | / suite! { -LL | | [is_nan, is_infinite, is_finite, is_normal, is_sign_positive, is_sign_negative] -LL | | -0.0 / 0.0 => [ true, false, false, false, NonDet, NonDet] -LL | | 0.0 / 0.0 => [ true, false, false, false, NonDet, NonDet] -... | -LL | | -1.0 / 0.0 => [ false, true, false, false, false, true] -LL | | } - | |_- in this macro invocation - | -note: required for `bool` to implement `PartialEq` - --> $DIR/const-float-classify.rs:12:12 - | -LL | impl const PartialEq for bool { - | ----- ^^^^^^^^^^^^^^^^^ ^^^^ - | | - | unsatisfied trait bound introduced here - = note: this error originates in the macro `const_assert` which comes from the expansion of the macro `suite` (in Nightly builds, run with -Z macro-backtrace for more info) - -error[E0284]: type annotations needed - --> $DIR/const-float-classify.rs:21:35 - | -LL | const _: () = assert!($a == $b); - | ^^ cannot infer the value of the constant `_` -... -LL | / suite! { -LL | | [is_nan, is_infinite, is_finite, is_normal, is_sign_positive, is_sign_negative] -LL | | -0.0 / 0.0 => [ true, false, false, false, NonDet, NonDet] -LL | | 0.0 / 0.0 => [ true, false, false, false, NonDet, NonDet] -... | -LL | | -1.0 / 0.0 => [ false, true, false, false, false, true] -LL | | } - | |_- in this macro invocation - | -note: required for `bool` to implement `PartialEq` - --> $DIR/const-float-classify.rs:12:12 - | -LL | impl const PartialEq for bool { - | ----- ^^^^^^^^^^^^^^^^^ ^^^^ - | | - | unsatisfied trait bound introduced here - = note: this error originates in the macro `const_assert` which comes from the expansion of the macro `suite` (in Nightly builds, run with -Z macro-backtrace for more info) - -error[E0284]: type annotations needed - --> $DIR/const-float-classify.rs:21:35 - | -LL | const _: () = assert!($a == $b); - | ^^ cannot infer the value of the constant `_` -... -LL | / suite! { -LL | | [is_nan, is_infinite, is_finite, is_normal, is_sign_positive, is_sign_negative] -LL | | -0.0 / 0.0 => [ true, false, false, false, NonDet, NonDet] -LL | | 0.0 / 0.0 => [ true, false, false, false, NonDet, NonDet] -... | -LL | | -1.0 / 0.0 => [ false, true, false, false, false, true] -LL | | } - | |_- in this macro invocation - | -note: required for `bool` to implement `PartialEq` - --> $DIR/const-float-classify.rs:12:12 - | -LL | impl const PartialEq for bool { - | ----- ^^^^^^^^^^^^^^^^^ ^^^^ - | | - | unsatisfied trait bound introduced here - = note: this error originates in the macro `const_assert` which comes from the expansion of the macro `suite` (in Nightly builds, run with -Z macro-backtrace for more info) - -error[E0284]: type annotations needed - --> $DIR/const-float-classify.rs:21:35 - | -LL | const _: () = assert!($a == $b); - | ^^ cannot infer the value of the constant `_` -... -LL | / suite! { -LL | | [is_nan, is_infinite, is_finite, is_normal, is_sign_positive, is_sign_negative] -LL | | -0.0 / 0.0 => [ true, false, false, false, NonDet, NonDet] -LL | | 0.0 / 0.0 => [ true, false, false, false, NonDet, NonDet] -... | -LL | | -1.0 / 0.0 => [ false, true, false, false, false, true] -LL | | } - | |_- in this macro invocation - | -note: required for `bool` to implement `PartialEq` - --> $DIR/const-float-classify.rs:12:12 - | -LL | impl const PartialEq for bool { - | ----- ^^^^^^^^^^^^^^^^^ ^^^^ - | | - | unsatisfied trait bound introduced here - = note: this error originates in the macro `const_assert` which comes from the expansion of the macro `suite` (in Nightly builds, run with -Z macro-backtrace for more info) - -error[E0284]: type annotations needed - --> $DIR/const-float-classify.rs:21:35 - | -LL | const _: () = assert!($a == $b); - | ^^ cannot infer the value of the constant `_` -... -LL | / suite! { -LL | | [is_nan, is_infinite, is_finite, is_normal, is_sign_positive, is_sign_negative] -LL | | -0.0 / 0.0 => [ true, false, false, false, NonDet, NonDet] -LL | | 0.0 / 0.0 => [ true, false, false, false, NonDet, NonDet] -... | -LL | | -1.0 / 0.0 => [ false, true, false, false, false, true] -LL | | } - | |_- in this macro invocation - | -note: required for `bool` to implement `PartialEq` - --> $DIR/const-float-classify.rs:12:12 - | -LL | impl const PartialEq for bool { - | ----- ^^^^^^^^^^^^^^^^^ ^^^^ - | | - | unsatisfied trait bound introduced here - = note: this error originates in the macro `const_assert` which comes from the expansion of the macro `suite` (in Nightly builds, run with -Z macro-backtrace for more info) - -error: aborting due to 10 previous errors; 1 warning emitted +error: aborting due to 1 previous error -Some errors have detailed explanations: E0207, E0284. -For more information about an error, try `rustc --explain E0207`. diff --git a/tests/ui/consts/const-try.rs b/tests/ui/consts/const-try.rs index f2d3db9be9c5b..9089dd70a26a6 100644 --- a/tests/ui/consts/const-try.rs +++ b/tests/ui/consts/const-try.rs @@ -4,8 +4,9 @@ #![crate_type = "lib"] #![feature(try_trait_v2)] -#![feature(const_trait_impl)] +#![feature(const_trait_impl, effects)] #![feature(const_try)] +#![allow(incomplete_features)] use std::ops::{ControlFlow, FromResidual, Try}; diff --git a/tests/ui/consts/const-try.stderr b/tests/ui/consts/const-try.stderr index 2d91424c8d320..27eb1252d7b7d 100644 --- a/tests/ui/consts/const-try.stderr +++ b/tests/ui/consts/const-try.stderr @@ -1,37 +1,20 @@ -error[E0015]: `?` cannot determine the branch of `TryMe` in constant functions - --> $DIR/const-try.rs:33:5 +error: const `impl` for trait `FromResidual` which is not marked with `#[const_trait]` + --> $DIR/const-try.rs:16:12 | -LL | TryMe?; - | ^^^^^^ - | -note: impl defined here, but it is not `const` - --> $DIR/const-try.rs:21:1 - | -LL | impl const Try for TryMe { - | ^^^^^^^^^^^^^^^^^^^^^^^^ - = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants -help: add `#![feature(effects)]` to the crate attributes to enable - | -LL + #![feature(effects)] +LL | impl const FromResidual 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[E0015]: `?` cannot convert from residual of `TryMe` in constant functions - --> $DIR/const-try.rs:33:5 +error: const `impl` for trait `Try` which is not marked with `#[const_trait]` + --> $DIR/const-try.rs:22:12 | -LL | TryMe?; - | ^^^^^^ - | -note: impl defined here, but it is not `const` - --> $DIR/const-try.rs:15:1 - | -LL | impl const FromResidual for TryMe { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants -help: add `#![feature(effects)]` to the crate attributes to enable - | -LL + #![feature(effects)] +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 2 previous errors -For more information about this error, try `rustc --explain E0015`. diff --git a/tests/ui/consts/constifconst-call-in-const-position.rs b/tests/ui/consts/constifconst-call-in-const-position.rs index 29c967f38a7d9..757e35bbab209 100644 --- a/tests/ui/consts/constifconst-call-in-const-position.rs +++ b/tests/ui/consts/constifconst-call-in-const-position.rs @@ -1,6 +1,7 @@ //@ known-bug: #102498 -#![feature(const_trait_impl, generic_const_exprs)] +#![feature(const_trait_impl, effects, generic_const_exprs)] +#![allow(incomplete_features)] #[const_trait] pub trait Tr { diff --git a/tests/ui/consts/constifconst-call-in-const-position.stderr b/tests/ui/consts/constifconst-call-in-const-position.stderr index 09827f29baf96..f980b8969de85 100644 --- a/tests/ui/consts/constifconst-call-in-const-position.stderr +++ b/tests/ui/consts/constifconst-call-in-const-position.stderr @@ -1,36 +1,9 @@ -warning: the feature `generic_const_exprs` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/constifconst-call-in-const-position.rs:3:30 - | -LL | #![feature(const_trait_impl, generic_const_exprs)] - | ^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #76560 for more information - = note: `#[warn(incomplete_features)]` on by default - -error[E0015]: cannot call non-const fn `::a` in constants - --> $DIR/constifconst-call-in-const-position.rs:17:9 - | -LL | [0; T::a()] - | ^^^^^^ - | - = note: calls in constants are limited to constant functions, tuple structs and tuple variants -help: add `#![feature(effects)]` to the crate attributes to enable - | -LL + #![feature(effects)] - | - -error[E0015]: cannot call non-const fn `::a` in constants - --> $DIR/constifconst-call-in-const-position.rs:16:38 +error[E0080]: evaluation of `foo::<()>::{constant#0}` failed + --> $DIR/constifconst-call-in-const-position.rs:17:38 | LL | const fn foo() -> [u8; T::a()] { - | ^^^^^^ - | - = note: calls in constants are limited to constant functions, tuple structs and tuple variants -help: add `#![feature(effects)]` to the crate attributes to enable - | -LL + #![feature(effects)] - | + | ^^^^^^ calling non-const function `<() as Tr>::a` -error: aborting due to 2 previous errors; 1 warning emitted +error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0015`. +For more information about this error, try `rustc --explain E0080`. diff --git a/tests/ui/consts/promoted-const-drop.rs b/tests/ui/consts/promoted-const-drop.rs index c896c011ab66a..b7d92d6523a81 100644 --- a/tests/ui/consts/promoted-const-drop.rs +++ b/tests/ui/consts/promoted-const-drop.rs @@ -4,6 +4,7 @@ struct A(); impl const Drop for A { + //~^ ERROR const `impl` for trait `Drop` which is not marked with `#[const_trait]` fn drop(&mut self) {} } diff --git a/tests/ui/consts/promoted-const-drop.stderr b/tests/ui/consts/promoted-const-drop.stderr index 4802834173fc5..1201f608232df 100644 --- a/tests/ui/consts/promoted-const-drop.stderr +++ b/tests/ui/consts/promoted-const-drop.stderr @@ -1,5 +1,14 @@ +error: const `impl` for trait `Drop` which is not marked with `#[const_trait]` + --> $DIR/promoted-const-drop.rs:6:12 + | +LL | impl const Drop for A { + | ^^^^ + | + = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` + = note: adding a non-const method body in the future would be a breaking change + error[E0716]: temporary value dropped while borrowed - --> $DIR/promoted-const-drop.rs:13:26 + --> $DIR/promoted-const-drop.rs:14:26 | LL | let _: &'static A = &A(); | ---------- ^^^ creates a temporary value which is freed while still in use @@ -10,7 +19,7 @@ LL | } | - temporary value is freed at the end of this statement error[E0716]: temporary value dropped while borrowed - --> $DIR/promoted-const-drop.rs:14:28 + --> $DIR/promoted-const-drop.rs:15:28 | LL | let _: &'static [A] = &[C]; | ------------ ^^^ creates a temporary value which is freed while still in use @@ -19,6 +28,6 @@ LL | let _: &'static [A] = &[C]; LL | } | - temporary value is freed at the end of this statement -error: aborting due to 2 previous errors +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0716`. diff --git a/tests/ui/consts/promoted_const_call.stderr b/tests/ui/consts/promoted_const_call.stderr index ace449fae9ce6..64bf6bd73b0a5 100644 --- a/tests/ui/consts/promoted_const_call.stderr +++ b/tests/ui/consts/promoted_const_call.stderr @@ -1,10 +1,31 @@ -error[E0493]: destructor of `Panic` cannot be evaluated at compile-time +error: const `impl` for trait `Drop` which is not marked with `#[const_trait]` + --> $DIR/promoted_const_call.rs:7:12 + | +LL | impl const Drop for Panic { fn drop(&mut self) { panic!(); } } + | ^^^^ + | + = 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[E0716]: temporary value dropped while borrowed + --> $DIR/promoted_const_call.rs:11:26 + | +LL | let _: &'static _ = &id(&Panic); + | ---------- ^^^^^^^^^^ creates a temporary value which is freed while still in use + | | + | type annotation requires that borrow lasts for `'static` +... +LL | }; + | - temporary value is freed at the end of this statement + +error[E0716]: temporary value dropped while borrowed --> $DIR/promoted_const_call.rs:11:30 | LL | let _: &'static _ = &id(&Panic); - | ^^^^^ - value is dropped here - | | - | the destructor for this type cannot be evaluated in constants + | ---------- ^^^^^ - temporary value is freed at the end of this statement + | | | + | | creates a temporary value which is freed while still in use + | type annotation requires that borrow lasts for `'static` error[E0716]: temporary value dropped while borrowed --> $DIR/promoted_const_call.rs:17:26 @@ -48,7 +69,6 @@ LL | let _: &'static _ = &&(Panic, 0).1; LL | } | - temporary value is freed at the end of this statement -error: aborting due to 5 previous errors +error: aborting due to 7 previous errors -Some errors have detailed explanations: E0493, E0716. -For more information about an error, try `rustc --explain E0493`. +For more information about this error, try `rustc --explain E0716`. diff --git a/tests/ui/consts/rustc-impl-const-stability.stderr b/tests/ui/consts/rustc-impl-const-stability.stderr index 250d1c3fc0553..84bd375ea406e 100644 --- a/tests/ui/consts/rustc-impl-const-stability.stderr +++ b/tests/ui/consts/rustc-impl-const-stability.stderr @@ -16,15 +16,5 @@ LL | impl const Default for Data { = 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[E0207]: the const parameter `host` is not constrained by the impl trait, self type, or predicates - --> $DIR/rustc-impl-const-stability.rs:15:6 - | -LL | impl const Default for Data { - | ^^^^^ unconstrained const parameter - | - = note: expressions using a const parameter must map each value to a distinct output value - = note: proving the result of expressions other than the parameter are unique is not supported - -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 E0207`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/auxiliary/cross-crate.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/auxiliary/cross-crate.rs index 62609384cff08..78e41ca6b7519 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/auxiliary/cross-crate.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/auxiliary/cross-crate.rs @@ -1,4 +1,5 @@ -#![feature(const_trait_impl, effects)] //~ WARN the feature `effects` is incomplete +#![allow(incomplete_features)] +#![feature(const_trait_impl, effects)] #[const_trait] pub trait MyTrait { diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/const-default-bound-non-const-specialized-bound.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/const-default-bound-non-const-specialized-bound.rs index fe4df09342f77..69dcb403aa908 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/const-default-bound-non-const-specialized-bound.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/const-default-bound-non-const-specialized-bound.rs @@ -1,6 +1,6 @@ // Tests that trait bounds on specializing trait impls must be `~const` if the // same bound is present on the default impl and is `~const` there. -//@ check-pass +//@ known-bug: #110395 // FIXME(effects) ^ should error #![feature(const_trait_impl)] diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/const-default-bound-non-const-specialized-bound.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/const-default-bound-non-const-specialized-bound.stderr new file mode 100644 index 0000000000000..b4c4cf0a89059 --- /dev/null +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/const-default-bound-non-const-specialized-bound.stderr @@ -0,0 +1,41 @@ +error[E0049]: method `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 + | +LL | / impl Bar for T +LL | | where +LL | | T: Foo, //FIXME ~ ERROR missing `~const` qualifier +LL | | T: Specialize, + | |__________________^ + +error[E0049]: method `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]: method `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 + +For more information about this error, try `rustc --explain E0049`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/const-default-const-specialized.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/const-default-const-specialized.rs index c653e62032e6e..a48a50b9e5ce4 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/const-default-const-specialized.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/const-default-const-specialized.rs @@ -1,9 +1,10 @@ // Tests that a const default trait impl can be specialized by another const // trait impl and that the specializing impl will be used during const-eval. -//@ run-pass +//@ known-bug: #110395 +// FIXME(effects) run-pass -#![feature(const_trait_impl, effects)] //~ WARN the feature `effects` is incomplete +#![feature(const_trait_impl)] #![feature(min_specialization)] #[const_trait] diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/const-default-const-specialized.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/const-default-const-specialized.stderr index f533fb61aad75..cabf201405f55 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/const-default-const-specialized.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/const-default-const-specialized.stderr @@ -1,11 +1,36 @@ -warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/const-default-const-specialized.rs:6:30 +error[E0049]: method `value` has 1 const parameter but its trait declaration has 0 const parameters + --> $DIR/const-default-const-specialized.rs:10:1 | -LL | #![feature(const_trait_impl, effects)] - | ^^^^^^^ +LL | #[const_trait] + | ^^^^^^^^^^^^^^ found 1 const parameter +LL | trait Value { +LL | fn value() -> u32; + | - expected 0 const parameters + +error[E0049]: method `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 + | +LL | T::value() + | ^^^^^^^^^^ + | + = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants +help: add `#![feature(effects)]` to the crate attributes to enable + | +LL + #![feature(effects)] | - = note: see issue #102090 for more information - = note: `#[warn(incomplete_features)]` on by default -warning: 1 warning emitted +error: aborting due to 3 previous errors +Some errors have detailed explanations: E0015, E0049. +For more information about an error, try `rustc --explain E0015`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/default-keyword.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/default-keyword.rs index bc45a70777ca5..d9ffd237dcefd 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/default-keyword.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/default-keyword.rs @@ -1,4 +1,5 @@ -//@ check-pass +//@ known-bug: #110395 +// FIXME check-pass #![feature(const_trait_impl)] #![feature(min_specialization)] diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/default-keyword.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/default-keyword.stderr new file mode 100644 index 0000000000000..52c8708f2c88d --- /dev/null +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/default-keyword.stderr @@ -0,0 +1,12 @@ +error[E0049]: method `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/rfcs/rfc-2632-const-trait-impl/specialization/issue-95186-specialize-on-tilde-const.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/issue-95186-specialize-on-tilde-const.rs index d80370aee8209..219e5f3a600c1 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/issue-95186-specialize-on-tilde-const.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/issue-95186-specialize-on-tilde-const.rs @@ -1,6 +1,7 @@ // Tests that `~const` trait bounds can be used to specialize const trait impls. -//@ check-pass +//@ known-bug: #110395 +// FIXME check-pass #![feature(const_trait_impl)] #![feature(rustc_attrs)] diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/issue-95186-specialize-on-tilde-const.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/issue-95186-specialize-on-tilde-const.stderr new file mode 100644 index 0000000000000..1aa34637ca482 --- /dev/null +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/issue-95186-specialize-on-tilde-const.stderr @@ -0,0 +1,43 @@ +error[E0049]: method `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]: method `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]: method `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]: method `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/rfcs/rfc-2632-const-trait-impl/specialization/issue-95187-same-trait-bound-different-constness.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/issue-95187-same-trait-bound-different-constness.rs index d97469edaf97f..7514baa2fd554 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/issue-95187-same-trait-bound-different-constness.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/issue-95187-same-trait-bound-different-constness.rs @@ -2,7 +2,8 @@ // `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`). -//@ check-pass +//@ known-bug: #110395 +// FIXME check-pass #![feature(rustc_attrs)] #![feature(min_specialization)] diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/issue-95187-same-trait-bound-different-constness.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/issue-95187-same-trait-bound-different-constness.stderr new file mode 100644 index 0000000000000..0e0f391b0865e --- /dev/null +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/issue-95187-same-trait-bound-different-constness.stderr @@ -0,0 +1,43 @@ +error[E0049]: method `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]: method `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]: method `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]: method `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/rfcs/rfc-2632-const-trait-impl/specialization/non-const-default-const-specialized.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/non-const-default-const-specialized.rs index fc8fc3f2a1d9c..912b35095f918 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/non-const-default-const-specialized.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/non-const-default-const-specialized.rs @@ -1,9 +1,9 @@ // Tests that a non-const default impl can be specialized by a const trait impl, // but that the default impl cannot be used in a const context. //@ known-bug: #110395 -// FIXME run-pass +// FIXME(effects) run-pass -#![feature(const_trait_impl, effects)] +#![feature(const_trait_impl)] #![feature(min_specialization)] #[const_trait] diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/non-const-default-const-specialized.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/non-const-default-const-specialized.stderr index bcccc855aab52..d49beb932591c 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/non-const-default-const-specialized.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/non-const-default-const-specialized.stderr @@ -1,21 +1,36 @@ -warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/non-const-default-const-specialized.rs:6:30 +error[E0049]: method `value` has 1 const parameter but its trait declaration has 0 const parameters + --> $DIR/non-const-default-const-specialized.rs:9:1 | -LL | #![feature(const_trait_impl, effects)] - | ^^^^^^^ +LL | #[const_trait] + | ^^^^^^^^^^^^^^ found 1 const parameter +LL | trait Value { +LL | fn value() -> u32; + | - expected 0 const parameters + +error[E0049]: method `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: see issue #102090 for more information - = note: `#[warn(incomplete_features)]` on by default + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -error[E0119]: conflicting implementations of trait `Value` for type `FortyTwo` - --> $DIR/non-const-default-const-specialized.rs:27:1 +error[E0015]: cannot call non-const fn `::value` in constant functions + --> $DIR/non-const-default-const-specialized.rs:15:5 + | +LL | T::value() + | ^^^^^^^^^^ + | + = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants +help: add `#![feature(effects)]` to the crate attributes to enable + | +LL + #![feature(effects)] | -LL | impl Value for T { - | ------------------- first implementation here -... -LL | impl const Value for FortyTwo { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `FortyTwo` -error: aborting due to 1 previous error; 1 warning emitted +error: aborting due to 3 previous errors -For more information about this error, try `rustc --explain E0119`. +Some errors have detailed explanations: E0015, E0049. +For more information about an error, try `rustc --explain E0015`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-const.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-const.rs index 364ddfcc8ddd5..516451d881106 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-const.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-const.rs @@ -3,8 +3,8 @@ // (`rustc_const_eval` instead of `rustc_hir_analysis`) Therefore one file as a // test is not enough. //@ known-bug: #110395 -// FIXME check-pass #![feature(const_trait_impl, effects)] +#![allow(incomplete_features)] #[const_trait] trait Bar {} @@ -19,9 +19,9 @@ trait Foo { const fn test1() { T::a(); T::b(); - //FIXME ~^ ERROR the trait bound + //~^ ERROR mismatched types T::c::(); - //FIXME ~^ ERROR the trait bound + //~^ ERROR mismatched types } const fn test2() { diff --git a/tests/ui/specialization/const_trait_impl.stderr b/tests/ui/specialization/const_trait_impl.stderr index fc02f6f8f7433..e39138983c6e6 100644 --- a/tests/ui/specialization/const_trait_impl.stderr +++ b/tests/ui/specialization/const_trait_impl.stderr @@ -1,3 +1,23 @@ +error[E0049]: method `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]: method `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 | @@ -16,6 +36,37 @@ error: `~const` can only be applied to `#[const_trait]` traits LL | impl const A for T { | ^^^^^^^ +error[E0049]: method `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[E0049]: method `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 + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error[E0049]: method `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 + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + error[E0015]: cannot call non-const fn `<() as A>::a` in constants --> $DIR/const_trait_impl.rs:52:23 | @@ -52,6 +103,19 @@ help: add `#![feature(effects)]` to the crate attributes to enable LL + #![feature(effects)] | -error: aborting due to 6 previous errors +error[E0015]: cannot call non-const fn `::foo` in constant functions + --> $DIR/const_trait_impl.rs:48:9 + | +LL | T::foo() + | ^^^^^^^^ + | + = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants +help: add `#![feature(effects)]` to the crate attributes to enable + | +LL + #![feature(effects)] + | + +error: aborting due to 12 previous errors -For more information about this error, try `rustc --explain E0015`. +Some errors have detailed explanations: E0015, E0049. +For more information about an error, try `rustc --explain E0015`. From f852a2c17373eda6994d83f75d8192ba4c2a653e Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Tue, 25 Jun 2024 09:19:23 +0000 Subject: [PATCH 06/10] Implement `Self::Effects: Compat` desugaring --- .../src/collect/item_bounds.rs | 4 +--- .../src/collect/predicates_of.rs | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs index 707a3f2d3c715..c8c82c711de18 100644 --- a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs +++ b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs @@ -130,7 +130,6 @@ pub(super) fn explicit_item_bounds_with_filter( let parent = tcx.local_parent(def_id); - let identity_args = ty::GenericArgs::identity_for_item(tcx, def_id); let preds = tcx.explicit_predicates_of(parent); if let ty::AssocItemContainer::TraitContainer = tcx.associated_item(def_id).container { @@ -141,8 +140,7 @@ pub(super) fn explicit_item_bounds_with_filter( let span = tcx.def_span(def_id); let assoc = tcx.require_lang_item(hir::LangItem::EffectsMinOutput, Some(span)); let proj = Ty::new_projection(tcx, assoc, [tup]); - // TODO this is bad - let self_proj = Ty::new_projection(tcx, def_id.to_def_id(), identity_args); + let self_proj = Ty::new_projection(tcx, def_id.to_def_id(), ty::GenericArgs::identity_for_item(tcx, def_id)); let trait_ = tcx.require_lang_item(hir::LangItem::EffectsTyCompat, Some(span)); let trait_ref = ty::TraitRef::new(tcx, trait_, [self_proj, proj]); predicates.push((ty::Binder::dummy(trait_ref).upcast(tcx), span)); diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs index 9a5feaf3d3c65..cc3078f037a06 100644 --- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs @@ -57,6 +57,7 @@ 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, .. }) => { @@ -313,6 +314,24 @@ 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), From 373e906296059e3fea51323e07fcf5b0cea41d11 Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Tue, 25 Jun 2024 09:50:01 +0000 Subject: [PATCH 07/10] bless UI tests --- ...constifconst-call-in-const-position.stderr | 20 ++- ...-type-const-bound-usage-0.qualified.stderr | 16 ++- .../assoc-type-const-bound-usage-0.rs | 12 +- .../assoc-type-const-bound-usage-0.stderr | 33 +++++ ...-type-const-bound-usage-1.qualified.stderr | 35 +++-- .../assoc-type-const-bound-usage-1.rs | 7 +- ...ype-const-bound-usage-1.unqualified.stderr | 33 +++++ .../rfc-2632-const-trait-impl/assoc-type.rs | 3 +- .../assoc-type.stderr | 16 +-- .../call-const-trait-method-fail.stderr | 14 +- .../call-const-trait-method-pass.stderr | 61 +++++++- .../call-generic-in-impl.stderr | 25 +++- .../call-generic-method-chain.stderr | 41 +----- .../call-generic-method-dup-bound.stderr | 55 +------ .../call-generic-method-nonconst.rs | 3 +- .../call-generic-method-nonconst.stderr | 6 +- .../call-generic-method-pass.stderr | 41 +----- .../const-and-non-const-impl.stderr | 20 ++- .../const-bound-on-not-const-associated-fn.rs | 3 +- ...st-bound-on-not-const-associated-fn.stderr | 8 +- .../const-closure-trait-method-fail.stderr | 14 +- .../const-closure-trait-method.stderr | 14 +- .../const-default-method-bodies.stderr | 14 +- .../const-drop-fail-2.stderr | 26 +++- .../const-drop-fail.precise.stderr | 15 +- .../const-drop-fail.stock.stderr | 11 +- .../const-drop.precise.stderr | 136 ++++++++---------- .../const-drop.stock.stderr | 77 ++++++++-- .../const-fns-are-early-bound.rs | 58 +++++++- .../const-fns-are-early-bound.stderr | 23 ++- .../const-impl-requires-const-trait.stderr | 12 +- .../const_derives/derive-const-gate.rs | 1 + .../const_derives/derive-const-gate.stderr | 12 +- .../derive-const-non-const-type.stderr | 8 +- .../const_derives/derive-const-use.stderr | 111 +++----------- .../derive-const-with-params.stderr | 22 +-- .../cross-crate.gatednc.stderr | 14 +- ...-method-body-is-const-same-trait-ck.stderr | 14 +- .../effects/minicore.stderr | 9 +- ...o-explicit-const-params-cross-crate.stderr | 16 ++- .../effects/no-explicit-const-params.stderr | 16 ++- .../effects/project.rs | 10 +- .../effects/project.stderr | 74 ---------- .../effects/span-bug-issue-121418.rs | 1 - .../effects/span-bug-issue-121418.stderr | 19 +-- .../effects/spec-effectvar-ice.rs | 5 +- .../effects/spec-effectvar-ice.stderr | 37 ++--- .../generic-bound.stderr | 16 ++- .../impl-with-default-fn-fail.rs | 3 +- .../impl-with-default-fn-fail.stderr | 2 +- .../impl-with-default-fn-pass.rs | 4 +- .../rfc-2632-const-trait-impl/issue-100222.rs | 3 +- .../issue-92230-wf-super-trait-env.rs | 1 + .../non-const-op-in-closure-in-const.stderr | 25 +++- .../specializing-constness.rs | 2 + .../specializing-constness.stderr | 14 +- .../super-traits-fail-2.rs | 2 +- .../super-traits-fail-2.yn.stderr | 22 ++- .../super-traits-fail-2.yy.stderr | 22 ++- .../super-traits-fail-3.nn.stderr | 23 +-- .../super-traits-fail-3.ny.stderr | 17 +-- .../super-traits-fail-3.rs | 7 +- .../super-traits-fail-3.yn.stderr | 39 ++--- .../super-traits-fail-3.yy.stderr | 25 +++- .../super-traits-fail.rs | 4 +- .../rfc-2632-const-trait-impl/super-traits.rs | 5 +- .../super-traits.stderr | 24 +++- .../tilde-const-invalid-places.stderr | 11 +- .../trait-default-body-stability.stderr | 109 +------------- .../trait-where-clause-const.rs | 4 +- .../trait-where-clause-const.stderr | 68 +++++---- .../unsatisfied-const-trait-bound.rs | 3 +- .../unsatisfied-const-trait-bound.stderr | 13 +- 73 files changed, 870 insertions(+), 819 deletions(-) create mode 100644 tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-0.stderr create mode 100644 tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-1.unqualified.stderr delete mode 100644 tests/ui/rfcs/rfc-2632-const-trait-impl/effects/project.stderr diff --git a/tests/ui/consts/constifconst-call-in-const-position.stderr b/tests/ui/consts/constifconst-call-in-const-position.stderr index f980b8969de85..9096bd7868272 100644 --- a/tests/ui/consts/constifconst-call-in-const-position.stderr +++ b/tests/ui/consts/constifconst-call-in-const-position.stderr @@ -1,9 +1,21 @@ -error[E0080]: evaluation of `foo::<()>::{constant#0}` failed +error[E0308]: mismatched types --> $DIR/constifconst-call-in-const-position.rs:17:38 | LL | const fn foo() -> [u8; T::a()] { - | ^^^^^^ calling non-const function `<() as Tr>::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` -error: aborting due to 1 previous error +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0080`. +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-0.qualified.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-0.qualified.stderr index 3aec4383eab3a..1af0f481943ab 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-0.qualified.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-0.qualified.stderr @@ -7,16 +7,20 @@ 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: Trait` is not satisfied - --> $DIR/assoc-type-const-bound-usage-0.rs:21:6 +error[E0277]: the trait bound `Trait::{synthetic#0}: Compat` is not satisfied + --> $DIR/assoc-type-const-bound-usage-0.rs:21:5 | LL | ::Assoc::func() - | ^ the trait `Trait` is not implemented for `T` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Compat` is not implemented for `Trait::{synthetic#0}` | -help: consider further restricting this bound +note: required by a bound in `Trait::func` + --> $DIR/assoc-type-const-bound-usage-0.rs:8:1 | -LL | const fn qualified() -> i32 { - | +++++++ +LL | #[const_trait] + | ^^^^^^^^^^^^^^ required by this bound in `Trait::func` +... +LL | fn func() -> i32; + | ---- required by a bound in this associated function error: aborting due to 1 previous error; 1 warning emitted diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-0.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-0.rs index eecd6e6109c1e..4399ae2d1be32 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-0.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-0.rs @@ -1,9 +1,7 @@ -// FIXME(effects): Collapse the revisions into one once we support `::Proj`. -//@ revisions: unqualified qualified -//@[unqualified] check-pass -//@[qualified] known-bug: unknown +//@ known-bug: unknown -#![feature(const_trait_impl, effects)] //[unqualified]~ WARN the feature `effects` is incomplete +#![allow(incomplete_features)] +#![feature(const_trait_impl, effects)] #[const_trait] trait Trait { @@ -11,14 +9,12 @@ trait Trait { fn func() -> i32; } -#[cfg(unqualified)] const fn unqualified() -> i32 { T::Assoc::func() } -#[cfg(qualified)] const fn qualified() -> i32 { - ::Assoc::func() + ::Assoc::func() } fn main() {} diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-0.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-0.stderr new file mode 100644 index 0000000000000..919b5b6cd913d --- /dev/null +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-0.stderr @@ -0,0 +1,33 @@ +error[E0277]: the trait bound `Trait::{synthetic#0}: Compat` is not satisfied + --> $DIR/assoc-type-const-bound-usage-0.rs:13:5 + | +LL | T::Assoc::func() + | ^^^^^^^^ the trait `Compat` is not implemented for `Trait::{synthetic#0}` + | +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 + +error[E0277]: the trait bound `Trait::{synthetic#0}: Compat` is not satisfied + --> $DIR/assoc-type-const-bound-usage-0.rs:17:5 + | +LL | ::Assoc::func() + | ^^^^^^^^^^^^^^^^^^^ the trait `Compat` is not implemented for `Trait::{synthetic#0}` + | +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 + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-1.qualified.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-1.qualified.stderr index 10e467da9521a..f8bab2d4c27fa 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-1.qualified.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-1.qualified.stderr @@ -1,14 +1,33 @@ -error[E0277]: the trait bound `T: Trait` is not satisfied - --> $DIR/assoc-type-const-bound-usage-1.rs:23:43 +error[E0277]: the trait bound `Trait::{synthetic#0}: Compat` is not satisfied + --> $DIR/assoc-type-const-bound-usage-1.rs:16:44 | -LL | fn qualified() -> Type<{ ::Assoc::func() }> { - | ^ the trait `Trait` is not implemented for `T` +LL | fn unqualified() -> Type<{ T::Assoc::func() }> { + | ^^^^^^^^ the trait `Compat` is not implemented for `Trait::{synthetic#0}` | -help: consider further restricting this bound +note: required by a bound in `Trait::func` + --> $DIR/assoc-type-const-bound-usage-1.rs:8:1 | -LL | fn qualified() -> Type<{ ::Assoc::func() }> { - | +++++++ +LL | #[const_trait] + | ^^^^^^^^^^^^^^ required by this bound in `Trait::func` +... +LL | fn func() -> i32; + | ---- required by a bound in this associated function -error: aborting due to 1 previous error +error[E0277]: the trait bound `Trait::{synthetic#0}: Compat` is not satisfied + --> $DIR/assoc-type-const-bound-usage-1.rs:20:42 + | +LL | fn qualified() -> Type<{ ::Assoc::func() }> { + | ^^^^^^^^^^^^^^^^^^^ the trait `Compat` is not implemented for `Trait::{synthetic#0}` + | +note: required by a bound in `Trait::func` + --> $DIR/assoc-type-const-bound-usage-1.rs:8:1 + | +LL | #[const_trait] + | ^^^^^^^^^^^^^^ required by this bound in `Trait::func` +... +LL | fn func() -> i32; + | ---- required by a bound in this associated function + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-1.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-1.rs index 8213dae136959..5394c3f2d070c 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-1.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-1.rs @@ -1,7 +1,6 @@ // FIXME(effects): Collapse the revisions into one once we support `::Proj`. //@ revisions: unqualified qualified -//@[unqualified] check-pass -//@[qualified] known-bug: unknown +//@known-bug: unknown #![feature(const_trait_impl, effects, generic_const_exprs)] #![allow(incomplete_features)] @@ -14,13 +13,11 @@ trait Trait { struct Type; -#[cfg(unqualified)] fn unqualified() -> Type<{ T::Assoc::func() }> { Type } -#[cfg(qualified)] -fn qualified() -> Type<{ ::Assoc::func() }> { +fn qualified() -> Type<{ ::Assoc::func() }> { Type } diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-1.unqualified.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-1.unqualified.stderr new file mode 100644 index 0000000000000..f8bab2d4c27fa --- /dev/null +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-1.unqualified.stderr @@ -0,0 +1,33 @@ +error[E0277]: the trait bound `Trait::{synthetic#0}: Compat` is not satisfied + --> $DIR/assoc-type-const-bound-usage-1.rs:16:44 + | +LL | fn unqualified() -> Type<{ T::Assoc::func() }> { + | ^^^^^^^^ the trait `Compat` is not implemented for `Trait::{synthetic#0}` + | +note: required by a bound in `Trait::func` + --> $DIR/assoc-type-const-bound-usage-1.rs:8:1 + | +LL | #[const_trait] + | ^^^^^^^^^^^^^^ required by this bound in `Trait::func` +... +LL | fn func() -> i32; + | ---- required by a bound in this associated function + +error[E0277]: the trait bound `Trait::{synthetic#0}: Compat` is not satisfied + --> $DIR/assoc-type-const-bound-usage-1.rs:20:42 + | +LL | fn qualified() -> Type<{ ::Assoc::func() }> { + | ^^^^^^^^^^^^^^^^^^^ the trait `Compat` is not implemented for `Trait::{synthetic#0}` + | +note: required by a bound in `Trait::func` + --> $DIR/assoc-type-const-bound-usage-1.rs:8:1 + | +LL | #[const_trait] + | ^^^^^^^^^^^^^^ required by this bound in `Trait::func` +... +LL | fn func() -> i32; + | ---- required by a bound in this associated function + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type.rs index 645fff4e01471..b542ec4e5d0ae 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type.rs @@ -32,12 +32,13 @@ trait Foo { } impl const Foo for NonConstAdd { - type Bar = NonConstAdd; //~ ERROR the trait bound `NonConstAdd: ~const Add` is not satisfied + type Bar = NonConstAdd; // FIXME(effects) ERROR the trait bound `NonConstAdd: ~const Add` is not satisfied } #[const_trait] trait Baz { type Qux: Add; + //~^ ERROR the trait bound } impl const Baz for NonConstAdd { diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type.stderr index cc3abea25eb56..333215adef217 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type.stderr @@ -7,18 +7,16 @@ 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 `NonConstAdd: ~const Add` is not satisfied - --> $DIR/assoc-type.rs:35:16 +error[E0277]: the trait bound `Add::{synthetic#0}: Compat` is not satisfied + --> $DIR/assoc-type.rs:40:15 | -LL | type Bar = NonConstAdd; - | ^^^^^^^^^^^ the trait `~const Add` is not implemented for `NonConstAdd` +LL | type Qux: Add; + | ^^^ the trait `Compat` is not implemented for `Add::{synthetic#0}` | - = help: the trait `Add` is implemented for `NonConstAdd` -note: required by a bound in `Foo::Bar` - --> $DIR/assoc-type.rs:31:15 +help: consider further restricting the associated type | -LL | type Bar: ~const Add; - | ^^^^^^^^^^ required by this bound in `Foo::Bar` +LL | trait Baz where Add::{synthetic#0}: Compat { + | ++++++++++++++++++++++++++++++++ error: aborting due to 1 previous error; 1 warning emitted diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-const-trait-method-fail.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-const-trait-method-fail.stderr index 0e4dcf0f3026a..336ee01dc8d73 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-const-trait-method-fail.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-const-trait-method-fail.stderr @@ -7,13 +7,21 @@ 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 `u32: ~const Plus` is not satisfied +error[E0277]: the trait bound `Runtime: ~const Compat` is not satisfied --> $DIR/call-const-trait-method-fail.rs:25:5 | LL | a.plus(b) - | ^ the trait `~const Plus` is not implemented for `u32` + | ^ the trait `~const Compat` is not implemented for `Runtime` | - = help: the trait `Plus` is implemented for `u32` + = help: the trait `Compat` is implemented for `Runtime` +note: required by a bound in `Plus::plus` + --> $DIR/call-const-trait-method-fail.rs:3: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 error: aborting due to 1 previous error; 1 warning emitted diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-const-trait-method-pass.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-const-trait-method-pass.stderr index 22e8e692752cc..bf455a714a343 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-const-trait-method-pass.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-const-trait-method-pass.stderr @@ -1,20 +1,66 @@ +error: const `impl` for trait `Add` which is not marked with `#[const_trait]` + --> $DIR/call-const-trait-method-pass.rs:7:12 + | +LL | impl const std::ops::Add 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: const `impl` for trait `PartialEq` which is not marked with `#[const_trait]` + --> $DIR/call-const-trait-method-pass.rs:15:12 + | +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 | LL | const ADD_INT: Int = Int(1i32) + Int(2i32); | ^^^^^^^^^^^^^^^^^^^^^ | -note: impl defined here, but it is not `const` - --> $DIR/call-const-trait-method-pass.rs:7:1 - | -LL | impl const std::ops::Add for Int { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = note: calls in constants are limited to constant functions, tuple structs and tuple variants help: add `#![feature(effects)]` to the crate attributes to enable | LL + #![feature(effects)] | +error[E0015]: cannot call non-const fn `::plus` in constant functions + --> $DIR/call-const-trait-method-pass.rs:11:20 + | +LL | Int(self.0.plus(rhs.0)) + | ^^^^^^^^^^^ + | + = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants +help: add `#![feature(effects)]` to the crate attributes to enable + | +LL + #![feature(effects)] + | + +error[E0015]: cannot call non-const fn `::eq` in constant functions + --> $DIR/call-const-trait-method-pass.rs:20:15 + | +LL | !self.eq(other) + | ^^^^^^^^^ + | + = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants +help: add `#![feature(effects)]` to the crate attributes to enable + | +LL + #![feature(effects)] + | + error[E0015]: cannot call non-const fn `::plus` in constant functions --> $DIR/call-const-trait-method-pass.rs:36:7 | @@ -27,6 +73,7 @@ help: add `#![feature(effects)]` to the crate attributes to enable LL + #![feature(effects)] | -error: aborting due to 2 previous errors +error: aborting due to 7 previous errors -For more information about this error, try `rustc --explain E0015`. +Some errors have detailed explanations: E0015, E0049. +For more information about an error, try `rustc --explain E0015`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-in-impl.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-in-impl.stderr index 12027c4d71362..5cd274c6c5a22 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-in-impl.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-in-impl.stderr @@ -4,5 +4,28 @@ error: `~const` can only be applied to `#[const_trait]` traits LL | impl const MyPartialEq for T { | ^^^^^^^^^ -error: aborting due to 1 previous error +error[E0049]: method `eq` has 1 const parameter but its trait declaration has 0 const parameters + --> $DIR/call-generic-in-impl.rs:5:1 + | +LL | #[const_trait] + | ^^^^^^^^^^^^^^ found 1 const parameter +LL | trait MyPartialEq { +LL | fn eq(&self, other: &Self) -> bool; + | - expected 0 const parameters + +error[E0015]: cannot call non-const fn `::eq` in constant functions + --> $DIR/call-generic-in-impl.rs:12:9 + | +LL | PartialEq::eq(self, other) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants +help: add `#![feature(effects)]` to the crate attributes to enable + | +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`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-chain.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-chain.stderr index 36c7a6544305b..2e1feccd0f358 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-chain.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-chain.stderr @@ -16,15 +16,6 @@ LL | impl const PartialEq for S { = 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[E0207]: the const parameter `host` is not constrained by the impl trait, self type, or predicates - --> $DIR/call-generic-method-chain.rs:10:6 - | -LL | impl const PartialEq for S { - | ^^^^^ unconstrained const parameter - | - = note: expressions using a const parameter must map each value to a distinct output value - = note: proving the result of expressions other than the parameter are unique is not supported - error: `~const` can only be applied to `#[const_trait]` traits --> $DIR/call-generic-method-chain.rs:19:32 | @@ -37,35 +28,5 @@ error: `~const` can only be applied to `#[const_trait]` traits LL | const fn equals_self_wrapper(t: &T) -> bool { | ^^^^^^^^^ -error[E0284]: type annotations needed - --> $DIR/call-generic-method-chain.rs:27:22 - | -LL | pub const EQ: bool = equals_self_wrapper(&S); - | ^^^^^^^^^^^^^^^^^^^^^^^ cannot infer the value of the constant `_` - | -note: required for `S` to implement `PartialEq` - --> $DIR/call-generic-method-chain.rs:10:12 - | -LL | impl const PartialEq for S { - | ----- ^^^^^^^^^ ^ - | | - | unsatisfied trait bound introduced here - -error[E0284]: type annotations needed - --> $DIR/call-generic-method-chain.rs:15:10 - | -LL | !self.eq(other) - | ^^^^^^^^^^^^^^ cannot infer the value of the constant `_` - | -note: required for `S` to implement `PartialEq` - --> $DIR/call-generic-method-chain.rs:10:12 - | -LL | impl const PartialEq for S { - | ----- ^^^^^^^^^ ^ - | | - | unsatisfied trait bound introduced here - -error: aborting due to 6 previous errors; 1 warning emitted +error: aborting due to 3 previous errors; 1 warning emitted -Some errors have detailed explanations: E0207, E0284. -For more information about an error, try `rustc --explain E0207`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-dup-bound.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-dup-bound.stderr index 320e420b80a30..d3b009636865a 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-dup-bound.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-dup-bound.stderr @@ -16,15 +16,6 @@ LL | impl const PartialEq for S { = 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[E0207]: the const parameter `host` is not constrained by the impl trait, self type, or predicates - --> $DIR/call-generic-method-dup-bound.rs:8:6 - | -LL | impl const PartialEq for S { - | ^^^^^ unconstrained const parameter - | - = note: expressions using a const parameter must map each value to a distinct output value - = note: proving the result of expressions other than the parameter are unique is not supported - error: `~const` can only be applied to `#[const_trait]` traits --> $DIR/call-generic-method-dup-bound.rs:19:44 | @@ -37,49 +28,5 @@ error: `~const` can only be applied to `#[const_trait]` traits LL | const fn equals_self2(t: &T) -> bool { | ^^^^^^^^^ -error[E0284]: type annotations needed - --> $DIR/call-generic-method-dup-bound.rs:30:22 - | -LL | pub const EQ: bool = equals_self(&S) && equals_self2(&S); - | ^^^^^^^^^^^^^^^ cannot infer the value of the constant `_` - | -note: required for `S` to implement `PartialEq` - --> $DIR/call-generic-method-dup-bound.rs:8:12 - | -LL | impl const PartialEq for S { - | ----- ^^^^^^^^^ ^ - | | - | unsatisfied trait bound introduced here - -error[E0284]: type annotations needed - --> $DIR/call-generic-method-dup-bound.rs:30:41 - | -LL | pub const EQ: bool = equals_self(&S) && equals_self2(&S); - | ^^^^^^^^^^^^^^^^ cannot infer the value of the constant `_` - | -note: required for `S` to implement `PartialEq` - --> $DIR/call-generic-method-dup-bound.rs:8:12 - | -LL | impl const PartialEq for S { - | ----- ^^^^^^^^^ ^ - | | - | unsatisfied trait bound introduced here - -error[E0284]: type annotations needed - --> $DIR/call-generic-method-dup-bound.rs:13:10 - | -LL | !self.eq(other) - | ^^^^^^^^^^^^^^ cannot infer the value of the constant `_` - | -note: required for `S` to implement `PartialEq` - --> $DIR/call-generic-method-dup-bound.rs:8:12 - | -LL | impl const PartialEq for S { - | ----- ^^^^^^^^^ ^ - | | - | unsatisfied trait bound introduced here - -error: aborting due to 7 previous errors; 1 warning emitted +error: aborting due to 3 previous errors; 1 warning emitted -Some errors have detailed explanations: E0207, E0284. -For more information about an error, try `rustc --explain E0207`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-nonconst.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-nonconst.rs index 222bff2db8807..74e33ca72fffc 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-nonconst.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-nonconst.rs @@ -21,6 +21,7 @@ const fn equals_self(t: &T) -> bool { // it not using the impl. pub const EQ: bool = equals_self(&S); -//~^ ERROR: the trait bound `S: const Foo` is not satisfied +//~^ ERROR: the trait bound `Runtime: const Compat` is not satisfied +// FIXME(effects) diagnostic fn main() {} diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-nonconst.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-nonconst.stderr index fa59e5ee03dd0..d48ee9c95f593 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-nonconst.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-nonconst.stderr @@ -7,15 +7,15 @@ 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 `S: const Foo` is not satisfied +error[E0277]: the trait bound `Runtime: const Compat` is not satisfied --> $DIR/call-generic-method-nonconst.rs:23:34 | LL | pub const EQ: bool = equals_self(&S); - | ----------- ^^ the trait `const Foo` is not implemented for `S` + | ----------- ^^ the trait `const Compat` is not implemented for `Runtime` | | | required by a bound introduced by this call | - = help: the trait `Foo` is implemented for `S` + = help: the trait `Compat` is implemented for `Runtime` note: required by a bound in `equals_self` --> $DIR/call-generic-method-nonconst.rs:16:25 | diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-pass.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-pass.stderr index 6b9d290839e5f..cab8d6d761195 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-pass.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-pass.stderr @@ -16,50 +16,11 @@ LL | impl const PartialEq for S { = 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[E0207]: the const parameter `host` is not constrained by the impl trait, self type, or predicates - --> $DIR/call-generic-method-pass.rs:10:6 - | -LL | impl const PartialEq for S { - | ^^^^^ unconstrained const parameter - | - = note: expressions using a const parameter must map each value to a distinct output value - = note: proving the result of expressions other than the parameter are unique is not supported - 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 { | ^^^^^^^^^ -error[E0284]: type annotations needed - --> $DIR/call-generic-method-pass.rs:23:22 - | -LL | pub const EQ: bool = equals_self(&S); - | ^^^^^^^^^^^^^^^ cannot infer the value of the constant `_` - | -note: required for `S` to implement `PartialEq` - --> $DIR/call-generic-method-pass.rs:10:12 - | -LL | impl const PartialEq for S { - | ----- ^^^^^^^^^ ^ - | | - | unsatisfied trait bound introduced here - -error[E0284]: type annotations needed - --> $DIR/call-generic-method-pass.rs:15:10 - | -LL | !self.eq(other) - | ^^^^^^^^^^^^^^ cannot infer the value of the constant `_` - | -note: required for `S` to implement `PartialEq` - --> $DIR/call-generic-method-pass.rs:10:12 - | -LL | impl const PartialEq for S { - | ----- ^^^^^^^^^ ^ - | | - | unsatisfied trait bound introduced here - -error: aborting due to 5 previous errors; 1 warning emitted +error: aborting due to 2 previous errors; 1 warning emitted -Some errors have detailed explanations: E0207, E0284. -For more information about an error, try `rustc --explain E0207`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-and-non-const-impl.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-and-non-const-impl.stderr index 8916450df2d4b..9c1c8df8da459 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-and-non-const-impl.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-and-non-const-impl.stderr @@ -1,3 +1,21 @@ +error: const `impl` for trait `Add` which is not marked with `#[const_trait]` + --> $DIR/const-and-non-const-impl.rs:7:12 + | +LL | impl const std::ops::Add for i32 { + | ^^^^^^^^^^^^^ + | + = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` + = note: adding a non-const method body in the future would be a breaking change + +error: const `impl` for trait `Add` which is not marked with `#[const_trait]` + --> $DIR/const-and-non-const-impl.rs:23:12 + | +LL | impl const std::ops::Add 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[E0119]: conflicting implementations of trait `Add` for type `Int` --> $DIR/const-and-non-const-impl.rs:23:1 | @@ -19,7 +37,7 @@ LL | impl const std::ops::Add for i32 { | = note: define and implement a trait or new type instead -error: aborting due to 2 previous errors +error: aborting due to 4 previous errors Some errors have detailed explanations: E0117, E0119. For more information about an error, try `rustc --explain E0117`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-bound-on-not-const-associated-fn.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-bound-on-not-const-associated-fn.rs index 0025449c4921f..099cf0b00d3f7 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-bound-on-not-const-associated-fn.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-bound-on-not-const-associated-fn.rs @@ -1,4 +1,5 @@ -#![feature(const_trait_impl)] +#![allow(incomplete_features)] +#![feature(const_trait_impl, effects)] #[const_trait] trait MyTrait { diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-bound-on-not-const-associated-fn.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-bound-on-not-const-associated-fn.stderr index db48c170d1c02..42964b9774e29 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-bound-on-not-const-associated-fn.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-bound-on-not-const-associated-fn.stderr @@ -1,23 +1,23 @@ error: `~const` is not allowed here - --> $DIR/const-bound-on-not-const-associated-fn.rs:9:40 + --> $DIR/const-bound-on-not-const-associated-fn.rs:10: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:9:8 + --> $DIR/const-bound-on-not-const-associated-fn.rs:10: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:20:32 + --> $DIR/const-bound-on-not-const-associated-fn.rs:21: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:20:12 + --> $DIR/const-bound-on-not-const-associated-fn.rs:21:12 | LL | pub fn foo(&self) where T: ~const MyTrait { | ^^^ diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-closure-trait-method-fail.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-closure-trait-method-fail.stderr index fb2e66db1d488..507ceaae2eab3 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-closure-trait-method-fail.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-closure-trait-method-fail.stderr @@ -1,3 +1,12 @@ +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 | @@ -20,6 +29,7 @@ help: add `#![feature(effects)]` to the crate attributes to enable LL + #![feature(effects)] | -error: aborting due to 2 previous errors +error: aborting due to 3 previous errors -For more information about this error, try `rustc --explain E0015`. +Some errors have detailed explanations: E0015, E0049. +For more information about an error, try `rustc --explain E0015`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-closure-trait-method.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-closure-trait-method.stderr index dede411e69c73..2a54cd5d7f6e5 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-closure-trait-method.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-closure-trait-method.stderr @@ -1,3 +1,12 @@ +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 | @@ -20,6 +29,7 @@ help: add `#![feature(effects)]` to the crate attributes to enable LL + #![feature(effects)] | -error: aborting due to 2 previous errors +error: aborting due to 3 previous errors -For more information about this error, try `rustc --explain E0015`. +Some errors have detailed explanations: E0015, E0049. +For more information about an error, try `rustc --explain E0015`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-default-method-bodies.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-default-method-bodies.stderr index 8e04d0bd20da0..32bc0093347c0 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-default-method-bodies.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-default-method-bodies.stderr @@ -7,13 +7,21 @@ 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 `NonConstImpl: ~const ConstDefaultFn` is not satisfied +error[E0277]: the trait bound `Runtime: ~const Compat` is not satisfied --> $DIR/const-default-method-bodies.rs:24:18 | LL | NonConstImpl.a(); - | ^ the trait `~const ConstDefaultFn` is not implemented for `NonConstImpl` + | ^ the trait `~const Compat` is not implemented for `Runtime` | - = help: the trait `ConstDefaultFn` is implemented for `NonConstImpl` + = help: the trait `Compat` is implemented for `Runtime` +note: required by a bound in `ConstDefaultFn::a` + --> $DIR/const-default-method-bodies.rs:3:1 + | +LL | #[const_trait] + | ^^^^^^^^^^^^^^ required by this bound in `ConstDefaultFn::a` +... +LL | fn a(self) { + | - required by a bound in this associated function error: aborting due to 1 previous error; 1 warning emitted diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-fail-2.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-fail-2.stderr index 085d9e710125a..1d56d015dfc15 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-fail-2.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-fail-2.stderr @@ -1,3 +1,12 @@ +error: const `impl` for trait `Drop` which is not marked with `#[const_trait]` + --> $DIR/const-drop-fail-2.rs:40:25 + | +LL | impl const Drop for ConstDropImplWithNonConstBounds { + | ^^^^ + | + = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` + = note: adding a non-const method body in the future would be a breaking change + error: `~const` can only be applied to `#[const_trait]` traits --> $DIR/const-drop-fail-2.rs:21:26 | @@ -12,6 +21,19 @@ LL | const fn check(_: T) {} | | | the destructor for this type cannot be evaluated in constant functions -error: aborting due to 2 previous errors +error[E0015]: cannot call non-const fn `::a` in constant functions + --> $DIR/const-drop-fail-2.rs:42:9 + | +LL | T::a(); + | ^^^^^^ + | + = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants +help: add `#![feature(effects)]` to the crate attributes to enable + | +LL + #![feature(effects)] + | + +error: aborting due to 4 previous errors -For more information about this error, try `rustc --explain E0493`. +Some errors have detailed explanations: E0015, E0493. +For more information about an error, try `rustc --explain E0015`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-fail.precise.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-fail.precise.stderr index e95215d471566..b251d84a9670e 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-fail.precise.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-fail.precise.stderr @@ -1,3 +1,12 @@ +error: const `impl` for trait `Drop` which is not marked with `#[const_trait]` + --> $DIR/const-drop-fail.rs:20:12 + | +LL | impl const Drop for ConstImplWithDropGlue { + | ^^^^ + | + = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` + = note: adding a non-const method body in the future would be a breaking change + error: `~const` can only be applied to `#[const_trait]` traits --> $DIR/const-drop-fail.rs:24:26 | @@ -38,8 +47,10 @@ LL | | } error[E0080]: evaluation of constant value failed --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL | - = note: calling non-const function `::drop` + = note: calling non-const function `::drop` | +note: inside `std::ptr::drop_in_place:: - shim(Some(NonTrivialDrop))` + --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL note: inside `std::ptr::drop_in_place:: - shim(Some(ConstImplWithDropGlue))` --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL note: inside `check::` @@ -60,7 +71,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 4 previous errors +error: aborting due to 5 previous errors Some errors have detailed explanations: E0080, E0493. For more information about an error, try `rustc --explain E0080`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-fail.stock.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-fail.stock.stderr index f9bd9953fcfd3..912700f2a8345 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-fail.stock.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-fail.stock.stderr @@ -1,3 +1,12 @@ +error: const `impl` for trait `Drop` which is not marked with `#[const_trait]` + --> $DIR/const-drop-fail.rs:20:12 + | +LL | impl const Drop for ConstImplWithDropGlue { + | ^^^^ + | + = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` + = note: adding a non-const method body in the future would be a breaking change + error: `~const` can only be applied to `#[const_trait]` traits --> $DIR/const-drop-fail.rs:24:26 | @@ -12,6 +21,6 @@ LL | const fn check(_: 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/rfcs/rfc-2632-const-trait-impl/const-drop.precise.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop.precise.stderr index 6aace10589605..9d1ca5dbf2c03 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop.precise.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop.precise.stderr @@ -1,32 +1,64 @@ +error: const `impl` for trait `Drop` which is not marked with `#[const_trait]` + --> $DIR/const-drop.rs:13:16 + | +LL | impl<'a> const Drop for S<'a> { + | ^^^^ + | + = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` + = note: adding a non-const method body in the future would be a breaking change + +error: const `impl` for trait `Drop` which is not marked with `#[const_trait]` + --> $DIR/const-drop.rs:47:16 + | +LL | impl const Drop for ConstDrop { + | ^^^^ + | + = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` + = note: adding a non-const method body in the future would be a breaking change + +error: const `impl` for trait `Drop` which is not marked with `#[const_trait]` + --> $DIR/const-drop.rs:68:37 + | +LL | impl const Drop for ConstDropWithBound { + | ^^^^ + | + = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` + = note: adding a non-const method body in the future would be a breaking change + +error: const `impl` for trait `Drop` which is not marked with `#[const_trait]` + --> $DIR/const-drop.rs:76:30 + | +LL | impl const Drop for ConstDropWithNonconstBound { + | ^^^^ + | + = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` + = note: adding a non-const method body in the future would be a breaking change + error: `~const` can only be applied to `#[const_trait]` traits --> $DIR/const-drop.rs:19:22 | LL | const fn a(_: T) {} | ^^^^^^^^ -error[E0493]: destructor of `S<'_>` cannot be evaluated at compile-time - --> $DIR/const-drop.rs:24:13 +error[E0049]: method `foo` has 1 const parameter but its trait declaration has 0 const parameters + --> $DIR/const-drop.rs:54:5 | -LL | let _ = S(&mut c); - | ^^^^^^^^^ the destructor for this type cannot be evaluated in constant functions +LL | #[const_trait] + | ^^^^^^^^^^^^^^ found 1 const parameter +LL | pub trait SomeTrait { +LL | fn foo(); + | - expected 0 const parameters -error[E0080]: evaluation of constant value failed - --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL - | - = note: calling non-const function ` as Drop>::drop` +error[E0049]: method `foo` has 1 const parameter but its trait declaration has 0 const parameters + --> $DIR/const-drop.rs:54:5 | -note: inside `std::ptr::drop_in_place::> - shim(Some(S<'_>))` - --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL -note: inside `b` - --> $DIR/const-drop.rs:24:22 +LL | #[const_trait] + | ^^^^^^^^^^^^^^ found 1 const parameter +LL | pub trait SomeTrait { +LL | fn foo(); + | - expected 0 const parameters | -LL | let _ = S(&mut c); - | ^ -note: inside `C` - --> $DIR/const-drop.rs:30:15 - | -LL | const C: u8 = b(); - | ^^^ + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error[E0493]: destructor of `T` cannot be evaluated at compile-time --> $DIR/const-drop.rs:19:32 @@ -34,65 +66,19 @@ error[E0493]: destructor of `T` cannot be evaluated at compile-time LL | const fn a(_: T) {} | ^ the destructor for this type cannot be evaluated in constant functions -error[E0080]: evaluation of constant value failed - --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL +error[E0015]: cannot call non-const fn `::foo` in constant functions + --> $DIR/const-drop.rs:70:13 | - = note: calling non-const function `::drop` +LL | T::foo(); + | ^^^^^^^^ | -note: inside `std::ptr::drop_in_place:: - shim(Some(t::ConstDrop))` - --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL -note: inside `a::` - --> $DIR/const-drop.rs:19:39 + = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants +help: add `#![feature(effects)]` to the crate attributes to enable | -LL | const fn a(_: T) {} - | ^ -note: inside `_` - --> $DIR/const-drop.rs:35:27 - | -LL | const _: () = a($exp); - | ^^^^^^^ -... -LL | / implements_const_drop! { -LL | | 1u8, -LL | | 2, -LL | | 3.0, -... | -LL | | Result::::Ok(1), -LL | | } - | |_- in this macro invocation - = note: this error originates in the macro `implements_const_drop` (in Nightly builds, run with -Z macro-backtrace for more info) - -error[E0080]: evaluation of constant value failed - --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL - | - = note: calling non-const function `::drop` +LL + #![feature(effects)] | -note: inside `std::ptr::drop_in_place:: - shim(Some(t::ConstDrop))` - --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL -note: inside `std::ptr::drop_in_place:: - shim(Some(t::HasConstDrop))` - --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL -note: inside `a::` - --> $DIR/const-drop.rs:19:39 - | -LL | const fn a(_: T) {} - | ^ -note: inside `_` - --> $DIR/const-drop.rs:35:27 - | -LL | const _: () = a($exp); - | ^^^^^^^ -... -LL | / implements_const_drop! { -LL | | 1u8, -LL | | 2, -LL | | 3.0, -... | -LL | | Result::::Ok(1), -LL | | } - | |_- in this macro invocation - = note: this error originates in the macro `implements_const_drop` (in Nightly builds, run with -Z macro-backtrace for more info) -error: aborting due to 6 previous errors +error: aborting due to 9 previous errors -Some errors have detailed explanations: E0080, E0493. -For more information about an error, try `rustc --explain E0080`. +Some errors have detailed explanations: E0015, E0049, E0493. +For more information about an error, try `rustc --explain E0015`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop.stock.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop.stock.stderr index 18dd4543c3d39..2f93f9a6743b8 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop.stock.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop.stock.stderr @@ -1,16 +1,64 @@ +error: const `impl` for trait `Drop` which is not marked with `#[const_trait]` + --> $DIR/const-drop.rs:13:16 + | +LL | impl<'a> const Drop for S<'a> { + | ^^^^ + | + = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` + = note: adding a non-const method body in the future would be a breaking change + +error: const `impl` for trait `Drop` which is not marked with `#[const_trait]` + --> $DIR/const-drop.rs:47:16 + | +LL | impl const Drop for ConstDrop { + | ^^^^ + | + = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` + = note: adding a non-const method body in the future would be a breaking change + +error: const `impl` for trait `Drop` which is not marked with `#[const_trait]` + --> $DIR/const-drop.rs:68:37 + | +LL | impl const Drop for ConstDropWithBound { + | ^^^^ + | + = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` + = note: adding a non-const method body in the future would be a breaking change + +error: const `impl` for trait `Drop` which is not marked with `#[const_trait]` + --> $DIR/const-drop.rs:76:30 + | +LL | impl const Drop for ConstDropWithNonconstBound { + | ^^^^ + | + = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` + = note: adding a non-const method body in the future would be a breaking change + error: `~const` can only be applied to `#[const_trait]` traits --> $DIR/const-drop.rs:19:22 | LL | const fn a(_: T) {} | ^^^^^^^^ -error[E0493]: destructor of `S<'_>` cannot be evaluated at compile-time - --> $DIR/const-drop.rs:24:13 +error[E0049]: method `foo` has 1 const parameter but its trait declaration has 0 const parameters + --> $DIR/const-drop.rs:54:5 + | +LL | #[const_trait] + | ^^^^^^^^^^^^^^ found 1 const parameter +LL | pub trait SomeTrait { +LL | fn foo(); + | - expected 0 const parameters + +error[E0049]: method `foo` has 1 const parameter but its trait declaration has 0 const parameters + --> $DIR/const-drop.rs:54:5 + | +LL | #[const_trait] + | ^^^^^^^^^^^^^^ found 1 const parameter +LL | pub trait SomeTrait { +LL | fn foo(); + | - expected 0 const parameters | -LL | let _ = S(&mut c); - | ^^^^^^^^^- value is dropped here - | | - | the destructor for this type cannot be evaluated in constant functions + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error[E0493]: destructor of `T` cannot be evaluated at compile-time --> $DIR/const-drop.rs:19:32 @@ -20,6 +68,19 @@ LL | const fn a(_: T) {} | | | the destructor for this type cannot be evaluated in constant functions -error: aborting due to 3 previous errors +error[E0015]: cannot call non-const fn `::foo` in constant functions + --> $DIR/const-drop.rs:70:13 + | +LL | T::foo(); + | ^^^^^^^^ + | + = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants +help: add `#![feature(effects)]` to the crate attributes to enable + | +LL + #![feature(effects)] + | + +error: aborting due to 9 previous errors -For more information about this error, try `rustc --explain E0493`. +Some errors have detailed explanations: E0015, E0049, E0493. +For more information about an error, try `rustc --explain E0015`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-fns-are-early-bound.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-fns-are-early-bound.rs index faa913c759884..fdc53dbab1cbc 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-fns-are-early-bound.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-fns-are-early-bound.rs @@ -1,17 +1,21 @@ -//@ check-pass +//@ known-bug: #110395 +// FIXME(effects) check-pass +//@ compile-flags: -Znext-solver #![crate_type = "lib"] -#![allow(internal_features)] +#![allow(internal_features, incomplete_features)] #![no_std] #![no_core] #![feature( auto_traits, const_trait_impl, - effects, //~ WARN the feature `effects` is incomplete + effects, lang_items, no_core, staged_api, - unboxed_closures + unboxed_closures, + rustc_attrs, + marker_trait_attr, )] #![stable(feature = "minicore", since = "1.0.0")] @@ -84,3 +88,49 @@ trait Receiver {} impl Receiver for &T {} impl Receiver 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 = "EffectsMin"] + #[stable(feature = "minicore", since = "1.0.0")] + pub trait Min { + #[lang = "EffectsMinOutput"] + #[stable(feature = "minicore", since = "1.0.0")] + type Output: ?Sized; + } +} diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-fns-are-early-bound.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-fns-are-early-bound.stderr index 42b19fce28e9c..7aa3aa8c6bbb3 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-fns-are-early-bound.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-fns-are-early-bound.stderr @@ -1,11 +1,20 @@ -warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/const-fns-are-early-bound.rs:10:5 +error[E0277]: the trait bound `FnOnce<()>::{synthetic#0}: const Compat` is not satisfied + --> $DIR/const-fns-are-early-bound.rs:31:17 | -LL | effects, - | ^^^^^^^ +LL | is_const_fn(foo); + | ----------- ^^^ the trait `const Compat` is not implemented for `FnOnce<()>::{synthetic#0}` + | | + | required by a bound introduced by this call | - = note: see issue #102090 for more information - = note: `#[warn(incomplete_features)]` on by default +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` -warning: 1 warning emitted +error: aborting due to 1 previous error +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-impl-requires-const-trait.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-impl-requires-const-trait.stderr index fb282d9ee2b47..7925cf53f42c4 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-impl-requires-const-trait.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-impl-requires-const-trait.stderr @@ -19,15 +19,5 @@ 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[E0207]: the const parameter `host` is not constrained by the impl trait, self type, or predicates - --> $DIR/const-impl-requires-const-trait.rs:8:6 - | -LL | impl const A for () {} - | ^^^^^ unconstrained const parameter - | - = note: expressions using a const parameter must map each value to a distinct output value - = note: proving the result of expressions other than the parameter are unique is not supported - -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 E0207`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-gate.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-gate.rs index 348ca0ab1906b..a772d69c9e2e2 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-gate.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-gate.rs @@ -1,4 +1,5 @@ #[derive_const(Default)] //~ ERROR use of unstable library feature +//~^ ERROR const `impl` for trait `Default` which is not marked with `#[const_trait]` pub struct S; fn main() {} diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-gate.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-gate.stderr index 9ec2ac9338175..3ccae5a83e665 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-gate.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-gate.stderr @@ -7,6 +7,16 @@ LL | #[derive_const(Default)] = help: add `#![feature(derive_const)]` 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: aborting due to 1 previous error +error: const `impl` for trait `Default` which is not marked with `#[const_trait]` + --> $DIR/derive-const-gate.rs:1:16 + | +LL | #[derive_const(Default)] + | ^^^^^^^ + | + = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` + = note: adding a non-const method body in the future would be a breaking change + = note: this error originates in the derive macro `Default` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-non-const-type.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-non-const-type.stderr index 1e091283510d6..78e5b70d41c38 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-non-const-type.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-non-const-type.stderr @@ -17,11 +17,5 @@ LL | #[derive_const(Default)] = note: adding a non-const method body in the future would be a breaking change = note: this error originates in the derive macro `Default` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0207]: the const parameter `host` is not constrained by the impl trait, self type, or predicates - | - = note: expressions using a const parameter must map each value to a distinct output value - = note: proving the result of expressions other than the parameter are unique is not supported - -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 E0207`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-use.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-use.stderr index 925b2c58ed77b..da6b77f623cc1 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-use.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-use.stderr @@ -28,33 +28,6 @@ LL | impl const Default for A { = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` = note: adding a non-const method body in the future would be a breaking change -error[E0207]: the const parameter `host` is not constrained by the impl trait, self type, or predicates - --> $DIR/derive-const-use.rs:7:6 - | -LL | impl const Default for A { - | ^^^^^ unconstrained const parameter - | - = note: expressions using a const parameter must map each value to a distinct output value - = note: proving the result of expressions other than the parameter are unique is not supported - -error: const `impl` for trait `PartialEq` which is not marked with `#[const_trait]` - --> $DIR/derive-const-use.rs:11:12 - | -LL | impl const PartialEq for A { - | ^^^^^^^^^ - | - = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` - = note: adding a non-const method body in the future would be a breaking change - -error[E0207]: the const parameter `host` is not constrained by the impl trait, self type, or predicates - --> $DIR/derive-const-use.rs:11:6 - | -LL | impl const PartialEq for A { - | ^^^^^ unconstrained const parameter - | - = note: expressions using a const parameter must map each value to a distinct output value - = note: proving the result of expressions other than the parameter are unique is not supported - error: const `impl` for trait `Default` which is not marked with `#[const_trait]` --> $DIR/derive-const-use.rs:15:16 | @@ -65,10 +38,14 @@ LL | #[derive_const(Default, PartialEq)] = note: adding a non-const method body in the future would be a breaking change = note: this error originates in the derive macro `Default` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0207]: the const parameter `host` is not constrained by the impl trait, self type, or predicates +error: const `impl` for trait `PartialEq` which is not marked with `#[const_trait]` + --> $DIR/derive-const-use.rs:11:12 + | +LL | impl const PartialEq for A { + | ^^^^^^^^^ | - = note: expressions using a const parameter must map each value to a distinct output value - = note: proving the result of expressions other than the parameter are unique is not supported + = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` + = note: adding a non-const method body in the future would be a breaking change error: const `impl` for trait `PartialEq` which is not marked with `#[const_trait]` --> $DIR/derive-const-use.rs:15:25 @@ -80,73 +57,29 @@ LL | #[derive_const(Default, PartialEq)] = note: adding a non-const method body in the future would be a breaking change = note: this error originates in the derive macro `PartialEq` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0207]: the const parameter `host` is not constrained by the impl trait, self type, or predicates - | - = note: expressions using a const parameter must map each value to a distinct output value - = note: proving the result of expressions other than the parameter are unique is not supported - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error[E0284]: type annotations needed - --> $DIR/derive-const-use.rs:18:35 - | -LL | const _: () = assert!(S((), A) == S::default()); - | ^^^^^^^^^^^^ cannot infer the value of the constant `_` - | -note: required for `S` to implement `Default` - --> $DIR/derive-const-use.rs:15:16 - | -LL | #[derive_const(Default, PartialEq)] - | ^^^^^^^ unsatisfied trait bound introduced in this `derive` macro - = note: this error originates in the derive macro `Default` (in Nightly builds, run with -Z macro-backtrace for more info) - -error[E0284]: type annotations needed - --> $DIR/derive-const-use.rs:18:23 - | -LL | const _: () = assert!(S((), A) == S::default()); - | ^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer the value of the constant `_` - | -note: required for `S` to implement `PartialEq` - --> $DIR/derive-const-use.rs:15:25 - | -LL | #[derive_const(Default, PartialEq)] - | ^^^^^^^^^ unsatisfied trait bound introduced in this `derive` macro - = note: this error originates in the derive macro `PartialEq` (in Nightly builds, run with -Z macro-backtrace for more info) - -error[E0284]: type annotations needed - --> $DIR/derive-const-use.rs:16:18 +error[E0080]: evaluation of constant value failed + --> $DIR/derive-const-use.rs:16:14 | LL | #[derive_const(Default, PartialEq)] | ------- in this derive macro expansion LL | pub struct S((), A); - | ^ cannot infer the value of the constant `_` + | ^^ calling non-const function `<() as Default>::default` | -note: required for `A` to implement `Default` - --> $DIR/derive-const-use.rs:7:12 - | -LL | impl const Default for A { - | ----- ^^^^^^^ ^ - | | - | unsatisfied trait bound introduced here - = note: this error originates in the derive macro `Default` (in Nightly builds, run with -Z macro-backtrace for more info) - -error[E0284]: type annotations needed - --> $DIR/derive-const-use.rs:16:18 +note: inside `::default` + --> $DIR/derive-const-use.rs:16:14 | LL | #[derive_const(Default, PartialEq)] - | --------- in this derive macro expansion + | ------- in this derive macro expansion LL | pub struct S((), A); - | ^ cannot infer the value of the constant `_` - | -note: required for `A` to implement `PartialEq` - --> $DIR/derive-const-use.rs:11:12 + | ^^ +note: inside `_` + --> $DIR/derive-const-use.rs:18:35 | -LL | impl const PartialEq for A { - | ----- ^^^^^^^^^ ^ - | | - | unsatisfied trait bound introduced here - = note: this error originates in the derive macro `PartialEq` (in Nightly builds, run with -Z macro-backtrace for more info) +LL | const _: () = assert!(S((), A) == S::default()); + | ^^^^^^^^^^^^ + = note: this error originates in the derive macro `Default` (in Nightly builds, run with -Z macro-backtrace for more info) -error: aborting due to 14 previous errors; 1 warning emitted +error: aborting due to 7 previous errors; 1 warning emitted -Some errors have detailed explanations: E0207, E0284, E0635. -For more information about an error, try `rustc --explain E0207`. +Some errors have detailed explanations: E0080, E0635. +For more information about an error, try `rustc --explain E0080`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-with-params.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-with-params.stderr index 5d3aa250d1854..102458450fbf7 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-with-params.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-with-params.stderr @@ -25,25 +25,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[E0207]: the const parameter `host` is not constrained by the impl trait, self type, or predicates - | - = note: expressions using a const parameter must map each value to a distinct output value - = note: proving the result of expressions other than the parameter are unique is not supported - -error[E0284]: type annotations needed - --> $DIR/derive-const-with-params.rs:11:5 - | -LL | a == b - | ^^^^^^ cannot infer the value of the constant `_` - | -note: required for `Reverse` to implement `PartialEq` - --> $DIR/derive-const-with-params.rs:7:16 - | -LL | #[derive_const(PartialEq)] - | ^^^^^^^^^ unsatisfied trait bound introduced in this `derive` macro - = 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 2 previous errors; 1 warning emitted -Some errors have detailed explanations: E0207, E0284. -For more information about an error, try `rustc --explain E0207`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/cross-crate.gatednc.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/cross-crate.gatednc.stderr index ddb5b3c7c5078..af042ecff953b 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/cross-crate.gatednc.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/cross-crate.gatednc.stderr @@ -7,13 +7,21 @@ LL | #![cfg_attr(any(gated, gatednc), feature(const_trait_impl, effects))] = note: see issue #102090 for more information = note: `#[warn(incomplete_features)]` on by default -error[E0277]: the trait bound `cross_crate::NonConst: ~const cross_crate::MyTrait` is not satisfied +error[E0277]: the trait bound `Runtime: ~const Compat` is not satisfied --> $DIR/cross-crate.rs:18:14 | LL | NonConst.func(); - | ^^^^ the trait `~const cross_crate::MyTrait` is not implemented for `cross_crate::NonConst` + | ^^^^ the trait `~const Compat` is not implemented for `Runtime` | - = help: the trait `cross_crate::MyTrait` is implemented for `cross_crate::NonConst` + = help: the trait `Compat` is implemented for `Runtime` +note: required by a bound in `func` + --> $DIR/auxiliary/cross-crate.rs:4:1 + | +LL | #[const_trait] + | ^^^^^^^^^^^^^^ required by this bound in `MyTrait::func` +... +LL | fn func(self); + | ---- required by a bound in this associated function error: aborting due to 1 previous error; 1 warning emitted diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/default-method-body-is-const-same-trait-ck.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/default-method-body-is-const-same-trait-ck.stderr index 67a936d0882f4..8b422d62578a0 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/default-method-body-is-const-same-trait-ck.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/default-method-body-is-const-same-trait-ck.stderr @@ -7,13 +7,21 @@ 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 `(): ~const Tr` is not satisfied +error[E0277]: the trait bound `Runtime: ~const Compat` is not satisfied --> $DIR/default-method-body-is-const-same-trait-ck.rs:8:12 | LL | ().a() - | ^ the trait `~const Tr` is not implemented for `()` + | ^ the trait `~const Compat` is not implemented for `Runtime` | - = help: the trait `Tr` is implemented for `()` + = help: the trait `Compat` is implemented for `Runtime` +note: required by a bound in `Tr::a` + --> $DIR/default-method-body-is-const-same-trait-ck.rs:3: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 error: aborting due to 1 previous error; 1 warning emitted diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/minicore.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/minicore.stderr index e4a5f3686084e..1963332b856de 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/minicore.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/minicore.stderr @@ -7,12 +7,11 @@ LL | #![feature(const_trait_impl, effects, const_mut_refs)] = note: see issue #102090 for more information = note: `#[warn(incomplete_features)]` on by default -error[E0094]: intrinsic has wrong number of const parameters: found 1, expected 0 - --> $DIR/minicore.rs:517:27 +error: requires `EffectsCompat` lang_item + --> $DIR/minicore.rs:455:9 | -LL | const fn const_eval_select( - | ^^^^^^^^^^^^^^^^^^^^^^^ expected 0 const parameters +LL | impl Clone for RefCell { + | ^^^^^ error: aborting due to 1 previous error; 1 warning emitted -For more information about this error, try `rustc --explain E0094`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/no-explicit-const-params-cross-crate.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/no-explicit-const-params-cross-crate.stderr index cc870ad336cd1..34732ac4f2ef7 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/no-explicit-const-params-cross-crate.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/no-explicit-const-params-cross-crate.stderr @@ -16,15 +16,17 @@ 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(); - | ^^^------- help: remove these generics - | | - | expected 0 generic arguments + | ^^^ expected 0 generic arguments | note: trait defined here, with 0 generic parameters --> $DIR/auxiliary/cross-crate.rs:6: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 @@ -44,15 +46,17 @@ 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(); - | ^^^------ help: remove these generics - | | - | expected 0 generic arguments + | ^^^ expected 0 generic arguments | note: trait defined here, with 0 generic parameters --> $DIR/auxiliary/cross-crate.rs:6: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/rfcs/rfc-2632-const-trait-impl/effects/no-explicit-const-params.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/no-explicit-const-params.stderr index 39aa5825611f3..c3ff30d2d797b 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/no-explicit-const-params.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/no-explicit-const-params.stderr @@ -25,15 +25,17 @@ 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(); - | ^^^------- help: remove these generics - | | - | expected 0 generic arguments + | ^^^ 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 @@ -62,15 +64,17 @@ 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(); - | ^^^------ help: remove these generics - | | - | expected 0 generic arguments + | ^^^ 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 5 previous errors; 1 warning emitted diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/project.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/project.rs index 0592ac2e0e70c..373a4393713c6 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/project.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/project.rs @@ -1,12 +1,10 @@ -//@ known-bug: #110395 -// FIXME: effects +//@ check-pass #![feature(const_trait_impl, effects)] +#![allow(incomplete_features)] -// This fails because `~const Uwu` doesn't imply (non-const) `Uwu`. - -// FIXME: #[const_trait] -pub trait Owo::T> {} +#[const_trait] +pub trait Owo::T> {} #[const_trait] pub trait Uwu: Owo { diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/project.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/project.stderr deleted file mode 100644 index ab5f7b55a4e47..0000000000000 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/project.stderr +++ /dev/null @@ -1,74 +0,0 @@ -warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/project.rs:4: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 `Self: Uwu` is not satisfied - --> $DIR/project.rs:12:1 - | -LL | pub trait Uwu: Owo { - | ^^^^^^^^^^^^^^^^^^ the trait `Uwu` is not implemented for `Self` - | -help: consider further restricting `Self` - | -LL | pub trait Uwu: Owo + Uwu { - | +++++ - -error[E0277]: the trait bound `Self: Uwu` is not satisfied - --> $DIR/project.rs:12:1 - | -LL | / pub trait Uwu: Owo { -LL | | type T; -LL | | } - | |_^ the trait `Uwu` is not implemented for `Self` - | -help: consider further restricting `Self` - | -LL | pub trait Uwu: Owo + Uwu { - | +++++ - -error[E0277]: the trait bound `Self: Uwu` is not satisfied - --> $DIR/project.rs:12:16 - | -LL | pub trait Uwu: Owo { - | ^^^ the trait `Uwu` is not implemented for `Self` - | -note: required by a bound in `Owo` - --> $DIR/project.rs:9:15 - | -LL | pub trait Owo::T> {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Owo` -help: consider further restricting `Self` - | -LL | pub trait Uwu: Owo + Uwu { - | +++++ - -error[E0277]: the trait bound `Self: Uwu` is not satisfied - --> $DIR/project.rs:13:5 - | -LL | type T; - | ^^^^^^ the trait `Uwu` is not implemented for `Self` - | -help: consider further restricting `Self` - | -LL | pub trait Uwu: Owo + Uwu { - | +++++ - -error[E0277]: the trait bound `Self: Uwu` is not satisfied - --> $DIR/project.rs:13:5 - | -LL | type T; - | ^^^^^^^ the trait `Uwu` is not implemented for `Self` - | -help: consider further restricting `Self` - | -LL | pub trait Uwu: Owo + Uwu { - | +++++ - -error: aborting due to 5 previous errors; 1 warning emitted - -For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/span-bug-issue-121418.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/span-bug-issue-121418.rs index 987a162cd6cae..e6e41c472bdc7 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/span-bug-issue-121418.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/span-bug-issue-121418.rs @@ -6,7 +6,6 @@ trait T {} impl const dyn T { //~^ ERROR inherent impls cannot be `const` - //~| ERROR the const parameter `host` is not constrained by the impl trait, self type, or pub const fn new() -> std::sync::Mutex {} //~^ ERROR mismatched types //~| ERROR cannot be known at compilation time diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/span-bug-issue-121418.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/span-bug-issue-121418.stderr index f24d7c7a16017..313ba4fc9565e 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/span-bug-issue-121418.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/span-bug-issue-121418.stderr @@ -17,17 +17,8 @@ LL | #![feature(effects)] = note: see issue #102090 for more information = note: `#[warn(incomplete_features)]` on by default -error[E0207]: the const parameter `host` is not constrained by the impl trait, self type, or predicates - --> $DIR/span-bug-issue-121418.rs:7:6 - | -LL | impl const dyn T { - | ^^^^^ unconstrained const parameter - | - = note: expressions using a const parameter must map each value to a distinct output value - = note: proving the result of expressions other than the parameter are unique is not supported - error[E0308]: mismatched types - --> $DIR/span-bug-issue-121418.rs:10:27 + --> $DIR/span-bug-issue-121418.rs:9:27 | LL | pub const fn new() -> std::sync::Mutex {} | --- ^^^^^^^^^^^^^^^^^^^^^^^ expected `Mutex`, found `()` @@ -38,7 +29,7 @@ LL | pub const fn new() -> std::sync::Mutex {} found unit type `()` error[E0277]: the size for values of type `(dyn T + 'static)` cannot be known at compilation time - --> $DIR/span-bug-issue-121418.rs:10:27 + --> $DIR/span-bug-issue-121418.rs:9:27 | LL | pub const fn new() -> std::sync::Mutex {} | ^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time @@ -48,7 +39,7 @@ note: required because it appears within the type `Mutex<(dyn T + 'static)>` --> $SRC_DIR/std/src/sync/mutex.rs:LL:COL = note: the return type of a function must have a statically known size -error: aborting due to 4 previous errors; 1 warning emitted +error: aborting due to 3 previous errors; 1 warning emitted -Some errors have detailed explanations: E0207, E0277, E0308. -For more information about an error, try `rustc --explain E0207`. +Some errors have detailed explanations: E0277, E0308. +For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/spec-effectvar-ice.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/spec-effectvar-ice.rs index 00465b0f53d5a..0508b1c5e26b6 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/spec-effectvar-ice.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/spec-effectvar-ice.rs @@ -11,12 +11,11 @@ trait Foo {} impl const Foo for T {} //~^ error: const `impl` for trait `Foo` which is not marked with `#[const_trait]` -//~| error: the const parameter `host` is not constrained by the impl trait, self type, or predicates [E0207] 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: the const parameter `host` is not constrained by the impl trait, self type, or predicates [E0207] -//~| error: conflicting implementations of trait `Foo` +//~| error: specialization impl does not specialize any associated items +//~| error: cannot specialize on trait `Specialize` fn main() {} diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/spec-effectvar-ice.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/spec-effectvar-ice.stderr index 8d69151bf74c3..047549bca75a5 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/spec-effectvar-ice.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/spec-effectvar-ice.stderr @@ -20,7 +20,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:16:15 + --> $DIR/spec-effectvar-ice.rs:15:15 | LL | trait Foo {} | - help: mark `Foo` as const: `#[const_trait]` @@ -32,39 +32,28 @@ 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:16:40 + --> $DIR/spec-effectvar-ice.rs:15:40 | LL | impl const Foo for T where T: const Specialize {} | ^^^^^^^^^^ -error[E0207]: the const parameter `host` is not constrained by the impl trait, self type, or predicates - --> $DIR/spec-effectvar-ice.rs:12:9 +error: specialization impl does not specialize any associated items + --> $DIR/spec-effectvar-ice.rs:15:1 | -LL | impl const Foo for T {} - | ^^^^^ unconstrained const parameter +LL | impl const Foo for T where T: const Specialize {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: expressions using a const parameter must map each value to a distinct output value - = note: proving the result of expressions other than the parameter are unique is not supported - -error[E0119]: conflicting implementations of trait `Foo` - --> $DIR/spec-effectvar-ice.rs:16:1 +note: impl is a specialization of this impl + --> $DIR/spec-effectvar-ice.rs:12:1 | LL | impl const Foo for T {} - | ----------------------- first implementation here -... -LL | impl const Foo for T where T: const Specialize {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation + | ^^^^^^^^^^^^^^^^^^^^^^^ -error[E0207]: the const parameter `host` is not constrained by the impl trait, self type, or predicates - --> $DIR/spec-effectvar-ice.rs:16:9 +error: cannot specialize on trait `Specialize` + --> $DIR/spec-effectvar-ice.rs:15:34 | LL | impl const Foo for T where T: const Specialize {} - | ^^^^^ unconstrained const parameter - | - = note: expressions using a const parameter must map each value to a distinct output value - = note: proving the result of expressions other than the parameter are unique is not supported + | ^^^^^^^^^^^^^^^^ -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: E0119, E0207. -For more information about an error, try `rustc --explain E0119`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/generic-bound.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/generic-bound.stderr index 7905abfa40ed6..2baac1d2a168e 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/generic-bound.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/generic-bound.stderr @@ -1,20 +1,24 @@ +error: const `impl` for trait `Add` which is not marked with `#[const_trait]` + --> $DIR/generic-bound.rs:16:15 + | +LL | impl const std::ops::Add for S { + | ^^^^^^^^^^^^^ + | + = 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[E0015]: cannot call non-const operator in constant functions --> $DIR/generic-bound.rs:25:5 | LL | arg + arg | ^^^^^^^^^ | -note: impl defined here, but it is not `const` - --> $DIR/generic-bound.rs:16:1 - | -LL | impl const std::ops::Add for S { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants help: add `#![feature(effects)]` to the crate attributes to enable | LL + #![feature(effects)] | -error: aborting due to 1 previous error +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0015`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/impl-with-default-fn-fail.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/impl-with-default-fn-fail.rs index 6df9696f2cbd7..49741ca24c7e7 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/impl-with-default-fn-fail.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/impl-with-default-fn-fail.rs @@ -1,4 +1,5 @@ -#![feature(const_trait_impl)] +#![allow(incomplete_features)] +#![feature(const_trait_impl, effects)] #[const_trait] trait Tr { diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/impl-with-default-fn-fail.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/impl-with-default-fn-fail.stderr index 36c8163f1c567..0135296526f96 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/impl-with-default-fn-fail.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/impl-with-default-fn-fail.stderr @@ -1,5 +1,5 @@ error[E0046]: not all trait items implemented, missing: `req` - --> $DIR/impl-with-default-fn-fail.rs:12:1 + --> $DIR/impl-with-default-fn-fail.rs:13:1 | LL | fn req(&self); | -------------- `req` from trait diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/impl-with-default-fn-pass.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/impl-with-default-fn-pass.rs index c6fab4aabb6b7..0a1d2355a75bc 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/impl-with-default-fn-pass.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/impl-with-default-fn-pass.rs @@ -1,6 +1,6 @@ //@ check-pass - -#![feature(const_trait_impl)] +#![allow(incomplete_features)] +#![feature(const_trait_impl, effects)] #[const_trait] trait Tr { diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-100222.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-100222.rs index 2a40a1b86ca28..10d7a3942e497 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-100222.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-100222.rs @@ -1,6 +1,7 @@ //@ revisions: nn ny yn yy //@ check-pass -#![feature(const_trait_impl, associated_type_defaults, const_mut_refs)] +#![allow(incomplete_features)] +#![feature(const_trait_impl, effects, associated_type_defaults, const_mut_refs)] #[cfg_attr(any(yn, yy), const_trait)] pub trait Index { diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-92230-wf-super-trait-env.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-92230-wf-super-trait-env.rs index a587de9f17963..e666355db6ffc 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-92230-wf-super-trait-env.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-92230-wf-super-trait-env.rs @@ -4,6 +4,7 @@ //@ compile-flags: -Znext-solver #![feature(const_trait_impl, effects)] +#![allow(incomplete_features)] #[const_trait] pub trait Super {} diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/non-const-op-in-closure-in-const.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/non-const-op-in-closure-in-const.stderr index ae76cab2f2e66..de4783bdb3fe6 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/non-const-op-in-closure-in-const.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/non-const-op-in-closure-in-const.stderr @@ -4,5 +4,28 @@ error: `~const` can only be applied to `#[const_trait]` traits LL | impl const Convert for A where B: ~const From { | ^^^^^^^ -error: aborting due to 1 previous error +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 + | +LL | #[const_trait] + | ^^^^^^^^^^^^^^ found 1 const parameter +LL | trait Convert { +LL | fn to(self) -> T; + | - expected 0 const parameters + +error[E0015]: cannot call non-const fn `>::from` in constant functions + --> $DIR/non-const-op-in-closure-in-const.rs:12:9 + | +LL | B::from(self) + | ^^^^^^^^^^^^^ + | + = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants +help: add `#![feature(effects)]` to the crate attributes to enable + | +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`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/specializing-constness.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/specializing-constness.rs index 3aabaf137d54c..4501a218ad723 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/specializing-constness.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/specializing-constness.rs @@ -22,6 +22,8 @@ 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/rfcs/rfc-2632-const-trait-impl/specializing-constness.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/specializing-constness.stderr index 226295bf949df..272cb26ff42e5 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/specializing-constness.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/specializing-constness.stderr @@ -13,5 +13,17 @@ error: cannot specialize on const impl with non-const impl LL | impl A for T { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 1 previous error; 1 warning emitted +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 3 previous errors; 1 warning emitted diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.rs index 2f26eebbe32f9..ba20a79a4df74 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.rs @@ -15,7 +15,7 @@ trait Bar: ~const Foo {} const fn foo(x: &T) { x.a(); - //[yy,yn]~^ ERROR mismatched types + //[yy,yn]~^ ERROR the trait bound // FIXME(effects) diagnostic } diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.yn.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.yn.stderr index f96e6fb4ae468..a4f1c94bca0bc 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.yn.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.yn.stderr @@ -19,15 +19,25 @@ LL | #![feature(const_trait_impl, effects)] = note: see issue #102090 for more information = note: `#[warn(incomplete_features)]` on by default -error[E0308]: mismatched types - --> $DIR/super-traits-fail-2.rs:17:5 +error[E0277]: the trait bound `Foo::{synthetic#0}: ~const Compat` is not satisfied + --> $DIR/super-traits-fail-2.rs:17:7 | LL | x.a(); - | ^^^^^ expected `host`, found `true` + | ^ the trait `~const Compat` is not implemented for `Foo::{synthetic#0}` | - = note: expected constant `host` - found constant `true` +note: required by a bound in `Foo::a` + --> $DIR/super-traits-fail-2.rs:4: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 the associated type + | +LL | const fn foo(x: &T) where Foo::{synthetic#0}: ~const Compat { + | +++++++++++++++++++++++++++++++++++++++ error: aborting due to 2 previous errors; 1 warning emitted -For more information about this error, try `rustc --explain E0308`. +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.yy.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.yy.stderr index ffc259e590e80..4e27ebc5e9ec7 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.yy.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.yy.stderr @@ -7,15 +7,25 @@ LL | #![feature(const_trait_impl, effects)] = note: see issue #102090 for more information = note: `#[warn(incomplete_features)]` on by default -error[E0308]: mismatched types - --> $DIR/super-traits-fail-2.rs:17:5 +error[E0277]: the trait bound `Foo::{synthetic#0}: ~const Compat` is not satisfied + --> $DIR/super-traits-fail-2.rs:17:7 | LL | x.a(); - | ^^^^^ expected `host`, found `true` + | ^ the trait `~const Compat` is not implemented for `Foo::{synthetic#0}` | - = note: expected constant `host` - found constant `true` +note: required by a bound in `Foo::a` + --> $DIR/super-traits-fail-2.rs:4: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 the associated type + | +LL | const fn foo(x: &T) where Foo::{synthetic#0}: ~const Compat { + | +++++++++++++++++++++++++++++++++++++++ error: aborting due to 1 previous error; 1 warning emitted -For more information about this error, try `rustc --explain E0308`. +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.nn.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.nn.stderr index cde4b1ff77f35..a9bf2687cb88f 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.nn.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.nn.stderr @@ -1,32 +1,23 @@ error: `~const` is not allowed here - --> $DIR/super-traits-fail-3.rs:12:12 + --> $DIR/super-traits-fail-3.rs:13:12 | LL | trait Bar: ~const Foo {} | ^^^^^^ | note: this trait is not a `#[const_trait]`, so it cannot have `~const` trait bounds - --> $DIR/super-traits-fail-3.rs:12:1 + --> $DIR/super-traits-fail-3.rs:13:1 | LL | trait Bar: ~const Foo {} | ^^^^^^^^^^^^^^^^^^^^^^^^ -warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/super-traits-fail-3.rs:1:30 - | -LL | #![feature(const_trait_impl, effects)] - | ^^^^^^^ - | - = note: see issue #102090 for more information - = note: `#[warn(incomplete_features)]` on by default - error: `~const` can only be applied to `#[const_trait]` traits - --> $DIR/super-traits-fail-3.rs:12:19 + --> $DIR/super-traits-fail-3.rs:13:19 | LL | trait Bar: ~const Foo {} | ^^^ error: `~const` can only be applied to `#[const_trait]` traits - --> $DIR/super-traits-fail-3.rs:12:19 + --> $DIR/super-traits-fail-3.rs:13:19 | LL | trait Bar: ~const Foo {} | ^^^ @@ -34,7 +25,7 @@ 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:12:19 + --> $DIR/super-traits-fail-3.rs:13:19 | LL | trait Bar: ~const Foo {} | ^^^ @@ -42,10 +33,10 @@ 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:18:24 + --> $DIR/super-traits-fail-3.rs:19:24 | LL | const fn foo(x: &T) { | ^^^ -error: aborting due to 5 previous errors; 1 warning emitted +error: aborting due to 5 previous errors diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.ny.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.ny.stderr index 6f1840181481c..c3811623c1c86 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.ny.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.ny.stderr @@ -1,20 +1,11 @@ -warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/super-traits-fail-3.rs:1:30 - | -LL | #![feature(const_trait_impl, effects)] - | ^^^^^^^ - | - = note: see issue #102090 for more information - = note: `#[warn(incomplete_features)]` on by default - error: `~const` can only be applied to `#[const_trait]` traits - --> $DIR/super-traits-fail-3.rs:12:19 + --> $DIR/super-traits-fail-3.rs:13:19 | LL | trait Bar: ~const Foo {} | ^^^ error: `~const` can only be applied to `#[const_trait]` traits - --> $DIR/super-traits-fail-3.rs:12:19 + --> $DIR/super-traits-fail-3.rs:13:19 | LL | trait Bar: ~const Foo {} | ^^^ @@ -22,12 +13,12 @@ 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:12:19 + --> $DIR/super-traits-fail-3.rs:13:19 | LL | trait Bar: ~const Foo {} | ^^^ | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -error: aborting due to 3 previous errors; 1 warning emitted +error: aborting due to 3 previous errors diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.rs index f7e85902a41b2..24661f078b017 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.rs @@ -1,7 +1,8 @@ -#![feature(const_trait_impl, effects)] //~ WARN the feature `effects` is incomplete +#![allow(incomplete_features)] +#![feature(const_trait_impl, effects)] //@ revisions: yy yn ny nn -//@[yy] check-pass +//@[yy] known-bug: #110395 #[cfg_attr(any(yy, yn), const_trait)] trait Foo { @@ -18,7 +19,7 @@ trait Bar: ~const Foo {} const fn foo(x: &T) { //[yn,nn]~^ ERROR: `~const` can only be applied to `#[const_trait]` x.a(); - //[yn]~^ ERROR: mismatched types + //[yn]~^ ERROR: the trait bound } fn main() {} diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.yn.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.yn.stderr index b0a3b39631dca..34a60329eb5e2 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.yn.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.yn.stderr @@ -1,39 +1,40 @@ error: `~const` is not allowed here - --> $DIR/super-traits-fail-3.rs:12:12 + --> $DIR/super-traits-fail-3.rs:13:12 | LL | trait Bar: ~const Foo {} | ^^^^^^ | note: this trait is not a `#[const_trait]`, so it cannot have `~const` trait bounds - --> $DIR/super-traits-fail-3.rs:12:1 + --> $DIR/super-traits-fail-3.rs:13:1 | LL | trait Bar: ~const Foo {} | ^^^^^^^^^^^^^^^^^^^^^^^^ -warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/super-traits-fail-3.rs:1:30 - | -LL | #![feature(const_trait_impl, effects)] - | ^^^^^^^ - | - = note: see issue #102090 for more information - = note: `#[warn(incomplete_features)]` on by default - error: `~const` can only be applied to `#[const_trait]` traits - --> $DIR/super-traits-fail-3.rs:18:24 + --> $DIR/super-traits-fail-3.rs:19:24 | LL | const fn foo(x: &T) { | ^^^ -error[E0308]: mismatched types - --> $DIR/super-traits-fail-3.rs:20:5 +error[E0277]: the trait bound `Foo::{synthetic#0}: ~const Compat` is not satisfied + --> $DIR/super-traits-fail-3.rs:21:7 | LL | x.a(); - | ^^^^^ expected `host`, found `true` + | ^ the trait `~const Compat` is not implemented for `Foo::{synthetic#0}` + | +note: required by a bound in `Foo::a` + --> $DIR/super-traits-fail-3.rs:7: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 the associated type | - = note: expected constant `host` - found constant `true` +LL | const fn foo(x: &T) where Foo::{synthetic#0}: ~const Compat { + | +++++++++++++++++++++++++++++++++++++++ -error: aborting due to 3 previous errors; 1 warning emitted +error: aborting due to 3 previous errors -For more information about this error, try `rustc --explain E0308`. +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.yy.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.yy.stderr index e354c66919ec6..8ac20b3e06852 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.yy.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.yy.stderr @@ -1,11 +1,22 @@ -warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/super-traits-fail-3.rs:1:30 +error[E0277]: the trait bound `Foo::{synthetic#0}: ~const Compat` is not satisfied + --> $DIR/super-traits-fail-3.rs:21:7 | -LL | #![feature(const_trait_impl, effects)] - | ^^^^^^^ +LL | x.a(); + | ^ the trait `~const Compat` is not implemented for `Foo::{synthetic#0}` | - = note: see issue #102090 for more information - = note: `#[warn(incomplete_features)]` on by default +note: required by a bound in `Foo::a` + --> $DIR/super-traits-fail-3.rs:7: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 the associated type + | +LL | const fn foo(x: &T) where Foo::{synthetic#0}: ~const Compat { + | +++++++++++++++++++++++++++++++++++++++ -warning: 1 warning emitted +error: aborting due to 1 previous error +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail.rs index 0bbf2dabffe57..bb8e06ab2f7a1 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail.rs @@ -1,7 +1,7 @@ //@ check-pass -//@ known-bug: #110395 -#![feature(const_trait_impl)] +#![allow(incomplete_features)] +#![feature(const_trait_impl, effects)] #[const_trait] trait Foo { diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits.rs index cfbb8e9f6be57..b32c8cab7ecbe 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits.rs @@ -1,5 +1,6 @@ -//@ check-pass -#![feature(const_trait_impl, effects)] //~ WARN the feature `effects` is incomplete +// FIXME(effects) check-pass +//@ known-bug: #110395 +#![feature(const_trait_impl, effects)] #[const_trait] trait Foo { diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits.stderr index 2ff1a880d84f0..a9cb68a247ccd 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits.stderr @@ -1,5 +1,5 @@ warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/super-traits.rs:2:30 + --> $DIR/super-traits.rs:3:30 | LL | #![feature(const_trait_impl, effects)] | ^^^^^^^ @@ -7,5 +7,25 @@ LL | #![feature(const_trait_impl, effects)] = note: see issue #102090 for more information = note: `#[warn(incomplete_features)]` on by default -warning: 1 warning emitted +error[E0277]: the trait bound `Foo::{synthetic#0}: ~const Compat` is not satisfied + --> $DIR/super-traits.rs:21:7 + | +LL | t.a(); + | ^ the trait `~const Compat` is not implemented for `Foo::{synthetic#0}` + | +note: required by a bound in `Foo::a` + --> $DIR/super-traits.rs:5:1 + | +LL | #[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 the associated type + | +LL | const fn foo(t: &T) where Foo::{synthetic#0}: ~const Compat { + | +++++++++++++++++++++++++++++++++++++++ + +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/rfcs/rfc-2632-const-trait-impl/tilde-const-invalid-places.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-invalid-places.stderr index 3b320f1c5424a..8151b9aaa23de 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-invalid-places.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-invalid-places.stderr @@ -282,21 +282,12 @@ help: wrap the field type in `ManuallyDrop<...>` LL | union Union { field: std::mem::ManuallyDrop } | +++++++++++++++++++++++ + -error[E0275]: overflow evaluating the requirement `Trait::{opaque#0} == _` +error[E0275]: overflow evaluating the requirement `(): Trait` --> $DIR/tilde-const-invalid-places.rs:34:34 | LL | type Type = (); | ^^ | -note: required for `()` to implement `Trait` - --> $DIR/tilde-const-invalid-places.rs:56:23 - | -LL | impl Trait for T {} - | ------------ ^^^^^ ^ - | | - | unsatisfied trait bound introduced here - = note: 1 redundant requirement hidden - = note: required for `()` to implement `Trait` note: required by a bound in `NonConstTrait::Type` --> $DIR/tilde-const-invalid-places.rs:25:33 | diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-default-body-stability.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-default-body-stability.stderr index adb1b01f08704..d0c2f88005d7a 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-default-body-stability.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-default-body-stability.stderr @@ -25,112 +25,5 @@ LL | impl const FromResidual for T { = 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[E0207]: the const parameter `host` is not constrained by the impl trait, self type, or predicates - --> $DIR/trait-default-body-stability.rs:18:6 - | -LL | impl const Try for T { - | ^^^^^ unconstrained const parameter - | - = note: expressions using a const parameter must map each value to a distinct output value - = note: proving the result of expressions other than the parameter are unique is not supported - -error[E0207]: the const parameter `host` is not constrained by the impl trait, self type, or predicates - --> $DIR/trait-default-body-stability.rs:33:6 - | -LL | impl const FromResidual for T { - | ^^^^^ unconstrained const parameter - | - = note: expressions using a const parameter must map each value to a distinct output value - = note: proving the result of expressions other than the parameter are unique is not supported - -error[E0284]: type annotations needed - --> $DIR/trait-default-body-stability.rs:33:6 - | -LL | impl const FromResidual for T { - | ^^^^^ cannot infer the value of the constant `_` - | -note: required for `T` to implement `Try` - --> $DIR/trait-default-body-stability.rs:18:12 - | -LL | impl const Try for T { - | ----- ^^^ ^ - | | - | unsatisfied trait bound introduced here - -error[E0284]: type annotations needed - --> $DIR/trait-default-body-stability.rs:44:9 - | -LL | T? - | ^^ cannot infer the value of the constant `_` - | -note: required for `T` to implement `Try` - --> $DIR/trait-default-body-stability.rs:18:12 - | -LL | impl const Try for T { - | ----- ^^^ ^ - | | - | unsatisfied trait bound introduced here - -error[E0284]: type annotations needed - --> $DIR/trait-default-body-stability.rs:44:9 - | -LL | T? - | ^^ cannot infer the value of the constant `_` - | -note: required for `T` to implement `FromResidual` - --> $DIR/trait-default-body-stability.rs:33:12 - | -LL | impl const FromResidual for T { - | ----- ^^^^^^^^^^^^ ^ - | | - | unsatisfied trait bound introduced here - -error[E0284]: type annotations needed - --> $DIR/trait-default-body-stability.rs:44:9 - | -LL | T? - | ^^ cannot infer the value of the constant `_` - | -note: required for `T` to implement `Try` - --> $DIR/trait-default-body-stability.rs:18:12 - | -LL | impl const Try for T { - | ----- ^^^ ^ - | | - | unsatisfied trait bound introduced here - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error[E0284]: type annotations needed - --> $DIR/trait-default-body-stability.rs:44:9 - | -LL | T? - | ^^ cannot infer the value of the constant `_` - | -note: required for `T` to implement `FromResidual` - --> $DIR/trait-default-body-stability.rs:33:12 - | -LL | impl const FromResidual for T { - | ----- ^^^^^^^^^^^^ ^ - | | - | unsatisfied trait bound introduced here - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error[E0284]: type annotations needed - --> $DIR/trait-default-body-stability.rs:44:9 - | -LL | T? - | ^^ cannot infer the value of the constant `_` - | -note: required for `T` to implement `Try` - --> $DIR/trait-default-body-stability.rs:18:12 - | -LL | impl const Try for T { - | ----- ^^^ ^ - | | - | unsatisfied trait bound introduced here - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error: aborting due to 10 previous errors; 1 warning emitted +error: aborting due to 2 previous errors; 1 warning emitted -Some errors have detailed explanations: E0207, E0284. -For more information about an error, try `rustc --explain E0207`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-const.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-const.rs index 516451d881106..dd5de62aff529 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-const.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-const.rs @@ -2,7 +2,7 @@ // Checking the validity of traits' where clauses happen at a later stage. // (`rustc_const_eval` instead of `rustc_hir_analysis`) Therefore one file as a // test is not enough. -//@ known-bug: #110395 + #![feature(const_trait_impl, effects)] #![allow(incomplete_features)] @@ -20,8 +20,10 @@ const fn test1() { T::a(); T::b(); //~^ ERROR mismatched types + //~| ERROR the trait bound T::c::(); //~^ ERROR mismatched types + //~| ERROR the trait bound } const fn test2() { diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-const.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-const.stderr index 95c32b12241c9..877152472c16e 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-const.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-const.stderr @@ -1,44 +1,60 @@ -warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/trait-where-clause-const.rs:7: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 Bar` is not satisfied +error[E0277]: the trait bound `Foo::{synthetic#0}: Compat` is not satisfied --> $DIR/trait-where-clause-const.rs:21:5 | LL | T::b(); - | ^ the trait `~const Bar` is not implemented for `T` + | ^ the trait `Compat` is not implemented for `Foo::{synthetic#0}` | note: required by a bound in `Foo::b` - --> $DIR/trait-where-clause-const.rs:15:24 + --> $DIR/trait-where-clause-const.rs:12:1 | +LL | #[const_trait] + | ^^^^^^^^^^^^^^ required by this bound in `Foo::b` +... LL | fn b() where Self: ~const Bar; - | ^^^^^^^^^^ required by this bound in `Foo::b` -help: consider further restricting this bound + | - required by a bound in this associated function +help: consider further restricting the associated type + | +LL | const fn test1() where Foo::{synthetic#0}: Compat { + | ++++++++++++++++++++++++++++++++ + +error[E0308]: mismatched types + --> $DIR/trait-where-clause-const.rs:21:5 | -LL | const fn test1() { - | ++++++++++++ +LL | T::b(); + | ^^^^^^ expected `host`, found `true` + | + = note: expected constant `host` + found constant `true` -error[E0277]: the trait bound `T: ~const Bar` is not satisfied - --> $DIR/trait-where-clause-const.rs:23:12 +error[E0277]: the trait bound `Foo::{synthetic#0}: Compat` is not satisfied + --> $DIR/trait-where-clause-const.rs:24:5 | LL | T::c::(); - | ^ the trait `~const Bar` is not implemented for `T` + | ^ the trait `Compat` is not implemented for `Foo::{synthetic#0}` | note: required by a bound in `Foo::c` - --> $DIR/trait-where-clause-const.rs:16:13 + --> $DIR/trait-where-clause-const.rs:12:1 | +LL | #[const_trait] + | ^^^^^^^^^^^^^^ required by this bound in `Foo::c` +... LL | fn c(); - | ^^^^^^^^^^ required by this bound in `Foo::c` -help: consider further restricting this bound + | - required by a bound in this associated function +help: consider further restricting the associated type + | +LL | const fn test1() where Foo::{synthetic#0}: Compat { + | ++++++++++++++++++++++++++++++++ + +error[E0308]: mismatched types + --> $DIR/trait-where-clause-const.rs:24:5 + | +LL | T::c::(); + | ^^^^^^^^^^^ expected `host`, found `true` | -LL | const fn test1() { - | ++++++++++++ + = note: expected constant `host` + found constant `true` -error: aborting due to 2 previous errors; 1 warning emitted +error: aborting due to 4 previous errors -For more information about this error, try `rustc --explain E0277`. +Some errors have detailed explanations: E0277, E0308. +For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/unsatisfied-const-trait-bound.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/unsatisfied-const-trait-bound.rs index 3a8c6d5b1a4fa..c50c755f667fc 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/unsatisfied-const-trait-bound.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/unsatisfied-const-trait-bound.rs @@ -18,7 +18,8 @@ impl Trait for Ty { } fn main() { - require::(); //~ ERROR the trait bound `Ty: const Trait` is not satisfied + // FIXME(effects): improve diagnostics on this + require::(); //~ ERROR the trait bound `Trait::{synthetic#0}: const Compat` is not satisfied } struct Container; diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/unsatisfied-const-trait-bound.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/unsatisfied-const-trait-bound.stderr index 258f95b5c4a89..b9f6c9e883562 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/unsatisfied-const-trait-bound.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/unsatisfied-const-trait-bound.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/unsatisfied-const-trait-bound.rs:27:37 + --> $DIR/unsatisfied-const-trait-bound.rs:29:37 | LL | fn accept0(_: Container<{ T::make() }>) {} | ^^^^^^^^^ expected `false`, found `true` @@ -8,7 +8,7 @@ LL | fn accept0(_: Container<{ T::make() }>) {} found constant `true` error[E0308]: mismatched types - --> $DIR/unsatisfied-const-trait-bound.rs:32:50 + --> $DIR/unsatisfied-const-trait-bound.rs:34:50 | LL | const fn accept1(_: Container<{ T::make() }>) {} | ^^^^^^^^^ expected `false`, found `host` @@ -16,15 +16,14 @@ LL | const fn accept1(_: Container<{ T::make() }>) {} = note: expected constant `false` found constant `host` -error[E0277]: the trait bound `Ty: const Trait` is not satisfied - --> $DIR/unsatisfied-const-trait-bound.rs:20:15 +error[E0277]: the trait bound `Trait::{synthetic#0}: const Compat` is not satisfied + --> $DIR/unsatisfied-const-trait-bound.rs:22:15 | LL | require::(); - | ^^ the trait `const Trait` is not implemented for `Ty` + | ^^ the trait `const Compat` is not implemented for `Trait::{synthetic#0}` | - = help: the trait `Trait` is implemented for `Ty` note: required by a bound in `require` - --> $DIR/unsatisfied-const-trait-bound.rs:6:15 + --> $DIR/unsatisfied-const-trait-bound.rs:7:15 | LL | fn require() {} | ^^^^^^^^^^^ required by this bound in `require` From 0a2330630d223ac3601a7b53e65e0d5867b60c2c Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Tue, 25 Jun 2024 09:57:31 +0000 Subject: [PATCH 08/10] general fixups and turn `TODO`s into `FIXME`s --- compiler/rustc_hir_analysis/src/bounds.rs | 6 ++-- .../src/collect/item_bounds.rs | 9 +++-- .../src/collect/predicates_of.rs | 6 ++-- .../src/hir_ty_lowering/generics.rs | 2 +- compiler/rustc_hir_typeck/src/method/mod.rs | 2 +- .../src/solve/normalizes_to/mod.rs | 5 ++- .../src/solve/trait_goals.rs | 4 +-- compiler/rustc_ty_utils/src/assoc.rs | 4 +-- compiler/rustc_type_ir/src/effects.rs | 6 ++-- library/core/src/marker.rs | 4 ++- ...-type-const-bound-usage-0.qualified.stderr | 27 --------------- ...ype-const-bound-usage-0.unqualified.stderr | 11 ------- .../assoc-type-const-bound-usage-1.rs | 5 ++- ... => assoc-type-const-bound-usage-1.stderr} | 0 ...ype-const-bound-usage-1.unqualified.stderr | 33 ------------------- .../rfc-2632-const-trait-impl/assoc-type.rs | 3 +- 16 files changed, 31 insertions(+), 96 deletions(-) delete mode 100644 tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-0.qualified.stderr delete mode 100644 tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-0.unqualified.stderr rename tests/ui/rfcs/rfc-2632-const-trait-impl/{assoc-type-const-bound-usage-1.qualified.stderr => assoc-type-const-bound-usage-1.stderr} (100%) delete mode 100644 tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-1.unqualified.stderr diff --git a/compiler/rustc_hir_analysis/src/bounds.rs b/compiler/rustc_hir_analysis/src/bounds.rs index 0b03eeaced1be..61b7dd8bb8c34 100644 --- a/compiler/rustc_hir_analysis/src/bounds.rs +++ b/compiler/rustc_hir_analysis/src/bounds.rs @@ -72,7 +72,7 @@ impl<'tcx> Bounds<'tcx> { // 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. if let Some(compat_val) = match (tcx.def_kind(defining_def_id), constness) { - // TODO: do we need `T: const Trait` anymore? + // FIXME(effects): revisit the correctness of this (_, ty::BoundConstness::Const) => Some(tcx.consts.false_), // body owners that can have trait bounds (DefKind::Const | DefKind::Fn | DefKind::AssocFn, ty::BoundConstness::ConstIfConst) => { @@ -120,7 +120,7 @@ impl<'tcx> Bounds<'tcx> { // 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, ty::BoundConstness::ConstIfConst) => { - // TODO write the actual impl + // FIXME(effects): implement this return; } // probably illegal in this position. @@ -169,7 +169,7 @@ impl<'tcx> Bounds<'tcx> { pub fn clauses( &self, - // TODO remove tcx + // FIXME(effects): remove tcx _tcx: TyCtxt<'tcx>, ) -> impl Iterator, Span)> + '_ { self.clauses.iter().cloned() diff --git a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs index c8c82c711de18..b32067ebd6aee 100644 --- a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs +++ b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs @@ -134,13 +134,16 @@ pub(super) fn explicit_item_bounds_with_filter( if let ty::AssocItemContainer::TraitContainer = tcx.associated_item(def_id).container { // for traits, emit `type Effects: TyCompat<<(T1::Effects, ..) as Min>::Output>` - // TODO do the same for impls let tup = Ty::new(tcx, ty::Tuple(preds.effects_min_tys)); - // TODO span + // FIXME(effects) span let span = tcx.def_span(def_id); let assoc = tcx.require_lang_item(hir::LangItem::EffectsMinOutput, Some(span)); let proj = Ty::new_projection(tcx, assoc, [tup]); - let self_proj = Ty::new_projection(tcx, def_id.to_def_id(), ty::GenericArgs::identity_for_item(tcx, def_id)); + let self_proj = Ty::new_projection( + tcx, + def_id.to_def_id(), + ty::GenericArgs::identity_for_item(tcx, def_id), + ); let trait_ = tcx.require_lang_item(hir::LangItem::EffectsTyCompat, Some(span)); let trait_ref = ty::TraitRef::new(tcx, trait_, [self_proj, proj]); predicates.push((ty::Binder::dummy(trait_ref).upcast(tcx), span)); diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs index cc3078f037a06..1c3c1a79cfbc3 100644 --- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs @@ -323,12 +323,14 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen 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 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()]); + let trait_ref = + ty::TraitRef::new(tcx, compat, [ty::GenericArg::from(effects), host.into()]); predicates.push((ty::Binder::dummy(trait_ref).upcast(tcx), span)); } diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs index 67046b5ac0e40..e92c377f0ce2a 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs @@ -256,7 +256,7 @@ pub fn lower_generic_args<'tcx: 'a, 'a>( | GenericParamDefKind::Lifetime, _, ) => { - // TODO: this should be removed + // FIXME(effects): this should be removed // SPECIAL CASE FOR DESUGARED EFFECT PARAMS // This comes from the following example: // diff --git a/compiler/rustc_hir_typeck/src/method/mod.rs b/compiler/rustc_hir_typeck/src/method/mod.rs index dad909fc4e102..ff8899ae0368d 100644 --- a/compiler/rustc_hir_typeck/src/method/mod.rs +++ b/compiler/rustc_hir_typeck/src/method/mod.rs @@ -404,7 +404,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { debug!("lookup_in_trait_adjusted: method_item={:?}", method_item); let mut obligations = vec![]; - // TODO there is something wrong here because now methods for binops may get `const host: bool` + // FIXME(effects): revisit when binops get `#[const_trait]` // Instantiate late-bound regions and instantiate the trait // parameters into the method type to get the actual method type. 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 f75c30eda9949..55c0440a53715 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 @@ -873,7 +873,6 @@ where return Err(NoSolution); }; - let cx = ecx.cx(); let mut first_non_maybe = None; @@ -907,11 +906,11 @@ where let Some(kind) = ty::EffectKind::try_from_ty(cx, ty) else { return Err(NoSolution); }; - + let Some(result) = ty::EffectKind::min(min, kind) else { return Err(NoSolution); }; - + min = result; } 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 8c6e5eb5a4d9d..73ae1c4b11359 100644 --- a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs +++ b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs @@ -731,11 +731,11 @@ where let Some(kind) = ty::EffectKind::try_from_ty(ecx.cx(), ty) else { return Err(NoSolution); }; - + let Some(result) = ty::EffectKind::min(min, kind) else { return Err(NoSolution); }; - + min = result; } } diff --git a/compiler/rustc_ty_utils/src/assoc.rs b/compiler/rustc_ty_utils/src/assoc.rs index 681f089e84fb7..6a55e83786cb8 100644 --- a/compiler/rustc_ty_utils/src/assoc.rs +++ b/compiler/rustc_ty_utils/src/assoc.rs @@ -255,7 +255,7 @@ fn associated_type_for_effects(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option, def_id: LocalDefId) -> Option None, } } -} \ No newline at end of file +} diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs index b71bedaa1948f..042acbf20b1a0 100644 --- a/library/core/src/marker.rs +++ b/library/core/src/marker.rs @@ -1028,6 +1028,9 @@ 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", @@ -1036,7 +1039,6 @@ pub macro SmartPointer($item:item) { )] #[allow(missing_debug_implementations)] // these unit structs don't need `Debug` impls. #[cfg(not(bootstrap))] -// TODO docs pub mod effects { #[lang = "EffectsNoRuntime"] pub struct NoRuntime; diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-0.qualified.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-0.qualified.stderr deleted file mode 100644 index 1af0f481943ab..0000000000000 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-0.qualified.stderr +++ /dev/null @@ -1,27 +0,0 @@ -warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/assoc-type-const-bound-usage-0.rs:6: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 `Trait::{synthetic#0}: Compat` is not satisfied - --> $DIR/assoc-type-const-bound-usage-0.rs:21:5 - | -LL | ::Assoc::func() - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Compat` is not implemented for `Trait::{synthetic#0}` - | -note: required by a bound in `Trait::func` - --> $DIR/assoc-type-const-bound-usage-0.rs:8:1 - | -LL | #[const_trait] - | ^^^^^^^^^^^^^^ required by this bound in `Trait::func` -... -LL | fn func() -> i32; - | ---- required by a bound in this associated function - -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/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-0.unqualified.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-0.unqualified.stderr deleted file mode 100644 index 3d592834600e0..0000000000000 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-0.unqualified.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/assoc-type-const-bound-usage-0.rs:6: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/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-1.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-1.rs index 5394c3f2d070c..8a1bf75f87e1a 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-1.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-1.rs @@ -1,6 +1,5 @@ -// FIXME(effects): Collapse the revisions into one once we support `::Proj`. -//@ revisions: unqualified qualified -//@known-bug: unknown +//@ known-bug: unknown +// FIXME(effects) #![feature(const_trait_impl, effects, generic_const_exprs)] #![allow(incomplete_features)] diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-1.qualified.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-1.stderr similarity index 100% rename from tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-1.qualified.stderr rename to tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-1.stderr diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-1.unqualified.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-1.unqualified.stderr deleted file mode 100644 index f8bab2d4c27fa..0000000000000 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-1.unqualified.stderr +++ /dev/null @@ -1,33 +0,0 @@ -error[E0277]: the trait bound `Trait::{synthetic#0}: Compat` is not satisfied - --> $DIR/assoc-type-const-bound-usage-1.rs:16:44 - | -LL | fn unqualified() -> Type<{ T::Assoc::func() }> { - | ^^^^^^^^ the trait `Compat` is not implemented for `Trait::{synthetic#0}` - | -note: required by a bound in `Trait::func` - --> $DIR/assoc-type-const-bound-usage-1.rs:8:1 - | -LL | #[const_trait] - | ^^^^^^^^^^^^^^ required by this bound in `Trait::func` -... -LL | fn func() -> i32; - | ---- required by a bound in this associated function - -error[E0277]: the trait bound `Trait::{synthetic#0}: Compat` is not satisfied - --> $DIR/assoc-type-const-bound-usage-1.rs:20:42 - | -LL | fn qualified() -> Type<{ ::Assoc::func() }> { - | ^^^^^^^^^^^^^^^^^^^ the trait `Compat` is not implemented for `Trait::{synthetic#0}` - | -note: required by a bound in `Trait::func` - --> $DIR/assoc-type-const-bound-usage-1.rs:8:1 - | -LL | #[const_trait] - | ^^^^^^^^^^^^^^ required by this bound in `Trait::func` -... -LL | fn func() -> i32; - | ---- required by a bound in this associated function - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type.rs index b542ec4e5d0ae..348bf839b6995 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type.rs @@ -32,7 +32,8 @@ trait Foo { } impl const Foo for NonConstAdd { - type Bar = NonConstAdd; // FIXME(effects) ERROR the trait bound `NonConstAdd: ~const Add` is not satisfied + type Bar = NonConstAdd; + // FIXME(effects) ERROR the trait bound `NonConstAdd: ~const Add` is not satisfied } #[const_trait] From 8b2fac9612e3840f9736bed31502b3b91ba01a08 Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Tue, 25 Jun 2024 10:44:00 +0000 Subject: [PATCH 09/10] finishing touches, move fixed ICEs to ui tests --- .../src/solve/normalizes_to/mod.rs | 4 +- .../src/solve/trait_goals.rs | 4 +- .../ui/missing_const_for_fn/could_be_const.rs | 3 ++ .../could_be_const.stderr | 20 ++++++---- tests/crashes/119717.rs | 10 ----- tests/crashes/123664.rs | 4 -- tests/crashes/124857.rs | 11 ------ tests/crashes/126148.rs | 23 ----------- tests/rustdoc/rfc-2632-const-trait-impl.rs | 3 +- .../assoc-type-const-bound-usage-1.stderr | 8 ++-- .../assoc-type.stderr | 2 +- .../ice-119717-constant-lifetime.rs | 15 ++++++++ .../ice-119717-constant-lifetime.stderr | 33 ++++++++++++++++ .../ice-123664-unexpected-bound-var.rs | 7 ++++ .../ice-123664-unexpected-bound-var.stderr | 8 ++++ ...-124857-combine-effect-const-infer-vars.rs | 14 +++++++ ...857-combine-effect-const-infer-vars.stderr | 12 ++++++ .../ice-126148-failed-to-normalize.rs | 28 ++++++++++++++ .../ice-126148-failed-to-normalize.stderr | 38 +++++++++++++++++++ 19 files changed, 182 insertions(+), 65 deletions(-) delete mode 100644 tests/crashes/119717.rs delete mode 100644 tests/crashes/123664.rs delete mode 100644 tests/crashes/124857.rs delete mode 100644 tests/crashes/126148.rs create mode 100644 tests/ui/rfcs/rfc-2632-const-trait-impl/ice-119717-constant-lifetime.rs create mode 100644 tests/ui/rfcs/rfc-2632-const-trait-impl/ice-119717-constant-lifetime.stderr create mode 100644 tests/ui/rfcs/rfc-2632-const-trait-impl/ice-123664-unexpected-bound-var.rs create mode 100644 tests/ui/rfcs/rfc-2632-const-trait-impl/ice-123664-unexpected-bound-var.stderr create mode 100644 tests/ui/rfcs/rfc-2632-const-trait-impl/ice-124857-combine-effect-const-infer-vars.rs create mode 100644 tests/ui/rfcs/rfc-2632-const-trait-impl/ice-124857-combine-effect-const-infer-vars.stderr create mode 100644 tests/ui/rfcs/rfc-2632-const-trait-impl/ice-126148-failed-to-normalize.rs create mode 100644 tests/ui/rfcs/rfc-2632-const-trait-impl/ice-126148-failed-to-normalize.stderr 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 55c0440a53715..7a81c210c5d04 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 @@ -877,7 +877,7 @@ where let mut first_non_maybe = None; let mut non_maybe_count = 0; - for ty in types { + 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; @@ -902,7 +902,7 @@ where _ => { let mut min = ty::EffectKind::Maybe; - for ty in types { + for ty in types.iter() { let Some(kind) = ty::EffectKind::try_from_ty(cx, ty) else { return Err(NoSolution); }; 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 73ae1c4b11359..08ed729b14405 100644 --- a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs +++ b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs @@ -717,7 +717,7 @@ where let cx = ecx.cx(); let maybe_count = types - .into_iter() + .iter() .filter_map(|ty| ty::EffectKind::try_from_ty(cx, ty)) .filter(|&ty| ty == ty::EffectKind::Maybe) .count(); @@ -727,7 +727,7 @@ where if types.len() - maybe_count > 1 { let mut min = ty::EffectKind::Maybe; - for ty in types { + for ty in types.iter() { let Some(kind) = ty::EffectKind::try_from_ty(ecx.cx(), ty) else { return Err(NoSolution); }; diff --git a/src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.rs b/src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.rs index 58e639cc7fd1f..5e4e2c58e5a4d 100644 --- a/src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.rs +++ b/src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.rs @@ -104,15 +104,18 @@ fn main() {} struct D; +/* FIXME(effects) impl const Drop for D { fn drop(&mut self) { todo!(); } } +*/ // Lint this, since it can be dropped in const contexts // FIXME(effects) fn d(this: D) {} +//~^ ERROR: this could be a `const fn` mod msrv { struct Foo(*const u8, &'static u8); diff --git a/src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.stderr b/src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.stderr index 8999af761e314..8ba42c0e5b673 100644 --- a/src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.stderr +++ b/src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.stderr @@ -157,7 +157,13 @@ LL | const fn msrv_1_46() -> i32 { | +++++ error: this could be a `const fn` - --> tests/ui/missing_const_for_fn/could_be_const.rs:122:9 + --> tests/ui/missing_const_for_fn/could_be_const.rs:117:1 + | +LL | fn d(this: D) {} + | ^^^^^^^^^^^^^^^^ + +error: this could be a `const fn` + --> tests/ui/missing_const_for_fn/could_be_const.rs:125:9 | LL | / fn deref_ptr_can_be_const(self) -> usize { LL | | @@ -171,7 +177,7 @@ LL | const fn deref_ptr_can_be_const(self) -> usize { | +++++ error: this could be a `const fn` - --> tests/ui/missing_const_for_fn/could_be_const.rs:127:9 + --> tests/ui/missing_const_for_fn/could_be_const.rs:130:9 | LL | / fn deref_copied_val(self) -> usize { LL | | @@ -185,7 +191,7 @@ LL | const fn deref_copied_val(self) -> usize { | +++++ error: this could be a `const fn` - --> tests/ui/missing_const_for_fn/could_be_const.rs:138:5 + --> tests/ui/missing_const_for_fn/could_be_const.rs:141:5 | LL | / fn union_access_can_be_const() { LL | | @@ -200,7 +206,7 @@ LL | const fn union_access_can_be_const() { | +++++ error: this could be a `const fn` - --> tests/ui/missing_const_for_fn/could_be_const.rs:152:9 + --> tests/ui/missing_const_for_fn/could_be_const.rs:155:9 | LL | / pub fn new(strings: Vec) -> Self { LL | | Self { strings } @@ -213,7 +219,7 @@ LL | pub const fn new(strings: Vec) -> Self { | +++++ error: this could be a `const fn` - --> tests/ui/missing_const_for_fn/could_be_const.rs:157:9 + --> tests/ui/missing_const_for_fn/could_be_const.rs:160:9 | LL | / pub fn empty() -> Self { LL | | Self { strings: Vec::new() } @@ -226,7 +232,7 @@ LL | pub const fn empty() -> Self { | +++++ error: this could be a `const fn` - --> tests/ui/missing_const_for_fn/could_be_const.rs:168:9 + --> tests/ui/missing_const_for_fn/could_be_const.rs:171:9 | LL | / pub fn new(text: String) -> Self { LL | | let vec = Vec::new(); @@ -239,5 +245,5 @@ help: make the function `const` LL | pub const fn new(text: String) -> Self { | +++++ -error: aborting due to 17 previous errors +error: aborting due to 18 previous errors diff --git a/tests/crashes/119717.rs b/tests/crashes/119717.rs deleted file mode 100644 index 22746548e02cb..0000000000000 --- a/tests/crashes/119717.rs +++ /dev/null @@ -1,10 +0,0 @@ -//@ known-bug: #119717 -#![feature(const_trait_impl, effects)] - -use std::ops::{FromResidual, Try}; - -impl const FromResidual for T { - fn from_residual(t: T) -> _ { - t - } -} diff --git a/tests/crashes/123664.rs b/tests/crashes/123664.rs deleted file mode 100644 index 80c415fe07bd7..0000000000000 --- a/tests/crashes/123664.rs +++ /dev/null @@ -1,4 +0,0 @@ -//@ known-bug: #123664 -#![feature(generic_const_exprs, effects)] -const fn with_positive() {} -pub fn main() {} diff --git a/tests/crashes/124857.rs b/tests/crashes/124857.rs deleted file mode 100644 index 4b952fd64ccfb..0000000000000 --- a/tests/crashes/124857.rs +++ /dev/null @@ -1,11 +0,0 @@ -//@ known-bug: rust-lang/rust#124857 -//@ compile-flags: -Znext-solver=coherence - -#![feature(effects)] - -#[const_trait] -trait Foo {} - -impl const Foo for i32 {} - -impl const Foo for T where T: ~const Foo {} diff --git a/tests/crashes/126148.rs b/tests/crashes/126148.rs deleted file mode 100644 index 79f8887b40154..0000000000000 --- a/tests/crashes/126148.rs +++ /dev/null @@ -1,23 +0,0 @@ -//@ known-bug: rust-lang/rust#126148 - -#![feature(effects)] -use std::ops::{FromResidual, Try}; - -struct TryMe; -struct Error; - -impl const FromResidual for TryMe {} - -impl const Try for TryMe { - type Output = (); - type Residual = Error; -} - -const fn t() -> TryMe { - TryMe?; - TryMe -} - -const _: () = { - t(); -}; diff --git a/tests/rustdoc/rfc-2632-const-trait-impl.rs b/tests/rustdoc/rfc-2632-const-trait-impl.rs index f6a5555dbadd0..eb3e00af3b0b5 100644 --- a/tests/rustdoc/rfc-2632-const-trait-impl.rs +++ b/tests/rustdoc/rfc-2632-const-trait-impl.rs @@ -8,7 +8,8 @@ // // FIXME(effects) add `const_trait` to `Fn` so we use `~const` // FIXME(effects) restore `const_trait` to `Destruct` -#![feature(const_trait_impl)] +#![allow(incomplete_features)] +#![feature(const_trait_impl, effects)] #![crate_name = "foo"] use std::marker::Destruct; diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-1.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-1.stderr index f8bab2d4c27fa..48855d64b58a1 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-1.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-1.stderr @@ -1,11 +1,11 @@ error[E0277]: the trait bound `Trait::{synthetic#0}: Compat` is not satisfied - --> $DIR/assoc-type-const-bound-usage-1.rs:16:44 + --> $DIR/assoc-type-const-bound-usage-1.rs:15:44 | LL | fn unqualified() -> Type<{ T::Assoc::func() }> { | ^^^^^^^^ the trait `Compat` is not implemented for `Trait::{synthetic#0}` | note: required by a bound in `Trait::func` - --> $DIR/assoc-type-const-bound-usage-1.rs:8:1 + --> $DIR/assoc-type-const-bound-usage-1.rs:7:1 | LL | #[const_trait] | ^^^^^^^^^^^^^^ required by this bound in `Trait::func` @@ -14,13 +14,13 @@ LL | fn func() -> i32; | ---- required by a bound in this associated function error[E0277]: the trait bound `Trait::{synthetic#0}: Compat` is not satisfied - --> $DIR/assoc-type-const-bound-usage-1.rs:20:42 + --> $DIR/assoc-type-const-bound-usage-1.rs:19:42 | LL | fn qualified() -> Type<{ ::Assoc::func() }> { | ^^^^^^^^^^^^^^^^^^^ the trait `Compat` is not implemented for `Trait::{synthetic#0}` | note: required by a bound in `Trait::func` - --> $DIR/assoc-type-const-bound-usage-1.rs:8:1 + --> $DIR/assoc-type-const-bound-usage-1.rs:7:1 | LL | #[const_trait] | ^^^^^^^^^^^^^^ required by this bound in `Trait::func` diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type.stderr index 333215adef217..1862339cddc5e 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type.stderr @@ -8,7 +8,7 @@ LL | #![feature(const_trait_impl, effects)] = note: `#[warn(incomplete_features)]` on by default error[E0277]: the trait bound `Add::{synthetic#0}: Compat` is not satisfied - --> $DIR/assoc-type.rs:40:15 + --> $DIR/assoc-type.rs:41:15 | LL | type Qux: Add; | ^^^ the trait `Compat` is not implemented for `Add::{synthetic#0}` diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-119717-constant-lifetime.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-119717-constant-lifetime.rs new file mode 100644 index 0000000000000..c2f452a9925c6 --- /dev/null +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-119717-constant-lifetime.rs @@ -0,0 +1,15 @@ +#![allow(incomplete_features)] +#![feature(const_trait_impl, effects, try_trait_v2)] + +use std::ops::FromResidual; + +impl const FromResidual for T { + //~^ ERROR const `impl` for trait `FromResidual` which is not marked with `#[const_trait]` + //~| type parameter `T` must be used as the type parameter for some local type + fn from_residual(t: T) -> _ { + //~^ the placeholder `_` is not allowed + t + } +} + +fn main() {} diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-119717-constant-lifetime.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-119717-constant-lifetime.stderr new file mode 100644 index 0000000000000..9e22422ad3b94 --- /dev/null +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-119717-constant-lifetime.stderr @@ -0,0 +1,33 @@ +error: const `impl` for trait `FromResidual` which is not marked with `#[const_trait]` + --> $DIR/ice-119717-constant-lifetime.rs:6:15 + | +LL | impl const FromResidual for T { + | ^^^^^^^^^^^^ + | + = 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[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct`) + --> $DIR/ice-119717-constant-lifetime.rs:6:6 + | +LL | impl const FromResidual for T { + | ^ type parameter `T` must be used as the type parameter for some local type + | + = note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local + = note: only traits defined in the current crate can be implemented for a type parameter + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions + --> $DIR/ice-119717-constant-lifetime.rs:9:31 + | +LL | fn from_residual(t: T) -> _ { + | ^ not allowed in type signatures + | +help: try replacing `_` with the type in the corresponding trait method signature + | +LL | fn from_residual(t: T) -> T { + | ~ + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0121, E0210. +For more information about an error, try `rustc --explain E0121`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-123664-unexpected-bound-var.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-123664-unexpected-bound-var.rs new file mode 100644 index 0000000000000..64634e7b7ac30 --- /dev/null +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-123664-unexpected-bound-var.rs @@ -0,0 +1,7 @@ +#![allow(incomplete_features)] +#![feature(generic_const_exprs, const_trait_impl, effects)] + +const fn with_positive() {} +//~^ ERROR `~const` can only be applied to `#[const_trait]` traits + +pub fn main() {} diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-123664-unexpected-bound-var.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-123664-unexpected-bound-var.stderr new file mode 100644 index 0000000000000..19369e38964f4 --- /dev/null +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-123664-unexpected-bound-var.stderr @@ -0,0 +1,8 @@ +error: `~const` can only be applied to `#[const_trait]` traits + --> $DIR/ice-123664-unexpected-bound-var.rs:4:34 + | +LL | const fn with_positive() {} + | ^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-124857-combine-effect-const-infer-vars.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-124857-combine-effect-const-infer-vars.rs new file mode 100644 index 0000000000000..d4fcbfb1b83e6 --- /dev/null +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-124857-combine-effect-const-infer-vars.rs @@ -0,0 +1,14 @@ +//@ compile-flags: -Znext-solver=coherence + +#![allow(incomplete_features)] +#![feature(const_trait_impl, effects)] + +#[const_trait] +trait Foo {} + +impl const Foo for i32 {} + +impl const Foo for T where T: ~const Foo {} +//~^ ERROR conflicting implementations of trait `Foo` for type `i32` + +fn main() {} diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-124857-combine-effect-const-infer-vars.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-124857-combine-effect-const-infer-vars.stderr new file mode 100644 index 0000000000000..0b1f8b40898e3 --- /dev/null +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-124857-combine-effect-const-infer-vars.stderr @@ -0,0 +1,12 @@ +error[E0119]: conflicting implementations of trait `Foo` for type `i32` + --> $DIR/ice-124857-combine-effect-const-infer-vars.rs:11:1 + | +LL | impl const Foo for i32 {} + | ---------------------- first implementation here +LL | +LL | impl const Foo for T where T: ~const Foo {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `i32` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0119`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-126148-failed-to-normalize.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-126148-failed-to-normalize.rs new file mode 100644 index 0000000000000..717c0e7c08829 --- /dev/null +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-126148-failed-to-normalize.rs @@ -0,0 +1,28 @@ +#![allow(incomplete_features)] +#![feature(const_trait_impl, effects, try_trait_v2, const_try)] +use std::ops::{FromResidual, Try}; + +struct TryMe; +struct Error; + +impl const FromResidual for TryMe {} +//~^ ERROR const `impl` for trait `FromResidual` which is not marked with `#[const_trait]` +//~| ERROR not all trait items implemented + +impl const Try for TryMe { + //~^ ERROR const `impl` for trait `Try` which is not marked with `#[const_trait]` + //~| ERROR not all trait items implemented + type Output = (); + type Residual = Error; +} + +const fn t() -> TryMe { + TryMe?; + TryMe +} + +const _: () = { + t(); +}; + +fn main() {} diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-126148-failed-to-normalize.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-126148-failed-to-normalize.stderr new file mode 100644 index 0000000000000..e641b457ef9c8 --- /dev/null +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-126148-failed-to-normalize.stderr @@ -0,0 +1,38 @@ +error: const `impl` for trait `FromResidual` which is not marked with `#[const_trait]` + --> $DIR/ice-126148-failed-to-normalize.rs:8:12 + | +LL | impl const FromResidual 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[E0046]: not all trait items implemented, missing: `from_residual` + --> $DIR/ice-126148-failed-to-normalize.rs:8:1 + | +LL | impl const FromResidual for TryMe {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `from_residual` in implementation + | + = help: implement the missing item: `fn from_residual(_: Error) -> Self { todo!() }` + +error: const `impl` for trait `Try` which is not marked with `#[const_trait]` + --> $DIR/ice-126148-failed-to-normalize.rs:12:12 + | +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[E0046]: not all trait items implemented, missing: `from_output`, `branch` + --> $DIR/ice-126148-failed-to-normalize.rs:12:1 + | +LL | impl const Try for TryMe { + | ^^^^^^^^^^^^^^^^^^^^^^^^ missing `from_output`, `branch` in implementation + | + = help: implement the missing item: `fn from_output(_: ::Output) -> Self { todo!() }` + = help: implement the missing item: `fn branch(self) -> ControlFlow<::Residual, ::Output> { todo!() }` + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0046`. From 65a0bee0b77bad05c1bf29bd2dd855e554a9eaf5 Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Wed, 26 Jun 2024 16:36:42 +0000 Subject: [PATCH 10/10] address review comments --- compiler/rustc_hir/src/lang_items.rs | 4 +- compiler/rustc_hir_analysis/src/bounds.rs | 52 +++++----- .../src/collect/item_bounds.rs | 2 +- compiler/rustc_middle/src/ty/context.rs | 4 +- .../src/solve/assembly/mod.rs | 6 +- .../src/solve/normalizes_to/mod.rs | 8 +- .../src/solve/trait_goals.rs | 4 +- compiler/rustc_span/src/symbol.rs | 4 +- compiler/rustc_ty_utils/src/assoc.rs | 99 +++++++------------ compiler/rustc_type_ir/src/effects.rs | 5 +- compiler/rustc_type_ir/src/lang_items.rs | 4 +- library/core/src/marker.rs | 11 ++- .../missing_const_for_fn/could_be_const.fixed | 5 +- .../could_be_const.stderr | 5 + .../const-fns-are-early-bound.rs | 6 +- .../super-traits-fail.rs | 1 + .../rfc-2632-const-trait-impl/super-traits.rs | 2 + .../super-traits.stderr | 15 +-- 18 files changed, 113 insertions(+), 124 deletions(-) diff --git a/compiler/rustc_hir/src/lang_items.rs b/compiler/rustc_hir/src/lang_items.rs index d49eb4ece99f8..3c44acb16577a 100644 --- a/compiler/rustc_hir/src/lang_items.rs +++ b/compiler/rustc_hir/src/lang_items.rs @@ -397,8 +397,8 @@ language_item_table! { 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; - EffectsMin, sym::EffectsMin, effects_min, Target::Trait, GenericRequirement::None; - EffectsMinOutput, sym::EffectsMinOutput, effects_min_output, Target::AssocTy, 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); } diff --git a/compiler/rustc_hir_analysis/src/bounds.rs b/compiler/rustc_hir_analysis/src/bounds.rs index 61b7dd8bb8c34..c7ee89e73c273 100644 --- a/compiler/rustc_hir_analysis/src/bounds.rs +++ b/compiler/rustc_hir_analysis/src/bounds.rs @@ -71,16 +71,19 @@ impl<'tcx> Bounds<'tcx> { } // 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. - if let Some(compat_val) = match (tcx.def_kind(defining_def_id), constness) { + let compat_val = match (tcx.def_kind(defining_def_id), constness) { // FIXME(effects): revisit the correctness of this - (_, ty::BoundConstness::Const) => Some(tcx.consts.false_), + (_, ty::BoundConstness::Const) => tcx.consts.false_, // body owners that can have trait bounds (DefKind::Const | DefKind::Fn | DefKind::AssocFn, ty::BoundConstness::ConstIfConst) => { - Some(tcx.expected_host_effect_param_for_body(defining_def_id)) + tcx.expected_host_effect_param_for_body(defining_def_id) } (_, ty::BoundConstness::NotConst) => { - tcx.has_attr(bound_trait_ref.def_id(), sym::const_trait).then_some(tcx.consts.true_) + if !tcx.has_attr(bound_trait_ref.def_id(), sym::const_trait) { + return; + } + tcx.consts.true_ } ( @@ -97,8 +100,12 @@ impl<'tcx> Bounds<'tcx> { let ty = bound_trait_ref .map_bound(|trait_ref| Ty::new_projection(tcx, assoc, trait_ref.args)); - // Replace the binder with dummy types/lifetimes. This should work for any - // binder as long as they don't have any bounds e.g. `for`. + // 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 { @@ -128,24 +135,23 @@ impl<'tcx> Bounds<'tcx> { 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()], + }; + // 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?", ); - self.clauses.push((bound_trait_ref.rebind(new_trait_ref).upcast(tcx), span)); - } + 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 fn push_projection_bound( diff --git a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs index b32067ebd6aee..c03e074c80b7a 100644 --- a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs +++ b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs @@ -137,7 +137,7 @@ pub(super) fn explicit_item_bounds_with_filter( let tup = Ty::new(tcx, ty::Tuple(preds.effects_min_tys)); // FIXME(effects) span let span = tcx.def_span(def_id); - let assoc = tcx.require_lang_item(hir::LangItem::EffectsMinOutput, Some(span)); + let assoc = tcx.require_lang_item(hir::LangItem::EffectsIntersectionOutput, Some(span)); let proj = Ty::new_projection(tcx, assoc, [tup]); let self_proj = Ty::new_projection( tcx, diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index c0ebad9616df3..fabbec683506c 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -599,8 +599,8 @@ fn trait_lang_item_to_lang_item(lang_item: TraitSolverLangItem) -> LangItem { TraitSolverLangItem::DiscriminantKind => LangItem::DiscriminantKind, TraitSolverLangItem::DynMetadata => LangItem::DynMetadata, TraitSolverLangItem::EffectsMaybe => LangItem::EffectsMaybe, - TraitSolverLangItem::EffectsMin => LangItem::EffectsMin, - TraitSolverLangItem::EffectsMinOutput => LangItem::EffectsMinOutput, + TraitSolverLangItem::EffectsIntersection => LangItem::EffectsIntersection, + TraitSolverLangItem::EffectsIntersectionOutput => LangItem::EffectsIntersectionOutput, TraitSolverLangItem::EffectsNoRuntime => LangItem::EffectsNoRuntime, TraitSolverLangItem::EffectsRuntime => LangItem::EffectsRuntime, TraitSolverLangItem::FnPtrTrait => LangItem::FnPtrTrait, 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 8d57c3d9af004..6ee684605ac60 100644 --- a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs @@ -270,7 +270,7 @@ where goal: Goal, ) -> Vec>; - fn consider_builtin_effects_min_candidate( + fn consider_builtin_effects_intersection_candidate( ecx: &mut EvalCtxt<'_, D>, goal: Goal, ) -> Result, NoSolution>; @@ -425,8 +425,8 @@ where G::consider_builtin_destruct_candidate(self, goal) } else if cx.is_lang_item(trait_def_id, TraitSolverLangItem::TransmuteTrait) { G::consider_builtin_transmute_candidate(self, goal) - } else if tcx.is_lang_item(trait_def_id, TraitSolverLangItem::EffectsMin) { - G::consider_builtin_effects_min_candidate(self, goal) + } else if cx.is_lang_item(trait_def_id, TraitSolverLangItem::EffectsIntersection) { + G::consider_builtin_effects_intersection_candidate(self, goal) } else { Err(NoSolution) }; 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 7a81c210c5d04..9275bcc8e97c9 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 @@ -865,7 +865,7 @@ where panic!("`BikeshedIntrinsicFrom` does not have an associated type: {:?}", goal) } - fn consider_builtin_effects_min_candidate( + fn consider_builtin_effects_intersection_candidate( ecx: &mut EvalCtxt<'_, D>, goal: Goal, ) -> Result, NoSolution> { @@ -903,11 +903,15 @@ where 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::min(min, kind) else { + let Some(result) = ty::EffectKind::intersection(min, kind) else { return Err(NoSolution); }; 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 08ed729b14405..f5832f7e5b4c9 100644 --- a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs +++ b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs @@ -703,7 +703,7 @@ where }) } - fn consider_builtin_effects_min_candidate( + fn consider_builtin_effects_intersection_candidate( ecx: &mut EvalCtxt<'_, D>, goal: Goal, ) -> Result, NoSolution> { @@ -732,7 +732,7 @@ where return Err(NoSolution); }; - let Some(result) = ty::EffectKind::min(min, kind) else { + let Some(result) = ty::EffectKind::intersection(min, kind) else { return Err(NoSolution); }; diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 4a26e8ae09734..8b7a63f5eb9b6 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -195,9 +195,9 @@ symbols! { DoubleEndedIterator, Duration, EffectsCompat, + EffectsIntersection, + EffectsIntersectionOutput, EffectsMaybe, - EffectsMin, - EffectsMinOutput, EffectsNoRuntime, EffectsRuntime, EffectsTyCompat, diff --git a/compiler/rustc_ty_utils/src/assoc.rs b/compiler/rustc_ty_utils/src/assoc.rs index 6a55e83786cb8..6726db8bb54df 100644 --- a/compiler/rustc_ty_utils/src/assoc.rs +++ b/compiler/rustc_ty_utils/src/assoc.rs @@ -184,12 +184,10 @@ fn associated_type_for_effects(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option { let trait_def_id = def_id; - let Some(attr) = tcx.get_attr(def_id, sym::const_trait) else { - return None; - }; + 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); @@ -197,8 +195,6 @@ fn associated_type_for_effects(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option, def_id: LocalDefId) -> Option { let impl_def_id = def_id; - let Some(trait_id) = tcx.trait_id_of_impl(def_id.to_def_id()) else { return None }; + 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 Some(trait_assoc_id) = tcx.associated_type_for_effects(trait_id) else { - return None; - }; + let trait_assoc_id = tcx.associated_type_for_effects(trait_id)?; // FIXME(effects): span let span = tcx.def_ident_span(def_id).unwrap(); @@ -263,8 +232,6 @@ fn associated_type_for_effects(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option, def_id: LocalDefId) -> Option, def_id: LocalDefId) -> Option 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: diff --git a/compiler/rustc_type_ir/src/effects.rs b/compiler/rustc_type_ir/src/effects.rs index 39605936e3031..f7942f2f982f5 100644 --- a/compiler/rustc_type_ir/src/effects.rs +++ b/compiler/rustc_type_ir/src/effects.rs @@ -44,7 +44,10 @@ impl EffectKind { I::Ty::new_adt(tcx, tcx.adt_def(self.to_def_id(tcx)), Default::default()) } - pub fn min(a: Self, b: Self) -> Option { + /// 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), diff --git a/compiler/rustc_type_ir/src/lang_items.rs b/compiler/rustc_type_ir/src/lang_items.rs index 55b9709b66876..cf00c37caa287 100644 --- a/compiler/rustc_type_ir/src/lang_items.rs +++ b/compiler/rustc_type_ir/src/lang_items.rs @@ -17,9 +17,9 @@ pub enum TraitSolverLangItem { Destruct, DiscriminantKind, DynMetadata, + EffectsIntersection, + EffectsIntersectionOutput, EffectsMaybe, - EffectsMin, - EffectsMinOutput, EffectsNoRuntime, EffectsRuntime, FnPtrTrait, diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs index 042acbf20b1a0..9f5818f675d86 100644 --- a/library/core/src/marker.rs +++ b/library/core/src/marker.rs @@ -1062,9 +1062,14 @@ pub mod effects { impl TyCompat for Maybe {} impl TyCompat for T {} - #[lang = "EffectsMin"] - pub trait Min { - #[lang = "EffectsMinOutput"] + #[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/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.fixed b/src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.fixed index 921dcf0b16261..f8fc935f3679d 100644 --- a/src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.fixed +++ b/src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.fixed @@ -104,15 +104,18 @@ fn main() {} struct D; +/* FIXME(effects) impl const Drop for D { fn drop(&mut self) { todo!(); } } +*/ // Lint this, since it can be dropped in const contexts // FIXME(effects) -fn d(this: D) {} +const fn d(this: D) {} +//~^ ERROR: this could be a `const fn` mod msrv { struct Foo(*const u8, &'static u8); diff --git a/src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.stderr b/src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.stderr index 8ba42c0e5b673..8302b074127e6 100644 --- a/src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.stderr +++ b/src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.stderr @@ -161,6 +161,11 @@ error: this could be a `const fn` | LL | fn d(this: D) {} | ^^^^^^^^^^^^^^^^ + | +help: make the function `const` + | +LL | const fn d(this: D) {} + | +++++ error: this could be a `const fn` --> tests/ui/missing_const_for_fn/could_be_const.rs:125:9 diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-fns-are-early-bound.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-fns-are-early-bound.rs index fdc53dbab1cbc..b3087349e4d3c 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-fns-are-early-bound.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-fns-are-early-bound.rs @@ -126,10 +126,10 @@ pub mod effects { #[stable(feature = "minicore", since = "1.0.0")] impl TyCompat for T {} - #[lang = "EffectsMin"] + #[lang = "EffectsIntersection"] #[stable(feature = "minicore", since = "1.0.0")] - pub trait Min { - #[lang = "EffectsMinOutput"] + pub trait Intersection { + #[lang = "EffectsIntersectionOutput"] #[stable(feature = "minicore", since = "1.0.0")] type Output: ?Sized; } diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail.rs index bb8e06ab2f7a1..637a24f53bc63 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail.rs @@ -1,4 +1,5 @@ //@ check-pass +//@ compile-flags: -Znext-solver #![allow(incomplete_features)] #![feature(const_trait_impl, effects)] diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits.rs index b32c8cab7ecbe..fbe89b00b974b 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits.rs @@ -1,5 +1,7 @@ // FIXME(effects) check-pass //@ known-bug: #110395 +//@ compile-flags: -Znext-solver +#![allow(incomplete_features)] #![feature(const_trait_impl, effects)] #[const_trait] diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits.stderr index a9cb68a247ccd..5b6b39ee05ef6 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits.stderr @@ -1,20 +1,11 @@ -warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/super-traits.rs:3: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 `Foo::{synthetic#0}: ~const Compat` is not satisfied - --> $DIR/super-traits.rs:21:7 + --> $DIR/super-traits.rs:23:7 | LL | t.a(); | ^ the trait `~const Compat` is not implemented for `Foo::{synthetic#0}` | note: required by a bound in `Foo::a` - --> $DIR/super-traits.rs:5:1 + --> $DIR/super-traits.rs:7:1 | LL | #[const_trait] | ^^^^^^^^^^^^^^ required by this bound in `Foo::a` @@ -26,6 +17,6 @@ help: consider further restricting the associated type LL | const fn foo(t: &T) where Foo::{synthetic#0}: ~const Compat { | +++++++++++++++++++++++++++++++++++++++ -error: aborting due to 1 previous error; 1 warning emitted +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0277`.