diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index f2e90fd8eed0b..58725a08c7c5f 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -313,6 +313,16 @@ pub enum TraitBoundModifier { MaybeConstMaybe, } +impl TraitBoundModifier { + pub fn to_constness(self) -> Const { + match self { + // FIXME(effects) span + Self::MaybeConst => Const::Yes(DUMMY_SP), + _ => Const::No, + } + } +} + /// The AST represents all type param bounds as types. /// `typeck::collect::compute_bounds` matches these against /// the "special" built-in traits (see `middle::lang_items`) and diff --git a/compiler/rustc_ast_lowering/src/asm.rs b/compiler/rustc_ast_lowering/src/asm.rs index ab55c09465b1b..a1e626996800f 100644 --- a/compiler/rustc_ast_lowering/src/asm.rs +++ b/compiler/rustc_ast_lowering/src/asm.rs @@ -207,6 +207,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { &sym.path, ParamMode::Optional, &ImplTraitContext::Disallowed(ImplTraitPosition::Path), + None, ); hir::InlineAsmOperand::SymStatic { path, def_id } } else { diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs index 42d0998d16259..b23cee14f7586 100644 --- a/compiler/rustc_ast_lowering/src/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs @@ -100,6 +100,7 @@ impl<'hir> LoweringContext<'_, 'hir> { ParamMode::Optional, ParenthesizedGenericArgs::Err, &ImplTraitContext::Disallowed(ImplTraitPosition::Path), + None, )); let receiver = self.lower_expr(receiver); let args = @@ -260,6 +261,7 @@ impl<'hir> LoweringContext<'_, 'hir> { path, ParamMode::Optional, &ImplTraitContext::Disallowed(ImplTraitPosition::Path), + None, ); hir::ExprKind::Path(qpath) } @@ -307,6 +309,7 @@ impl<'hir> LoweringContext<'_, 'hir> { &se.path, ParamMode::Optional, &ImplTraitContext::Disallowed(ImplTraitPosition::Path), + None, )), self.arena .alloc_from_iter(se.fields.iter().map(|x| self.lower_expr_field(x))), @@ -1179,6 +1182,7 @@ impl<'hir> LoweringContext<'_, 'hir> { path, ParamMode::Optional, &ImplTraitContext::Disallowed(ImplTraitPosition::Path), + None, ); // Destructure like a tuple struct. let tuple_struct_pat = hir::PatKind::TupleStruct( @@ -1198,6 +1202,7 @@ impl<'hir> LoweringContext<'_, 'hir> { path, ParamMode::Optional, &ImplTraitContext::Disallowed(ImplTraitPosition::Path), + None, ); // Destructure like a unit struct. let unit_struct_pat = hir::PatKind::Path(qpath); @@ -1222,6 +1227,7 @@ impl<'hir> LoweringContext<'_, 'hir> { &se.path, ParamMode::Optional, &ImplTraitContext::Disallowed(ImplTraitPosition::Path), + None, ); let fields_omitted = match &se.rest { StructRest::Base(e) => { diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index df73c721ade23..7954297900f90 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -90,6 +90,7 @@ impl<'a, 'hir> ItemLowerer<'a, 'hir> { allow_try_trait: Some([sym::try_trait_v2, sym::yeet_desugar_details][..].into()), allow_gen_future, generics_def_id_map: Default::default(), + host_param_id: None, }; lctx.with_hir_id_owner(owner, |lctx| f(lctx)); @@ -144,8 +145,24 @@ impl<'a, 'hir> ItemLowerer<'a, 'hir> { // This is used to track which lifetimes have already been defined, // and which need to be replicated when lowering an async fn. - if let hir::ItemKind::Impl(impl_) = parent_hir.node().expect_item().kind { - lctx.is_in_trait_impl = impl_.of_trait.is_some(); + match parent_hir.node().expect_item().kind { + hir::ItemKind::Impl(impl_) => { + lctx.is_in_trait_impl = impl_.of_trait.is_some(); + } + hir::ItemKind::Trait(_, _, generics, _, _) if lctx.tcx.features().effects => { + lctx.host_param_id = generics + .params + .iter() + .find(|param| { + parent_hir + .attrs + .get(param.hir_id.local_id) + .iter() + .any(|attr| attr.has_name(sym::rustc_host)) + }) + .map(|param| param.def_id); + } + _ => {} } match ctxt { @@ -389,6 +406,7 @@ impl<'hir> LoweringContext<'_, 'hir> { self.lower_generics(ast_generics, *constness, id, &itctx, |this| { let trait_ref = trait_ref.as_ref().map(|trait_ref| { this.lower_trait_ref( + *constness, trait_ref, &ImplTraitContext::Disallowed(ImplTraitPosition::Trait), ) @@ -419,7 +437,6 @@ impl<'hir> LoweringContext<'_, 'hir> { polarity, defaultness, defaultness_span, - constness: self.lower_constness(*constness), generics, of_trait: trait_ref, self_ty: lowered_ty, @@ -1363,6 +1380,29 @@ impl<'hir> LoweringContext<'_, 'hir> { } } + // Desugar `~const` bound in generics into an additional `const host: bool` param + // if the effects feature is enabled. This needs to be done before we lower where + // clauses since where clauses need to bind to the DefId of the host param + let host_param_parts = if let Const::Yes(span) = constness && self.tcx.features().effects { + if let Some(param) = generics.params.iter().find(|x| { + x.attrs.iter().any(|x| x.has_name(sym::rustc_host)) + }) { + // user has manually specified a `rustc_host` param, in this case, we set + // the param id so that lowering logic can use that. But we don't create + // another host param, so this gives `None`. + self.host_param_id = Some(self.local_def_id(param.id)); + None + } else { + let param_node_id = self.next_node_id(); + let hir_id = self.next_id(); + let def_id = self.create_def(self.local_def_id(parent_node_id), param_node_id, DefPathData::TypeNs(sym::host), span); + self.host_param_id = Some(def_id); + Some((span, hir_id, def_id)) + } + } else { + None + }; + let mut predicates: SmallVec<[hir::WherePredicate<'hir>; 4]> = SmallVec::new(); predicates.extend(generics.params.iter().filter_map(|param| { self.lower_generic_bound_predicate( @@ -1410,22 +1450,11 @@ impl<'hir> LoweringContext<'_, 'hir> { let impl_trait_bounds = std::mem::take(&mut self.impl_trait_bounds); predicates.extend(impl_trait_bounds.into_iter()); - // Desugar `~const` bound in generics into an additional `const host: bool` param - // if the effects feature is enabled. - if let Const::Yes(span) = constness && self.tcx.features().effects - // Do not add host param if it already has it (manually specified) - && !params.iter().any(|x| { - self.attrs.get(&x.hir_id.local_id).map_or(false, |attrs| { - attrs.iter().any(|x| x.has_name(sym::rustc_host)) - }) - }) - { - let param_node_id = self.next_node_id(); + if let Some((span, hir_id, def_id)) = host_param_parts { let const_node_id = self.next_node_id(); - let def_id = self.create_def(self.local_def_id(parent_node_id), param_node_id, DefPathData::TypeNs(sym::host), span); - let anon_const: LocalDefId = self.create_def(def_id, const_node_id, DefPathData::AnonConst, span); + let anon_const: LocalDefId = + self.create_def(def_id, const_node_id, DefPathData::AnonConst, span); - let hir_id = self.next_id(); let const_id = self.next_id(); let const_expr_id = self.next_id(); let bool_id = self.next_id(); @@ -1435,14 +1464,15 @@ impl<'hir> LoweringContext<'_, 'hir> { let attr_id = self.tcx.sess.parse_sess.attr_id_generator.mk_attr_id(); - let attrs = self.arena.alloc_from_iter([ - Attribute { - kind: AttrKind::Normal(P(NormalAttr::from_ident(Ident::new(sym::rustc_host, span)))), + let attrs = self.arena.alloc_from_iter([Attribute { + kind: AttrKind::Normal(P(NormalAttr::from_ident(Ident::new( + sym::rustc_host, span, - id: attr_id, - style: AttrStyle::Outer, - }, - ]); + )))), + span, + id: attr_id, + style: AttrStyle::Outer, + }]); self.attrs.insert(hir_id.local_id, attrs); let const_body = self.lower_body(|this| { @@ -1481,7 +1511,11 @@ impl<'hir> LoweringContext<'_, 'hir> { }), )), )), - default: Some(hir::AnonConst { def_id: anon_const, hir_id: const_id, body: const_body }), + default: Some(hir::AnonConst { + def_id: anon_const, + hir_id: const_id, + body: const_body, + }), }, 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 a8151ccfff3c9..0aeff22ca9f8a 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -142,6 +142,8 @@ struct LoweringContext<'a, 'hir> { /// defined on the TAIT, so we have type Foo<'a1> = ... and we establish a mapping in this /// field from the original parameter 'a to the new parameter 'a1. generics_def_id_map: Vec>, + + host_param_id: Option, } trait ResolverAstLoweringExt { @@ -1262,6 +1264,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { span: t.span }, itctx, + ast::Const::No, ); let bounds = this.arena.alloc_from_iter([bound]); let lifetime_bound = this.elided_dyn_bound(t.span); @@ -1272,7 +1275,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { } let id = self.lower_node_id(t.id); - let qpath = self.lower_qpath(t.id, qself, path, param_mode, itctx); + let qpath = self.lower_qpath(t.id, qself, path, param_mode, itctx, None); self.ty_path(id, t.span, qpath) } @@ -1356,10 +1359,12 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { this.arena.alloc_from_iter(bounds.iter().filter_map(|bound| match bound { GenericBound::Trait( ty, - TraitBoundModifier::None + modifier @ (TraitBoundModifier::None | TraitBoundModifier::MaybeConst - | TraitBoundModifier::Negative, - ) => Some(this.lower_poly_trait_ref(ty, itctx)), + | TraitBoundModifier::Negative), + ) => { + Some(this.lower_poly_trait_ref(ty, itctx, modifier.to_constness())) + } // `~const ?Bound` will cause an error during AST validation // anyways, so treat it like `?Bound` as compilation proceeds. GenericBound::Trait( @@ -1952,7 +1957,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { ) -> hir::GenericBound<'hir> { match tpb { GenericBound::Trait(p, modifier) => hir::GenericBound::Trait( - self.lower_poly_trait_ref(p, itctx), + self.lower_poly_trait_ref(p, itctx, modifier.to_constness()), self.lower_trait_bound_modifier(*modifier), ), GenericBound::Outlives(lifetime) => { @@ -2095,8 +2100,20 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { } } - fn lower_trait_ref(&mut self, p: &TraitRef, itctx: &ImplTraitContext) -> hir::TraitRef<'hir> { - let path = match self.lower_qpath(p.ref_id, &None, &p.path, ParamMode::Explicit, itctx) { + fn lower_trait_ref( + &mut self, + constness: ast::Const, + p: &TraitRef, + itctx: &ImplTraitContext, + ) -> hir::TraitRef<'hir> { + let path = match self.lower_qpath( + p.ref_id, + &None, + &p.path, + ParamMode::Explicit, + itctx, + Some(constness), + ) { hir::QPath::Resolved(None, path) => path, qpath => panic!("lower_trait_ref: unexpected QPath `{qpath:?}`"), }; @@ -2108,10 +2125,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { &mut self, p: &PolyTraitRef, itctx: &ImplTraitContext, + constness: ast::Const, ) -> hir::PolyTraitRef<'hir> { let bound_generic_params = self.lower_lifetime_binder(p.trait_ref.ref_id, &p.bound_generic_params); - let trait_ref = self.lower_trait_ref(&p.trait_ref, itctx); + let trait_ref = self.lower_trait_ref(constness, &p.trait_ref, itctx); hir::PolyTraitRef { bound_generic_params, trait_ref, span: self.lower_span(p.span) } } @@ -2465,6 +2483,67 @@ struct GenericArgsCtor<'hir> { } impl<'hir> GenericArgsCtor<'hir> { + fn push_constness(&mut self, lcx: &mut LoweringContext<'_, 'hir>, constness: ast::Const) { + if !lcx.tcx.features().effects { + return; + } + + // if bound is non-const, don't add host effect param + let ast::Const::Yes(span) = constness else { return }; + + let span = lcx.lower_span(span); + + let id = lcx.next_node_id(); + let hir_id = lcx.next_id(); + let body = lcx.lower_body(|lcx| { + ( + &[], + match constness { + ast::Const::Yes(_) => { + let hir_id = lcx.next_id(); + let res = + Res::Def(DefKind::ConstParam, lcx.host_param_id.unwrap().to_def_id()); + let expr_kind = 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)], + }), + )); + lcx.expr(span, expr_kind) + } + ast::Const::No => lcx.expr( + span, + hir::ExprKind::Lit( + lcx.arena.alloc(hir::Lit { span, node: ast::LitKind::Bool(true) }), + ), + ), + }, + ) + }); + + let attr_id = lcx.tcx.sess.parse_sess.attr_id_generator.mk_attr_id(); + let attr = lcx.arena.alloc(Attribute { + kind: AttrKind::Normal(P(NormalAttr::from_ident(Ident::new(sym::rustc_host, span)))), + span, + id: attr_id, + style: AttrStyle::Outer, + }); + lcx.attrs.insert(hir_id.local_id, std::slice::from_ref(attr)); + + let def_id = + lcx.create_def(lcx.current_hir_id_owner.def_id, id, DefPathData::AnonConst, span); + lcx.children.push((def_id, hir::MaybeOwner::NonOwner(hir_id))); + self.args.push(hir::GenericArg::Const(hir::ConstArg { + value: hir::AnonConst { def_id, hir_id, body }, + span, + })) + } + fn is_empty(&self) -> bool { self.args.is_empty() && self.bindings.is_empty() diff --git a/compiler/rustc_ast_lowering/src/pat.rs b/compiler/rustc_ast_lowering/src/pat.rs index 2509b70563956..a30f264bc7dc7 100644 --- a/compiler/rustc_ast_lowering/src/pat.rs +++ b/compiler/rustc_ast_lowering/src/pat.rs @@ -38,6 +38,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { path, ParamMode::Optional, &ImplTraitContext::Disallowed(ImplTraitPosition::Path), + None, ); let (pats, ddpos) = self.lower_pat_tuple(pats, "tuple struct"); break hir::PatKind::TupleStruct(qpath, pats, ddpos); @@ -54,6 +55,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { path, ParamMode::Optional, &ImplTraitContext::Disallowed(ImplTraitPosition::Path), + None, ); break hir::PatKind::Path(qpath); } @@ -64,6 +66,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { path, ParamMode::Optional, &ImplTraitContext::Disallowed(ImplTraitPosition::Path), + None, ); let fs = self.arena.alloc_from_iter(fields.iter().map(|f| { diff --git a/compiler/rustc_ast_lowering/src/path.rs b/compiler/rustc_ast_lowering/src/path.rs index 441282c05b424..899f92a995821 100644 --- a/compiler/rustc_ast_lowering/src/path.rs +++ b/compiler/rustc_ast_lowering/src/path.rs @@ -23,6 +23,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { p: &Path, param_mode: ParamMode, itctx: &ImplTraitContext, + // constness of the impl/bound if this is a trait path + constness: Option, ) -> hir::QPath<'hir> { let qself_position = qself.as_ref().map(|q| q.position); let qself = qself.as_ref().map(|q| self.lower_ty(&q.ty, itctx)); @@ -73,6 +75,8 @@ 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 { constness } else { None }, ) }, )), @@ -119,6 +123,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { param_mode, ParenthesizedGenericArgs::Err, itctx, + None, )); let qpath = hir::QPath::TypeRelative(ty, hir_segment); @@ -159,6 +164,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { param_mode, ParenthesizedGenericArgs::Err, &ImplTraitContext::Disallowed(ImplTraitPosition::Path), + None, ) })), span: self.lower_span(p.span), @@ -172,8 +178,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { param_mode: ParamMode, parenthesized_generic_args: ParenthesizedGenericArgs, itctx: &ImplTraitContext, + constness: Option, ) -> hir::PathSegment<'hir> { - debug!("path_span: {:?}, lower_path_segment(segment: {:?})", path_span, segment,); + debug!("path_span: {:?}, lower_path_segment(segment: {:?})", path_span, segment); let (mut generic_args, infer_args) = if let Some(generic_args) = segment.args.as_deref() { match generic_args { GenericArgs::AngleBracketed(data) => { @@ -231,6 +238,10 @@ 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 cc39387c41fc1..4ee4ebbb9e449 100644 --- a/compiler/rustc_const_eval/src/const_eval/fn_queries.rs +++ b/compiler/rustc_const_eval/src/const_eval/fn_queries.rs @@ -40,7 +40,7 @@ fn constness(tcx: TyCtxt<'_>, def_id: LocalDefId) -> hir::Constness { | hir::Node::AnonConst(_) | hir::Node::ConstBlock(_) | hir::Node::ImplItem(hir::ImplItem { kind: hir::ImplItemKind::Const(..), .. }) => hir::Constness::Const, - hir::Node::Item(hir::Item { kind: hir::ItemKind::Impl(impl_), .. }) => impl_.constness, + 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::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_const_eval/src/transform/check_consts/mod.rs b/compiler/rustc_const_eval/src/transform/check_consts/mod.rs index e77fb4ea2a2c7..e51082e1ec0e3 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/mod.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/mod.rs @@ -127,15 +127,8 @@ fn is_parent_const_stable_trait(tcx: TyCtxt<'_>, def_id: DefId) -> bool { let hir_id = tcx.local_def_id_to_hir_id(local_def_id); let Some(parent) = tcx.hir().opt_parent_id(hir_id) else { return false }; - let parent_def = tcx.hir().get(parent); - - if !matches!( - parent_def, - hir::Node::Item(hir::Item { - kind: hir::ItemKind::Impl(hir::Impl { constness: hir::Constness::Const, .. }), - .. - }) - ) { + + if !tcx.is_const_trait_impl_raw(parent.owner.def_id.to_def_id()) { return false; } diff --git a/compiler/rustc_const_eval/src/transform/check_consts/ops.rs b/compiler/rustc_const_eval/src/transform/check_consts/ops.rs index e785196c744c3..1f3cda35c2ba1 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/ops.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/ops.rs @@ -145,8 +145,11 @@ impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> { let implsrc = selcx.select(&obligation); if let Ok(Some(ImplSource::UserDefined(data))) = implsrc { - let span = tcx.def_span(data.impl_def_id); - err.subdiagnostic(errors::NonConstImplNote { span }); + // FIXME(effects) revisit this + if !tcx.is_const_trait_impl_raw(data.impl_def_id) { + let span = tcx.def_span(data.impl_def_id); + err.subdiagnostic(errors::NonConstImplNote { span }); + } } } _ => {} diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 61353c7b1ec51..92a91766d9134 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -3359,7 +3359,6 @@ pub struct Impl<'hir> { // We do not put a `Span` in `Defaultness` because it breaks foreign crate metadata // decoding as `Span`s cannot be decoded when a `Session` is not available. pub defaultness_span: Option, - pub constness: Constness, pub generics: &'hir Generics<'hir>, /// The trait being implemented, if any. diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs index 9d1d899eef0bd..172f557f8e2ae 100644 --- a/compiler/rustc_hir/src/intravisit.rs +++ b/compiler/rustc_hir/src/intravisit.rs @@ -522,7 +522,6 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item<'v>) { unsafety: _, defaultness: _, polarity: _, - constness: _, defaultness_span: _, ref generics, ref of_trait, diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs index 319573c85b44b..668763f9bf60d 100644 --- a/compiler/rustc_hir_analysis/src/astconv/mod.rs +++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs @@ -532,6 +532,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { if let Err(guar) = ty.error_reported() { return ty::Const::new_error(tcx, guar, ty).into(); } + // FIXME(effects) see if we should special case effect params here if !infer_args && has_default { tcx.const_param_default(param.def_id) .instantiate(tcx, args.unwrap()) @@ -659,7 +660,6 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { &self, trait_ref: &hir::TraitRef<'_>, self_ty: Ty<'tcx>, - constness: ty::BoundConstness, ) -> ty::TraitRef<'tcx> { self.prohibit_generics(trait_ref.path.segments.split_last().unwrap().1.iter(), |_| {}); @@ -669,7 +669,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { self_ty, trait_ref.path.segments.last().unwrap(), true, - constness, + ty::BoundConstness::NotConst, ) } @@ -849,6 +849,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { self_ty: Ty<'tcx>, trait_segment: &hir::PathSegment<'_>, is_impl: bool, + // FIXME(effects) move all host param things in astconv to hir lowering constness: ty::BoundConstness, ) -> ty::TraitRef<'tcx> { let (generic_args, _) = self.create_args_for_ast_trait_ref( @@ -2714,11 +2715,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { }; let i = hir.get_parent(fn_hir_id).expect_item().expect_impl(); - let trait_ref = self.instantiate_mono_trait_ref( - i.of_trait.as_ref()?, - self.ast_ty_to_ty(i.self_ty), - ty::BoundConstness::NotConst, - ); + let trait_ref = + self.instantiate_mono_trait_ref(i.of_trait.as_ref()?, self.ast_ty_to_ty(i.self_ty)); let assoc = tcx.associated_items(trait_ref.def_id).find_by_name_and_kind( tcx, diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index f568b75195198..02a5d28b1e233 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -1359,38 +1359,60 @@ fn impl_trait_ref( .as_ref() .map(|ast_trait_ref| { let selfty = tcx.type_of(def_id).instantiate_identity(); - icx.astconv().instantiate_mono_trait_ref( - ast_trait_ref, - selfty, - check_impl_constness(tcx, impl_.constness, ast_trait_ref), - ) + + if let Some(ErrorGuaranteed { .. }) = check_impl_constness( + tcx, + tcx.is_const_trait_impl_raw(def_id.to_def_id()), + &ast_trait_ref, + ) { + // we have a const impl, but for a trait without `#[const_trait]`, so + // without the host param. If we continue with the HIR trait ref, we get + // ICEs for generic arg count mismatch. We do a little HIR editing to + // make astconv happy. + let mut path_segments = ast_trait_ref.path.segments.to_vec(); + let last_segment = path_segments.len() - 1; + let mut args = path_segments[last_segment].args().clone(); + let last_arg = args.args.len() - 1; + assert!(matches!(args.args[last_arg], hir::GenericArg::Const(anon_const) if tcx.has_attr(anon_const.value.def_id, sym::rustc_host))); + args.args = &args.args[..args.args.len() - 1]; + path_segments[last_segment].args = Some(&args); + let path = hir::Path { + span: ast_trait_ref.path.span, + res: ast_trait_ref.path.res, + segments: &path_segments, + }; + let trait_ref = hir::TraitRef { path: &path, hir_ref_id: ast_trait_ref.hir_ref_id }; + icx.astconv().instantiate_mono_trait_ref(&trait_ref, selfty) + } else { + icx.astconv().instantiate_mono_trait_ref(&ast_trait_ref, selfty) + } }) .map(ty::EarlyBinder::bind) } fn check_impl_constness( tcx: TyCtxt<'_>, - constness: hir::Constness, + is_const: bool, ast_trait_ref: &hir::TraitRef<'_>, -) -> ty::BoundConstness { - match constness { - hir::Constness::Const => { - if let Some(trait_def_id) = ast_trait_ref.trait_def_id() && !tcx.has_attr(trait_def_id, sym::const_trait) { - let trait_name = tcx.item_name(trait_def_id).to_string(); - tcx.sess.emit_err(errors::ConstImplForNonConstTrait { - trait_ref_span: ast_trait_ref.path.span, - trait_name, - local_trait_span: trait_def_id.as_local().map(|_| tcx.def_span(trait_def_id).shrink_to_lo()), - marking: (), - adding: (), - }); - ty::BoundConstness::NotConst - } else { - ty::BoundConstness::ConstIfConst - } - }, - hir::Constness::NotConst => ty::BoundConstness::NotConst, +) -> Option { + if !is_const { + return None; } + + let trait_def_id = ast_trait_ref.trait_def_id()?; + if tcx.has_attr(trait_def_id, sym::const_trait) { + return None; + } + + let trait_name = tcx.item_name(trait_def_id).to_string(); + Some(tcx.sess.emit_err(errors::ConstImplForNonConstTrait { + trait_ref_span: ast_trait_ref.path.span, + trait_name, + local_trait_span: + trait_def_id.as_local().map(|_| tcx.def_span(trait_def_id).shrink_to_lo()), + marking: (), + adding: (), + })) } fn impl_polarity(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::ImplPolarity { diff --git a/compiler/rustc_hir_analysis/src/collect/generics_of.rs b/compiler/rustc_hir_analysis/src/collect/generics_of.rs index 6e1762c54f21e..4842008279a90 100644 --- a/compiler/rustc_hir_analysis/src/collect/generics_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/generics_of.rs @@ -320,7 +320,7 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics { bug!("parent also has host effect param? index: {idx}, def: {def_id:?}"); } - host_effect_index = Some(parent_count + index as usize); + host_effect_index = Some(index as usize); } Some(ty::GenericParamDef { diff --git a/compiler/rustc_hir_analysis/src/structured_errors/wrong_number_of_generic_args.rs b/compiler/rustc_hir_analysis/src/structured_errors/wrong_number_of_generic_args.rs index 6be8d72aed205..61b182b1be782 100644 --- a/compiler/rustc_hir_analysis/src/structured_errors/wrong_number_of_generic_args.rs +++ b/compiler/rustc_hir_analysis/src/structured_errors/wrong_number_of_generic_args.rs @@ -578,6 +578,9 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> { MissingTypesOrConsts { .. } => { self.suggest_adding_type_and_const_args(err); } + ExcessTypesOrConsts { .. } => { + // this can happen with `~const T` where T isn't a const_trait. + } _ => unreachable!(), } } diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs index fda4679870806..89efdc269c466 100644 --- a/compiler/rustc_hir_pretty/src/lib.rs +++ b/compiler/rustc_hir_pretty/src/lib.rs @@ -626,7 +626,6 @@ impl<'a> State<'a> { unsafety, polarity, defaultness, - constness, defaultness_span: _, generics, ref of_trait, @@ -643,10 +642,6 @@ impl<'a> State<'a> { self.space(); } - if constness == hir::Constness::Const { - self.word_nbsp("const"); - } - if let hir::ImplPolarity::Negative(_) = polarity { self.word("!"); } diff --git a/compiler/rustc_hir_typeck/src/callee.rs b/compiler/rustc_hir_typeck/src/callee.rs index c68f2d94f3521..ba00954db9182 100644 --- a/compiler/rustc_hir_typeck/src/callee.rs +++ b/compiler/rustc_hir_typeck/src/callee.rs @@ -767,9 +767,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ) { let tcx = self.tcx; - if !tcx.features().effects || tcx.sess.opts.unstable_opts.unleash_the_miri_inside_of_you { - return; - } + // fast-reject if callee doesn't have the host effect param (non-const) + let generics = tcx.generics_of(callee_did); + let Some(host_effect_index) = generics.host_effect_index else { return }; + + // if the callee does have the param, we need to equate the param to some const + // value no matter whether the effects feature is enabled in the local crate, + // because inference will fail if we don't. + let mut host_always_on = + !tcx.features().effects || tcx.sess.opts.unstable_opts.unleash_the_miri_inside_of_you; // Compute the constness required by the context. let context = tcx.hir().enclosing_body_owner(call_expr_hir); @@ -780,10 +786,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if tcx.has_attr(context.to_def_id(), sym::rustc_do_not_const_check) { trace!("do not const check this context"); - return; + host_always_on = true; } let effect = match const_context { + _ if host_always_on => tcx.consts.true_, Some(hir::ConstContext::Static(_) | hir::ConstContext::Const) => tcx.consts.false_, Some(hir::ConstContext::ConstFn) => { let args = ty::GenericArgs::identity_for_item(tcx, context); @@ -792,21 +799,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { None => tcx.consts.true_, }; - let generics = tcx.generics_of(callee_did); - trace!(?effect, ?generics, ?callee_args); - if let Some(idx) = generics.host_effect_index { - let param = callee_args.const_at(idx); - let cause = self.misc(span); - match self.at(&cause, self.param_env).eq(infer::DefineOpaqueTypes::No, effect, param) { - Ok(infer::InferOk { obligations, value: () }) => { - self.register_predicates(obligations); - } - Err(e) => { - // FIXME(effects): better diagnostic - self.err_ctxt().report_mismatched_consts(&cause, effect, param, e).emit(); - } + let param = callee_args.const_at(host_effect_index); + let cause = self.misc(span); + match self.at(&cause, self.param_env).eq(infer::DefineOpaqueTypes::No, effect, param) { + Ok(infer::InferOk { obligations, value: () }) => { + self.register_predicates(obligations); + } + Err(e) => { + // FIXME(effects): better diagnostic + self.err_ctxt().report_mismatched_consts(&cause, effect, param, e).emit(); } } } diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index 322d726a89d71..8fad0a6c9e495 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -1349,7 +1349,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } GenericParamDefKind::Const { has_default } => { - if !infer_args && has_default { + if !infer_args + && has_default + && !tcx.has_attr(param.def_id, sym::rustc_host) + { tcx.const_param_default(param.def_id) .instantiate(tcx, args.unwrap()) .into() diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 6446f48bd1a5a..8ac1d02ce50e6 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -2041,9 +2041,9 @@ impl<'tcx> TyCtxt<'tcx> { matches!( node, hir::Node::Item(hir::Item { - kind: hir::ItemKind::Impl(hir::Impl { constness: hir::Constness::Const, .. }), + kind: hir::ItemKind::Impl(hir::Impl { generics, .. }), .. - }) + }) if generics.params.iter().any(|p| self.has_attr(p.def_id, sym::rustc_host)) ) } diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index 27ade16739de6..e5b4232431bda 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -2841,6 +2841,11 @@ define_print_and_forward_display! { ty::TraitPredicate<'tcx> { p!(print(self.trait_ref.self_ty()), ": "); + if let Some(idx) = cx.tcx().generics_of(self.trait_ref.def_id).host_effect_index { + if self.trait_ref.args.const_at(idx) != cx.tcx().consts.true_ { + p!("~const "); + } + } // FIXME(effects) print `~const` here if let ty::ImplPolarity::Negative = self.polarity { p!("!"); diff --git a/compiler/rustc_passes/src/stability.rs b/compiler/rustc_passes/src/stability.rs index 25a3d38c14425..3950ac9dd31c9 100644 --- a/compiler/rustc_passes/src/stability.rs +++ b/compiler/rustc_passes/src/stability.rs @@ -732,13 +732,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'tcx> { // For implementations of traits, check the stability of each item // individually as it's possible to have a stable trait with unstable // items. - hir::ItemKind::Impl(hir::Impl { - of_trait: Some(ref t), - self_ty, - items, - constness, - .. - }) => { + hir::ItemKind::Impl(hir::Impl { of_trait: Some(ref t), self_ty, items, .. }) => { let features = self.tcx.features(); if features.staged_api { let attrs = self.tcx.hir().attrs(item.hir_id()); @@ -769,7 +763,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'tcx> { // `#![feature(const_trait_impl)]` is unstable, so any impl declared stable // needs to have an error emitted. if features.const_trait_impl - && *constness == hir::Constness::Const + && self.tcx.is_const_trait_impl_raw(item.owner_id.to_def_id()) && const_stab.is_some_and(|(stab, _)| stab.is_const_stable()) { self.tcx.sess.emit_err(errors::TraitImplConstStable { span: item.span }); diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs index 4d85e2b60893e..647840829921c 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -3110,27 +3110,6 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { ) -> UnsatisfiedConst { let unsatisfied_const = UnsatisfiedConst(false); // FIXME(effects) - /* if trait_predicate.is_const_if_const() { - let non_const_predicate = trait_ref.without_const(); - let non_const_obligation = Obligation { - cause: obligation.cause.clone(), - param_env: obligation.param_env, - predicate: non_const_predicate.to_predicate(self.tcx), - recursion_depth: obligation.recursion_depth, - }; - if self.predicate_may_hold(&non_const_obligation) { - unsatisfied_const = UnsatisfiedConst(true); - err.span_note( - span, - format!( - "the trait `{}` is implemented for `{}`, \ - but that implementation is not `const`", - non_const_predicate.print_modifiers_and_trait_path(), - trait_ref.skip_binder().self_ty(), - ), - ); - } - } */ unsatisfied_const } 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 6e04cfaec31fb..88dff91920674 100644 --- a/tests/ui/const-generics/const_trait_fn-issue-88433.rs +++ b/tests/ui/const-generics/const_trait_fn-issue-88433.rs @@ -1,6 +1,6 @@ // build-pass -#![feature(const_trait_impl)] +#![feature(const_trait_impl, effects)] #[const_trait] trait Func { 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 7f28771cee83f..eb71ebb62ebbf 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,11 +1,39 @@ -error: const `impl` for trait `Add` which is not marked with `#[const_trait]` - --> $DIR/unify-op-with-fn-call.rs:10:12 +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 | -LL | impl const std::ops::Add for Foo { - | ^^^^^^^^^^^^^ +LL | struct Evaluatable; + | ^^^ + | +help: add `#[derive(ConstParamTy)]` to the struct + | +LL + #[derive(ConstParamTy)] +LL | struct Foo(u8); + | + +error[E0741]: `Foo` must implement `ConstParamTy` to be used as the type of a const generic parameter + --> $DIR/unify-op-with-fn-call.rs:20:17 + | +LL | fn foo(a: Evaluatable<{ N + N }>) { + | ^^^ + | +help: add `#[derive(ConstParamTy)]` to the struct + | +LL + #[derive(ConstParamTy)] +LL | struct Foo(u8); + | + +error[E0741]: `Foo` must implement `ConstParamTy` to be used as the type of a const generic parameter + --> $DIR/unify-op-with-fn-call.rs:24:17 + | +LL | fn bar() {} + | ^^^ + | +help: add `#[derive(ConstParamTy)]` to the struct + | +LL + #[derive(ConstParamTy)] +LL | struct Foo(u8); | - = 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 previous error +error: aborting due to 3 previous errors +For more information about this error, try `rustc --explain E0741`. diff --git a/tests/ui/consts/const-try.stderr b/tests/ui/consts/const-try.stderr index 37014f9b83f69..94f4153a29e7b 100644 --- a/tests/ui/consts/const-try.stderr +++ b/tests/ui/consts/const-try.stderr @@ -1,20 +1,29 @@ -error: const `impl` for trait `FromResidual` which is not marked with `#[const_trait]` - --> $DIR/const-try.rs:15:12 +error[E0015]: `?` cannot determine the branch of `TryMe` in constant functions + --> $DIR/const-try.rs:33:5 | -LL | impl const FromResidual for TryMe { - | ^^^^^^^^^^^^^^^^^^^ +LL | 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: const `impl` for trait `Try` which is not marked with `#[const_trait]` - --> $DIR/const-try.rs:21:12 +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 + +error[E0015]: `?` cannot convert from residual of `TryMe` in constant functions + --> $DIR/const-try.rs:33:5 | - = 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 +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 error: aborting due to 2 previous errors +For more information about this error, try `rustc --explain E0015`. diff --git a/tests/ui/consts/rustc-impl-const-stability.rs b/tests/ui/consts/rustc-impl-const-stability.rs index a1a741e80e55e..2b67c2f2cffe7 100644 --- a/tests/ui/consts/rustc-impl-const-stability.rs +++ b/tests/ui/consts/rustc-impl-const-stability.rs @@ -2,7 +2,7 @@ #![crate_type = "lib"] #![feature(staged_api)] -#![feature(const_trait_impl)] +#![feature(const_trait_impl, effects)] #![stable(feature = "foo", since = "1.0.0")] #[stable(feature = "potato", since = "1.27.0")] diff --git a/tests/ui/consts/rustc-impl-const-stability.stderr b/tests/ui/consts/rustc-impl-const-stability.stderr index e6930da71ec78..ba8e6c1555ce2 100644 --- a/tests/ui/consts/rustc-impl-const-stability.stderr +++ b/tests/ui/consts/rustc-impl-const-stability.stderr @@ -7,5 +7,15 @@ 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: aborting due to previous error +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 +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 e73082c11276f..f40dc27cb4c6f 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,4 @@ -#![feature(const_trait_impl)] +#![feature(const_trait_impl, effects)] #[const_trait] pub trait MyTrait { diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/auxiliary/staged-api.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/auxiliary/staged-api.rs index 589e3f02420f7..687cb128b05be 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/auxiliary/staged-api.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/auxiliary/staged-api.rs @@ -1,4 +1,4 @@ -#![feature(const_trait_impl)] +#![feature(const_trait_impl, effects)] #![feature(staged_api)] #![stable(feature = "rust1", since = "1.0.0")] diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-const-trait-method-fail.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-const-trait-method-fail.rs index 646955fd867f0..771c35cf6ab9d 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-const-trait-method-fail.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-const-trait-method-fail.rs @@ -1,4 +1,4 @@ -#![feature(const_trait_impl)] +#![feature(const_trait_impl, effects)] #[const_trait] pub trait Plus { @@ -23,7 +23,7 @@ pub const fn add_i32(a: i32, b: i32) -> i32 { pub const fn add_u32(a: u32, b: u32) -> u32 { a.plus(b) - //~^ ERROR cannot call + //~^ ERROR the trait bound } fn main() {} 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 0ee1b1a5cb25b..2d9c49af85a9a 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 @@ -1,11 +1,11 @@ -error[E0015]: cannot call non-const fn `::plus` in constant functions +error[E0277]: the trait bound `u32: ~const Plus` is not satisfied --> $DIR/call-const-trait-method-fail.rs:25:7 | LL | a.plus(b) - | ^^^^^^^ + | ^^^^ the trait `Plus` is not implemented for `u32` | - = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants + = help: the trait `Plus` is implemented for `u32` error: aborting due to previous error -For more information about this error, try `rustc --explain E0015`. +For more information about this error, try `rustc --explain E0277`. 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 ff53eea1110c0..60cd000f2d8c4 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,24 @@ -error: const `impl` for trait `Add` which is not marked with `#[const_trait]` - --> $DIR/call-const-trait-method-pass.rs:7:12 +error[E0015]: cannot call non-const fn `::plus` in constant functions + --> $DIR/call-const-trait-method-pass.rs:36:7 | -LL | impl const std::ops::Add for Int { - | ^^^^^^^^^^^^^ +LL | a.plus(b) + | ^^^^^^^ | - = 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: calls in constant functions are limited to constant functions, tuple structs and tuple variants -error: const `impl` for trait `PartialEq` which is not marked with `#[const_trait]` - --> $DIR/call-const-trait-method-pass.rs:15:12 +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); + | ^^^^^^^^^^^^^^^^^^^^^ | -LL | impl const PartialEq for Int { - | ^^^^^^^^^ +note: impl defined here, but it is not `const` + --> $DIR/call-const-trait-method-pass.rs:7:1 | - = 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 +LL | impl const std::ops::Add for Int { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: calls in constants are limited to constant functions, tuple structs and tuple variants 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/call-generic-method-chain.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-chain.stderr index 529a472e0bda5..37faa3f6bce23 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 @@ -1,12 +1,3 @@ -error: const `impl` for trait `PartialEq` which is not marked with `#[const_trait]` - --> $DIR/call-generic-method-chain.rs:9:12 - | -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: ~const can only be applied to `#[const_trait]` traits --> $DIR/call-generic-method-chain.rs:18:32 | @@ -19,5 +10,5 @@ error: ~const can only be applied to `#[const_trait]` traits LL | const fn equals_self_wrapper(t: &T) -> bool { | ^^^^^^^^^ -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors 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 bdc6ccc8aec23..90cfe04a9a862 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 @@ -1,12 +1,3 @@ -error: const `impl` for trait `PartialEq` which is not marked with `#[const_trait]` - --> $DIR/call-generic-method-dup-bound.rs:7:12 - | -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: ~const can only be applied to `#[const_trait]` traits --> $DIR/call-generic-method-dup-bound.rs:18:44 | @@ -19,5 +10,5 @@ error: ~const can only be applied to `#[const_trait]` traits LL | const fn equals_self2(t: &T) -> bool { | ^^^^^^^^^ -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors 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 7fbe89dba3cb3..bea1846e79be7 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 @@ -1,17 +1,8 @@ -error: const `impl` for trait `PartialEq` which is not marked with `#[const_trait]` - --> $DIR/call-generic-method-pass.rs:9:12 - | -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: ~const can only be applied to `#[const_trait]` traits --> $DIR/call-generic-method-pass.rs:18:32 | LL | const fn equals_self(t: &T) -> bool { | ^^^^^^^^^ -error: aborting due to 2 previous errors +error: aborting due to previous error 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 4f858d61eebaa..54bc434772297 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,20 +1,25 @@ -error: const `impl` for trait `Add` which is not marked with `#[const_trait]` - --> $DIR/const-and-non-const-impl.rs:7:12 +error[E0117]: only traits defined in the current crate can be implemented for primitive types + --> $DIR/const-and-non-const-impl.rs:7:1 | LL | impl const std::ops::Add for i32 { - | ^^^^^^^^^^^^^ + | ^^^^^^^^^^^-------------^^^^^--- + | | | | + | | | `i32` is not defined in the current crate + | | `i32` is not defined in the current crate + | impl doesn't use only types from inside the current crate | - = 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: define and implement a trait or new type instead -error: const `impl` for trait `Add` which is not marked with `#[const_trait]` - --> $DIR/const-and-non-const-impl.rs:23:12 +error[E0119]: conflicting implementations of trait `Add` for type `Int` + --> $DIR/const-and-non-const-impl.rs:23:1 | +LL | impl std::ops::Add for Int { + | -------------------------- first implementation here +... 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 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `Int` error: aborting due to 2 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-check-fns-in-const-impl.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-check-fns-in-const-impl.rs index 52984fb6be490..4854f41bf04f4 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-check-fns-in-const-impl.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-check-fns-in-const-impl.rs @@ -1,4 +1,4 @@ -#![feature(const_trait_impl)] +#![feature(const_trait_impl, effects)] struct S; #[const_trait] diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-default-method-bodies.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-default-method-bodies.rs index 3370f32061c28..be668b4f13a85 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-default-method-bodies.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-default-method-bodies.rs @@ -1,4 +1,4 @@ -#![feature(const_trait_impl)] +#![feature(const_trait_impl, effects)] #[const_trait] trait ConstDefaultFn: Sized { @@ -22,7 +22,7 @@ impl const ConstDefaultFn for ConstImpl { const fn test() { NonConstImpl.a(); - //~^ ERROR cannot call + //~^ ERROR the trait bound ConstImpl.a(); } 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 414688f71edf5..7b558e3f773c4 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 @@ -1,11 +1,11 @@ -error[E0015]: cannot call non-const fn `::a` in constant functions +error[E0277]: the trait bound `NonConstImpl: ~const ConstDefaultFn` is not satisfied --> $DIR/const-default-method-bodies.rs:24:18 | LL | NonConstImpl.a(); - | ^^^ + | ^ the trait `ConstDefaultFn` is not implemented for `NonConstImpl` | - = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants + = help: the trait `ConstDefaultFn` is implemented for `NonConstImpl` error: aborting due to previous error -For more information about this error, try `rustc --explain E0015`. +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-fail-2.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-fail-2.rs index 3de9d37d49337..747ccbf0fabc0 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-fail-2.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-fail-2.rs @@ -18,6 +18,10 @@ trait A { fn a() { } } impl A for NonTrivialDrop {} +const fn check(_: T) {} + + +/* FIXME(effects) struct ConstDropImplWithBounds(PhantomData); impl const Drop for ConstDropImplWithBounds { @@ -26,11 +30,10 @@ impl const Drop for ConstDropImplWithBounds { } } -const fn check(_: T) {} - const _: () = check::>( ConstDropImplWithBounds(PhantomData) ); +*/ struct ConstDropImplWithNonConstBounds(PhantomData); 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 7de33003c48b9..100d1df87d697 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,28 +1,11 @@ -error[E0015]: cannot call non-const fn `::a` in constant functions - --> $DIR/const-drop-fail-2.rs:25:9 - | -LL | T::a(); - | ^^^^^^ - | - = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants - error[E0493]: destructor of `T` cannot be evaluated at compile-time - --> $DIR/const-drop-fail-2.rs:29:36 + --> $DIR/const-drop-fail-2.rs:21:36 | LL | const fn check(_: T) {} | ^ - value is dropped here | | | the destructor for this type cannot be evaluated in constant functions -error[E0015]: cannot call non-const fn `::a` in constant functions - --> $DIR/const-drop-fail-2.rs:39:9 - | -LL | T::a(); - | ^^^^^^ - | - = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants - -error: aborting due to 3 previous errors +error: aborting due to previous error -Some errors have detailed explanations: E0015, E0493. -For more information about an error, try `rustc --explain E0015`. +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 b28584e7e36fb..23e368870258e 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 @@ -14,15 +14,6 @@ LL | let _ = S(&mut c); | | | the destructor for this type cannot be evaluated in constant functions -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 - -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors -Some errors have detailed explanations: E0015, E0493. -For more information about an error, try `rustc --explain E0015`. +For more information about this error, try `rustc --explain E0493`. 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 b28584e7e36fb..23e368870258e 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 @@ -14,15 +14,6 @@ LL | let _ = S(&mut c); | | | the destructor for this type cannot be evaluated in constant functions -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 - -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors -Some errors have detailed explanations: E0015, E0493. -For more information about an error, try `rustc --explain E0015`. +For more information about this error, try `rustc --explain E0493`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-impl-requires-const-trait.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-impl-requires-const-trait.rs index 2b4963991dbef..fc3a83876c5bb 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-impl-requires-const-trait.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-impl-requires-const-trait.rs @@ -1,9 +1,11 @@ -#![feature(const_trait_impl)] +// known-bug: #110395 + +#![feature(const_trait_impl, effects)] pub trait A {} -//~^ HELP: mark `A` as const +// FIXME ~^ HELP: mark `A` as const impl const A for () {} -//~^ ERROR: const `impl` for trait `A` which is not marked with `#[const_trait]` +// FIXME ~^ ERROR: const `impl` for trait `A` which is not marked with `#[const_trait]` fn main() {} 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 478adcf3e9e89..c45af1a9f8ac2 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 @@ -1,5 +1,5 @@ error: const `impl` for trait `A` which is not marked with `#[const_trait]` - --> $DIR/const-impl-requires-const-trait.rs:6:12 + --> $DIR/const-impl-requires-const-trait.rs:8:12 | LL | pub trait A {} | - help: mark `A` as const: `#[const_trait]` 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 dba3ad7f8701e..348ca0ab1906b 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,5 +1,4 @@ #[derive_const(Default)] //~ ERROR use of unstable library feature -//~^ ERROR 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 6a81f96d88d2e..cc9bdd2715f70 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 @@ -6,16 +6,6 @@ LL | #[derive_const(Default)] | = help: add `#![feature(derive_const)]` to the crate attributes to enable -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 +error: aborting due to previous error 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.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-non-const-type.rs index b575ea8dae298..ce39045d71b38 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-non-const-type.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-non-const-type.rs @@ -1,5 +1,5 @@ // known-bug: #110395 -#![feature(derive_const)] +#![feature(derive_const, effects)] pub struct A; 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 88054096e630b..046dbae0eae7e 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 @@ -10,44 +10,6 @@ error[E0635]: unknown feature `const_default_impls` LL | #![feature(const_trait_impl, const_cmp, const_default_impls, derive_const)] | ^^^^^^^^^^^^^^^^^^^ -error: const `impl` for trait `Default` which is not marked with `#[const_trait]` - --> $DIR/derive-const-use.rs:6:12 - | -LL | impl const Default for A { - | ^^^^^^^ - | - = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` - = note: adding a non-const method body in the future would be a breaking change - -error: const `impl` for trait `PartialEq` which is not marked with `#[const_trait]` - --> $DIR/derive-const-use.rs:10: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: const `impl` for trait `Default` which is not marked with `#[const_trait]` - --> $DIR/derive-const-use.rs:14:16 - | -LL | #[derive_const(Default, PartialEq)] - | ^^^^^^^ - | - = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` - = note: adding a non-const method body in the future would be a breaking change - = note: this error originates in the derive macro `Default` (in Nightly builds, run with -Z macro-backtrace for more info) - -error: const `impl` for trait `PartialEq` which is not marked with `#[const_trait]` - --> $DIR/derive-const-use.rs:14:25 - | -LL | #[derive_const(Default, PartialEq)] - | ^^^^^^^^^ - | - = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` - = note: adding a non-const method body in the future would be a breaking change - = note: this error originates in the derive macro `PartialEq` (in Nightly builds, run with -Z macro-backtrace for more info) - -error: aborting due to 6 previous errors +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0635`. 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 fa78326587c71..37d123e4ccc4d 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 @@ -1,13 +1,3 @@ -error: const `impl` for trait `PartialEq` which is not marked with `#[const_trait]` - --> $DIR/derive-const-with-params.rs:6:16 - | -LL | #[derive_const(PartialEq)] - | ^^^^^^^^^ - | - = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` - = note: adding a non-const method body in the future would be a breaking change - = note: this error originates in the derive macro `PartialEq` (in Nightly builds, run with -Z macro-backtrace for more info) - error: ~const can only be applied to `#[const_trait]` traits --> $DIR/derive-const-with-params.rs:6:16 | @@ -16,5 +6,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: aborting due to 2 previous errors +error: aborting due to previous error 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 c936270de266b..428286e0b12ad 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 @@ -1,11 +1,11 @@ -error[E0015]: cannot call non-const fn `::func` in constant functions +error[E0277]: the trait bound `cross_crate::NonConst: ~const cross_crate::MyTrait` is not satisfied --> $DIR/cross-crate.rs:17:14 | LL | NonConst.func(); - | ^^^^^^ + | ^^^^ the trait `cross_crate::MyTrait` is not implemented for `cross_crate::NonConst` | - = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants + = help: the trait `cross_crate::MyTrait` is implemented for `cross_crate::NonConst` error: aborting due to previous error -For more information about this error, try `rustc --explain E0015`. +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/cross-crate.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/cross-crate.rs index 1f78af794185f..95edbdc0efa10 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/cross-crate.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/cross-crate.rs @@ -1,6 +1,6 @@ // revisions: stock gated stocknc gatednc // [gated] check-pass -#![cfg_attr(any(gated, gatednc), feature(const_trait_impl))] +#![cfg_attr(any(gated, gatednc), feature(const_trait_impl, effects))] // aux-build: cross-crate.rs extern crate cross_crate; @@ -16,7 +16,7 @@ const fn const_context() { #[cfg(any(stocknc, gatednc))] NonConst.func(); //[stocknc]~^ ERROR: cannot call - //[gatednc]~^^ ERROR: cannot call + //[gatednc]~^^ ERROR: the trait bound Const.func(); //[stock]~^ ERROR: cannot call //[stocknc]~^^ ERROR: cannot call 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 c21c73f40f28a..a6881b8fed51e 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 @@ -1,4 +1,4 @@ -error[E0277]: the trait bound `(): Tr` is not satisfied +error[E0277]: the trait bound `(): ~const Tr` is not satisfied --> $DIR/default-method-body-is-const-same-trait-ck.rs:8:12 | LL | ().a() diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/do-not-const-check-override.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/do-not-const-check-override.rs index 730e268c09124..5a0db816a2bc0 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/do-not-const-check-override.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/do-not-const-check-override.rs @@ -1,5 +1,5 @@ // check-pass -#![feature(const_trait_impl, rustc_attrs)] +#![feature(const_trait_impl, rustc_attrs, effects)] #[const_trait] trait Foo { diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/helloworld.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/helloworld.rs index 49457354cc9f4..e7ba0505d9b71 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/helloworld.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/helloworld.rs @@ -7,7 +7,7 @@ // ensure we are passing in the correct host effect in always const contexts. -pub const fn hmm() -> usize { +pub const fn hmm() -> usize { if host { 1 } else { @@ -16,14 +16,12 @@ pub const fn hmm() -> usize { } const _: () = { - let x = hmm(); + let x = hmm::<()>(); assert!(0 == x); }; -/* FIXME(effects) pub const fn uwu(x: [u8; hmm::<()>()]) { let [] = x; } -*/ fn main() {} 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 1b21d7c0e0e60..6a177592b6453 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,11 +1,16 @@ -error: const `impl` for trait `Add` which is not marked with `#[const_trait]` - --> $DIR/generic-bound.rs:16:15 +error[E0015]: cannot call non-const operator in constant functions + --> $DIR/generic-bound.rs:25:5 | -LL | impl const std::ops::Add for S { - | ^^^^^^^^^^^^^ +LL | arg + arg + | ^^^^^^^^^ + | +note: impl defined here, but it is not `const` + --> $DIR/generic-bound.rs:16:1 | - = 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 +LL | impl const std::ops::Add for S { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants error: aborting due to previous error +For more information about this error, try `rustc --explain E0015`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/hir-const-check.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/hir-const-check.rs index 337c733403b24..426534deb67e7 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/hir-const-check.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/hir-const-check.rs @@ -1,6 +1,6 @@ // Regression test for #69615. -#![feature(const_trait_impl)] +#![feature(const_trait_impl, effects)] #[const_trait] pub trait MyTrait { diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/const-default-impl-non-const-specialized-impl.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/const-default-impl-non-const-specialized-impl.rs index a3bb9b3f93eda..9a93d01ed06e9 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/const-default-impl-non-const-specialized-impl.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/const-default-impl-non-const-specialized-impl.rs @@ -1,6 +1,6 @@ // Tests that specializing trait impls must be at least as const as the default impl. -#![feature(const_trait_impl)] +#![feature(const_trait_impl, effects)] #![feature(min_specialization)] #[const_trait] 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 0a28da9e65e64..7206a89e5c58c 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 @@ -1,4 +1,4 @@ -#![feature(const_trait_impl, min_specialization, rustc_attrs)] +#![feature(const_trait_impl, effects, min_specialization, rustc_attrs)] #[rustc_specialization_trait] #[const_trait] diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/staged-api.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/staged-api.rs index 1d79f5adf93f3..b3977e6cede0f 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/staged-api.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/staged-api.rs @@ -1,7 +1,7 @@ // revisions: stable unstable #![cfg_attr(unstable, feature(unstable))] // The feature from the ./auxiliary/staged-api.rs file. -#![feature(const_trait_impl)] +#![feature(const_trait_impl, effects)] #![feature(staged_api)] #![stable(feature = "rust1", since = "1.0.0")] 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 35dc1ca129b12..deed05ae17982 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 @@ -1,20 +1,29 @@ -error: const `impl` for trait `Try` which is not marked with `#[const_trait]` - --> $DIR/trait-default-body-stability.rs:18:12 +error[E0015]: `?` cannot determine the branch of `T` in constant functions + --> $DIR/trait-default-body-stability.rs:44:9 | -LL | impl const Try for T { - | ^^^ +LL | T? + | ^^ + | +note: impl defined here, but it is not `const` + --> $DIR/trait-default-body-stability.rs:18:1 | - = 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 +LL | impl const Try for T { + | ^^^^^^^^^^^^^^^^^^^^ + = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants -error: const `impl` for trait `FromResidual` which is not marked with `#[const_trait]` - --> $DIR/trait-default-body-stability.rs:33:12 +error[E0015]: `?` cannot convert from residual of `T` in constant functions + --> $DIR/trait-default-body-stability.rs:44:9 | -LL | impl const FromResidual for T { - | ^^^^^^^^^^^^ +LL | T? + | ^^ + | +note: impl defined here, but it is not `const` + --> $DIR/trait-default-body-stability.rs:33:1 | - = 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 +LL | impl const FromResidual for T { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants 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/trait-where-clause-run.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-run.rs index 29809a2ee569b..6e1074035b744 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,7 @@ // known-bug: #110395 // FIXME run-pass -#![feature(const_trait_impl)] +#![feature(const_trait_impl, effects)] #[const_trait] trait Bar { diff --git a/tests/ui/stability-attribute/missing-const-stability.rs b/tests/ui/stability-attribute/missing-const-stability.rs index 6eff899bfbf16..621e857624910 100644 --- a/tests/ui/stability-attribute/missing-const-stability.rs +++ b/tests/ui/stability-attribute/missing-const-stability.rs @@ -1,5 +1,5 @@ #![feature(staged_api)] -#![feature(const_trait_impl)] +#![feature(const_trait_impl, effects)] #![stable(feature = "stable", since = "1.0.0")] #[stable(feature = "stable", since = "1.0.0")]