diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index d03f0369648..28ed88e8345 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -236,7 +236,7 @@ pub(crate) fn type_check<'mir, 'tcx>( .unwrap(); let mut hidden_type = infcx.resolve_vars_if_possible(decl.hidden_type); trace!("finalized opaque type {:?} to {:#?}", opaque_type_key, hidden_type.ty.kind()); - if hidden_type.has_infer_types_or_consts() { + if hidden_type.has_non_region_infer() { infcx.tcx.sess.delay_span_bug( decl.hidden_type.span, &format!("could not resolve {:#?}", hidden_type.ty.kind()), diff --git a/compiler/rustc_hir_analysis/src/check/fn_ctxt/_impl.rs b/compiler/rustc_hir_analysis/src/check/fn_ctxt/_impl.rs index 4bd5e9f6ab5..e51e5280620 100644 --- a/compiler/rustc_hir_analysis/src/check/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_analysis/src/check/fn_ctxt/_impl.rs @@ -91,14 +91,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { mutate_fulfillment_errors: impl Fn(&mut Vec>), ) -> Ty<'tcx> { // No Infer()? Nothing needs doing. - if !ty.has_infer_types_or_consts() { + if !ty.has_non_region_infer() { debug!("no inference var, nothing needs doing"); return ty; } // If `ty` is a type variable, see whether we already know what it is. ty = self.resolve_vars_if_possible(ty); - if !ty.has_infer_types_or_consts() { + if !ty.has_non_region_infer() { debug!(?ty); return ty; } diff --git a/compiler/rustc_hir_analysis/src/check/fn_ctxt/checks.rs b/compiler/rustc_hir_analysis/src/check/fn_ctxt/checks.rs index 44d7973d632..13e74021b9e 100644 --- a/compiler/rustc_hir_analysis/src/check/fn_ctxt/checks.rs +++ b/compiler/rustc_hir_analysis/src/check/fn_ctxt/checks.rs @@ -63,7 +63,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let get_operand_ty = |expr| { let ty = self.typeck_results.borrow().expr_ty_adjusted(expr); let ty = self.resolve_vars_if_possible(ty); - if ty.has_infer_types_or_consts() { + if ty.has_non_region_infer() { assert!(self.is_tainted_by_errors()); self.tcx.ty_error() } else { diff --git a/compiler/rustc_hir_analysis/src/check/intrinsicck.rs b/compiler/rustc_hir_analysis/src/check/intrinsicck.rs index 13a80030415..4abc00cefb6 100644 --- a/compiler/rustc_hir_analysis/src/check/intrinsicck.rs +++ b/compiler/rustc_hir_analysis/src/check/intrinsicck.rs @@ -149,7 +149,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { target_features: &FxHashSet, ) -> Option { let ty = (self.get_operand_ty)(expr); - if ty.has_infer_types_or_consts() { + if ty.has_non_region_infer() { bug!("inference variable in asm operand ty: {:?} {:?}", expr, ty); } let asm_ty_isize = match self.tcx.sess.target.pointer_width { diff --git a/compiler/rustc_hir_analysis/src/check/op.rs b/compiler/rustc_hir_analysis/src/check/op.rs index 2d7d9020e3e..d876b1d20fe 100644 --- a/compiler/rustc_hir_analysis/src/check/op.rs +++ b/compiler/rustc_hir_analysis/src/check/op.rs @@ -471,7 +471,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // This has nothing here because it means we did string // concatenation (e.g., "Hello " + "World!"). This means // we don't want the note in the else clause to be emitted - } else if lhs_ty.has_param_types_or_consts() { + } else if lhs_ty.has_non_region_param() { // Look for a TraitPredicate in the Fulfillment errors, // and use it to generate a suggestion. // @@ -657,7 +657,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { format!("cannot apply unary operator `{}`", op.as_str()), ); - if operand_ty.has_param_types_or_consts() { + if operand_ty.has_non_region_param() { let predicates = errors.iter().filter_map(|error| { error.obligation.predicate.to_opt_poly_trait_pred() }); diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index 7965ec1b43f..d607f901420 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -1428,9 +1428,7 @@ fn check_where_clauses<'tcx>(wfcx: &WfCheckingCtxt<'_, 'tcx>, span: Span, def_id let substituted_pred = predicates.rebind(pred).subst(tcx, substs); // Don't check non-defaulted params, dependent defaults (including lifetimes) // or preds with multiple params. - if substituted_pred.has_param_types_or_consts() - || param_count.params.len() > 1 - || has_region + if substituted_pred.has_non_region_param() || param_count.params.len() > 1 || has_region { None } else if predicates.0.predicates.iter().any(|&(p, _)| p == substituted_pred) { diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index b9fd79e0d2f..70edcd10f5f 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -712,9 +712,9 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { ) -> bool { // Reject any attempt to unify two unevaluated constants that contain inference // variables, since inference variables in queries lead to ICEs. - if a.substs.has_infer_types_or_consts() - || b.substs.has_infer_types_or_consts() - || param_env.has_infer_types_or_consts() + if a.substs.has_non_region_infer() + || b.substs.has_non_region_infer() + || param_env.has_non_region_infer() { debug!("a or b or param_env contain infer vars in its substs -> cannot unify"); return false; @@ -1734,7 +1734,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { // Postpone the evaluation of constants whose substs depend on inference // variables - if substs.has_infer_types_or_consts() { + if substs.has_non_region_infer() { let ac = AbstractConst::new(self.tcx, unevaluated); match ac { Ok(None) => { @@ -2072,21 +2072,17 @@ fn replace_param_and_infer_substs_with_placeholder<'tcx>( ) -> SubstsRef<'tcx> { tcx.mk_substs(substs.iter().enumerate().map(|(idx, arg)| { match arg.unpack() { - GenericArgKind::Type(_) - if arg.has_param_types_or_consts() || arg.has_infer_types_or_consts() => - { + GenericArgKind::Type(_) if arg.has_non_region_param() || arg.has_non_region_infer() => { tcx.mk_ty(ty::Placeholder(ty::PlaceholderType { universe: ty::UniverseIndex::ROOT, name: ty::BoundVar::from_usize(idx), })) .into() } - GenericArgKind::Const(ct) - if ct.has_infer_types_or_consts() || ct.has_param_types_or_consts() => - { + GenericArgKind::Const(ct) if ct.has_non_region_infer() || ct.has_non_region_param() => { let ty = ct.ty(); // If the type references param or infer, replace that too... - if ty.has_param_types_or_consts() || ty.has_infer_types_or_consts() { + if ty.has_non_region_param() || ty.has_non_region_infer() { bug!("const `{ct}`'s type should not reference params or types"); } tcx.mk_const(ty::ConstS { diff --git a/compiler/rustc_infer/src/infer/nll_relate/mod.rs b/compiler/rustc_infer/src/infer/nll_relate/mod.rs index bb6f6ae60e2..91e73451a0f 100644 --- a/compiler/rustc_infer/src/infer/nll_relate/mod.rs +++ b/compiler/rustc_infer/src/infer/nll_relate/mod.rs @@ -357,7 +357,7 @@ where // In NLL, we don't have type inference variables // floating around, so we can do this rather imprecise // variant of the occurs-check. - assert!(!generalized_ty.has_infer_types_or_consts()); + assert!(!generalized_ty.has_non_region_infer()); } self.infcx.inner.borrow_mut().type_variables().instantiate(vid, generalized_ty); diff --git a/compiler/rustc_infer/src/infer/resolve.rs b/compiler/rustc_infer/src/infer/resolve.rs index 3d99f0958f7..bb188496caa 100644 --- a/compiler/rustc_infer/src/infer/resolve.rs +++ b/compiler/rustc_infer/src/infer/resolve.rs @@ -32,7 +32,7 @@ impl<'a, 'tcx> TypeFolder<'tcx> for OpportunisticVarResolver<'a, 'tcx> { } fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> { - if !t.has_infer_types_or_consts() { + if !t.has_non_region_infer() { t // micro-optimize -- if there is nothing in this type that this fold affects... } else { let t = self.infcx.shallow_resolve(t); @@ -41,7 +41,7 @@ impl<'a, 'tcx> TypeFolder<'tcx> for OpportunisticVarResolver<'a, 'tcx> { } fn fold_const(&mut self, ct: Const<'tcx>) -> Const<'tcx> { - if !ct.has_infer_types_or_consts() { + if !ct.has_non_region_infer() { ct // micro-optimize -- if there is nothing in this const that this fold affects... } else { let ct = self.infcx.shallow_resolve(ct); diff --git a/compiler/rustc_middle/src/mir/interpret/queries.rs b/compiler/rustc_middle/src/mir/interpret/queries.rs index 734c31192c7..8f67161420d 100644 --- a/compiler/rustc_middle/src/mir/interpret/queries.rs +++ b/compiler/rustc_middle/src/mir/interpret/queries.rs @@ -45,7 +45,7 @@ impl<'tcx> TyCtxt<'tcx> { // // When trying to evaluate constants containing inference variables, // use `Infcx::const_eval_resolve` instead. - if ct.substs.has_infer_types_or_consts() { + if ct.substs.has_non_region_infer() { bug!("did not expect inference variables here"); } @@ -76,7 +76,7 @@ impl<'tcx> TyCtxt<'tcx> { // // When trying to evaluate constants containing inference variables, // use `Infcx::const_eval_resolve` instead. - if ct.substs.has_infer_types_or_consts() { + if ct.substs.has_non_region_infer() { bug!("did not expect inference variables here"); } diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index 78a16788815..a9ebd783403 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -313,7 +313,7 @@ impl<'tcx> Body<'tcx> { is_polymorphic: false, tainted_by_errors, }; - body.is_polymorphic = body.has_param_types_or_consts(); + body.is_polymorphic = body.has_non_region_param(); body } @@ -339,7 +339,7 @@ impl<'tcx> Body<'tcx> { is_polymorphic: false, tainted_by_errors: None, }; - body.is_polymorphic = body.has_param_types_or_consts(); + body.is_polymorphic = body.has_non_region_param(); body } @@ -2760,7 +2760,7 @@ fn pretty_print_const_value<'tcx>( } // Aggregates, printed as array/tuple/struct/variant construction syntax. // - // NB: the `has_param_types_or_consts` check ensures that we can use + // NB: the `has_non_region_param` check ensures that we can use // the `destructure_const` query with an empty `ty::ParamEnv` without // introducing ICEs (e.g. via `layout_of`) from missing bounds. // E.g. `transmute([0usize; 2]): (u8, *mut T)` needs to know `T: Sized` @@ -2768,7 +2768,7 @@ fn pretty_print_const_value<'tcx>( // // FIXME(eddyb) for `--emit=mir`/`-Z dump-mir`, we should provide the // correct `ty::ParamEnv` to allow printing *all* constant values. - (_, ty::Array(..) | ty::Tuple(..) | ty::Adt(..)) if !ty.has_param_types_or_consts() => { + (_, ty::Array(..) | ty::Tuple(..) | ty::Adt(..)) if !ty.has_non_region_param() => { let ct = tcx.lift(ct).unwrap(); let ty = tcx.lift(ty).unwrap(); if let Some(contents) = tcx.try_destructure_mir_constant( diff --git a/compiler/rustc_middle/src/ty/abstract_const.rs b/compiler/rustc_middle/src/ty/abstract_const.rs index 641e53f2a15..1aa4df77800 100644 --- a/compiler/rustc_middle/src/ty/abstract_const.rs +++ b/compiler/rustc_middle/src/ty/abstract_const.rs @@ -71,16 +71,16 @@ impl<'tcx> AbstractConst<'tcx> { walk_abstract_const::(tcx, self, |node| { match node.root(tcx) { Node::Leaf(leaf) => { - if leaf.has_infer_types_or_consts() { + if leaf.has_non_region_infer() { failure_kind = FailureKind::MentionsInfer; - } else if leaf.has_param_types_or_consts() { + } else if leaf.has_non_region_param() { failure_kind = cmp::min(failure_kind, FailureKind::MentionsParam); } } Node::Cast(_, _, ty) => { - if ty.has_infer_types_or_consts() { + if ty.has_non_region_infer() { failure_kind = FailureKind::MentionsInfer; - } else if ty.has_param_types_or_consts() { + } else if ty.has_non_region_param() { failure_kind = cmp::min(failure_kind, FailureKind::MentionsParam); } } diff --git a/compiler/rustc_middle/src/ty/fast_reject.rs b/compiler/rustc_middle/src/ty/fast_reject.rs index 41bb3c71401..3be0bc4defc 100644 --- a/compiler/rustc_middle/src/ty/fast_reject.rs +++ b/compiler/rustc_middle/src/ty/fast_reject.rs @@ -132,7 +132,7 @@ pub fn simplify_type<'tcx>( // don't unify with anything else as long as they are fully normalized. // // We will have to be careful with lazy normalization here. - TreatParams::AsPlaceholder if !ty.has_infer_types_or_consts() => { + TreatParams::AsPlaceholder if !ty.has_non_region_infer() => { debug!("treating `{}` as a placeholder", ty); Some(PlaceholderSimplifiedType) } diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs index 4fb4c9b11e7..5f8729a8ddf 100644 --- a/compiler/rustc_middle/src/ty/layout.rs +++ b/compiler/rustc_middle/src/ty/layout.rs @@ -244,7 +244,7 @@ impl<'tcx> SizeSkeleton<'tcx> { tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>, ) -> Result, LayoutError<'tcx>> { - debug_assert!(!ty.has_infer_types_or_consts()); + debug_assert!(!ty.has_non_region_infer()); // First try computing a static layout. let err = match tcx.layout_of(param_env.and(ty)) { @@ -260,7 +260,7 @@ impl<'tcx> SizeSkeleton<'tcx> { let tail = tcx.struct_tail_erasing_lifetimes(pointee, param_env); match tail.kind() { ty::Param(_) | ty::Projection(_) => { - debug_assert!(tail.has_param_types_or_consts()); + debug_assert!(tail.has_non_region_param()); Ok(SizeSkeleton::Pointer { non_zero, tail: tcx.erase_regions(tail) }) } _ => bug!( diff --git a/compiler/rustc_middle/src/ty/visit.rs b/compiler/rustc_middle/src/ty/visit.rs index 9c3b6a794e1..44efb93a53b 100644 --- a/compiler/rustc_middle/src/ty/visit.rs +++ b/compiler/rustc_middle/src/ty/visit.rs @@ -104,8 +104,8 @@ pub trait TypeVisitable<'tcx>: fmt::Debug + Clone { None } } - fn has_param_types_or_consts(&self) -> bool { - self.has_type_flags(TypeFlags::HAS_TY_PARAM | TypeFlags::HAS_CT_PARAM) + fn has_non_region_param(&self) -> bool { + self.has_type_flags(TypeFlags::NEEDS_SUBST - TypeFlags::HAS_RE_PARAM) } fn has_infer_regions(&self) -> bool { self.has_type_flags(TypeFlags::HAS_RE_INFER) @@ -113,8 +113,8 @@ pub trait TypeVisitable<'tcx>: fmt::Debug + Clone { fn has_infer_types(&self) -> bool { self.has_type_flags(TypeFlags::HAS_TY_INFER) } - fn has_infer_types_or_consts(&self) -> bool { - self.has_type_flags(TypeFlags::HAS_TY_INFER | TypeFlags::HAS_CT_INFER) + fn has_non_region_infer(&self) -> bool { + self.has_type_flags(TypeFlags::NEEDS_INFER - TypeFlags::HAS_RE_INFER) } fn needs_infer(&self) -> bool { self.has_type_flags(TypeFlags::NEEDS_INFER) diff --git a/compiler/rustc_monomorphize/src/polymorphize.rs b/compiler/rustc_monomorphize/src/polymorphize.rs index b7e3ca571e1..a93f6a60114 100644 --- a/compiler/rustc_monomorphize/src/polymorphize.rs +++ b/compiler/rustc_monomorphize/src/polymorphize.rs @@ -290,7 +290,7 @@ impl<'a, 'tcx> Visitor<'tcx> for MarkUsedGenericParams<'a, 'tcx> { impl<'a, 'tcx> TypeVisitor<'tcx> for MarkUsedGenericParams<'a, 'tcx> { #[instrument(level = "debug", skip(self))] fn visit_const(&mut self, c: Const<'tcx>) -> ControlFlow { - if !c.has_param_types_or_consts() { + if !c.has_non_region_param() { return ControlFlow::CONTINUE; } @@ -311,7 +311,7 @@ impl<'a, 'tcx> TypeVisitor<'tcx> for MarkUsedGenericParams<'a, 'tcx> { } fn visit_mir_const(&mut self, constant: ConstantKind<'tcx>) -> ControlFlow { - if !constant.has_param_types_or_consts() { + if !constant.has_non_region_param() { return ControlFlow::CONTINUE; } @@ -336,7 +336,7 @@ impl<'a, 'tcx> TypeVisitor<'tcx> for MarkUsedGenericParams<'a, 'tcx> { #[instrument(level = "debug", skip(self))] fn visit_ty(&mut self, ty: Ty<'tcx>) -> ControlFlow { - if !ty.has_param_types_or_consts() { + if !ty.has_non_region_param() { return ControlFlow::CONTINUE; } @@ -373,7 +373,7 @@ impl<'a, 'tcx> TypeVisitor<'tcx> for HasUsedGenericParams<'a> { #[instrument(level = "debug", skip(self))] fn visit_const(&mut self, c: Const<'tcx>) -> ControlFlow { - if !c.has_param_types_or_consts() { + if !c.has_non_region_param() { return ControlFlow::CONTINUE; } @@ -391,7 +391,7 @@ impl<'a, 'tcx> TypeVisitor<'tcx> for HasUsedGenericParams<'a> { #[instrument(level = "debug", skip(self))] fn visit_ty(&mut self, ty: Ty<'tcx>) -> ControlFlow { - if !ty.has_param_types_or_consts() { + if !ty.has_non_region_param() { return ControlFlow::CONTINUE; } diff --git a/compiler/rustc_passes/src/check_const.rs b/compiler/rustc_passes/src/check_const.rs index 116aaf48349..e502b9b54e3 100644 --- a/compiler/rustc_passes/src/check_const.rs +++ b/compiler/rustc_passes/src/check_const.rs @@ -191,32 +191,6 @@ impl<'tcx> Visitor<'tcx> for CheckConstVisitor<'tcx> { self.tcx.hir() } - fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) { - let tcx = self.tcx; - if let hir::ItemKind::Impl(hir::Impl { - constness: hir::Constness::Const, - of_trait: Some(trait_ref), - .. - }) = item.kind - && let Some(def_id) = trait_ref.trait_def_id() - { - let source_map = tcx.sess.source_map(); - if !tcx.has_attr(def_id, sym::const_trait) { - tcx.sess - .struct_span_err( - source_map.guess_head_span(item.span), - "const `impl`s must be for traits marked with `#[const_trait]`", - ) - .span_note( - source_map.guess_head_span(tcx.def_span(def_id)), - "this trait must be annotated with `#[const_trait]`", - ) - .emit(); - } - } - intravisit::walk_item(self, item); - } - fn visit_anon_const(&mut self, anon: &'tcx hir::AnonConst) { let kind = Some(hir::ConstContext::Const); self.recurse_into(kind, None, |this| intravisit::walk_anon_const(this, anon)); diff --git a/compiler/rustc_symbol_mangling/src/v0.rs b/compiler/rustc_symbol_mangling/src/v0.rs index 18e7e74741a..ecfe6861e84 100644 --- a/compiler/rustc_symbol_mangling/src/v0.rs +++ b/compiler/rustc_symbol_mangling/src/v0.rs @@ -301,7 +301,7 @@ impl<'tcx> Printer<'tcx> for &mut SymbolMangler<'tcx> { // Encode impl generic params if the substitutions contain parameters (implying // polymorphization is enabled) and this isn't an inherent impl. - if impl_trait_ref.is_some() && substs.iter().any(|a| a.has_param_types_or_consts()) { + if impl_trait_ref.is_some() && substs.iter().any(|a| a.has_non_region_param()) { self = self.path_generic_args( |this| { this.path_append_ns( diff --git a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs index 3f98db6b2a9..911d1cf8bdf 100644 --- a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs +++ b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs @@ -236,9 +236,9 @@ pub fn is_const_evaluatable<'cx, 'tcx>( } Err(ErrorHandled::TooGeneric) => { - let err = if uv.has_infer_types_or_consts() { + let err = if uv.has_non_region_infer() { NotConstEvaluatable::MentionsInfer - } else if uv.has_param_types_or_consts() { + } else if uv.has_non_region_param() { NotConstEvaluatable::MentionsParam } else { let guar = infcx.tcx.sess.delay_span_bug(span, format!("Missing value for constant, but no error reported?")); @@ -254,7 +254,7 @@ pub fn is_const_evaluatable<'cx, 'tcx>( } Err(ErrorHandled::Reported(e)) => Err(NotConstEvaluatable::Error(e)), Ok(_) => { - if uv.substs.has_param_types_or_consts() { + if uv.substs.has_non_region_param() { assert!(matches!(infcx.tcx.def_kind(uv.def.did), DefKind::AnonConst)); let mir_body = infcx.tcx.mir_for_ctfe_opt_const_arg(uv.def); 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 5fdadd0b4b4..4398d71a89d 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -661,7 +661,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { ); } } - } else if !trait_ref.has_infer_types_or_consts() + } else if !trait_ref.has_non_region_infer() && self.predicate_can_apply(obligation.param_env, trait_ref) { // If a where-clause may be useful, remind the @@ -2093,7 +2093,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> { // Pick the first substitution that still contains inference variables as the one // we're going to emit an error for. If there are none (see above), fall back to // a more general error. - let subst = data.trait_ref.substs.iter().find(|s| s.has_infer_types_or_consts()); + let subst = data.trait_ref.substs.iter().find(|s| s.has_non_region_infer()); let mut err = if let Some(subst) = subst { self.emit_inference_failure_err(body_id, span, subst, ErrorCode::E0283, true) @@ -2323,7 +2323,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> { .substs .iter() .chain(Some(data.term.into_arg())) - .find(|g| g.has_infer_types_or_consts()); + .find(|g| g.has_non_region_infer()); if let Some(subst) = subst { let mut err = self.emit_inference_failure_err( body_id, @@ -2352,7 +2352,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> { if predicate.references_error() || self.is_tainted_by_errors() { return; } - let subst = data.substs.iter().find(|g| g.has_infer_types_or_consts()); + let subst = data.substs.iter().find(|g| g.has_non_region_infer()); if let Some(subst) = subst { let err = self.emit_inference_failure_err( body_id, 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 698fc81c587..7aae014af60 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -1231,7 +1231,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { return; } let trait_pred = self.resolve_vars_if_possible(trait_pred); - if trait_pred.has_infer_types_or_consts() { + if trait_pred.has_non_region_infer() { // Do not ICE while trying to find if a reborrow would succeed on a trait with // unresolved bindings. return; diff --git a/compiler/rustc_trait_selection/src/traits/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs index f13736a76b2..5802f038e89 100644 --- a/compiler/rustc_trait_selection/src/traits/fulfill.rs +++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs @@ -279,7 +279,7 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> { debug!(?obligation, "pre-resolve"); - if obligation.predicate.has_infer_types_or_consts() { + if obligation.predicate.has_non_region_infer() { obligation.predicate = self.selcx.infcx().resolve_vars_if_possible(obligation.predicate); } @@ -569,7 +569,7 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> { ) } (Err(ErrorHandled::TooGeneric), _) | (_, Err(ErrorHandled::TooGeneric)) => { - if c1.has_infer_types_or_consts() || c2.has_infer_types_or_consts() { + if c1.has_non_region_infer() || c2.has_non_region_infer() { ProcessResult::Unchanged } else { // Two different constants using generic parameters ~> error. @@ -726,11 +726,11 @@ fn substs_infer_vars<'a, 'tcx>( .resolve_vars_if_possible(substs) .skip_binder() // ok because this check doesn't care about regions .iter() - .filter(|arg| arg.has_infer_types_or_consts()) + .filter(|arg| arg.has_non_region_infer()) .flat_map(|arg| { let mut walker = arg.walk(); while let Some(c) = walker.next() { - if !c.has_infer_types_or_consts() { + if !c.has_non_region_infer() { walker.visited.remove(&c); walker.skip_current_subtree(); } diff --git a/compiler/rustc_trait_selection/src/traits/misc.rs b/compiler/rustc_trait_selection/src/traits/misc.rs index e1bd48ba8ac..41b742734cd 100644 --- a/compiler/rustc_trait_selection/src/traits/misc.rs +++ b/compiler/rustc_trait_selection/src/traits/misc.rs @@ -57,7 +57,7 @@ pub fn can_type_implement_copy<'tcx>( // to begin with, and point to the bad field's span instead. let cause = if field .ty(tcx, traits::InternalSubsts::identity_for_item(tcx, adt.did())) - .has_param_types_or_consts() + .has_non_region_param() { parent_cause.clone() } else { diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs index 8da68c225d8..659ffc178aa 100644 --- a/compiler/rustc_trait_selection/src/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/mod.rs @@ -170,7 +170,7 @@ pub fn type_known_to_meet_bound_modulo_regions<'a, 'tcx>( result ); - if result && ty.has_infer_types_or_consts() { + if result && ty.has_non_region_infer() { // Because of inference "guessing", selection can sometimes claim // to succeed while the success requires a guess. To ensure // this function's result remains infallible, we must confirm diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index 07b65a9748d..085045bcdcb 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -1488,7 +1488,7 @@ fn assemble_candidates_from_predicates<'cx, 'tcx>( candidate_set.push_candidate(ctor(data)); if potentially_unnormalized_candidates - && !obligation.predicate.has_infer_types_or_consts() + && !obligation.predicate.has_non_region_infer() { // HACK: Pick the first trait def candidate for a fully // inferred predicate. This is to allow duplicates that @@ -2146,10 +2146,10 @@ fn confirm_impl_candidate<'cx, 'tcx>( } else { ty.map_bound(|ty| ty.into()) }; - if substs.len() != tcx.generics_of(assoc_ty.item.def_id).count() { + if !check_substs_compatible(tcx, &assoc_ty.item, substs) { let err = tcx.ty_error_with_message( obligation.cause.span, - "impl item and trait item have different parameter counts", + "impl item and trait item have different parameters", ); Progress { term: err.into(), obligations: nested } } else { @@ -2158,6 +2158,44 @@ fn confirm_impl_candidate<'cx, 'tcx>( } } +// Verify that the trait item and its implementation have compatible substs lists +fn check_substs_compatible<'tcx>( + tcx: TyCtxt<'tcx>, + assoc_ty: &ty::AssocItem, + substs: ty::SubstsRef<'tcx>, +) -> bool { + fn check_substs_compatible_inner<'tcx>( + tcx: TyCtxt<'tcx>, + generics: &'tcx ty::Generics, + args: &'tcx [ty::GenericArg<'tcx>], + ) -> bool { + if generics.count() != args.len() { + return false; + } + + let (parent_args, own_args) = args.split_at(generics.parent_count); + + if let Some(parent) = generics.parent + && let parent_generics = tcx.generics_of(parent) + && !check_substs_compatible_inner(tcx, parent_generics, parent_args) { + return false; + } + + for (param, arg) in std::iter::zip(&generics.params, own_args) { + match (¶m.kind, arg.unpack()) { + (ty::GenericParamDefKind::Type { .. }, ty::GenericArgKind::Type(_)) + | (ty::GenericParamDefKind::Lifetime, ty::GenericArgKind::Lifetime(_)) + | (ty::GenericParamDefKind::Const { .. }, ty::GenericArgKind::Const(_)) => {} + _ => return false, + } + } + + true + } + + check_substs_compatible_inner(tcx, tcx.generics_of(assoc_ty.def_id), substs.as_slice()) +} + fn confirm_impl_trait_in_trait_candidate<'tcx>( selcx: &mut SelectionContext<'_, 'tcx>, obligation: &ProjectionTyObligation<'tcx>, diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs index 6d856435355..9a8331614b0 100644 --- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs +++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs @@ -174,7 +174,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { debug!(?stack, ?candidates, "winnowed to {} candidates", candidates.len()); - let needs_infer = stack.obligation.predicate.has_infer_types_or_consts(); + let needs_infer = stack.obligation.predicate.has_non_region_infer(); // If there are STILL multiple candidates, we can further // reduce the list by dropping duplicates -- including @@ -889,11 +889,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { obligation: &TraitObligation<'tcx>, candidates: &mut SelectionCandidateSet<'tcx>, ) { - if obligation.has_param_types_or_consts() { + if obligation.has_non_region_param() { return; } - if obligation.has_infer_types_or_consts() { + if obligation.has_non_region_infer() { candidates.ambiguous = true; return; } diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index bac34985237..8f2a6f337ba 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -728,7 +728,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { ) } (Err(ErrorHandled::TooGeneric), _) | (_, Err(ErrorHandled::TooGeneric)) => { - if c1.has_infer_types_or_consts() || c2.has_infer_types_or_consts() { + if c1.has_non_region_infer() || c2.has_non_region_infer() { Ok(EvaluatedToAmbig) } else { // Two different constants using generic parameters ~> error. @@ -1520,7 +1520,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { if !generics.params.is_empty() && obligation.predicate.substs[generics.parent_count..] .iter() - .any(|&p| p.has_infer_types_or_consts() && self.infcx.shallow_resolve(p) != p) + .any(|&p| p.has_non_region_infer() && self.infcx.shallow_resolve(p) != p) { ProjectionMatchesProjection::Ambiguous } else { diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs index 9722b48a68a..5f901d6995e 100644 --- a/compiler/rustc_trait_selection/src/traits/wf.rs +++ b/compiler/rustc_trait_selection/src/traits/wf.rs @@ -308,6 +308,32 @@ impl<'tcx> WfPredicates<'tcx> { let obligations = if trait_pred.constness == ty::BoundConstness::NotConst { self.nominal_obligations_without_const(trait_ref.def_id, trait_ref.substs) } else { + if !tcx.has_attr(trait_ref.def_id, rustc_span::sym::const_trait) { + if let Some(item) = self.item && + let hir::ItemKind::Impl(impl_) = item.kind && + let Some(trait_) = &impl_.of_trait && + let Some(def_id) = trait_.trait_def_id() && + def_id == trait_ref.def_id + { + let trait_name = tcx.item_name(def_id); + let mut err = tcx.sess.struct_span_err( + self.span, + &format!("const `impl` for trait `{trait_name}` which is not marked with `#[const_trait]`"), + ); + if def_id.is_local() { + let sp = tcx.def_span(def_id).shrink_to_lo(); + err.span_suggestion(sp, &format!("mark `{trait_name}` as const"), "#[const_trait]", rustc_errors::Applicability::MachineApplicable); + } + err.note("marking a trait with `#[const_trait]` ensures all default method bodies are `const`"); + err.note("adding a non-const method body in the future would be a breaking change"); + err.emit(); + } else { + tcx.sess.span_err( + self.span, + "~const can only be applied to `#[const_trait]` traits", + ); + } + } self.nominal_obligations(trait_ref.def_id, trait_ref.substs) }; diff --git a/compiler/rustc_traits/src/implied_outlives_bounds.rs b/compiler/rustc_traits/src/implied_outlives_bounds.rs index 32aca4a8a3f..e540ee1664d 100644 --- a/compiler/rustc_traits/src/implied_outlives_bounds.rs +++ b/compiler/rustc_traits/src/implied_outlives_bounds.rs @@ -79,7 +79,7 @@ fn compute_implied_outlives_bounds<'tcx>( // implied bounds in some cases, mostly when dealing with projections. fulfill_cx.register_predicate_obligations( infcx, - obligations.iter().filter(|o| o.predicate.has_infer_types_or_consts()).cloned(), + obligations.iter().filter(|o| o.predicate.has_non_region_infer()).cloned(), ); // From the full set of obligations, just filter down to the diff --git a/compiler/rustc_ty_utils/src/consts.rs b/compiler/rustc_ty_utils/src/consts.rs index 493ef335113..e057bb66825 100644 --- a/compiler/rustc_ty_utils/src/consts.rs +++ b/compiler/rustc_ty_utils/src/consts.rs @@ -135,30 +135,30 @@ impl<'a, 'tcx> AbstractConstBuilder<'a, 'tcx> { impl<'a, 'tcx> IsThirPolymorphic<'a, 'tcx> { fn expr_is_poly(&mut self, expr: &thir::Expr<'tcx>) -> bool { - if expr.ty.has_param_types_or_consts() { + if expr.ty.has_non_region_param() { return true; } match expr.kind { - thir::ExprKind::NamedConst { substs, .. } => substs.has_param_types_or_consts(), + thir::ExprKind::NamedConst { substs, .. } => substs.has_non_region_param(), thir::ExprKind::ConstParam { .. } => true, thir::ExprKind::Repeat { value, count } => { self.visit_expr(&self.thir()[value]); - count.has_param_types_or_consts() + count.has_non_region_param() } _ => false, } } fn pat_is_poly(&mut self, pat: &thir::Pat<'tcx>) -> bool { - if pat.ty.has_param_types_or_consts() { + if pat.ty.has_non_region_param() { return true; } match pat.kind { - thir::PatKind::Constant { value } => value.has_param_types_or_consts(), + thir::PatKind::Constant { value } => value.has_non_region_param(), thir::PatKind::Range(box thir::PatRange { lo, hi, .. }) => { - lo.has_param_types_or_consts() || hi.has_param_types_or_consts() + lo.has_non_region_param() || hi.has_non_region_param() } _ => false, } diff --git a/compiler/rustc_ty_utils/src/instance.rs b/compiler/rustc_ty_utils/src/instance.rs index fa1dc90e4a2..81ca8b646ff 100644 --- a/compiler/rustc_ty_utils/src/instance.rs +++ b/compiler/rustc_ty_utils/src/instance.rs @@ -171,9 +171,13 @@ fn resolve_associated_item<'tcx>( return Ok(None); } - // If the item does not have a value, then we cannot return an instance. + // Any final impl is required to define all associated items. if !leaf_def.item.defaultness(tcx).has_value() { - return Ok(None); + let guard = tcx.sess.delay_span_bug( + tcx.def_span(leaf_def.item.def_id), + "missing value for assoc item in impl", + ); + return Err(guard); } let substs = tcx.erase_regions(substs); diff --git a/compiler/rustc_ty_utils/src/layout.rs b/compiler/rustc_ty_utils/src/layout.rs index 9e4dc26bfd4..345911f4309 100644 --- a/compiler/rustc_ty_utils/src/layout.rs +++ b/compiler/rustc_ty_utils/src/layout.rs @@ -351,7 +351,7 @@ fn layout_of_uncached<'tcx>( let univariant = |fields: &[TyAndLayout<'_>], repr: &ReprOptions, kind| { Ok(tcx.intern_layout(univariant_uninterned(cx, ty, fields, repr, kind)?)) }; - debug_assert!(!ty.has_infer_types_or_consts()); + debug_assert!(!ty.has_non_region_infer()); Ok(match *ty.kind() { // Basic scalars. @@ -1688,7 +1688,7 @@ fn record_layout_for_printing_outlined<'tcx>( // Ignore layouts that are done with non-empty environments or // non-monomorphic layouts, as the user only wants to see the stuff // resulting from the final codegen session. - if layout.ty.has_param_types_or_consts() || !cx.param_env.caller_bounds().is_empty() { + if layout.ty.has_non_region_param() || !cx.param_env.caller_bounds().is_empty() { return; } diff --git a/library/core/src/iter/traits/collect.rs b/library/core/src/iter/traits/collect.rs index e598a54b4f1..e099700e3e7 100644 --- a/library/core/src/iter/traits/collect.rs +++ b/library/core/src/iter/traits/collect.rs @@ -264,7 +264,7 @@ pub trait IntoIterator { #[rustc_const_unstable(feature = "const_intoiterator_identity", issue = "90603")] #[stable(feature = "rust1", since = "1.0.0")] -impl const IntoIterator for I { +impl const IntoIterator for I { type Item = I::Item; type IntoIter = I; diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs index 5cb5e4458cc..d5ed52124e2 100644 --- a/library/core/src/marker.rs +++ b/library/core/src/marker.rs @@ -799,6 +799,7 @@ impl Unpin for *mut T {} #[unstable(feature = "const_trait_impl", issue = "67792")] #[lang = "destruct"] #[rustc_on_unimplemented(message = "can't drop `{Self}`", append_const_msg)] +#[const_trait] pub trait Destruct {} /// A marker for tuple types. diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index de945398c58..7eb8f8bbb30 100644 --- a/src/bootstrap/dist.rs +++ b/src/bootstrap/dist.rs @@ -1367,6 +1367,7 @@ impl Step for Extended { } add_component!("rust-docs" => Docs { host: target }); + add_component!("rust-json-docs" => JsonDocs { host: target }); add_component!("rust-demangler"=> RustDemangler { compiler, target }); add_component!("cargo" => Cargo { compiler, target }); add_component!("rustfmt" => Rustfmt { compiler, target }); diff --git a/src/test/ui/consts/const-fn-error.stderr b/src/test/ui/consts/const-fn-error.stderr index e36324f0b3e..02960b363e7 100644 --- a/src/test/ui/consts/const-fn-error.stderr +++ b/src/test/ui/consts/const-fn-error.stderr @@ -22,8 +22,8 @@ LL | for i in 0..x { note: impl defined here, but it is not `const` --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL | -LL | impl const IntoIterator for I { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | impl const IntoIterator for I { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants error[E0658]: mutable references are not allowed in constant functions diff --git a/src/test/ui/consts/const-for.stderr b/src/test/ui/consts/const-for.stderr index f2e1c8a4991..11e4ae309c0 100644 --- a/src/test/ui/consts/const-for.stderr +++ b/src/test/ui/consts/const-for.stderr @@ -7,8 +7,8 @@ LL | for _ in 0..5 {} note: impl defined here, but it is not `const` --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL | -LL | impl const IntoIterator for I { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | impl const IntoIterator for I { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = note: calls in constants are limited to constant functions, tuple structs and tuple variants error[E0015]: cannot call non-const fn ` as Iterator>::next` in constants diff --git a/src/test/ui/consts/constifconst-call-in-const-position.rs b/src/test/ui/consts/constifconst-call-in-const-position.rs index bf67e5a3f76..fcf01d5bc71 100644 --- a/src/test/ui/consts/constifconst-call-in-const-position.rs +++ b/src/test/ui/consts/constifconst-call-in-const-position.rs @@ -2,6 +2,7 @@ #![feature(const_trait_impl, generic_const_exprs)] +#[const_trait] pub trait Tr { fn a() -> usize; } diff --git a/src/test/ui/consts/constifconst-call-in-const-position.stderr b/src/test/ui/consts/constifconst-call-in-const-position.stderr index e3f67b44678..d4a445120a2 100644 --- a/src/test/ui/consts/constifconst-call-in-const-position.stderr +++ b/src/test/ui/consts/constifconst-call-in-const-position.stderr @@ -8,7 +8,7 @@ LL | #![feature(const_trait_impl, generic_const_exprs)] = note: `#[warn(incomplete_features)]` on by default error[E0080]: evaluation of `foo::<()>::{constant#0}` failed - --> $DIR/constifconst-call-in-const-position.rs:15:38 + --> $DIR/constifconst-call-in-const-position.rs:16:38 | LL | const fn foo() -> [u8; T::a()] { | ^^^^^^ calling non-const function `<() as Tr>::a` diff --git a/src/test/ui/generic-associated-types/issue-102114.rs b/src/test/ui/generic-associated-types/issue-102114.rs new file mode 100644 index 00000000000..de31737efef --- /dev/null +++ b/src/test/ui/generic-associated-types/issue-102114.rs @@ -0,0 +1,16 @@ +trait A { + type B<'b>; + fn a() -> Self::B<'static>; +} + +struct C; + +struct Wrapper(T); + +impl A for C { + type B = Wrapper; + //~^ ERROR type `B` has 1 type parameter but its trait declaration has 0 type parameters + fn a() -> Self::B<'static> {} +} + +fn main() {} diff --git a/src/test/ui/generic-associated-types/issue-102114.stderr b/src/test/ui/generic-associated-types/issue-102114.stderr new file mode 100644 index 00000000000..8e41dee54d7 --- /dev/null +++ b/src/test/ui/generic-associated-types/issue-102114.stderr @@ -0,0 +1,12 @@ +error[E0049]: type `B` has 1 type parameter but its trait declaration has 0 type parameters + --> $DIR/issue-102114.rs:11:12 + | +LL | type B<'b>; + | -- expected 0 type parameters +... +LL | type B = Wrapper; + | ^ found 1 type parameter + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0049`. diff --git a/src/test/ui/impl-trait/issue-102605.rs b/src/test/ui/impl-trait/issue-102605.rs new file mode 100644 index 00000000000..3bbdf35af8f --- /dev/null +++ b/src/test/ui/impl-trait/issue-102605.rs @@ -0,0 +1,15 @@ +// edition:2021 + +async fn foo() -> Result<(), String> { + Ok(()) +} + +fn convert_result(r: Result) -> Option { + None +} + +fn main() -> Option<()> { + //~^ ERROR `main` has invalid return type `Option<()>` + convert_result(foo()) + //~^ ERROR mismatched types +} diff --git a/src/test/ui/impl-trait/issue-102605.stderr b/src/test/ui/impl-trait/issue-102605.stderr new file mode 100644 index 00000000000..d4aba914908 --- /dev/null +++ b/src/test/ui/impl-trait/issue-102605.stderr @@ -0,0 +1,41 @@ +error[E0308]: mismatched types + --> $DIR/issue-102605.rs:13:20 + | +LL | convert_result(foo()) + | -------------- ^^^^^ expected enum `Result`, found opaque type + | | + | arguments to this function are incorrect + | +note: while checking the return type of the `async fn` + --> $DIR/issue-102605.rs:3:19 + | +LL | async fn foo() -> Result<(), String> { + | ^^^^^^^^^^^^^^^^^^ checked the `Output` of this `async fn`, found opaque type + = note: expected enum `Result<(), _>` + found opaque type `impl Future>` +note: function defined here + --> $DIR/issue-102605.rs:7:4 + | +LL | fn convert_result(r: Result) -> Option { + | ^^^^^^^^^^^^^^ --------------- +help: consider `await`ing on the `Future` + | +LL | convert_result(foo().await) + | ++++++ +help: try wrapping the expression in `Err` + | +LL | convert_result(Err(foo())) + | ++++ + + +error[E0277]: `main` has invalid return type `Option<()>` + --> $DIR/issue-102605.rs:11:14 + | +LL | fn main() -> Option<()> { + | ^^^^^^^^^^ `main` can only return types that implement `Termination` + | + = help: consider using `()`, or a `Result` + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0277, E0308. +For more information about an error, try `rustc --explain E0277`. diff --git a/src/test/ui/never_type/issue-52443.stderr b/src/test/ui/never_type/issue-52443.stderr index 3c0daa4c55f..0910e9ad77a 100644 --- a/src/test/ui/never_type/issue-52443.stderr +++ b/src/test/ui/never_type/issue-52443.stderr @@ -47,8 +47,8 @@ LL | [(); { for _ in 0usize.. {}; 0}]; note: impl defined here, but it is not `const` --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL | -LL | impl const IntoIterator for I { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | impl const IntoIterator for I { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = note: calls in constants are limited to constant functions, tuple structs and tuple variants error[E0658]: mutable references are not allowed in constants diff --git a/src/test/ui/rfc-2632-const-trait-impl/call-generic-method-nonconst.rs b/src/test/ui/rfc-2632-const-trait-impl/call-generic-method-nonconst.rs index d3e14a53a2f..414a8c87d2c 100644 --- a/src/test/ui/rfc-2632-const-trait-impl/call-generic-method-nonconst.rs +++ b/src/test/ui/rfc-2632-const-trait-impl/call-generic-method-nonconst.rs @@ -2,13 +2,18 @@ struct S; -impl PartialEq for S { +#[const_trait] +trait Foo { + fn eq(&self, _: &Self) -> bool; +} + +impl Foo for S { fn eq(&self, _: &S) -> bool { true } } -const fn equals_self(t: &T) -> bool { +const fn equals_self(t: &T) -> bool { true } diff --git a/src/test/ui/rfc-2632-const-trait-impl/call-generic-method-nonconst.stderr b/src/test/ui/rfc-2632-const-trait-impl/call-generic-method-nonconst.stderr index 0a2a5f0f245..706f5234365 100644 --- a/src/test/ui/rfc-2632-const-trait-impl/call-generic-method-nonconst.stderr +++ b/src/test/ui/rfc-2632-const-trait-impl/call-generic-method-nonconst.stderr @@ -1,26 +1,21 @@ -error[E0277]: can't compare `S` with `S` in const contexts - --> $DIR/call-generic-method-nonconst.rs:18:34 +error[E0277]: the trait bound `S: ~const Foo` is not satisfied + --> $DIR/call-generic-method-nonconst.rs:23:34 | LL | pub const EQ: bool = equals_self(&S); - | ----------- ^^ no implementation for `S == S` + | ----------- ^^ the trait `~const Foo` is not implemented for `S` | | | required by a bound introduced by this call | - = help: the trait `~const PartialEq` is not implemented for `S` -note: the trait `PartialEq` is implemented for `S`, but that implementation is not `const` - --> $DIR/call-generic-method-nonconst.rs:18:34 +note: the trait `Foo` is implemented for `S`, but that implementation is not `const` + --> $DIR/call-generic-method-nonconst.rs:23:34 | LL | pub const EQ: bool = equals_self(&S); | ^^ note: required by a bound in `equals_self` - --> $DIR/call-generic-method-nonconst.rs:11:25 - | -LL | const fn equals_self(t: &T) -> bool { - | ^^^^^^^^^^^^^^^^ required by this bound in `equals_self` -help: consider annotating `S` with `#[derive(PartialEq)]` - | -LL | #[derive(PartialEq)] + --> $DIR/call-generic-method-nonconst.rs:16:25 | +LL | const fn equals_self(t: &T) -> bool { + | ^^^^^^^^^^ required by this bound in `equals_self` error: aborting due to previous error diff --git a/src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.precise.stderr b/src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.precise.stderr index 2295a822fa4..ddf0e2d91c0 100644 --- a/src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.precise.stderr +++ b/src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.precise.stderr @@ -1,5 +1,5 @@ error[E0277]: can't drop `NonTrivialDrop` in const contexts - --> $DIR/const-drop-fail.rs:43:5 + --> $DIR/const-drop-fail.rs:44:5 | LL | const _: () = check($exp); | ----- required by a bound introduced by this call @@ -9,7 +9,7 @@ LL | NonTrivialDrop, | = note: the trait bound `NonTrivialDrop: ~const Destruct` is not satisfied note: required by a bound in `check` - --> $DIR/const-drop-fail.rs:34:19 + --> $DIR/const-drop-fail.rs:35:19 | LL | const fn check(_: T) {} | ^^^^^^^^^^^^^^^ required by this bound in `check` @@ -21,7 +21,7 @@ LL | &mut NonTrivialDrop, | ++++ error[E0277]: can't drop `NonTrivialDrop` in const contexts - --> $DIR/const-drop-fail.rs:45:5 + --> $DIR/const-drop-fail.rs:46:5 | LL | const _: () = check($exp); | ----- required by a bound introduced by this call @@ -30,7 +30,7 @@ LL | ConstImplWithDropGlue(NonTrivialDrop), | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ within `ConstImplWithDropGlue`, the trait `~const Destruct` is not implemented for `NonTrivialDrop` | note: the trait `Destruct` is implemented for `NonTrivialDrop`, but that implementation is not `const` - --> $DIR/const-drop-fail.rs:45:5 + --> $DIR/const-drop-fail.rs:46:5 | LL | ConstImplWithDropGlue(NonTrivialDrop), | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -40,13 +40,13 @@ note: required because it appears within the type `ConstImplWithDropGlue` LL | struct ConstImplWithDropGlue(NonTrivialDrop); | ^^^^^^^^^^^^^^^^^^^^^ note: required by a bound in `check` - --> $DIR/const-drop-fail.rs:34:19 + --> $DIR/const-drop-fail.rs:35:19 | LL | const fn check(_: T) {} | ^^^^^^^^^^^^^^^ required by this bound in `check` error[E0277]: the trait bound `ConstDropImplWithBounds: ~const Destruct` is not satisfied - --> $DIR/const-drop-fail.rs:47:5 + --> $DIR/const-drop-fail.rs:48:5 | LL | const _: () = check($exp); | ----- required by a bound introduced by this call @@ -55,14 +55,14 @@ LL | ConstDropImplWithBounds::(PhantomData), | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `~const Destruct` is not implemented for `ConstDropImplWithBounds` | note: required for `ConstDropImplWithBounds` to implement `~const Destruct` - --> $DIR/const-drop-fail.rs:28:25 + --> $DIR/const-drop-fail.rs:29:25 | LL | impl const Drop for ConstDropImplWithBounds { | ^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^ = note: 1 redundant requirement hidden = note: required for `ConstDropImplWithBounds` to implement `~const Destruct` note: required by a bound in `check` - --> $DIR/const-drop-fail.rs:34:19 + --> $DIR/const-drop-fail.rs:35:19 | LL | const fn check(_: T) {} | ^^^^^^^^^^^^^^^ required by this bound in `check` diff --git a/src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.rs b/src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.rs index 001dd430a86..565e2c77ac5 100644 --- a/src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.rs +++ b/src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.rs @@ -19,7 +19,8 @@ impl const Drop for ConstImplWithDropGlue { fn drop(&mut self) {} } -trait A { fn a() { println!("A"); } } +#[const_trait] +trait A { fn a() { } } impl A for NonTrivialDrop {} diff --git a/src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.stock.stderr b/src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.stock.stderr index 2295a822fa4..ddf0e2d91c0 100644 --- a/src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.stock.stderr +++ b/src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.stock.stderr @@ -1,5 +1,5 @@ error[E0277]: can't drop `NonTrivialDrop` in const contexts - --> $DIR/const-drop-fail.rs:43:5 + --> $DIR/const-drop-fail.rs:44:5 | LL | const _: () = check($exp); | ----- required by a bound introduced by this call @@ -9,7 +9,7 @@ LL | NonTrivialDrop, | = note: the trait bound `NonTrivialDrop: ~const Destruct` is not satisfied note: required by a bound in `check` - --> $DIR/const-drop-fail.rs:34:19 + --> $DIR/const-drop-fail.rs:35:19 | LL | const fn check(_: T) {} | ^^^^^^^^^^^^^^^ required by this bound in `check` @@ -21,7 +21,7 @@ LL | &mut NonTrivialDrop, | ++++ error[E0277]: can't drop `NonTrivialDrop` in const contexts - --> $DIR/const-drop-fail.rs:45:5 + --> $DIR/const-drop-fail.rs:46:5 | LL | const _: () = check($exp); | ----- required by a bound introduced by this call @@ -30,7 +30,7 @@ LL | ConstImplWithDropGlue(NonTrivialDrop), | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ within `ConstImplWithDropGlue`, the trait `~const Destruct` is not implemented for `NonTrivialDrop` | note: the trait `Destruct` is implemented for `NonTrivialDrop`, but that implementation is not `const` - --> $DIR/const-drop-fail.rs:45:5 + --> $DIR/const-drop-fail.rs:46:5 | LL | ConstImplWithDropGlue(NonTrivialDrop), | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -40,13 +40,13 @@ note: required because it appears within the type `ConstImplWithDropGlue` LL | struct ConstImplWithDropGlue(NonTrivialDrop); | ^^^^^^^^^^^^^^^^^^^^^ note: required by a bound in `check` - --> $DIR/const-drop-fail.rs:34:19 + --> $DIR/const-drop-fail.rs:35:19 | LL | const fn check(_: T) {} | ^^^^^^^^^^^^^^^ required by this bound in `check` error[E0277]: the trait bound `ConstDropImplWithBounds: ~const Destruct` is not satisfied - --> $DIR/const-drop-fail.rs:47:5 + --> $DIR/const-drop-fail.rs:48:5 | LL | const _: () = check($exp); | ----- required by a bound introduced by this call @@ -55,14 +55,14 @@ LL | ConstDropImplWithBounds::(PhantomData), | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `~const Destruct` is not implemented for `ConstDropImplWithBounds` | note: required for `ConstDropImplWithBounds` to implement `~const Destruct` - --> $DIR/const-drop-fail.rs:28:25 + --> $DIR/const-drop-fail.rs:29:25 | LL | impl const Drop for ConstDropImplWithBounds { | ^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^ = note: 1 redundant requirement hidden = note: required for `ConstDropImplWithBounds` to implement `~const Destruct` note: required by a bound in `check` - --> $DIR/const-drop-fail.rs:34:19 + --> $DIR/const-drop-fail.rs:35:19 | LL | const fn check(_: T) {} | ^^^^^^^^^^^^^^^ required by this bound in `check` diff --git a/src/test/ui/rfc-2632-const-trait-impl/const-impl-requires-const-trait.rs b/src/test/ui/rfc-2632-const-trait-impl/const-impl-requires-const-trait.rs index 1aff0562785..2b4963991db 100644 --- a/src/test/ui/rfc-2632-const-trait-impl/const-impl-requires-const-trait.rs +++ b/src/test/ui/rfc-2632-const-trait-impl/const-impl-requires-const-trait.rs @@ -1,9 +1,9 @@ #![feature(const_trait_impl)] pub trait A {} -//~^ NOTE: this trait must be annotated with `#[const_trait]` +//~^ HELP: mark `A` as const impl const A for () {} -//~^ ERROR: const `impl`s must be for traits marked with `#[const_trait]` +//~^ ERROR: const `impl` for trait `A` which is not marked with `#[const_trait]` fn main() {} diff --git a/src/test/ui/rfc-2632-const-trait-impl/const-impl-requires-const-trait.stderr b/src/test/ui/rfc-2632-const-trait-impl/const-impl-requires-const-trait.stderr index 6b465a9c62e..478adcf3e9e 100644 --- a/src/test/ui/rfc-2632-const-trait-impl/const-impl-requires-const-trait.stderr +++ b/src/test/ui/rfc-2632-const-trait-impl/const-impl-requires-const-trait.stderr @@ -1,14 +1,14 @@ -error: const `impl`s must be for traits marked with `#[const_trait]` - --> $DIR/const-impl-requires-const-trait.rs:6:1 - | -LL | impl const A for () {} - | ^^^^^^^^^^^^^^^^^^^ - | -note: this trait must be annotated with `#[const_trait]` - --> $DIR/const-impl-requires-const-trait.rs:3:1 +error: const `impl` for trait `A` which is not marked with `#[const_trait]` + --> $DIR/const-impl-requires-const-trait.rs:6:12 | LL | pub trait A {} - | ^^^^^^^^^^^ + | - help: mark `A` as const: `#[const_trait]` +... +LL | impl const A for () {} + | ^ + | + = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` + = note: adding a non-const method body in the future would be a breaking change error: aborting due to previous error diff --git a/src/test/ui/rfc-2632-const-trait-impl/default-method-body-is-const-body-checking.rs b/src/test/ui/rfc-2632-const-trait-impl/default-method-body-is-const-body-checking.rs index d27291231fb..96acdc300e0 100644 --- a/src/test/ui/rfc-2632-const-trait-impl/default-method-body-is-const-body-checking.rs +++ b/src/test/ui/rfc-2632-const-trait-impl/default-method-body-is-const-body-checking.rs @@ -1,5 +1,6 @@ #![feature(const_trait_impl)] +#[const_trait] trait Tr {} impl Tr for () {} diff --git a/src/test/ui/rfc-2632-const-trait-impl/default-method-body-is-const-body-checking.stderr b/src/test/ui/rfc-2632-const-trait-impl/default-method-body-is-const-body-checking.stderr index 7542b81fe2a..d102956cd2e 100644 --- a/src/test/ui/rfc-2632-const-trait-impl/default-method-body-is-const-body-checking.stderr +++ b/src/test/ui/rfc-2632-const-trait-impl/default-method-body-is-const-body-checking.stderr @@ -1,16 +1,16 @@ error[E0277]: the trait bound `(): ~const Tr` is not satisfied - --> $DIR/default-method-body-is-const-body-checking.rs:11:15 + --> $DIR/default-method-body-is-const-body-checking.rs:12:15 | LL | foo::<()>(); | ^^ the trait `~const Tr` is not implemented for `()` | note: the trait `Tr` is implemented for `()`, but that implementation is not `const` - --> $DIR/default-method-body-is-const-body-checking.rs:11:15 + --> $DIR/default-method-body-is-const-body-checking.rs:12:15 | LL | foo::<()>(); | ^^ note: required by a bound in `foo` - --> $DIR/default-method-body-is-const-body-checking.rs:6:28 + --> $DIR/default-method-body-is-const-body-checking.rs:7:28 | LL | const fn foo() where T: ~const Tr {} | ^^^^^^^^^ required by this bound in `foo` diff --git a/src/test/ui/rfc-2632-const-trait-impl/super-traits-fail-2.nn.stderr b/src/test/ui/rfc-2632-const-trait-impl/super-traits-fail-2.nn.stderr new file mode 100644 index 00000000000..b86acb2cc9a --- /dev/null +++ b/src/test/ui/rfc-2632-const-trait-impl/super-traits-fail-2.nn.stderr @@ -0,0 +1,8 @@ +error: ~const can only be applied to `#[const_trait]` traits + --> $DIR/super-traits-fail-2.rs:11:12 + | +LL | trait Bar: ~const Foo {} + | ^^^^^^^^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/rfc-2632-const-trait-impl/super-traits-fail-2.ny.stderr b/src/test/ui/rfc-2632-const-trait-impl/super-traits-fail-2.ny.stderr new file mode 100644 index 00000000000..b86acb2cc9a --- /dev/null +++ b/src/test/ui/rfc-2632-const-trait-impl/super-traits-fail-2.ny.stderr @@ -0,0 +1,8 @@ +error: ~const can only be applied to `#[const_trait]` traits + --> $DIR/super-traits-fail-2.rs:11:12 + | +LL | trait Bar: ~const Foo {} + | ^^^^^^^^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/rfc-2632-const-trait-impl/super-traits-fail-2.rs b/src/test/ui/rfc-2632-const-trait-impl/super-traits-fail-2.rs index 7b38c15afc2..d183efde2df 100644 --- a/src/test/ui/rfc-2632-const-trait-impl/super-traits-fail-2.rs +++ b/src/test/ui/rfc-2632-const-trait-impl/super-traits-fail-2.rs @@ -1,14 +1,19 @@ #![feature(const_trait_impl)] +// revisions: yy yn ny nn + +#[cfg_attr(any(yy, yn), const_trait)] trait Foo { fn a(&self); } + +#[cfg_attr(any(yy, ny), const_trait)] trait Bar: ~const Foo {} +//[ny,nn]~^ ERROR: ~const can only be applied to `#[const_trait]` const fn foo(x: &T) { x.a(); - //~^ ERROR the trait bound - //~| ERROR cannot call + //[yn,yy]~^ ERROR the trait bound } fn main() {} diff --git a/src/test/ui/rfc-2632-const-trait-impl/super-traits-fail-2.stderr b/src/test/ui/rfc-2632-const-trait-impl/super-traits-fail-2.stderr deleted file mode 100644 index 1766cdbee8a..00000000000 --- a/src/test/ui/rfc-2632-const-trait-impl/super-traits-fail-2.stderr +++ /dev/null @@ -1,24 +0,0 @@ -error[E0277]: the trait bound `T: ~const Foo` is not satisfied - --> $DIR/super-traits-fail-2.rs:9:7 - | -LL | x.a(); - | ^^^ the trait `~const Foo` is not implemented for `T` - | -note: the trait `Foo` is implemented for `T`, but that implementation is not `const` - --> $DIR/super-traits-fail-2.rs:9:7 - | -LL | x.a(); - | ^^^ - -error[E0015]: cannot call non-const fn `::a` in constant functions - --> $DIR/super-traits-fail-2.rs:9:7 - | -LL | x.a(); - | ^^^ - | - = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants - -error: aborting due to 2 previous errors - -Some errors have detailed explanations: E0015, E0277. -For more information about an error, try `rustc --explain E0015`. diff --git a/src/test/ui/rfc-2632-const-trait-impl/super-traits-fail-2.yn.stderr b/src/test/ui/rfc-2632-const-trait-impl/super-traits-fail-2.yn.stderr new file mode 100644 index 00000000000..b52eb2c0332 --- /dev/null +++ b/src/test/ui/rfc-2632-const-trait-impl/super-traits-fail-2.yn.stderr @@ -0,0 +1,21 @@ +error[E0277]: the trait bound `T: ~const Foo` is not satisfied + --> $DIR/super-traits-fail-2.rs:15:5 + | +LL | x.a(); + | ^ - required by a bound introduced by this call + | | + | the trait `~const Foo` is not implemented for `T` + | +note: the trait `Foo` is implemented for `T`, but that implementation is not `const` + --> $DIR/super-traits-fail-2.rs:15:5 + | +LL | x.a(); + | ^ +help: consider further restricting this bound + | +LL | const fn foo(x: &T) { + | ++++++++++++ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/rfc-2632-const-trait-impl/super-traits-fail-2.yy.stderr b/src/test/ui/rfc-2632-const-trait-impl/super-traits-fail-2.yy.stderr new file mode 100644 index 00000000000..b52eb2c0332 --- /dev/null +++ b/src/test/ui/rfc-2632-const-trait-impl/super-traits-fail-2.yy.stderr @@ -0,0 +1,21 @@ +error[E0277]: the trait bound `T: ~const Foo` is not satisfied + --> $DIR/super-traits-fail-2.rs:15:5 + | +LL | x.a(); + | ^ - required by a bound introduced by this call + | | + | the trait `~const Foo` is not implemented for `T` + | +note: the trait `Foo` is implemented for `T`, but that implementation is not `const` + --> $DIR/super-traits-fail-2.rs:15:5 + | +LL | x.a(); + | ^ +help: consider further restricting this bound + | +LL | const fn foo(x: &T) { + | ++++++++++++ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/rfc-2632-const-trait-impl/super-traits-fail-3.nn.stderr b/src/test/ui/rfc-2632-const-trait-impl/super-traits-fail-3.nn.stderr new file mode 100644 index 00000000000..191edca1761 --- /dev/null +++ b/src/test/ui/rfc-2632-const-trait-impl/super-traits-fail-3.nn.stderr @@ -0,0 +1,14 @@ +error: ~const can only be applied to `#[const_trait]` traits + --> $DIR/super-traits-fail-3.rs:12:12 + | +LL | trait Bar: ~const Foo {} + | ^^^^^^^^^^ + +error: ~const can only be applied to `#[const_trait]` traits + --> $DIR/super-traits-fail-3.rs:15:17 + | +LL | const fn foo(x: &T) { + | ^^^^^^^^^^ + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/rfc-2632-const-trait-impl/super-traits-fail-3.ny.stderr b/src/test/ui/rfc-2632-const-trait-impl/super-traits-fail-3.ny.stderr new file mode 100644 index 00000000000..a3b4c302a57 --- /dev/null +++ b/src/test/ui/rfc-2632-const-trait-impl/super-traits-fail-3.ny.stderr @@ -0,0 +1,8 @@ +error: ~const can only be applied to `#[const_trait]` traits + --> $DIR/super-traits-fail-3.rs:12:12 + | +LL | trait Bar: ~const Foo {} + | ^^^^^^^^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/rfc-2632-const-trait-impl/super-traits-fail-3.rs b/src/test/ui/rfc-2632-const-trait-impl/super-traits-fail-3.rs new file mode 100644 index 00000000000..70d2936d3b2 --- /dev/null +++ b/src/test/ui/rfc-2632-const-trait-impl/super-traits-fail-3.rs @@ -0,0 +1,20 @@ +#![feature(const_trait_impl)] + +// revisions: yy yn ny nn +//[yy] check-pass + +#[cfg_attr(any(yy, yn), const_trait)] +trait Foo { + fn a(&self); +} + +#[cfg_attr(any(yy, ny), const_trait)] +trait Bar: ~const Foo {} +//[ny,nn]~^ ERROR: ~const can only be applied to `#[const_trait]` + +const fn foo(x: &T) { + //[yn,nn]~^ ERROR: ~const can only be applied to `#[const_trait]` + x.a(); +} + +fn main() {} diff --git a/src/test/ui/rfc-2632-const-trait-impl/super-traits-fail-3.yn.stderr b/src/test/ui/rfc-2632-const-trait-impl/super-traits-fail-3.yn.stderr new file mode 100644 index 00000000000..9d611665465 --- /dev/null +++ b/src/test/ui/rfc-2632-const-trait-impl/super-traits-fail-3.yn.stderr @@ -0,0 +1,8 @@ +error: ~const can only be applied to `#[const_trait]` traits + --> $DIR/super-traits-fail-3.rs:15:17 + | +LL | const fn foo(x: &T) { + | ^^^^^^^^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/rfc-2632-const-trait-impl/tilde-const-invalid-places.rs b/src/test/ui/rfc-2632-const-trait-impl/tilde-const-invalid-places.rs index 350be4d8250..5bd52151f42 100644 --- a/src/test/ui/rfc-2632-const-trait-impl/tilde-const-invalid-places.rs +++ b/src/test/ui/rfc-2632-const-trait-impl/tilde-const-invalid-places.rs @@ -1,6 +1,7 @@ #![feature(const_trait_impl)] #![feature(associated_type_bounds)] +#[const_trait] trait T {} struct S; impl T for S {} diff --git a/src/test/ui/rfc-2632-const-trait-impl/tilde-const-invalid-places.stderr b/src/test/ui/rfc-2632-const-trait-impl/tilde-const-invalid-places.stderr index 8d781d063d1..5d213315634 100644 --- a/src/test/ui/rfc-2632-const-trait-impl/tilde-const-invalid-places.stderr +++ b/src/test/ui/rfc-2632-const-trait-impl/tilde-const-invalid-places.stderr @@ -1,5 +1,5 @@ error: `~const` is not allowed here - --> $DIR/tilde-const-invalid-places.rs:8:19 + --> $DIR/tilde-const-invalid-places.rs:9:19 | LL | fn rpit() -> impl ~const T { S } | ^^^^^^^^ @@ -7,7 +7,7 @@ LL | fn rpit() -> impl ~const T { S } = note: only allowed on bounds on functions, traits' associated types and functions, const impls and its associated functions error: `~const` is not allowed here - --> $DIR/tilde-const-invalid-places.rs:11:17 + --> $DIR/tilde-const-invalid-places.rs:12:17 | LL | fn apit(_: impl ~const T) {} | ^^^^^^^^ @@ -15,7 +15,7 @@ LL | fn apit(_: impl ~const T) {} = note: only allowed on bounds on functions, traits' associated types and functions, const impls and its associated functions error: `~const` is not allowed here - --> $DIR/tilde-const-invalid-places.rs:14:50 + --> $DIR/tilde-const-invalid-places.rs:15:50 | LL | fn rpit_assoc_bound() -> impl IntoIterator { Some(S) } | ^^^^^^^^ @@ -23,7 +23,7 @@ LL | fn rpit_assoc_bound() -> impl IntoIterator { Some(S) } = note: only allowed on bounds on functions, traits' associated types and functions, const impls and its associated functions error: `~const` is not allowed here - --> $DIR/tilde-const-invalid-places.rs:17:48 + --> $DIR/tilde-const-invalid-places.rs:18:48 | LL | fn apit_assoc_bound(_: impl IntoIterator) {} | ^^^^^^^^ @@ -31,7 +31,7 @@ LL | fn apit_assoc_bound(_: impl IntoIterator) {} = note: only allowed on bounds on functions, traits' associated types and functions, const impls and its associated functions error: `~const` and `?` are mutually exclusive - --> $DIR/tilde-const-invalid-places.rs:20:25 + --> $DIR/tilde-const-invalid-places.rs:21:25 | LL | struct TildeQuestion(std::marker::PhantomData); | ^^^^^^^^^^^^^ diff --git a/src/test/ui/rfc-2632-const-trait-impl/trait-where-clause-const.rs b/src/test/ui/rfc-2632-const-trait-impl/trait-where-clause-const.rs index 47c38c979c3..bfe98b98c74 100644 --- a/src/test/ui/rfc-2632-const-trait-impl/trait-where-clause-const.rs +++ b/src/test/ui/rfc-2632-const-trait-impl/trait-where-clause-const.rs @@ -4,8 +4,10 @@ // test is not enough. #![feature(const_trait_impl)] +#[const_trait] trait Bar {} +#[const_trait] trait Foo { fn a(); fn b() where Self: ~const Bar; diff --git a/src/test/ui/rfc-2632-const-trait-impl/trait-where-clause-const.stderr b/src/test/ui/rfc-2632-const-trait-impl/trait-where-clause-const.stderr index 13d8639de30..f2846b6a662 100644 --- a/src/test/ui/rfc-2632-const-trait-impl/trait-where-clause-const.stderr +++ b/src/test/ui/rfc-2632-const-trait-impl/trait-where-clause-const.stderr @@ -1,11 +1,11 @@ error[E0277]: the trait bound `T: ~const Bar` is not satisfied - --> $DIR/trait-where-clause-const.rs:17:5 + --> $DIR/trait-where-clause-const.rs:19:5 | LL | T::b(); | ^^^^^^ the trait `~const Bar` is not implemented for `T` | note: the trait `Bar` is implemented for `T`, but that implementation is not `const` - --> $DIR/trait-where-clause-const.rs:17:5 + --> $DIR/trait-where-clause-const.rs:19:5 | LL | T::b(); | ^^^^^^ @@ -15,13 +15,13 @@ LL | const fn test1() { | ++++++++++++ error[E0277]: the trait bound `T: ~const Bar` is not satisfied - --> $DIR/trait-where-clause-const.rs:19:5 + --> $DIR/trait-where-clause-const.rs:21:5 | LL | T::c::(); | ^^^^^^^^^^^ the trait `~const Bar` is not implemented for `T` | note: the trait `Bar` is implemented for `T`, but that implementation is not `const` - --> $DIR/trait-where-clause-const.rs:19:5 + --> $DIR/trait-where-clause-const.rs:21:5 | LL | T::c::(); | ^^^^^^^^^^^ diff --git a/src/test/ui/rfc-2632-const-trait-impl/trait-where-clause-self-referential.rs b/src/test/ui/rfc-2632-const-trait-impl/trait-where-clause-self-referential.rs index acea58eaecb..3b028ac48db 100644 --- a/src/test/ui/rfc-2632-const-trait-impl/trait-where-clause-self-referential.rs +++ b/src/test/ui/rfc-2632-const-trait-impl/trait-where-clause-self-referential.rs @@ -2,6 +2,7 @@ #![feature(const_trait_impl)] +#[const_trait] trait Foo { fn bar() where Self: ~const Foo; } diff --git a/src/test/ui/rfc-2632-const-trait-impl/trait-where-clause.rs b/src/test/ui/rfc-2632-const-trait-impl/trait-where-clause.rs index 5bd23a8cb20..85ca5fc9048 100644 --- a/src/test/ui/rfc-2632-const-trait-impl/trait-where-clause.rs +++ b/src/test/ui/rfc-2632-const-trait-impl/trait-where-clause.rs @@ -1,5 +1,6 @@ #![feature(const_trait_impl)] +#[const_trait] trait Bar {} trait Foo { diff --git a/src/test/ui/rfc-2632-const-trait-impl/trait-where-clause.stderr b/src/test/ui/rfc-2632-const-trait-impl/trait-where-clause.stderr index 96365d33433..11f0c40160d 100644 --- a/src/test/ui/rfc-2632-const-trait-impl/trait-where-clause.stderr +++ b/src/test/ui/rfc-2632-const-trait-impl/trait-where-clause.stderr @@ -1,11 +1,11 @@ error[E0277]: the trait bound `T: Bar` is not satisfied - --> $DIR/trait-where-clause.rs:13:5 + --> $DIR/trait-where-clause.rs:14:5 | LL | T::b(); | ^^^^ the trait `Bar` is not implemented for `T` | note: required by a bound in `Foo::b` - --> $DIR/trait-where-clause.rs:7:24 + --> $DIR/trait-where-clause.rs:8:24 | LL | fn b() where Self: ~const Bar; | ^^^^^^^^^^ required by this bound in `Foo::b` @@ -15,13 +15,13 @@ LL | fn test1() { | +++++ error[E0277]: the trait bound `T: Bar` is not satisfied - --> $DIR/trait-where-clause.rs:15:12 + --> $DIR/trait-where-clause.rs:16:12 | LL | T::c::(); | ^ the trait `Bar` is not implemented for `T` | note: required by a bound in `Foo::c` - --> $DIR/trait-where-clause.rs:8:13 + --> $DIR/trait-where-clause.rs:9:13 | LL | fn c(); | ^^^^^^^^^^ required by this bound in `Foo::c` diff --git a/src/tools/build-manifest/src/main.rs b/src/tools/build-manifest/src/main.rs index 14311cff5c8..b0006cb90bd 100644 --- a/src/tools/build-manifest/src/main.rs +++ b/src/tools/build-manifest/src/main.rs @@ -193,6 +193,12 @@ macro_rules! t { Err(e) => panic!("{} failed with {}", stringify!($e), e), } }; + ($e:expr, $extra:expr) => { + match $e { + Ok(e) => e, + Err(e) => panic!("{} failed with {}: {}", stringify!($e), e, $extra), + } + }; } struct Builder { @@ -437,7 +443,7 @@ impl Builder { host_component("rustfmt-preview"), host_component("llvm-tools-preview"), host_component("rust-analysis"), - host_component("rust-docs-json"), + host_component("rust-docs-json-preview"), ]); extensions.extend( @@ -584,7 +590,7 @@ impl Builder { self.shipped_files.insert(name.clone()); let dst = self.output.join(name); - t!(fs::write(&dst, contents)); + t!(fs::write(&dst, contents), format!("failed to create manifest {}", dst.display())); } fn write_shipped_files(&self, path: &Path) { diff --git a/src/tools/build-manifest/src/versions.rs b/src/tools/build-manifest/src/versions.rs index 92ef9968fe5..0186194a41f 100644 --- a/src/tools/build-manifest/src/versions.rs +++ b/src/tools/build-manifest/src/versions.rs @@ -20,6 +20,7 @@ pub(crate) enum PkgType { Rustfmt, LlvmTools, Miri, + JsonDocs, Other(String), } @@ -36,6 +37,7 @@ impl PkgType { "rustfmt" | "rustfmt-preview" => PkgType::Rustfmt, "llvm-tools" | "llvm-tools-preview" => PkgType::LlvmTools, "miri" | "miri-preview" => PkgType::Miri, + "rust-docs-json" | "rust-docs-json-preview" => PkgType::JsonDocs, other => PkgType::Other(other.into()), } } @@ -53,6 +55,7 @@ impl PkgType { PkgType::Rustfmt => "rustfmt", PkgType::LlvmTools => "llvm-tools", PkgType::Miri => "miri", + PkgType::JsonDocs => "rust-docs-json", PkgType::Other(component) => component, } } @@ -72,6 +75,7 @@ impl PkgType { PkgType::Rust => true, PkgType::RustSrc => true, PkgType::Rustc => true, + PkgType::JsonDocs => true, PkgType::Other(_) => true, } } @@ -113,6 +117,9 @@ impl Versions { Some(version) => Ok(version.clone()), None => { let version_info = self.load_version_from_tarball(package)?; + if *package == PkgType::Rust && version_info.version.is_none() { + panic!("missing version info for toolchain"); + } self.versions.insert(package.clone(), version_info.clone()); Ok(version_info) } @@ -127,6 +134,7 @@ impl Versions { Ok(file) => file, Err(err) if err.kind() == std::io::ErrorKind::NotFound => { // Missing tarballs do not return an error, but return empty data. + println!("warning: missing tarball {}", tarball.display()); return Ok(VersionInfo::default()); } Err(err) => return Err(err.into()), diff --git a/src/tools/clippy/clippy_lints/src/dereference.rs b/src/tools/clippy/clippy_lints/src/dereference.rs index e54d71fc8e4..f0d5ed6f594 100644 --- a/src/tools/clippy/clippy_lints/src/dereference.rs +++ b/src/tools/clippy/clippy_lints/src/dereference.rs @@ -1238,7 +1238,7 @@ fn ty_auto_deref_stability<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>, precedenc ty::Adt(..) if ty.has_placeholders() || ty.has_opaque_types() => { Position::ReborrowStable(precedence).into() }, - ty::Adt(_, substs) if substs.has_param_types_or_consts() => { + ty::Adt(_, substs) if substs.has_non_region_param() => { TyPosition::new_deref_stable_for_result(precedence, ty) }, ty::Bool