diff --git a/compiler/rustc_const_eval/messages.ftl b/compiler/rustc_const_eval/messages.ftl index 0b336109921fe..e5dd5729d8905 100644 --- a/compiler/rustc_const_eval/messages.ftl +++ b/compiler/rustc_const_eval/messages.ftl @@ -303,8 +303,6 @@ const_eval_remainder_overflow = overflow in signed remainder (dividing MIN by -1) const_eval_scalar_size_mismatch = scalar size mismatch: expected {$target_size} bytes but got {$data_size} bytes instead -const_eval_size_of_unsized = - size_of called on unsized type `{$ty}` const_eval_size_overflow = overflow computing total size of `{$name}` diff --git a/compiler/rustc_const_eval/src/errors.rs b/compiler/rustc_const_eval/src/errors.rs index 3a4e2648b808e..4362cae7ed746 100644 --- a/compiler/rustc_const_eval/src/errors.rs +++ b/compiler/rustc_const_eval/src/errors.rs @@ -862,7 +862,6 @@ impl<'tcx> ReportErrorExt for InvalidProgramInfo<'tcx> { InvalidProgramInfo::FnAbiAdjustForForeignAbi(_) => { rustc_middle::error::middle_adjust_for_foreign_abi_error } - InvalidProgramInfo::SizeOfUnsizedType(_) => const_eval_size_of_unsized, InvalidProgramInfo::ConstPropNonsense => { panic!("We had const-prop nonsense, this should never be printed") } @@ -890,9 +889,6 @@ impl<'tcx> ReportErrorExt for InvalidProgramInfo<'tcx> { builder.set_arg("arch", arch); builder.set_arg("abi", abi.name()); } - InvalidProgramInfo::SizeOfUnsizedType(ty) => { - builder.set_arg("ty", ty); - } } } } diff --git a/compiler/rustc_const_eval/src/interpret/step.rs b/compiler/rustc_const_eval/src/interpret/step.rs index f04c73105d223..0740894a4ffa6 100644 --- a/compiler/rustc_const_eval/src/interpret/step.rs +++ b/compiler/rustc_const_eval/src/interpret/step.rs @@ -269,13 +269,10 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let ty = self.subst_from_current_frame_and_normalize_erasing_regions(ty)?; let layout = self.layout_of(ty)?; if let mir::NullOp::SizeOf | mir::NullOp::AlignOf = null_op && layout.is_unsized() { - // FIXME: This should be a span_bug, but const generics can run MIR - // that is not properly type-checked yet (#97477). - self.tcx.sess.delay_span_bug( + span_bug!( self.frame().current_span(), - format!("{null_op:?} MIR operator called for unsized type {ty}"), + "{null_op:?} MIR operator called for unsized type {ty}", ); - throw_inval!(SizeOfUnsizedType(ty)); } let val = match null_op { mir::NullOp::SizeOf => layout.size.bytes(), diff --git a/compiler/rustc_llvm/llvm-wrapper/LLVMWrapper.h b/compiler/rustc_llvm/llvm-wrapper/LLVMWrapper.h index ea04546284523..3f2bf2c9b444d 100644 --- a/compiler/rustc_llvm/llvm-wrapper/LLVMWrapper.h +++ b/compiler/rustc_llvm/llvm-wrapper/LLVMWrapper.h @@ -15,7 +15,6 @@ #include "llvm/Support/DynamicLibrary.h" #include "llvm/Support/FormattedStream.h" #include "llvm/Support/JSON.h" -#include "llvm/Support/Host.h" #include "llvm/Support/Memory.h" #include "llvm/Support/SourceMgr.h" #include "llvm/Support/TargetSelect.h" diff --git a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp index 48b5fd6e283be..69580c0f76e5a 100644 --- a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp @@ -25,7 +25,6 @@ #if LLVM_VERSION_GE(17, 0) #include "llvm/Support/VirtualFileSystem.h" #endif -#include "llvm/Support/Host.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Transforms/IPO/AlwaysInliner.h" #include "llvm/Transforms/IPO/FunctionImport.h" diff --git a/compiler/rustc_middle/src/mir/interpret/error.rs b/compiler/rustc_middle/src/mir/interpret/error.rs index 2e46bfc1a3819..e6ef5a41ee0c6 100644 --- a/compiler/rustc_middle/src/mir/interpret/error.rs +++ b/compiler/rustc_middle/src/mir/interpret/error.rs @@ -184,8 +184,6 @@ pub enum InvalidProgramInfo<'tcx> { /// (which unfortunately typeck does not reject). /// Not using `FnAbiError` as that contains a nested `LayoutError`. FnAbiAdjustForForeignAbi(call::AdjustForForeignAbiError), - /// SizeOf of unsized type was requested. - SizeOfUnsizedType(Ty<'tcx>), /// We are runnning into a nonsense situation due to ConstProp violating our invariants. ConstPropNonsense, } diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs index f99a51fea0bc2..bf798adee199e 100644 --- a/compiler/rustc_mir_transform/src/lib.rs +++ b/compiler/rustc_mir_transform/src/lib.rs @@ -75,7 +75,7 @@ mod errors; mod ffi_unwind_calls; mod function_item_references; mod generator; -mod inline; +pub mod inline; mod instsimplify; mod large_enums; mod lower_intrinsics; @@ -431,7 +431,9 @@ fn mir_drops_elaborated_and_const_checked(tcx: TyCtxt<'_>, def: LocalDefId) -> & tcx.alloc_steal_mir(body) } -fn run_analysis_to_runtime_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { +// Made public such that `mir_drops_elaborated_and_const_checked` can be overridden +// by custom rustc drivers, running all the steps by themselves. +pub fn run_analysis_to_runtime_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { assert!(body.phase == MirPhase::Analysis(AnalysisPhase::Initial)); let did = body.source.def_id(); diff --git a/compiler/rustc_target/src/spec/aarch64_unknown_teeos.rs b/compiler/rustc_target/src/spec/aarch64_unknown_teeos.rs new file mode 100644 index 0000000000000..64a7dc681c896 --- /dev/null +++ b/compiler/rustc_target/src/spec/aarch64_unknown_teeos.rs @@ -0,0 +1,16 @@ +use crate::spec::Target; + +pub fn target() -> Target { + let mut base = super::teeos_base::opts(); + base.features = "+strict-align,+neon,+fp-armv8".into(); + base.max_atomic_width = Some(128); + base.linker = Some("aarch64-linux-gnu-ld".into()); + + Target { + llvm_target: "aarch64-unknown-none".into(), + pointer_width: 64, + data_layout: "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128".into(), + arch: "aarch64".into(), + options: base, + } +} diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index c215a7c4b6e04..6ab0aed1ab8a7 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -83,6 +83,7 @@ mod openbsd_base; mod redox_base; mod solaris_base; mod solid_base; +mod teeos_base; mod thumb_base; mod uefi_msvc_base; mod unikraft_linux_musl_base; @@ -1494,6 +1495,8 @@ supported_targets! { ("x86_64-unknown-none", x86_64_unknown_none), + ("aarch64-unknown-teeos", aarch64_unknown_teeos), + ("mips64-openwrt-linux-musl", mips64_openwrt_linux_musl), ("aarch64-unknown-nto-qnx710", aarch64_unknown_nto_qnx_710), diff --git a/compiler/rustc_target/src/spec/teeos_base.rs b/compiler/rustc_target/src/spec/teeos_base.rs new file mode 100644 index 0000000000000..1bc71bab01605 --- /dev/null +++ b/compiler/rustc_target/src/spec/teeos_base.rs @@ -0,0 +1,29 @@ +use super::{Cc, LinkerFlavor, Lld, PanicStrategy}; +use crate::spec::{RelroLevel, TargetOptions}; + +pub fn opts() -> TargetOptions { + let lld_args = &["-zmax-page-size=4096", "-znow", "-ztext", "--execute-only"]; + let cc_args = &["-Wl,-zmax-page-size=4096", "-Wl,-znow", "-Wl,-ztext", "-mexecute-only"]; + + let mut pre_link_args = TargetOptions::link_args(LinkerFlavor::Gnu(Cc::No, Lld::No), lld_args); + super::add_link_args(&mut pre_link_args, LinkerFlavor::Gnu(Cc::Yes, Lld::No), cc_args); + + TargetOptions { + os: "teeos".into(), + vendor: "unknown".into(), + dynamic_linking: true, + linker_flavor: LinkerFlavor::Gnu(Cc::Yes, Lld::No), + // rpath hardcodes -Wl, so it can't be used together with ld.lld. + // C TAs also don't support rpath, so this is fine. + has_rpath: false, + // Note: Setting has_thread_local to true causes an error when + // loading / dyn-linking the TA + has_thread_local: false, + position_independent_executables: true, + relro_level: RelroLevel::Full, + crt_static_respected: true, + pre_link_args, + panic_strategy: PanicStrategy::Abort, + ..Default::default() + } +} diff --git a/compiler/rustc_trait_selection/src/solve/assembly/mod.rs b/compiler/rustc_trait_selection/src/solve/assembly/mod.rs index 1391b51e67f31..3750b3750bff1 100644 --- a/compiler/rustc_trait_selection/src/solve/assembly/mod.rs +++ b/compiler/rustc_trait_selection/src/solve/assembly/mod.rs @@ -316,6 +316,8 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { self.assemble_param_env_candidates(goal, &mut candidates); + self.assemble_coherence_unknowable_candidates(goal, &mut candidates); + candidates } @@ -363,10 +365,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { self.assemble_object_bound_candidates(goal, &mut candidates); - self.assemble_coherence_unknowable_candidates(goal, &mut candidates); - self.assemble_candidates_after_normalizing_self_ty(goal, &mut candidates, num_steps); - candidates } @@ -877,26 +876,43 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { goal: Goal<'tcx, G>, candidates: &mut Vec>, ) { + let tcx = self.tcx(); match self.solver_mode() { SolverMode::Normal => return, - SolverMode::Coherence => { - let trait_ref = goal.predicate.trait_ref(self.tcx()); - match coherence::trait_ref_is_knowable(self.tcx(), trait_ref) { - Ok(()) => {} - Err(_) => match self - .evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS) - { - Ok(result) => candidates.push(Candidate { - source: CandidateSource::BuiltinImpl(BuiltinImplSource::Misc), - result, - }), - // FIXME: This will be reachable at some point if we're in - // `assemble_candidates_after_normalizing_self_ty` and we get a - // universe error. We'll deal with it at this point. - Err(NoSolution) => bug!("coherence candidate resulted in NoSolution"), - }, + SolverMode::Coherence => {} + }; + + let result = self.probe_candidate("coherence unknowable").enter(|ecx| { + let trait_ref = goal.predicate.trait_ref(tcx); + + #[derive(Debug)] + enum FailureKind { + Overflow, + NoSolution(NoSolution), + } + let lazily_normalize_ty = |ty| match ecx.try_normalize_ty(goal.param_env, ty) { + Ok(Some(ty)) => Ok(ty), + Ok(None) => Err(FailureKind::Overflow), + Err(e) => Err(FailureKind::NoSolution(e)), + }; + + match coherence::trait_ref_is_knowable(tcx, trait_ref, lazily_normalize_ty) { + Err(FailureKind::Overflow) => { + ecx.evaluate_added_goals_and_make_canonical_response(Certainty::OVERFLOW) + } + Err(FailureKind::NoSolution(NoSolution)) | Ok(Ok(())) => Err(NoSolution), + Ok(Err(_)) => { + ecx.evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS) } } + }); + + match result { + Ok(result) => candidates.push(Candidate { + source: CandidateSource::BuiltinImpl(BuiltinImplSource::Misc), + result, + }), + Err(NoSolution) => {} } } diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs index 60c49f665a6a9..5c2cbe399536a 100644 --- a/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs +++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs @@ -388,44 +388,60 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> { && is_normalizes_to_hack == IsNormalizesToHack::No && !self.search_graph.in_cycle() { - debug!("rerunning goal to check result is stable"); - self.search_graph.reset_encountered_overflow(encountered_overflow); - let (_orig_values, canonical_goal) = self.canonicalize_goal(goal); - let Ok(new_canonical_response) = EvalCtxt::evaluate_canonical_goal( - self.tcx(), - self.search_graph, - canonical_goal, - // FIXME(-Ztrait-solver=next): we do not track what happens in `evaluate_canonical_goal` - &mut ProofTreeBuilder::new_noop(), - ) else { - bug!( - "goal went from {certainty:?} to error: re-canonicalized goal={canonical_goal:#?} \ - first_response={canonical_response:#?}, - second response was error" - ); - }; - // We only check for modulo regions as we convert all regions in - // the input to new existentials, even if they're expected to be - // `'static` or a placeholder region. - if !new_canonical_response.value.var_values.is_identity_modulo_regions() { - bug!( - "unstable result: re-canonicalized goal={canonical_goal:#?} \ - first_response={canonical_response:#?} \ - second_response={new_canonical_response:#?}" - ); - } - if certainty != new_canonical_response.value.certainty { - bug!( - "unstable certainty: {certainty:#?} re-canonicalized goal={canonical_goal:#?} \ - first_response={canonical_response:#?} \ - second_response={new_canonical_response:#?}" - ); - } + // The nested evaluation has to happen with the original state + // of `encountered_overflow`. + let from_original_evaluation = + self.search_graph.reset_encountered_overflow(encountered_overflow); + self.check_evaluate_goal_stable_result(goal, canonical_goal, canonical_response); + // In case the evaluation was unstable, we manually make sure that this + // debug check does not influence the result of the parent goal. + self.search_graph.reset_encountered_overflow(from_original_evaluation); } Ok((has_changed, certainty, nested_goals)) } + fn check_evaluate_goal_stable_result( + &mut self, + goal: Goal<'tcx, ty::Predicate<'tcx>>, + original_input: CanonicalInput<'tcx>, + original_result: CanonicalResponse<'tcx>, + ) { + let (_orig_values, canonical_goal) = self.canonicalize_goal(goal); + let result = EvalCtxt::evaluate_canonical_goal( + self.tcx(), + self.search_graph, + canonical_goal, + // FIXME(-Ztrait-solver=next): we do not track what happens in `evaluate_canonical_goal` + &mut ProofTreeBuilder::new_noop(), + ); + + macro_rules! fail { + ($msg:expr) => {{ + let msg = $msg; + warn!( + "unstable result: {msg}\n\ + original goal: {original_input:?},\n\ + original result: {original_result:?}\n\ + re-canonicalized goal: {canonical_goal:?}\n\ + second response: {result:?}" + ); + return; + }}; + } + + let Ok(new_canonical_response) = result else { fail!("second response was error") }; + // We only check for modulo regions as we convert all regions in + // the input to new existentials, even if they're expected to be + // `'static` or a placeholder region. + if !new_canonical_response.value.var_values.is_identity_modulo_regions() { + fail!("additional constraints from second response") + } + if original_result.value.certainty != new_canonical_response.value.certainty { + fail!("unstable certainty") + } + } + fn compute_goal(&mut self, goal: Goal<'tcx, ty::Predicate<'tcx>>) -> QueryResult<'tcx> { let Goal { param_env, predicate } = goal; let kind = predicate.kind(); diff --git a/compiler/rustc_trait_selection/src/solve/mod.rs b/compiler/rustc_trait_selection/src/solve/mod.rs index 63d4a38119f93..75a99f799a24c 100644 --- a/compiler/rustc_trait_selection/src/solve/mod.rs +++ b/compiler/rustc_trait_selection/src/solve/mod.rs @@ -283,6 +283,37 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { Ok(self.make_ambiguous_response_no_constraints(maybe_cause)) } + + /// Normalize a type when it is structually matched on. + /// + /// For self types this is generally already handled through + /// `assemble_candidates_after_normalizing_self_ty`, so anything happening + /// in [`EvalCtxt::assemble_candidates_via_self_ty`] does not have to normalize + /// the self type. It is required when structurally matching on any other + /// arguments of a trait goal, e.g. when assembling builtin unsize candidates. + fn try_normalize_ty( + &mut self, + param_env: ty::ParamEnv<'tcx>, + mut ty: Ty<'tcx>, + ) -> Result>, NoSolution> { + for _ in 0..self.local_overflow_limit() { + let ty::Alias(_, projection_ty) = *ty.kind() else { + return Ok(Some(ty)); + }; + + let normalized_ty = self.next_ty_infer(); + let normalizes_to_goal = Goal::new( + self.tcx(), + param_env, + ty::ProjectionPredicate { projection_ty, term: normalized_ty.into() }, + ); + self.add_goal(normalizes_to_goal); + self.try_evaluate_added_goals()?; + ty = self.resolve_vars_if_possible(normalized_ty); + } + + Ok(None) + } } fn response_no_constraints_raw<'tcx>( diff --git a/compiler/rustc_trait_selection/src/solve/search_graph/mod.rs b/compiler/rustc_trait_selection/src/solve/search_graph/mod.rs index 21c8d476902ab..87fe62645de83 100644 --- a/compiler/rustc_trait_selection/src/solve/search_graph/mod.rs +++ b/compiler/rustc_trait_selection/src/solve/search_graph/mod.rs @@ -134,9 +134,13 @@ impl<'tcx> SearchGraph<'tcx> { /// Resets `encountered_overflow` of the current goal. /// /// This should only be used for the check in `evaluate_goal`. - pub(super) fn reset_encountered_overflow(&mut self, encountered_overflow: bool) { - if encountered_overflow { - self.stack.raw.last_mut().unwrap().encountered_overflow = true; + pub(super) fn reset_encountered_overflow(&mut self, encountered_overflow: bool) -> bool { + if let Some(last) = self.stack.raw.last_mut() { + let prev = last.encountered_overflow; + last.encountered_overflow = encountered_overflow; + prev + } else { + false } } diff --git a/compiler/rustc_trait_selection/src/solve/trait_goals.rs b/compiler/rustc_trait_selection/src/solve/trait_goals.rs index db80b62d8a28f..ee6f1686b8238 100644 --- a/compiler/rustc_trait_selection/src/solve/trait_goals.rs +++ b/compiler/rustc_trait_selection/src/solve/trait_goals.rs @@ -448,7 +448,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { // We need to normalize the b_ty since it's matched structurally // in the other functions below. let b_ty = match ecx - .normalize_non_self_ty(goal.predicate.trait_ref.args.type_at(1), goal.param_env) + .try_normalize_ty(goal.param_env, goal.predicate.trait_ref.args.type_at(1)) { Ok(Some(b_ty)) => b_ty, Ok(None) => return vec![misc_candidate(ecx, Certainty::OVERFLOW)], @@ -927,41 +927,4 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { let candidates = self.assemble_and_evaluate_candidates(goal); self.merge_candidates(candidates) } - - /// Normalize a non-self type when it is structually matched on when solving - /// a built-in goal. - /// - /// This is handled already through `assemble_candidates_after_normalizing_self_ty` - /// for the self type, but for other goals, additional normalization of other - /// arguments may be needed to completely implement the semantics of the trait. - /// - /// This is required when structurally matching on any trait argument that is - /// not the self type. - fn normalize_non_self_ty( - &mut self, - mut ty: Ty<'tcx>, - param_env: ty::ParamEnv<'tcx>, - ) -> Result>, NoSolution> { - if !matches!(ty.kind(), ty::Alias(..)) { - return Ok(Some(ty)); - } - - for _ in 0..self.local_overflow_limit() { - let ty::Alias(_, projection_ty) = *ty.kind() else { - return Ok(Some(ty)); - }; - - let normalized_ty = self.next_ty_infer(); - let normalizes_to_goal = Goal::new( - self.tcx(), - param_env, - ty::ProjectionPredicate { projection_ty, term: normalized_ty.into() }, - ); - self.add_goal(normalizes_to_goal); - self.try_evaluate_added_goals()?; - ty = self.resolve_vars_if_possible(normalized_ty); - } - - Ok(None) - } } diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs index 19d5baa30ec6b..e56af586ed875 100644 --- a/compiler/rustc_trait_selection/src/traits/coherence.rs +++ b/compiler/rustc_trait_selection/src/traits/coherence.rs @@ -452,22 +452,23 @@ fn prove_negated_obligation<'tcx>( /// This both checks whether any downstream or sibling crates could /// implement it and whether an upstream crate can add this impl /// without breaking backwards compatibility. -#[instrument(level = "debug", skip(tcx), ret)] -pub fn trait_ref_is_knowable<'tcx>( +#[instrument(level = "debug", skip(tcx, lazily_normalize_ty), ret)] +pub fn trait_ref_is_knowable<'tcx, E: Debug>( tcx: TyCtxt<'tcx>, trait_ref: ty::TraitRef<'tcx>, -) -> Result<(), Conflict> { + mut lazily_normalize_ty: impl FnMut(Ty<'tcx>) -> Result, E>, +) -> Result, E> { if Some(trait_ref.def_id) == tcx.lang_items().fn_ptr_trait() { // The only types implementing `FnPtr` are function pointers, // so if there's no impl of `FnPtr` in the current crate, // then such an impl will never be added in the future. - return Ok(()); + return Ok(Ok(())); } - if orphan_check_trait_ref(trait_ref, InCrate::Remote).is_ok() { + if orphan_check_trait_ref(trait_ref, InCrate::Remote, &mut lazily_normalize_ty)?.is_ok() { // A downstream or cousin crate is allowed to implement some // substitution of this trait-ref. - return Err(Conflict::Downstream); + return Ok(Err(Conflict::Downstream)); } if trait_ref_is_local_or_fundamental(tcx, trait_ref) { @@ -476,7 +477,7 @@ pub fn trait_ref_is_knowable<'tcx>( // allowed to implement a substitution of this trait ref, which // means impls could only come from dependencies of this crate, // which we already know about. - return Ok(()); + return Ok(Ok(())); } // This is a remote non-fundamental trait, so if another crate @@ -487,10 +488,10 @@ pub fn trait_ref_is_knowable<'tcx>( // and if we are an intermediate owner, then we don't care // about future-compatibility, which means that we're OK if // we are an owner. - if orphan_check_trait_ref(trait_ref, InCrate::Local).is_ok() { - Ok(()) + if orphan_check_trait_ref(trait_ref, InCrate::Local, &mut lazily_normalize_ty)?.is_ok() { + Ok(Ok(())) } else { - Err(Conflict::Upstream) + Ok(Err(Conflict::Upstream)) } } @@ -526,7 +527,7 @@ pub fn orphan_check(tcx: TyCtxt<'_>, impl_def_id: DefId) -> Result<(), OrphanChe return Ok(()); } - orphan_check_trait_ref(trait_ref, InCrate::Local) + orphan_check_trait_ref::(trait_ref, InCrate::Local, |ty| Ok(ty)).unwrap() } /// Checks whether a trait-ref is potentially implementable by a crate. @@ -615,11 +616,12 @@ pub fn orphan_check(tcx: TyCtxt<'_>, impl_def_id: DefId) -> Result<(), OrphanChe /// /// Note that this function is never called for types that have both type /// parameters and inference variables. -#[instrument(level = "trace", ret)] -fn orphan_check_trait_ref<'tcx>( +#[instrument(level = "trace", skip(lazily_normalize_ty), ret)] +fn orphan_check_trait_ref<'tcx, E: Debug>( trait_ref: ty::TraitRef<'tcx>, in_crate: InCrate, -) -> Result<(), OrphanCheckErr<'tcx>> { + lazily_normalize_ty: impl FnMut(Ty<'tcx>) -> Result, E>, +) -> Result>, E> { if trait_ref.has_infer() && trait_ref.has_param() { bug!( "can't orphan check a trait ref with both params and inference variables {:?}", @@ -627,9 +629,10 @@ fn orphan_check_trait_ref<'tcx>( ); } - let mut checker = OrphanChecker::new(in_crate); - match trait_ref.visit_with(&mut checker) { + let mut checker = OrphanChecker::new(in_crate, lazily_normalize_ty); + Ok(match trait_ref.visit_with(&mut checker) { ControlFlow::Continue(()) => Err(OrphanCheckErr::NonLocalInputType(checker.non_local_tys)), + ControlFlow::Break(OrphanCheckEarlyExit::NormalizationFailure(err)) => return Err(err), ControlFlow::Break(OrphanCheckEarlyExit::ParamTy(ty)) => { // Does there exist some local type after the `ParamTy`. checker.search_first_local_ty = true; @@ -642,34 +645,39 @@ fn orphan_check_trait_ref<'tcx>( } } ControlFlow::Break(OrphanCheckEarlyExit::LocalTy(_)) => Ok(()), - } + }) } -struct OrphanChecker<'tcx> { +struct OrphanChecker<'tcx, F> { in_crate: InCrate, in_self_ty: bool, + lazily_normalize_ty: F, /// Ignore orphan check failures and exclusively search for the first /// local type. search_first_local_ty: bool, non_local_tys: Vec<(Ty<'tcx>, bool)>, } -impl<'tcx> OrphanChecker<'tcx> { - fn new(in_crate: InCrate) -> Self { +impl<'tcx, F, E> OrphanChecker<'tcx, F> +where + F: FnOnce(Ty<'tcx>) -> Result, E>, +{ + fn new(in_crate: InCrate, lazily_normalize_ty: F) -> Self { OrphanChecker { in_crate, in_self_ty: true, + lazily_normalize_ty, search_first_local_ty: false, non_local_tys: Vec::new(), } } - fn found_non_local_ty(&mut self, t: Ty<'tcx>) -> ControlFlow> { + fn found_non_local_ty(&mut self, t: Ty<'tcx>) -> ControlFlow> { self.non_local_tys.push((t, self.in_self_ty)); ControlFlow::Continue(()) } - fn found_param_ty(&mut self, t: Ty<'tcx>) -> ControlFlow> { + fn found_param_ty(&mut self, t: Ty<'tcx>) -> ControlFlow> { if self.search_first_local_ty { ControlFlow::Continue(()) } else { @@ -685,18 +693,28 @@ impl<'tcx> OrphanChecker<'tcx> { } } -enum OrphanCheckEarlyExit<'tcx> { +enum OrphanCheckEarlyExit<'tcx, E> { + NormalizationFailure(E), ParamTy(Ty<'tcx>), LocalTy(Ty<'tcx>), } -impl<'tcx> TypeVisitor> for OrphanChecker<'tcx> { - type BreakTy = OrphanCheckEarlyExit<'tcx>; +impl<'tcx, F, E> TypeVisitor> for OrphanChecker<'tcx, F> +where + F: FnMut(Ty<'tcx>) -> Result, E>, +{ + type BreakTy = OrphanCheckEarlyExit<'tcx, E>; fn visit_region(&mut self, _r: ty::Region<'tcx>) -> ControlFlow { ControlFlow::Continue(()) } fn visit_ty(&mut self, ty: Ty<'tcx>) -> ControlFlow { + // Need to lazily normalize here in with `-Ztrait-solver=next-coherence`. + let ty = match (self.lazily_normalize_ty)(ty) { + Ok(ty) => ty, + Err(err) => return ControlFlow::Break(OrphanCheckEarlyExit::NormalizationFailure(err)), + }; + let result = match *ty.kind() { ty::Bool | ty::Char diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index f1bd9f8b71a71..eb5ea90c5fde3 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -1457,7 +1457,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // bound regions. let trait_ref = predicate.skip_binder().trait_ref; - coherence::trait_ref_is_knowable(self.tcx(), trait_ref) + coherence::trait_ref_is_knowable::(self.tcx(), trait_ref, |ty| Ok(ty)).unwrap() } /// Returns `true` if the global caches can be used. diff --git a/library/std/src/process.rs b/library/std/src/process.rs index f9cb755b01a3a..f1305dee14614 100644 --- a/library/std/src/process.rs +++ b/library/std/src/process.rs @@ -1528,7 +1528,7 @@ impl From for Stdio { // vs `_exit`. Naming of Unix system calls is not standardised across Unices, so terminology is a // matter of convention and tradition. For clarity we usually speak of `exit`, even when we might // mean an underlying system call such as `_exit`. -#[derive(PartialEq, Eq, Clone, Copy, Debug)] +#[derive(PartialEq, Eq, Clone, Copy, Debug, Default)] #[stable(feature = "process", since = "1.0.0")] pub struct ExitStatus(imp::ExitStatus); diff --git a/library/std/src/sys/unix/process/process_fuchsia.rs b/library/std/src/sys/unix/process/process_fuchsia.rs index e45c380a0bb84..9931c2af2f1e0 100644 --- a/library/std/src/sys/unix/process/process_fuchsia.rs +++ b/library/std/src/sys/unix/process/process_fuchsia.rs @@ -235,7 +235,7 @@ impl Process { } } -#[derive(PartialEq, Eq, Clone, Copy, Debug)] +#[derive(PartialEq, Eq, Clone, Copy, Debug, Default)] pub struct ExitStatus(i64); impl ExitStatus { diff --git a/library/std/src/sys/unix/process/process_unix.rs b/library/std/src/sys/unix/process/process_unix.rs index 0ce93af66ac0f..d87a28f2f6571 100644 --- a/library/std/src/sys/unix/process/process_unix.rs +++ b/library/std/src/sys/unix/process/process_unix.rs @@ -800,7 +800,7 @@ impl Process { // // This is not actually an "exit status" in Unix terminology. Rather, it is a "wait status". // See the discussion in comments and doc comments for `std::process::ExitStatus`. -#[derive(PartialEq, Eq, Clone, Copy)] +#[derive(PartialEq, Eq, Clone, Copy, Default)] pub struct ExitStatus(c_int); impl fmt::Debug for ExitStatus { diff --git a/library/std/src/sys/unix/process/process_unsupported.rs b/library/std/src/sys/unix/process/process_unsupported.rs index f28ca58d02038..8e0b971af7316 100644 --- a/library/std/src/sys/unix/process/process_unsupported.rs +++ b/library/std/src/sys/unix/process/process_unsupported.rs @@ -55,7 +55,7 @@ impl Process { } } -#[derive(PartialEq, Eq, Clone, Copy, Debug)] +#[derive(PartialEq, Eq, Clone, Copy, Debug, Default)] pub struct ExitStatus(c_int); impl ExitStatus { diff --git a/library/std/src/sys/unix/process/process_vxworks.rs b/library/std/src/sys/unix/process/process_vxworks.rs index f70d3cb396bfa..1ff2b2fb3833f 100644 --- a/library/std/src/sys/unix/process/process_vxworks.rs +++ b/library/std/src/sys/unix/process/process_vxworks.rs @@ -179,7 +179,7 @@ impl Process { } /// Unix exit statuses -#[derive(PartialEq, Eq, Clone, Copy, Debug)] +#[derive(PartialEq, Eq, Clone, Copy, Debug, Default)] pub struct ExitStatus(c_int); impl ExitStatus { diff --git a/library/std/src/sys/unsupported/process.rs b/library/std/src/sys/unsupported/process.rs index a494f2d6b4c15..77b675aaa4e49 100644 --- a/library/std/src/sys/unsupported/process.rs +++ b/library/std/src/sys/unsupported/process.rs @@ -99,58 +99,59 @@ impl fmt::Debug for Command { } } -pub struct ExitStatus(!); +#[derive(PartialEq, Eq, Clone, Copy, Debug, Default)] +#[non_exhaustive] +pub struct ExitStatus(); impl ExitStatus { pub fn exit_ok(&self) -> Result<(), ExitStatusError> { - self.0 + Ok(()) } pub fn code(&self) -> Option { - self.0 + Some(0) } } -impl Clone for ExitStatus { - fn clone(&self) -> ExitStatus { - self.0 +impl fmt::Display for ExitStatus { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "") } } -impl Copy for ExitStatus {} +pub struct ExitStatusError(!); -impl PartialEq for ExitStatus { - fn eq(&self, _other: &ExitStatus) -> bool { +impl Clone for ExitStatusError { + fn clone(&self) -> ExitStatusError { self.0 } } -impl Eq for ExitStatus {} +impl Copy for ExitStatusError {} -impl fmt::Debug for ExitStatus { - fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result { +impl PartialEq for ExitStatusError { + fn eq(&self, _other: &ExitStatusError) -> bool { self.0 } } -impl fmt::Display for ExitStatus { +impl Eq for ExitStatusError {} + +impl fmt::Debug for ExitStatusError { fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result { self.0 } } -#[derive(PartialEq, Eq, Clone, Copy, Debug)] -pub struct ExitStatusError(ExitStatus); - impl Into for ExitStatusError { fn into(self) -> ExitStatus { - self.0.0 + self.0 } } impl ExitStatusError { pub fn code(self) -> Option { - self.0.0 + self.0 } } diff --git a/library/std/src/sys/windows/process.rs b/library/std/src/sys/windows/process.rs index e3493cbb85094..2dd0c67acdb4e 100644 --- a/library/std/src/sys/windows/process.rs +++ b/library/std/src/sys/windows/process.rs @@ -652,7 +652,7 @@ impl Process { } } -#[derive(PartialEq, Eq, Clone, Copy, Debug)] +#[derive(PartialEq, Eq, Clone, Copy, Debug, Default)] pub struct ExitStatus(c::DWORD); impl ExitStatus { diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs index 2c63ec80c3e58..62c7b96b5be94 100644 --- a/src/bootstrap/compile.rs +++ b/src/bootstrap/compile.rs @@ -31,6 +31,7 @@ use crate::util::get_clang_cl_resource_dir; use crate::util::{exe, is_debug_info, is_dylib, output, symlink_dir, t, up_to_date}; use crate::LLVM_TOOLS; use crate::{CLang, Compiler, DependencyType, GitRepo, Mode}; +use filetime::FileTime; #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct Std { @@ -904,19 +905,12 @@ impl Step for Rustc { // our LLVM wrapper. Unless we're explicitly requesting `librustc_driver` to be built with // debuginfo (via the debuginfo level of the executables using it): strip this debuginfo // away after the fact. - // FIXME: to make things simpler for now, limit this to the host and target where we know - // `strip -g` is both available and will fix the issue, i.e. on a x64 linux host that is not - // cross-compiling. Expand this to other appropriate targets in the future. if builder.config.rust_debuginfo_level_rustc == DebuginfoLevel::None && builder.config.rust_debuginfo_level_tools == DebuginfoLevel::None - && target == "x86_64-unknown-linux-gnu" - && target == builder.config.build { let target_root_dir = stamp.parent().unwrap(); let rustc_driver = target_root_dir.join("librustc_driver.so"); - if rustc_driver.exists() { - output(Command::new("strip").arg("--strip-debug").arg(rustc_driver)); - } + strip_debug(builder, target, &rustc_driver); } builder.ensure(RustcLink::from_rustc( @@ -1974,3 +1968,30 @@ pub enum CargoMessage<'a> { success: bool, }, } + +pub fn strip_debug(builder: &Builder<'_>, target: TargetSelection, path: &Path) { + // FIXME: to make things simpler for now, limit this to the host and target where we know + // `strip -g` is both available and will fix the issue, i.e. on a x64 linux host that is not + // cross-compiling. Expand this to other appropriate targets in the future. + if target != "x86_64-unknown-linux-gnu" || target != builder.config.build || !path.exists() { + return; + } + + let previous_mtime = FileTime::from_last_modification_time(&path.metadata().unwrap()); + // Note: `output` will propagate any errors here. + output(Command::new("strip").arg("--strip-debug").arg(path)); + + // After running `strip`, we have to set the file modification time to what it was before, + // otherwise we risk Cargo invalidating its fingerprint and rebuilding the world next time + // bootstrap is invoked. + // + // An example of this is if we run this on librustc_driver.so. In the first invocation: + // - Cargo will build librustc_driver.so (mtime of 1) + // - Cargo will build rustc-main (mtime of 2) + // - Bootstrap will strip librustc_driver.so (changing the mtime to 3). + // + // In the second invocation of bootstrap, Cargo will see that the mtime of librustc_driver.so + // is greater than the mtime of rustc-main, and will rebuild rustc-main. That will then cause + // everything else (standard library, future stages...) to be rebuilt. + t!(filetime::set_file_mtime(path, previous_mtime)); +} diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs index 8c674d075b8c5..e3a9434a16481 100644 --- a/src/bootstrap/lib.rs +++ b/src/bootstrap/lib.rs @@ -133,7 +133,7 @@ const EXTRA_CHECK_CFGS: &[(Option, &'static str, Option<&[&'static str]>)] // #[cfg(bootstrap)] (Some(Mode::Std), "target_vendor", Some(&["unikraft"])), (Some(Mode::Std), "target_env", Some(&["libnx"])), - // (Some(Mode::Std), "target_os", Some(&[])), + (Some(Mode::Std), "target_os", Some(&["teeos"])), // #[cfg(bootstrap)] mips32r6, mips64r6 ( Some(Mode::Std), diff --git a/src/bootstrap/llvm.rs b/src/bootstrap/llvm.rs index 14ee5659ed563..4943f93fa9a01 100644 --- a/src/bootstrap/llvm.rs +++ b/src/bootstrap/llvm.rs @@ -512,27 +512,21 @@ impl Step for Llvm { // When building LLVM as a shared library on linux, it can contain unexpected debuginfo: // some can come from the C++ standard library. Unless we're explicitly requesting LLVM to // be built with debuginfo, strip it away after the fact, to make dist artifacts smaller. - // FIXME: to make things simpler for now, limit this to the host and target where we know - // `strip -g` is both available and will fix the issue, i.e. on a x64 linux host that is not - // cross-compiling. Expand this to other appropriate targets in the future. if builder.llvm_link_shared() && builder.config.llvm_optimize && !builder.config.llvm_release_debuginfo - && target == "x86_64-unknown-linux-gnu" - && target == builder.config.build { // Find the name of the LLVM shared library that we just built. let lib_name = find_llvm_lib_name("so"); // If the shared library exists in LLVM's `/build/lib/` or `/lib/` folders, strip its - // debuginfo. Note: `output` will propagate any errors here. - let strip_if_possible = |path: PathBuf| { - if path.exists() { - output(Command::new("strip").arg("--strip-debug").arg(path)); - } - }; - strip_if_possible(out_dir.join("lib").join(&lib_name)); - strip_if_possible(out_dir.join("build").join("lib").join(&lib_name)); + // debuginfo. + crate::compile::strip_debug(builder, target, &out_dir.join("lib").join(&lib_name)); + crate::compile::strip_debug( + builder, + target, + &out_dir.join("build").join("lib").join(&lib_name), + ); } t!(stamp.write()); diff --git a/src/doc/rustc/src/SUMMARY.md b/src/doc/rustc/src/SUMMARY.md index 851be1c0a2c87..817abbfaf268b 100644 --- a/src/doc/rustc/src/SUMMARY.md +++ b/src/doc/rustc/src/SUMMARY.md @@ -28,6 +28,7 @@ - [armv7-unknown-linux-uclibceabihf](platform-support/armv7-unknown-linux-uclibceabihf.md) - [\*-android and \*-androideabi](platform-support/android.md) - [\*-linux-ohos](platform-support/openharmony.md) + - [aarch64-unknown-teeos](platform-support/aarch64-unknown-teeos.md) - [\*-esp-espidf](platform-support/esp-idf.md) - [\*-unknown-fuchsia](platform-support/fuchsia.md) - [\*-kmc-solid_\*](platform-support/kmc-solid.md) diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md index 1b791f5eb3645..393719e7115cc 100644 --- a/src/doc/rustc/src/platform-support.md +++ b/src/doc/rustc/src/platform-support.md @@ -221,6 +221,7 @@ target | std | host | notes [`aarch64-nintendo-switch-freestanding`](platform-support/aarch64-nintendo-switch-freestanding.md) | * | | ARM64 Nintendo Switch, Horizon [`aarch64-pc-windows-gnullvm`](platform-support/pc-windows-gnullvm.md) | ✓ | ✓ | [`aarch64-unknown-linux-ohos`](platform-support/openharmony.md) | ✓ | | ARM64 OpenHarmony | +[`aarch64-unknown-teeos`](platform-support/aarch64-unknown-teeos.md) | ? | | ARM64 TEEOS | [`aarch64-unknown-nto-qnx710`](platform-support/nto-qnx.md) | ✓ | | ARM64 QNX Neutrino 7.1 RTOS | `aarch64-unknown-freebsd` | ✓ | ✓ | ARM64 FreeBSD [`aarch64-unknown-hermit`](platform-support/hermit.md) | ✓ | | ARM64 Hermit diff --git a/src/doc/rustc/src/platform-support/aarch64-unknown-teeos.md b/src/doc/rustc/src/platform-support/aarch64-unknown-teeos.md new file mode 100644 index 0000000000000..8fc5e6dd92b42 --- /dev/null +++ b/src/doc/rustc/src/platform-support/aarch64-unknown-teeos.md @@ -0,0 +1,100 @@ +# `aarch64-unknown-teeos` + +**Tier: 3** + +Target for the TEEOS operating system. + +TEEOS is a mini os run in TrustZone, for trusted/security apps. The kernel of TEEOS is HongMeng/ChCore micro kernel. The libc for TEEOS is a part of musl. +It's very small that there is no RwLock, no network, no stdin, and no file system for apps in TEEOS. + +Some abbreviation: +| Abbreviation | The full text | Description | +| ---- | ---- | ---- | +| TEE | Trusted Execution Environment | ARM TrustZone devide the system into two worlds/modes -- the secure world/mode and the normal world/mode. TEE is in the secure world/mode. | +| REE | Rich Execution Environment | The normal world. for example, Linux for Android phone is in REE side. | +| TA | Trusted Application | The app run in TEE side system. | +| CA | Client Application | The progress run in REE side system. | + +TEEOS is open source in progress. [MORE about](https://gitee.com/opentrustee-group) + +## Target maintainers + +- Petrochenkov Vadim +- Sword-Destiny + +## Setup +We use OpenHarmony SDK for TEEOS. + +The OpenHarmony SDK doesn't currently support Rust compilation directly, so +some setup is required. + +First, you must obtain the OpenHarmony SDK from [this page](https://gitee.com/openharmony/docs/tree/master/en/release-notes). +Select the version of OpenHarmony you are developing for and download the "Public SDK package for the standard system". + +Create the following shell scripts that wrap Clang from the OpenHarmony SDK: + +`aarch64-unknown-teeos-clang.sh` + +```sh +#!/bin/sh +exec /path/to/ohos-sdk/linux/native/llvm/bin/clang \ + --target aarch64-linux-gnu \ + "$@" +``` + +`aarch64-unknown-teeos-clang++.sh` + +```sh +#!/bin/sh +exec /path/to/ohos-sdk/linux/native/llvm/bin/clang++ \ + --target aarch64-linux-gnu \ + "$@" +``` + +## Building the target + +To build a rust toolchain, create a `config.toml` with the following contents: + +```toml +profile = "compiler" +changelog-seen = 2 + +[build] +sanitizers = true +profiler = true +target = ["x86_64-unknown-linux-gnu", "aarch64-unknown-teeos"] +submodules = false +compiler-docs = false +extended = true + +[install] +bindir = "bin" +libdir = "lib" + +[target.aarch64-unknown-teeos] +cc = "/path/to/scripts/aarch64-unknown-teeos-clang.sh" +cxx = "/path/to/scripts/aarch64-unknown-teeos-clang.sh" +linker = "/path/to/scripts/aarch64-unknown-teeos-clang.sh" +ar = "/path/to/ohos-sdk/linux/native/llvm/bin/llvm-ar" +ranlib = "/path/to/ohos-sdk/linux/native/llvm/bin/llvm-ranlib" +llvm-config = "/path/to/ohos-sdk/linux/native/llvm/bin/llvm-config" +``` + +## Building Rust programs + +Rust does not yet ship pre-compiled artifacts for this target. To compile for +this target, you will either need to build Rust with the target enabled (see +"Building the target" above), or build your own copy of `core` by using +`build-std` or similar. + +You will need to configure the linker to use in `~/.cargo/config`: +```toml +[target.aarch64-unknown-teeos] +linker = "/path/to/aarch64-unknown-teeos-clang.sh" +``` + +## Testing + +Running the Rust testsuite is not possible now. + +More information about how to test CA/TA. [See here](https://gitee.com/openharmony-sig/tee_tee_dev_kit/tree/master/docs) diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index c198742041707..3d237eb25cc9a 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -1645,7 +1645,7 @@ impl<'test> TestCx<'test> { if self.props.known_bug { if !expected_errors.is_empty() { self.fatal_proc_rec( - "`known_bug` tests should not have an expected errors", + "`known_bug` tests should not have an expected error", proc_res, ); } diff --git a/tests/ui/check-cfg/values-target-json.stderr b/tests/ui/check-cfg/values-target-json.stderr index eb81535e3edb0..e773d5d83ccfa 100644 --- a/tests/ui/check-cfg/values-target-json.stderr +++ b/tests/ui/check-cfg/values-target-json.stderr @@ -6,7 +6,7 @@ LL | #[cfg(target_os = "linuz")] | | | help: there is a expected value with a similar name: `"linux"` | - = note: expected values for `target_os` are: `aix`, `android`, `cuda`, `dragonfly`, `emscripten`, `ericos`, `espidf`, `freebsd`, `fuchsia`, `haiku`, `hermit`, `horizon`, `illumos`, `ios`, `l4re`, `linux`, `macos`, `netbsd`, `none`, `nto`, `openbsd`, `psp`, `redox`, `solaris`, `solid_asp3`, `tvos`, `uefi`, `unknown`, `vita`, `vxworks`, `wasi`, `watchos`, `windows`, `xous` + = note: expected values for `target_os` are: `aix`, `android`, `cuda`, `dragonfly`, `emscripten`, `ericos`, `espidf`, `freebsd`, `fuchsia`, `haiku`, `hermit`, `horizon`, `illumos`, `ios`, `l4re`, `linux`, `macos`, `netbsd`, `none`, `nto`, `openbsd`, `psp`, `redox`, `solaris`, `solid_asp3`, `teeos`, `tvos`, `uefi`, `unknown`, `vita`, `vxworks`, `wasi`, `watchos`, `windows`, `xous` = note: `#[warn(unexpected_cfgs)]` on by default warning: 1 warning emitted diff --git a/tests/ui/check-cfg/well-known-values.stderr b/tests/ui/check-cfg/well-known-values.stderr index 2d18cb82e037a..1f7758146563f 100644 --- a/tests/ui/check-cfg/well-known-values.stderr +++ b/tests/ui/check-cfg/well-known-values.stderr @@ -6,7 +6,7 @@ LL | #[cfg(target_os = "linuz")] | | | help: there is a expected value with a similar name: `"linux"` | - = note: expected values for `target_os` are: `aix`, `android`, `cuda`, `dragonfly`, `emscripten`, `espidf`, `freebsd`, `fuchsia`, `haiku`, `hermit`, `horizon`, `illumos`, `ios`, `l4re`, `linux`, `macos`, `netbsd`, `none`, `nto`, `openbsd`, `psp`, `redox`, `solaris`, `solid_asp3`, `tvos`, `uefi`, `unknown`, `vita`, `vxworks`, `wasi`, `watchos`, `windows`, `xous` + = note: expected values for `target_os` are: `aix`, `android`, `cuda`, `dragonfly`, `emscripten`, `espidf`, `freebsd`, `fuchsia`, `haiku`, `hermit`, `horizon`, `illumos`, `ios`, `l4re`, `linux`, `macos`, `netbsd`, `none`, `nto`, `openbsd`, `psp`, `redox`, `solaris`, `solid_asp3`, `teeos`, `tvos`, `uefi`, `unknown`, `vita`, `vxworks`, `wasi`, `watchos`, `windows`, `xous` = note: `#[warn(unexpected_cfgs)]` on by default warning: unexpected `cfg` condition value diff --git a/tests/ui/const-generics/generic_const_exprs/issue-80742.rs b/tests/ui/const-generics/generic_const_exprs/issue-80742.rs index 275f69953024c..6b2a0153f5106 100644 --- a/tests/ui/const-generics/generic_const_exprs/issue-80742.rs +++ b/tests/ui/const-generics/generic_const_exprs/issue-80742.rs @@ -1,4 +1,9 @@ // check-fail +// known-bug: #97477 +// failure-status: 101 +// normalize-stderr-test "note: .*\n\n" -> "" +// normalize-stderr-test "thread 'rustc' panicked.*\n" -> "" +// rustc-env:RUST_BACKTRACE=0 // This test used to cause an ICE in rustc_mir::interpret::step::eval_rvalue_into_place @@ -27,6 +32,5 @@ where } fn main() { - let dst = Inline::::new(0); //~ ERROR - //~^ ERROR + let dst = Inline::::new(0); } diff --git a/tests/ui/const-generics/generic_const_exprs/issue-80742.stderr b/tests/ui/const-generics/generic_const_exprs/issue-80742.stderr index dc3a400cbaa83..79ed82e02e0d6 100644 --- a/tests/ui/const-generics/generic_const_exprs/issue-80742.stderr +++ b/tests/ui/const-generics/generic_const_exprs/issue-80742.stderr @@ -1,71 +1,10 @@ -error[E0080]: evaluation of `Inline::::{constant#0}` failed +error: internal compiler error: compiler/rustc_const_eval/src/interpret/step.rs:272:21: SizeOf MIR operator called for unsized type dyn Debug --> $SRC_DIR/core/src/mem/mod.rs:LL:COL - | - = note: size_of called on unsized type `dyn Debug` - | -note: inside `std::mem::size_of::` - --> $SRC_DIR/core/src/mem/mod.rs:LL:COL -note: inside `Inline::::{constant#0}` - --> $DIR/issue-80742.rs:22:10 - | -LL | [u8; size_of::() + 1]: , - | ^^^^^^^^^^^^^^ - -error[E0599]: the function or associated item `new` exists for struct `Inline`, but its trait bounds were not satisfied - --> $DIR/issue-80742.rs:30:36 - | -LL | struct Inline - | ---------------- function or associated item `new` not found for this struct -... -LL | let dst = Inline::::new(0); - | ^^^ function or associated item cannot be called on `Inline` due to unsatisfied trait bounds - --> $SRC_DIR/core/src/fmt/mod.rs:LL:COL - | - = note: doesn't satisfy `dyn Debug: Sized` - | -note: trait bound `dyn Debug: Sized` was not satisfied - --> $DIR/issue-80742.rs:20:6 - | -LL | impl Inline - | ^ --------- - | | - | unsatisfied trait bound introduced here -help: consider relaxing the type parameter's implicit `Sized` bound - | -LL | impl Inline - | ++++++++ - -error[E0080]: evaluation of `Inline::::{constant#0}` failed - --> $SRC_DIR/core/src/mem/mod.rs:LL:COL - | - = note: size_of called on unsized type `dyn Debug` - | -note: inside `std::mem::size_of::` - --> $SRC_DIR/core/src/mem/mod.rs:LL:COL -note: inside `Inline::::{constant#0}` - --> $DIR/issue-80742.rs:14:10 - | -LL | [u8; size_of::() + 1]: , - | ^^^^^^^^^^^^^^ - -error[E0277]: the size for values of type `dyn Debug` cannot be known at compilation time - --> $DIR/issue-80742.rs:30:15 - | -LL | let dst = Inline::::new(0); - | ^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time - | - = help: the trait `Sized` is not implemented for `dyn Debug` -note: required by a bound in `Inline` - --> $DIR/issue-80742.rs:12:15 - | -LL | struct Inline - | ^ required by this bound in `Inline` -help: consider relaxing the implicit `Sized` restriction - | -LL | struct Inline - | ++++++++ -error: aborting due to 4 previous errors +Box +query stack during panic: +#0 [eval_to_allocation_raw] const-evaluating + checking `::{constant#0}` +#1 [eval_to_valtree] evaluating type-level constant +end of query stack +error: aborting due to previous error -Some errors have detailed explanations: E0080, E0277, E0599. -For more information about an error, try `rustc --explain E0080`. diff --git a/tests/ui/traits/new-solver/coherence/trait_ref_is_knowable-norm-overflow.rs b/tests/ui/traits/new-solver/coherence/trait_ref_is_knowable-norm-overflow.rs new file mode 100644 index 0000000000000..4c98052b12590 --- /dev/null +++ b/tests/ui/traits/new-solver/coherence/trait_ref_is_knowable-norm-overflow.rs @@ -0,0 +1,23 @@ +// compile-flags: -Ztrait-solver=next + +// Coherence should handle overflow while normalizing for +// `trait_ref_is_knowable` correctly. + +// FIXME(-Ztrait-solver=next-coherence): This currently has unstable query results. +// Figure out how to deal with this. + +trait Overflow { + type Assoc; +} +impl Overflow for T { + type Assoc = ::Assoc; +} + + +trait Trait {} +impl Trait for T {} +struct LocalTy; +impl Trait for ::Assoc {} +//~^ ERROR conflicting implementations of trait `Trait` for type `::Assoc` + +fn main() {} diff --git a/tests/ui/traits/new-solver/coherence/trait_ref_is_knowable-norm-overflow.stderr b/tests/ui/traits/new-solver/coherence/trait_ref_is_knowable-norm-overflow.stderr new file mode 100644 index 0000000000000..453f06079aa3b --- /dev/null +++ b/tests/ui/traits/new-solver/coherence/trait_ref_is_knowable-norm-overflow.stderr @@ -0,0 +1,152 @@ +WARN rustc_trait_selection::solve::eval_ctxt unstable result: unstable certainty +original goal: Canonical { value: QueryInput { goal: Goal { predicate: Binder { value: ProjectionPredicate(AliasTy { args: [LocalTy], def_id: DefId(0:4 ~ trait_ref_is_knowable_norm_overflow[81b2]::Overflow::Assoc) }, Term::Ty(^1_0)), bound_vars: [] }, param_env: ParamEnv { caller_bounds: [], reveal: UserFacing } }, anchor: Bubble, predefined_opaques_in_body: PredefinedOpaques(PredefinedOpaquesData { opaque_types: [] }) }, max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }] }, +original result: Canonical { value: Response { certainty: Yes, var_values: CanonicalVarValues { var_values: [::Assoc] }, external_constraints: ExternalConstraints(ExternalConstraintsData { region_constraints: QueryRegionConstraints { outlives: [], member_constraints: [] }, opaque_types: [] }) }, max_universe: U0, variables: [] } +re-canonicalized goal: Canonical { value: QueryInput { goal: Goal { predicate: Binder { value: ProjectionPredicate(AliasTy { args: [LocalTy], def_id: DefId(0:4 ~ trait_ref_is_knowable_norm_overflow[81b2]::Overflow::Assoc) }, Term::Ty(::Assoc)), bound_vars: [] }, param_env: ParamEnv { caller_bounds: [], reveal: UserFacing } }, anchor: Bubble, predefined_opaques_in_body: PredefinedOpaques(PredefinedOpaquesData { opaque_types: [] }) }, max_universe: U0, variables: [] } +second response: Ok(Canonical { value: Response { certainty: Maybe(Overflow), var_values: CanonicalVarValues { var_values: [] }, external_constraints: ExternalConstraints(ExternalConstraintsData { region_constraints: QueryRegionConstraints { outlives: [], member_constraints: [] }, opaque_types: [] }) }, max_universe: U0, variables: [] }) +WARN rustc_trait_selection::solve::eval_ctxt unstable result: unstable certainty +original goal: Canonical { value: QueryInput { goal: Goal { predicate: Binder { value: ProjectionPredicate(AliasTy { args: [LocalTy], def_id: DefId(0:4 ~ trait_ref_is_knowable_norm_overflow[81b2]::Overflow::Assoc) }, Term::Ty(^1_0)), bound_vars: [] }, param_env: ParamEnv { caller_bounds: [], reveal: UserFacing } }, anchor: Bubble, predefined_opaques_in_body: PredefinedOpaques(PredefinedOpaquesData { opaque_types: [] }) }, max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }] }, +original result: Canonical { value: Response { certainty: Yes, var_values: CanonicalVarValues { var_values: [::Assoc] }, external_constraints: ExternalConstraints(ExternalConstraintsData { region_constraints: QueryRegionConstraints { outlives: [], member_constraints: [] }, opaque_types: [] }) }, max_universe: U0, variables: [] } +re-canonicalized goal: Canonical { value: QueryInput { goal: Goal { predicate: Binder { value: ProjectionPredicate(AliasTy { args: [LocalTy], def_id: DefId(0:4 ~ trait_ref_is_knowable_norm_overflow[81b2]::Overflow::Assoc) }, Term::Ty(::Assoc)), bound_vars: [] }, param_env: ParamEnv { caller_bounds: [], reveal: UserFacing } }, anchor: Bubble, predefined_opaques_in_body: PredefinedOpaques(PredefinedOpaquesData { opaque_types: [] }) }, max_universe: U0, variables: [] } +second response: Ok(Canonical { value: Response { certainty: Maybe(Overflow), var_values: CanonicalVarValues { var_values: [] }, external_constraints: ExternalConstraints(ExternalConstraintsData { region_constraints: QueryRegionConstraints { outlives: [], member_constraints: [] }, opaque_types: [] }) }, max_universe: U0, variables: [] }) +WARN rustc_trait_selection::solve::eval_ctxt unstable result: unstable certainty +original goal: Canonical { value: QueryInput { goal: Goal { predicate: Binder { value: ProjectionPredicate(AliasTy { args: [LocalTy], def_id: DefId(0:4 ~ trait_ref_is_knowable_norm_overflow[81b2]::Overflow::Assoc) }, Term::Ty(^1_0)), bound_vars: [] }, param_env: ParamEnv { caller_bounds: [], reveal: UserFacing } }, anchor: Bubble, predefined_opaques_in_body: PredefinedOpaques(PredefinedOpaquesData { opaque_types: [] }) }, max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }] }, +original result: Canonical { value: Response { certainty: Yes, var_values: CanonicalVarValues { var_values: [::Assoc] }, external_constraints: ExternalConstraints(ExternalConstraintsData { region_constraints: QueryRegionConstraints { outlives: [], member_constraints: [] }, opaque_types: [] }) }, max_universe: U0, variables: [] } +re-canonicalized goal: Canonical { value: QueryInput { goal: Goal { predicate: Binder { value: ProjectionPredicate(AliasTy { args: [LocalTy], def_id: DefId(0:4 ~ trait_ref_is_knowable_norm_overflow[81b2]::Overflow::Assoc) }, Term::Ty(::Assoc)), bound_vars: [] }, param_env: ParamEnv { caller_bounds: [], reveal: UserFacing } }, anchor: Bubble, predefined_opaques_in_body: PredefinedOpaques(PredefinedOpaquesData { opaque_types: [] }) }, max_universe: U0, variables: [] } +second response: Ok(Canonical { value: Response { certainty: Maybe(Overflow), var_values: CanonicalVarValues { var_values: [] }, external_constraints: ExternalConstraints(ExternalConstraintsData { region_constraints: QueryRegionConstraints { outlives: [], member_constraints: [] }, opaque_types: [] }) }, max_universe: U0, variables: [] }) +WARN rustc_trait_selection::solve::eval_ctxt unstable result: unstable certainty +original goal: Canonical { value: QueryInput { goal: Goal { predicate: Binder { value: ProjectionPredicate(AliasTy { args: [LocalTy], def_id: DefId(0:4 ~ trait_ref_is_knowable_norm_overflow[81b2]::Overflow::Assoc) }, Term::Ty(^1_0)), bound_vars: [] }, param_env: ParamEnv { caller_bounds: [], reveal: UserFacing } }, anchor: Bubble, predefined_opaques_in_body: PredefinedOpaques(PredefinedOpaquesData { opaque_types: [] }) }, max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }] }, +original result: Canonical { value: Response { certainty: Yes, var_values: CanonicalVarValues { var_values: [::Assoc] }, external_constraints: ExternalConstraints(ExternalConstraintsData { region_constraints: QueryRegionConstraints { outlives: [], member_constraints: [] }, opaque_types: [] }) }, max_universe: U0, variables: [] } +re-canonicalized goal: Canonical { value: QueryInput { goal: Goal { predicate: Binder { value: ProjectionPredicate(AliasTy { args: [LocalTy], def_id: DefId(0:4 ~ trait_ref_is_knowable_norm_overflow[81b2]::Overflow::Assoc) }, Term::Ty(::Assoc)), bound_vars: [] }, param_env: ParamEnv { caller_bounds: [], reveal: UserFacing } }, anchor: Bubble, predefined_opaques_in_body: PredefinedOpaques(PredefinedOpaquesData { opaque_types: [] }) }, max_universe: U0, variables: [] } +second response: Ok(Canonical { value: Response { certainty: Maybe(Overflow), var_values: CanonicalVarValues { var_values: [] }, external_constraints: ExternalConstraints(ExternalConstraintsData { region_constraints: QueryRegionConstraints { outlives: [], member_constraints: [] }, opaque_types: [] }) }, max_universe: U0, variables: [] }) +WARN rustc_trait_selection::solve::eval_ctxt unstable result: unstable certainty +original goal: Canonical { value: QueryInput { goal: Goal { predicate: Binder { value: ProjectionPredicate(AliasTy { args: [LocalTy], def_id: DefId(0:4 ~ trait_ref_is_knowable_norm_overflow[81b2]::Overflow::Assoc) }, Term::Ty(^1_0)), bound_vars: [] }, param_env: ParamEnv { caller_bounds: [], reveal: UserFacing } }, anchor: Bubble, predefined_opaques_in_body: PredefinedOpaques(PredefinedOpaquesData { opaque_types: [] }) }, max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }] }, +original result: Canonical { value: Response { certainty: Yes, var_values: CanonicalVarValues { var_values: [::Assoc] }, external_constraints: ExternalConstraints(ExternalConstraintsData { region_constraints: QueryRegionConstraints { outlives: [], member_constraints: [] }, opaque_types: [] }) }, max_universe: U0, variables: [] } +re-canonicalized goal: Canonical { value: QueryInput { goal: Goal { predicate: Binder { value: ProjectionPredicate(AliasTy { args: [LocalTy], def_id: DefId(0:4 ~ trait_ref_is_knowable_norm_overflow[81b2]::Overflow::Assoc) }, Term::Ty(::Assoc)), bound_vars: [] }, param_env: ParamEnv { caller_bounds: [], reveal: UserFacing } }, anchor: Bubble, predefined_opaques_in_body: PredefinedOpaques(PredefinedOpaquesData { opaque_types: [] }) }, max_universe: U0, variables: [] } +second response: Ok(Canonical { value: Response { certainty: Maybe(Overflow), var_values: CanonicalVarValues { var_values: [] }, external_constraints: ExternalConstraints(ExternalConstraintsData { region_constraints: QueryRegionConstraints { outlives: [], member_constraints: [] }, opaque_types: [] }) }, max_universe: U0, variables: [] }) +WARN rustc_trait_selection::solve::eval_ctxt unstable result: unstable certainty +original goal: Canonical { value: QueryInput { goal: Goal { predicate: Binder { value: ProjectionPredicate(AliasTy { args: [LocalTy], def_id: DefId(0:4 ~ trait_ref_is_knowable_norm_overflow[81b2]::Overflow::Assoc) }, Term::Ty(^1_0)), bound_vars: [] }, param_env: ParamEnv { caller_bounds: [], reveal: UserFacing } }, anchor: Bubble, predefined_opaques_in_body: PredefinedOpaques(PredefinedOpaquesData { opaque_types: [] }) }, max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }] }, +original result: Canonical { value: Response { certainty: Yes, var_values: CanonicalVarValues { var_values: [::Assoc] }, external_constraints: ExternalConstraints(ExternalConstraintsData { region_constraints: QueryRegionConstraints { outlives: [], member_constraints: [] }, opaque_types: [] }) }, max_universe: U0, variables: [] } +re-canonicalized goal: Canonical { value: QueryInput { goal: Goal { predicate: Binder { value: ProjectionPredicate(AliasTy { args: [LocalTy], def_id: DefId(0:4 ~ trait_ref_is_knowable_norm_overflow[81b2]::Overflow::Assoc) }, Term::Ty(::Assoc)), bound_vars: [] }, param_env: ParamEnv { caller_bounds: [], reveal: UserFacing } }, anchor: Bubble, predefined_opaques_in_body: PredefinedOpaques(PredefinedOpaquesData { opaque_types: [] }) }, max_universe: U0, variables: [] } +second response: Ok(Canonical { value: Response { certainty: Maybe(Overflow), var_values: CanonicalVarValues { var_values: [] }, external_constraints: ExternalConstraints(ExternalConstraintsData { region_constraints: QueryRegionConstraints { outlives: [], member_constraints: [] }, opaque_types: [] }) }, max_universe: U0, variables: [] }) +WARN rustc_trait_selection::solve::eval_ctxt unstable result: unstable certainty +original goal: Canonical { value: QueryInput { goal: Goal { predicate: Binder { value: ProjectionPredicate(AliasTy { args: [LocalTy], def_id: DefId(0:4 ~ trait_ref_is_knowable_norm_overflow[81b2]::Overflow::Assoc) }, Term::Ty(^1_0)), bound_vars: [] }, param_env: ParamEnv { caller_bounds: [], reveal: UserFacing } }, anchor: Bubble, predefined_opaques_in_body: PredefinedOpaques(PredefinedOpaquesData { opaque_types: [] }) }, max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }] }, +original result: Canonical { value: Response { certainty: Yes, var_values: CanonicalVarValues { var_values: [::Assoc] }, external_constraints: ExternalConstraints(ExternalConstraintsData { region_constraints: QueryRegionConstraints { outlives: [], member_constraints: [] }, opaque_types: [] }) }, max_universe: U0, variables: [] } +re-canonicalized goal: Canonical { value: QueryInput { goal: Goal { predicate: Binder { value: ProjectionPredicate(AliasTy { args: [LocalTy], def_id: DefId(0:4 ~ trait_ref_is_knowable_norm_overflow[81b2]::Overflow::Assoc) }, Term::Ty(::Assoc)), bound_vars: [] }, param_env: ParamEnv { caller_bounds: [], reveal: UserFacing } }, anchor: Bubble, predefined_opaques_in_body: PredefinedOpaques(PredefinedOpaquesData { opaque_types: [] }) }, max_universe: U0, variables: [] } +second response: Ok(Canonical { value: Response { certainty: Maybe(Overflow), var_values: CanonicalVarValues { var_values: [] }, external_constraints: ExternalConstraints(ExternalConstraintsData { region_constraints: QueryRegionConstraints { outlives: [], member_constraints: [] }, opaque_types: [] }) }, max_universe: U0, variables: [] }) +WARN rustc_trait_selection::solve::eval_ctxt unstable result: unstable certainty +original goal: Canonical { value: QueryInput { goal: Goal { predicate: Binder { value: ProjectionPredicate(AliasTy { args: [LocalTy], def_id: DefId(0:4 ~ trait_ref_is_knowable_norm_overflow[81b2]::Overflow::Assoc) }, Term::Ty(^1_0)), bound_vars: [] }, param_env: ParamEnv { caller_bounds: [], reveal: UserFacing } }, anchor: Bubble, predefined_opaques_in_body: PredefinedOpaques(PredefinedOpaquesData { opaque_types: [] }) }, max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }] }, +original result: Canonical { value: Response { certainty: Yes, var_values: CanonicalVarValues { var_values: [::Assoc] }, external_constraints: ExternalConstraints(ExternalConstraintsData { region_constraints: QueryRegionConstraints { outlives: [], member_constraints: [] }, opaque_types: [] }) }, max_universe: U0, variables: [] } +re-canonicalized goal: Canonical { value: QueryInput { goal: Goal { predicate: Binder { value: ProjectionPredicate(AliasTy { args: [LocalTy], def_id: DefId(0:4 ~ trait_ref_is_knowable_norm_overflow[81b2]::Overflow::Assoc) }, Term::Ty(::Assoc)), bound_vars: [] }, param_env: ParamEnv { caller_bounds: [], reveal: UserFacing } }, anchor: Bubble, predefined_opaques_in_body: PredefinedOpaques(PredefinedOpaquesData { opaque_types: [] }) }, max_universe: U0, variables: [] } +second response: Ok(Canonical { value: Response { certainty: Maybe(Overflow), var_values: CanonicalVarValues { var_values: [] }, external_constraints: ExternalConstraints(ExternalConstraintsData { region_constraints: QueryRegionConstraints { outlives: [], member_constraints: [] }, opaque_types: [] }) }, max_universe: U0, variables: [] }) +WARN rustc_trait_selection::solve::eval_ctxt unstable result: unstable certainty +original goal: Canonical { value: QueryInput { goal: Goal { predicate: Binder { value: ProjectionPredicate(AliasTy { args: [LocalTy], def_id: DefId(0:4 ~ trait_ref_is_knowable_norm_overflow[81b2]::Overflow::Assoc) }, Term::Ty(^1_0)), bound_vars: [] }, param_env: ParamEnv { caller_bounds: [], reveal: UserFacing } }, anchor: Bubble, predefined_opaques_in_body: PredefinedOpaques(PredefinedOpaquesData { opaque_types: [] }) }, max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }] }, +original result: Canonical { value: Response { certainty: Yes, var_values: CanonicalVarValues { var_values: [::Assoc] }, external_constraints: ExternalConstraints(ExternalConstraintsData { region_constraints: QueryRegionConstraints { outlives: [], member_constraints: [] }, opaque_types: [] }) }, max_universe: U0, variables: [] } +re-canonicalized goal: Canonical { value: QueryInput { goal: Goal { predicate: Binder { value: ProjectionPredicate(AliasTy { args: [LocalTy], def_id: DefId(0:4 ~ trait_ref_is_knowable_norm_overflow[81b2]::Overflow::Assoc) }, Term::Ty(::Assoc)), bound_vars: [] }, param_env: ParamEnv { caller_bounds: [], reveal: UserFacing } }, anchor: Bubble, predefined_opaques_in_body: PredefinedOpaques(PredefinedOpaquesData { opaque_types: [] }) }, max_universe: U0, variables: [] } +second response: Ok(Canonical { value: Response { certainty: Maybe(Overflow), var_values: CanonicalVarValues { var_values: [] }, external_constraints: ExternalConstraints(ExternalConstraintsData { region_constraints: QueryRegionConstraints { outlives: [], member_constraints: [] }, opaque_types: [] }) }, max_universe: U0, variables: [] }) +WARN rustc_trait_selection::solve::eval_ctxt unstable result: unstable certainty +original goal: Canonical { value: QueryInput { goal: Goal { predicate: Binder { value: ProjectionPredicate(AliasTy { args: [LocalTy], def_id: DefId(0:4 ~ trait_ref_is_knowable_norm_overflow[81b2]::Overflow::Assoc) }, Term::Ty(^1_0)), bound_vars: [] }, param_env: ParamEnv { caller_bounds: [], reveal: UserFacing } }, anchor: Bubble, predefined_opaques_in_body: PredefinedOpaques(PredefinedOpaquesData { opaque_types: [] }) }, max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }] }, +original result: Canonical { value: Response { certainty: Yes, var_values: CanonicalVarValues { var_values: [::Assoc] }, external_constraints: ExternalConstraints(ExternalConstraintsData { region_constraints: QueryRegionConstraints { outlives: [], member_constraints: [] }, opaque_types: [] }) }, max_universe: U0, variables: [] } +re-canonicalized goal: Canonical { value: QueryInput { goal: Goal { predicate: Binder { value: ProjectionPredicate(AliasTy { args: [LocalTy], def_id: DefId(0:4 ~ trait_ref_is_knowable_norm_overflow[81b2]::Overflow::Assoc) }, Term::Ty(::Assoc)), bound_vars: [] }, param_env: ParamEnv { caller_bounds: [], reveal: UserFacing } }, anchor: Bubble, predefined_opaques_in_body: PredefinedOpaques(PredefinedOpaquesData { opaque_types: [] }) }, max_universe: U0, variables: [] } +second response: Ok(Canonical { value: Response { certainty: Maybe(Overflow), var_values: CanonicalVarValues { var_values: [] }, external_constraints: ExternalConstraints(ExternalConstraintsData { region_constraints: QueryRegionConstraints { outlives: [], member_constraints: [] }, opaque_types: [] }) }, max_universe: U0, variables: [] }) +WARN rustc_trait_selection::solve::eval_ctxt unstable result: unstable certainty +original goal: Canonical { value: QueryInput { goal: Goal { predicate: Binder { value: ProjectionPredicate(AliasTy { args: [LocalTy], def_id: DefId(0:4 ~ trait_ref_is_knowable_norm_overflow[81b2]::Overflow::Assoc) }, Term::Ty(^1_0)), bound_vars: [] }, param_env: ParamEnv { caller_bounds: [], reveal: UserFacing } }, anchor: Bubble, predefined_opaques_in_body: PredefinedOpaques(PredefinedOpaquesData { opaque_types: [] }) }, max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }] }, +original result: Canonical { value: Response { certainty: Yes, var_values: CanonicalVarValues { var_values: [::Assoc] }, external_constraints: ExternalConstraints(ExternalConstraintsData { region_constraints: QueryRegionConstraints { outlives: [], member_constraints: [] }, opaque_types: [] }) }, max_universe: U0, variables: [] } +re-canonicalized goal: Canonical { value: QueryInput { goal: Goal { predicate: Binder { value: ProjectionPredicate(AliasTy { args: [LocalTy], def_id: DefId(0:4 ~ trait_ref_is_knowable_norm_overflow[81b2]::Overflow::Assoc) }, Term::Ty(::Assoc)), bound_vars: [] }, param_env: ParamEnv { caller_bounds: [], reveal: UserFacing } }, anchor: Bubble, predefined_opaques_in_body: PredefinedOpaques(PredefinedOpaquesData { opaque_types: [] }) }, max_universe: U0, variables: [] } +second response: Ok(Canonical { value: Response { certainty: Maybe(Overflow), var_values: CanonicalVarValues { var_values: [] }, external_constraints: ExternalConstraints(ExternalConstraintsData { region_constraints: QueryRegionConstraints { outlives: [], member_constraints: [] }, opaque_types: [] }) }, max_universe: U0, variables: [] }) +WARN rustc_trait_selection::solve::eval_ctxt unstable result: unstable certainty +original goal: Canonical { value: QueryInput { goal: Goal { predicate: Binder { value: ProjectionPredicate(AliasTy { args: [LocalTy], def_id: DefId(0:4 ~ trait_ref_is_knowable_norm_overflow[81b2]::Overflow::Assoc) }, Term::Ty(^1_0)), bound_vars: [] }, param_env: ParamEnv { caller_bounds: [], reveal: UserFacing } }, anchor: Bubble, predefined_opaques_in_body: PredefinedOpaques(PredefinedOpaquesData { opaque_types: [] }) }, max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }] }, +original result: Canonical { value: Response { certainty: Yes, var_values: CanonicalVarValues { var_values: [::Assoc] }, external_constraints: ExternalConstraints(ExternalConstraintsData { region_constraints: QueryRegionConstraints { outlives: [], member_constraints: [] }, opaque_types: [] }) }, max_universe: U0, variables: [] } +re-canonicalized goal: Canonical { value: QueryInput { goal: Goal { predicate: Binder { value: ProjectionPredicate(AliasTy { args: [LocalTy], def_id: DefId(0:4 ~ trait_ref_is_knowable_norm_overflow[81b2]::Overflow::Assoc) }, Term::Ty(::Assoc)), bound_vars: [] }, param_env: ParamEnv { caller_bounds: [], reveal: UserFacing } }, anchor: Bubble, predefined_opaques_in_body: PredefinedOpaques(PredefinedOpaquesData { opaque_types: [] }) }, max_universe: U0, variables: [] } +second response: Ok(Canonical { value: Response { certainty: Maybe(Overflow), var_values: CanonicalVarValues { var_values: [] }, external_constraints: ExternalConstraints(ExternalConstraintsData { region_constraints: QueryRegionConstraints { outlives: [], member_constraints: [] }, opaque_types: [] }) }, max_universe: U0, variables: [] }) +WARN rustc_trait_selection::solve::eval_ctxt unstable result: unstable certainty +original goal: Canonical { value: QueryInput { goal: Goal { predicate: Binder { value: ProjectionPredicate(AliasTy { args: [LocalTy], def_id: DefId(0:4 ~ trait_ref_is_knowable_norm_overflow[81b2]::Overflow::Assoc) }, Term::Ty(^1_0)), bound_vars: [] }, param_env: ParamEnv { caller_bounds: [], reveal: UserFacing } }, anchor: Bubble, predefined_opaques_in_body: PredefinedOpaques(PredefinedOpaquesData { opaque_types: [] }) }, max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }] }, +original result: Canonical { value: Response { certainty: Yes, var_values: CanonicalVarValues { var_values: [::Assoc] }, external_constraints: ExternalConstraints(ExternalConstraintsData { region_constraints: QueryRegionConstraints { outlives: [], member_constraints: [] }, opaque_types: [] }) }, max_universe: U0, variables: [] } +re-canonicalized goal: Canonical { value: QueryInput { goal: Goal { predicate: Binder { value: ProjectionPredicate(AliasTy { args: [LocalTy], def_id: DefId(0:4 ~ trait_ref_is_knowable_norm_overflow[81b2]::Overflow::Assoc) }, Term::Ty(::Assoc)), bound_vars: [] }, param_env: ParamEnv { caller_bounds: [], reveal: UserFacing } }, anchor: Bubble, predefined_opaques_in_body: PredefinedOpaques(PredefinedOpaquesData { opaque_types: [] }) }, max_universe: U0, variables: [] } +second response: Ok(Canonical { value: Response { certainty: Maybe(Overflow), var_values: CanonicalVarValues { var_values: [] }, external_constraints: ExternalConstraints(ExternalConstraintsData { region_constraints: QueryRegionConstraints { outlives: [], member_constraints: [] }, opaque_types: [] }) }, max_universe: U0, variables: [] }) +WARN rustc_trait_selection::solve::eval_ctxt unstable result: unstable certainty +original goal: Canonical { value: QueryInput { goal: Goal { predicate: Binder { value: ProjectionPredicate(AliasTy { args: [LocalTy], def_id: DefId(0:4 ~ trait_ref_is_knowable_norm_overflow[81b2]::Overflow::Assoc) }, Term::Ty(^1_0)), bound_vars: [] }, param_env: ParamEnv { caller_bounds: [], reveal: UserFacing } }, anchor: Bubble, predefined_opaques_in_body: PredefinedOpaques(PredefinedOpaquesData { opaque_types: [] }) }, max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }] }, +original result: Canonical { value: Response { certainty: Yes, var_values: CanonicalVarValues { var_values: [::Assoc] }, external_constraints: ExternalConstraints(ExternalConstraintsData { region_constraints: QueryRegionConstraints { outlives: [], member_constraints: [] }, opaque_types: [] }) }, max_universe: U0, variables: [] } +re-canonicalized goal: Canonical { value: QueryInput { goal: Goal { predicate: Binder { value: ProjectionPredicate(AliasTy { args: [LocalTy], def_id: DefId(0:4 ~ trait_ref_is_knowable_norm_overflow[81b2]::Overflow::Assoc) }, Term::Ty(::Assoc)), bound_vars: [] }, param_env: ParamEnv { caller_bounds: [], reveal: UserFacing } }, anchor: Bubble, predefined_opaques_in_body: PredefinedOpaques(PredefinedOpaquesData { opaque_types: [] }) }, max_universe: U0, variables: [] } +second response: Ok(Canonical { value: Response { certainty: Maybe(Overflow), var_values: CanonicalVarValues { var_values: [] }, external_constraints: ExternalConstraints(ExternalConstraintsData { region_constraints: QueryRegionConstraints { outlives: [], member_constraints: [] }, opaque_types: [] }) }, max_universe: U0, variables: [] }) +WARN rustc_trait_selection::solve::eval_ctxt unstable result: unstable certainty +original goal: Canonical { value: QueryInput { goal: Goal { predicate: Binder { value: ProjectionPredicate(AliasTy { args: [LocalTy], def_id: DefId(0:4 ~ trait_ref_is_knowable_norm_overflow[81b2]::Overflow::Assoc) }, Term::Ty(^1_0)), bound_vars: [] }, param_env: ParamEnv { caller_bounds: [], reveal: UserFacing } }, anchor: Bubble, predefined_opaques_in_body: PredefinedOpaques(PredefinedOpaquesData { opaque_types: [] }) }, max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }] }, +original result: Canonical { value: Response { certainty: Yes, var_values: CanonicalVarValues { var_values: [::Assoc] }, external_constraints: ExternalConstraints(ExternalConstraintsData { region_constraints: QueryRegionConstraints { outlives: [], member_constraints: [] }, opaque_types: [] }) }, max_universe: U0, variables: [] } +re-canonicalized goal: Canonical { value: QueryInput { goal: Goal { predicate: Binder { value: ProjectionPredicate(AliasTy { args: [LocalTy], def_id: DefId(0:4 ~ trait_ref_is_knowable_norm_overflow[81b2]::Overflow::Assoc) }, Term::Ty(::Assoc)), bound_vars: [] }, param_env: ParamEnv { caller_bounds: [], reveal: UserFacing } }, anchor: Bubble, predefined_opaques_in_body: PredefinedOpaques(PredefinedOpaquesData { opaque_types: [] }) }, max_universe: U0, variables: [] } +second response: Ok(Canonical { value: Response { certainty: Maybe(Overflow), var_values: CanonicalVarValues { var_values: [] }, external_constraints: ExternalConstraints(ExternalConstraintsData { region_constraints: QueryRegionConstraints { outlives: [], member_constraints: [] }, opaque_types: [] }) }, max_universe: U0, variables: [] }) +WARN rustc_trait_selection::solve::eval_ctxt unstable result: unstable certainty +original goal: Canonical { value: QueryInput { goal: Goal { predicate: Binder { value: ProjectionPredicate(AliasTy { args: [LocalTy], def_id: DefId(0:4 ~ trait_ref_is_knowable_norm_overflow[81b2]::Overflow::Assoc) }, Term::Ty(^1_0)), bound_vars: [] }, param_env: ParamEnv { caller_bounds: [], reveal: UserFacing } }, anchor: Bubble, predefined_opaques_in_body: PredefinedOpaques(PredefinedOpaquesData { opaque_types: [] }) }, max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }] }, +original result: Canonical { value: Response { certainty: Yes, var_values: CanonicalVarValues { var_values: [::Assoc] }, external_constraints: ExternalConstraints(ExternalConstraintsData { region_constraints: QueryRegionConstraints { outlives: [], member_constraints: [] }, opaque_types: [] }) }, max_universe: U0, variables: [] } +re-canonicalized goal: Canonical { value: QueryInput { goal: Goal { predicate: Binder { value: ProjectionPredicate(AliasTy { args: [LocalTy], def_id: DefId(0:4 ~ trait_ref_is_knowable_norm_overflow[81b2]::Overflow::Assoc) }, Term::Ty(::Assoc)), bound_vars: [] }, param_env: ParamEnv { caller_bounds: [], reveal: UserFacing } }, anchor: Bubble, predefined_opaques_in_body: PredefinedOpaques(PredefinedOpaquesData { opaque_types: [] }) }, max_universe: U0, variables: [] } +second response: Ok(Canonical { value: Response { certainty: Maybe(Overflow), var_values: CanonicalVarValues { var_values: [] }, external_constraints: ExternalConstraints(ExternalConstraintsData { region_constraints: QueryRegionConstraints { outlives: [], member_constraints: [] }, opaque_types: [] }) }, max_universe: U0, variables: [] }) +WARN rustc_trait_selection::solve::eval_ctxt unstable result: unstable certainty +original goal: Canonical { value: QueryInput { goal: Goal { predicate: Binder { value: ProjectionPredicate(AliasTy { args: [LocalTy], def_id: DefId(0:4 ~ trait_ref_is_knowable_norm_overflow[81b2]::Overflow::Assoc) }, Term::Ty(^1_0)), bound_vars: [] }, param_env: ParamEnv { caller_bounds: [], reveal: UserFacing } }, anchor: Bubble, predefined_opaques_in_body: PredefinedOpaques(PredefinedOpaquesData { opaque_types: [] }) }, max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }] }, +original result: Canonical { value: Response { certainty: Yes, var_values: CanonicalVarValues { var_values: [::Assoc] }, external_constraints: ExternalConstraints(ExternalConstraintsData { region_constraints: QueryRegionConstraints { outlives: [], member_constraints: [] }, opaque_types: [] }) }, max_universe: U0, variables: [] } +re-canonicalized goal: Canonical { value: QueryInput { goal: Goal { predicate: Binder { value: ProjectionPredicate(AliasTy { args: [LocalTy], def_id: DefId(0:4 ~ trait_ref_is_knowable_norm_overflow[81b2]::Overflow::Assoc) }, Term::Ty(::Assoc)), bound_vars: [] }, param_env: ParamEnv { caller_bounds: [], reveal: UserFacing } }, anchor: Bubble, predefined_opaques_in_body: PredefinedOpaques(PredefinedOpaquesData { opaque_types: [] }) }, max_universe: U0, variables: [] } +second response: Ok(Canonical { value: Response { certainty: Maybe(Overflow), var_values: CanonicalVarValues { var_values: [] }, external_constraints: ExternalConstraints(ExternalConstraintsData { region_constraints: QueryRegionConstraints { outlives: [], member_constraints: [] }, opaque_types: [] }) }, max_universe: U0, variables: [] }) +WARN rustc_trait_selection::solve::eval_ctxt unstable result: unstable certainty +original goal: Canonical { value: QueryInput { goal: Goal { predicate: Binder { value: ProjectionPredicate(AliasTy { args: [LocalTy], def_id: DefId(0:4 ~ trait_ref_is_knowable_norm_overflow[81b2]::Overflow::Assoc) }, Term::Ty(^1_0)), bound_vars: [] }, param_env: ParamEnv { caller_bounds: [], reveal: UserFacing } }, anchor: Bubble, predefined_opaques_in_body: PredefinedOpaques(PredefinedOpaquesData { opaque_types: [] }) }, max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }] }, +original result: Canonical { value: Response { certainty: Yes, var_values: CanonicalVarValues { var_values: [::Assoc] }, external_constraints: ExternalConstraints(ExternalConstraintsData { region_constraints: QueryRegionConstraints { outlives: [], member_constraints: [] }, opaque_types: [] }) }, max_universe: U0, variables: [] } +re-canonicalized goal: Canonical { value: QueryInput { goal: Goal { predicate: Binder { value: ProjectionPredicate(AliasTy { args: [LocalTy], def_id: DefId(0:4 ~ trait_ref_is_knowable_norm_overflow[81b2]::Overflow::Assoc) }, Term::Ty(::Assoc)), bound_vars: [] }, param_env: ParamEnv { caller_bounds: [], reveal: UserFacing } }, anchor: Bubble, predefined_opaques_in_body: PredefinedOpaques(PredefinedOpaquesData { opaque_types: [] }) }, max_universe: U0, variables: [] } +second response: Ok(Canonical { value: Response { certainty: Maybe(Overflow), var_values: CanonicalVarValues { var_values: [] }, external_constraints: ExternalConstraints(ExternalConstraintsData { region_constraints: QueryRegionConstraints { outlives: [], member_constraints: [] }, opaque_types: [] }) }, max_universe: U0, variables: [] }) +WARN rustc_trait_selection::solve::eval_ctxt unstable result: unstable certainty +original goal: Canonical { value: QueryInput { goal: Goal { predicate: Binder { value: ProjectionPredicate(AliasTy { args: [LocalTy], def_id: DefId(0:4 ~ trait_ref_is_knowable_norm_overflow[81b2]::Overflow::Assoc) }, Term::Ty(^1_0)), bound_vars: [] }, param_env: ParamEnv { caller_bounds: [], reveal: UserFacing } }, anchor: Bubble, predefined_opaques_in_body: PredefinedOpaques(PredefinedOpaquesData { opaque_types: [] }) }, max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }] }, +original result: Canonical { value: Response { certainty: Yes, var_values: CanonicalVarValues { var_values: [::Assoc] }, external_constraints: ExternalConstraints(ExternalConstraintsData { region_constraints: QueryRegionConstraints { outlives: [], member_constraints: [] }, opaque_types: [] }) }, max_universe: U0, variables: [] } +re-canonicalized goal: Canonical { value: QueryInput { goal: Goal { predicate: Binder { value: ProjectionPredicate(AliasTy { args: [LocalTy], def_id: DefId(0:4 ~ trait_ref_is_knowable_norm_overflow[81b2]::Overflow::Assoc) }, Term::Ty(::Assoc)), bound_vars: [] }, param_env: ParamEnv { caller_bounds: [], reveal: UserFacing } }, anchor: Bubble, predefined_opaques_in_body: PredefinedOpaques(PredefinedOpaquesData { opaque_types: [] }) }, max_universe: U0, variables: [] } +second response: Ok(Canonical { value: Response { certainty: Maybe(Overflow), var_values: CanonicalVarValues { var_values: [] }, external_constraints: ExternalConstraints(ExternalConstraintsData { region_constraints: QueryRegionConstraints { outlives: [], member_constraints: [] }, opaque_types: [] }) }, max_universe: U0, variables: [] }) +WARN rustc_trait_selection::solve::eval_ctxt unstable result: unstable certainty +original goal: Canonical { value: QueryInput { goal: Goal { predicate: Binder { value: ProjectionPredicate(AliasTy { args: [LocalTy], def_id: DefId(0:4 ~ trait_ref_is_knowable_norm_overflow[81b2]::Overflow::Assoc) }, Term::Ty(^1_0)), bound_vars: [] }, param_env: ParamEnv { caller_bounds: [], reveal: UserFacing } }, anchor: Bubble, predefined_opaques_in_body: PredefinedOpaques(PredefinedOpaquesData { opaque_types: [] }) }, max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }] }, +original result: Canonical { value: Response { certainty: Yes, var_values: CanonicalVarValues { var_values: [::Assoc] }, external_constraints: ExternalConstraints(ExternalConstraintsData { region_constraints: QueryRegionConstraints { outlives: [], member_constraints: [] }, opaque_types: [] }) }, max_universe: U0, variables: [] } +re-canonicalized goal: Canonical { value: QueryInput { goal: Goal { predicate: Binder { value: ProjectionPredicate(AliasTy { args: [LocalTy], def_id: DefId(0:4 ~ trait_ref_is_knowable_norm_overflow[81b2]::Overflow::Assoc) }, Term::Ty(::Assoc)), bound_vars: [] }, param_env: ParamEnv { caller_bounds: [], reveal: UserFacing } }, anchor: Bubble, predefined_opaques_in_body: PredefinedOpaques(PredefinedOpaquesData { opaque_types: [] }) }, max_universe: U0, variables: [] } +second response: Ok(Canonical { value: Response { certainty: Maybe(Overflow), var_values: CanonicalVarValues { var_values: [] }, external_constraints: ExternalConstraints(ExternalConstraintsData { region_constraints: QueryRegionConstraints { outlives: [], member_constraints: [] }, opaque_types: [] }) }, max_universe: U0, variables: [] }) +WARN rustc_trait_selection::solve::eval_ctxt unstable result: unstable certainty +original goal: Canonical { value: QueryInput { goal: Goal { predicate: Binder { value: ProjectionPredicate(AliasTy { args: [LocalTy], def_id: DefId(0:4 ~ trait_ref_is_knowable_norm_overflow[81b2]::Overflow::Assoc) }, Term::Ty(^1_0)), bound_vars: [] }, param_env: ParamEnv { caller_bounds: [], reveal: UserFacing } }, anchor: Bubble, predefined_opaques_in_body: PredefinedOpaques(PredefinedOpaquesData { opaque_types: [] }) }, max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }] }, +original result: Canonical { value: Response { certainty: Yes, var_values: CanonicalVarValues { var_values: [::Assoc] }, external_constraints: ExternalConstraints(ExternalConstraintsData { region_constraints: QueryRegionConstraints { outlives: [], member_constraints: [] }, opaque_types: [] }) }, max_universe: U0, variables: [] } +re-canonicalized goal: Canonical { value: QueryInput { goal: Goal { predicate: Binder { value: ProjectionPredicate(AliasTy { args: [LocalTy], def_id: DefId(0:4 ~ trait_ref_is_knowable_norm_overflow[81b2]::Overflow::Assoc) }, Term::Ty(::Assoc)), bound_vars: [] }, param_env: ParamEnv { caller_bounds: [], reveal: UserFacing } }, anchor: Bubble, predefined_opaques_in_body: PredefinedOpaques(PredefinedOpaquesData { opaque_types: [] }) }, max_universe: U0, variables: [] } +second response: Ok(Canonical { value: Response { certainty: Maybe(Overflow), var_values: CanonicalVarValues { var_values: [] }, external_constraints: ExternalConstraints(ExternalConstraintsData { region_constraints: QueryRegionConstraints { outlives: [], member_constraints: [] }, opaque_types: [] }) }, max_universe: U0, variables: [] }) +WARN rustc_trait_selection::solve::eval_ctxt unstable result: unstable certainty +original goal: Canonical { value: QueryInput { goal: Goal { predicate: Binder { value: ProjectionPredicate(AliasTy { args: [LocalTy], def_id: DefId(0:4 ~ trait_ref_is_knowable_norm_overflow[81b2]::Overflow::Assoc) }, Term::Ty(^1_0)), bound_vars: [] }, param_env: ParamEnv { caller_bounds: [], reveal: UserFacing } }, anchor: Bubble, predefined_opaques_in_body: PredefinedOpaques(PredefinedOpaquesData { opaque_types: [] }) }, max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }] }, +original result: Canonical { value: Response { certainty: Yes, var_values: CanonicalVarValues { var_values: [::Assoc] }, external_constraints: ExternalConstraints(ExternalConstraintsData { region_constraints: QueryRegionConstraints { outlives: [], member_constraints: [] }, opaque_types: [] }) }, max_universe: U0, variables: [] } +re-canonicalized goal: Canonical { value: QueryInput { goal: Goal { predicate: Binder { value: ProjectionPredicate(AliasTy { args: [LocalTy], def_id: DefId(0:4 ~ trait_ref_is_knowable_norm_overflow[81b2]::Overflow::Assoc) }, Term::Ty(::Assoc)), bound_vars: [] }, param_env: ParamEnv { caller_bounds: [], reveal: UserFacing } }, anchor: Bubble, predefined_opaques_in_body: PredefinedOpaques(PredefinedOpaquesData { opaque_types: [] }) }, max_universe: U0, variables: [] } +second response: Ok(Canonical { value: Response { certainty: Maybe(Overflow), var_values: CanonicalVarValues { var_values: [] }, external_constraints: ExternalConstraints(ExternalConstraintsData { region_constraints: QueryRegionConstraints { outlives: [], member_constraints: [] }, opaque_types: [] }) }, max_universe: U0, variables: [] }) +WARN rustc_trait_selection::solve::eval_ctxt unstable result: unstable certainty +original goal: Canonical { value: QueryInput { goal: Goal { predicate: Binder { value: ProjectionPredicate(AliasTy { args: [LocalTy], def_id: DefId(0:4 ~ trait_ref_is_knowable_norm_overflow[81b2]::Overflow::Assoc) }, Term::Ty(^1_0)), bound_vars: [] }, param_env: ParamEnv { caller_bounds: [], reveal: UserFacing } }, anchor: Bubble, predefined_opaques_in_body: PredefinedOpaques(PredefinedOpaquesData { opaque_types: [] }) }, max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }] }, +original result: Canonical { value: Response { certainty: Yes, var_values: CanonicalVarValues { var_values: [::Assoc] }, external_constraints: ExternalConstraints(ExternalConstraintsData { region_constraints: QueryRegionConstraints { outlives: [], member_constraints: [] }, opaque_types: [] }) }, max_universe: U0, variables: [] } +re-canonicalized goal: Canonical { value: QueryInput { goal: Goal { predicate: Binder { value: ProjectionPredicate(AliasTy { args: [LocalTy], def_id: DefId(0:4 ~ trait_ref_is_knowable_norm_overflow[81b2]::Overflow::Assoc) }, Term::Ty(::Assoc)), bound_vars: [] }, param_env: ParamEnv { caller_bounds: [], reveal: UserFacing } }, anchor: Bubble, predefined_opaques_in_body: PredefinedOpaques(PredefinedOpaquesData { opaque_types: [] }) }, max_universe: U0, variables: [] } +second response: Ok(Canonical { value: Response { certainty: Maybe(Overflow), var_values: CanonicalVarValues { var_values: [] }, external_constraints: ExternalConstraints(ExternalConstraintsData { region_constraints: QueryRegionConstraints { outlives: [], member_constraints: [] }, opaque_types: [] }) }, max_universe: U0, variables: [] }) +WARN rustc_trait_selection::solve::eval_ctxt unstable result: unstable certainty +original goal: Canonical { value: QueryInput { goal: Goal { predicate: Binder { value: ProjectionPredicate(AliasTy { args: [LocalTy], def_id: DefId(0:4 ~ trait_ref_is_knowable_norm_overflow[81b2]::Overflow::Assoc) }, Term::Ty(^1_0)), bound_vars: [] }, param_env: ParamEnv { caller_bounds: [], reveal: UserFacing } }, anchor: Bubble, predefined_opaques_in_body: PredefinedOpaques(PredefinedOpaquesData { opaque_types: [] }) }, max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }] }, +original result: Canonical { value: Response { certainty: Yes, var_values: CanonicalVarValues { var_values: [::Assoc] }, external_constraints: ExternalConstraints(ExternalConstraintsData { region_constraints: QueryRegionConstraints { outlives: [], member_constraints: [] }, opaque_types: [] }) }, max_universe: U0, variables: [] } +re-canonicalized goal: Canonical { value: QueryInput { goal: Goal { predicate: Binder { value: ProjectionPredicate(AliasTy { args: [LocalTy], def_id: DefId(0:4 ~ trait_ref_is_knowable_norm_overflow[81b2]::Overflow::Assoc) }, Term::Ty(::Assoc)), bound_vars: [] }, param_env: ParamEnv { caller_bounds: [], reveal: UserFacing } }, anchor: Bubble, predefined_opaques_in_body: PredefinedOpaques(PredefinedOpaquesData { opaque_types: [] }) }, max_universe: U0, variables: [] } +second response: Ok(Canonical { value: Response { certainty: Maybe(Overflow), var_values: CanonicalVarValues { var_values: [] }, external_constraints: ExternalConstraints(ExternalConstraintsData { region_constraints: QueryRegionConstraints { outlives: [], member_constraints: [] }, opaque_types: [] }) }, max_universe: U0, variables: [] }) +WARN rustc_trait_selection::solve::eval_ctxt unstable result: unstable certainty +original goal: Canonical { value: QueryInput { goal: Goal { predicate: Binder { value: ProjectionPredicate(AliasTy { args: [LocalTy], def_id: DefId(0:4 ~ trait_ref_is_knowable_norm_overflow[81b2]::Overflow::Assoc) }, Term::Ty(^1_0)), bound_vars: [] }, param_env: ParamEnv { caller_bounds: [], reveal: UserFacing } }, anchor: Bubble, predefined_opaques_in_body: PredefinedOpaques(PredefinedOpaquesData { opaque_types: [] }) }, max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }] }, +original result: Canonical { value: Response { certainty: Yes, var_values: CanonicalVarValues { var_values: [::Assoc] }, external_constraints: ExternalConstraints(ExternalConstraintsData { region_constraints: QueryRegionConstraints { outlives: [], member_constraints: [] }, opaque_types: [] }) }, max_universe: U0, variables: [] } +re-canonicalized goal: Canonical { value: QueryInput { goal: Goal { predicate: Binder { value: ProjectionPredicate(AliasTy { args: [LocalTy], def_id: DefId(0:4 ~ trait_ref_is_knowable_norm_overflow[81b2]::Overflow::Assoc) }, Term::Ty(::Assoc)), bound_vars: [] }, param_env: ParamEnv { caller_bounds: [], reveal: UserFacing } }, anchor: Bubble, predefined_opaques_in_body: PredefinedOpaques(PredefinedOpaquesData { opaque_types: [] }) }, max_universe: U0, variables: [] } +second response: Ok(Canonical { value: Response { certainty: Maybe(Overflow), var_values: CanonicalVarValues { var_values: [] }, external_constraints: ExternalConstraints(ExternalConstraintsData { region_constraints: QueryRegionConstraints { outlives: [], member_constraints: [] }, opaque_types: [] }) }, max_universe: U0, variables: [] }) +WARN rustc_trait_selection::solve::eval_ctxt unstable result: unstable certainty +original goal: Canonical { value: QueryInput { goal: Goal { predicate: Binder { value: ProjectionPredicate(AliasTy { args: [LocalTy], def_id: DefId(0:4 ~ trait_ref_is_knowable_norm_overflow[81b2]::Overflow::Assoc) }, Term::Ty(^1_0)), bound_vars: [] }, param_env: ParamEnv { caller_bounds: [], reveal: UserFacing } }, anchor: Bubble, predefined_opaques_in_body: PredefinedOpaques(PredefinedOpaquesData { opaque_types: [] }) }, max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }] }, +original result: Canonical { value: Response { certainty: Yes, var_values: CanonicalVarValues { var_values: [::Assoc] }, external_constraints: ExternalConstraints(ExternalConstraintsData { region_constraints: QueryRegionConstraints { outlives: [], member_constraints: [] }, opaque_types: [] }) }, max_universe: U0, variables: [] } +re-canonicalized goal: Canonical { value: QueryInput { goal: Goal { predicate: Binder { value: ProjectionPredicate(AliasTy { args: [LocalTy], def_id: DefId(0:4 ~ trait_ref_is_knowable_norm_overflow[81b2]::Overflow::Assoc) }, Term::Ty(::Assoc)), bound_vars: [] }, param_env: ParamEnv { caller_bounds: [], reveal: UserFacing } }, anchor: Bubble, predefined_opaques_in_body: PredefinedOpaques(PredefinedOpaquesData { opaque_types: [] }) }, max_universe: U0, variables: [] } +second response: Ok(Canonical { value: Response { certainty: Maybe(Overflow), var_values: CanonicalVarValues { var_values: [] }, external_constraints: ExternalConstraints(ExternalConstraintsData { region_constraints: QueryRegionConstraints { outlives: [], member_constraints: [] }, opaque_types: [] }) }, max_universe: U0, variables: [] }) +WARN rustc_trait_selection::solve::eval_ctxt unstable result: unstable certainty +original goal: Canonical { value: QueryInput { goal: Goal { predicate: Binder { value: ProjectionPredicate(AliasTy { args: [LocalTy], def_id: DefId(0:4 ~ trait_ref_is_knowable_norm_overflow[81b2]::Overflow::Assoc) }, Term::Ty(^1_0)), bound_vars: [] }, param_env: ParamEnv { caller_bounds: [], reveal: UserFacing } }, anchor: Bubble, predefined_opaques_in_body: PredefinedOpaques(PredefinedOpaquesData { opaque_types: [] }) }, max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }] }, +original result: Canonical { value: Response { certainty: Yes, var_values: CanonicalVarValues { var_values: [::Assoc] }, external_constraints: ExternalConstraints(ExternalConstraintsData { region_constraints: QueryRegionConstraints { outlives: [], member_constraints: [] }, opaque_types: [] }) }, max_universe: U0, variables: [] } +re-canonicalized goal: Canonical { value: QueryInput { goal: Goal { predicate: Binder { value: ProjectionPredicate(AliasTy { args: [LocalTy], def_id: DefId(0:4 ~ trait_ref_is_knowable_norm_overflow[81b2]::Overflow::Assoc) }, Term::Ty(::Assoc)), bound_vars: [] }, param_env: ParamEnv { caller_bounds: [], reveal: UserFacing } }, anchor: Bubble, predefined_opaques_in_body: PredefinedOpaques(PredefinedOpaquesData { opaque_types: [] }) }, max_universe: U0, variables: [] } +second response: Ok(Canonical { value: Response { certainty: Maybe(Overflow), var_values: CanonicalVarValues { var_values: [] }, external_constraints: ExternalConstraints(ExternalConstraintsData { region_constraints: QueryRegionConstraints { outlives: [], member_constraints: [] }, opaque_types: [] }) }, max_universe: U0, variables: [] }) +WARN rustc_trait_selection::solve::eval_ctxt unstable result: unstable certainty +original goal: Canonical { value: QueryInput { goal: Goal { predicate: Binder { value: ProjectionPredicate(AliasTy { args: [LocalTy], def_id: DefId(0:4 ~ trait_ref_is_knowable_norm_overflow[81b2]::Overflow::Assoc) }, Term::Ty(^1_0)), bound_vars: [] }, param_env: ParamEnv { caller_bounds: [], reveal: UserFacing } }, anchor: Bubble, predefined_opaques_in_body: PredefinedOpaques(PredefinedOpaquesData { opaque_types: [] }) }, max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }] }, +original result: Canonical { value: Response { certainty: Yes, var_values: CanonicalVarValues { var_values: [::Assoc] }, external_constraints: ExternalConstraints(ExternalConstraintsData { region_constraints: QueryRegionConstraints { outlives: [], member_constraints: [] }, opaque_types: [] }) }, max_universe: U0, variables: [] } +re-canonicalized goal: Canonical { value: QueryInput { goal: Goal { predicate: Binder { value: ProjectionPredicate(AliasTy { args: [LocalTy], def_id: DefId(0:4 ~ trait_ref_is_knowable_norm_overflow[81b2]::Overflow::Assoc) }, Term::Ty(::Assoc)), bound_vars: [] }, param_env: ParamEnv { caller_bounds: [], reveal: UserFacing } }, anchor: Bubble, predefined_opaques_in_body: PredefinedOpaques(PredefinedOpaquesData { opaque_types: [] }) }, max_universe: U0, variables: [] } +second response: Ok(Canonical { value: Response { certainty: Maybe(Overflow), var_values: CanonicalVarValues { var_values: [] }, external_constraints: ExternalConstraints(ExternalConstraintsData { region_constraints: QueryRegionConstraints { outlives: [], member_constraints: [] }, opaque_types: [] }) }, max_universe: U0, variables: [] }) +error[E0119]: conflicting implementations of trait `Trait` for type `::Assoc` + --> $DIR/trait_ref_is_knowable-norm-overflow.rs:20:1 + | +LL | impl Trait for T {} + | ------------------------- first implementation here +LL | struct LocalTy; +LL | impl Trait for ::Assoc {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `::Assoc` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0119`. diff --git a/tests/ui/traits/new-solver/coherence/trait_ref_is_knowable-normalization-1.rs b/tests/ui/traits/new-solver/coherence/trait_ref_is_knowable-normalization-1.rs new file mode 100644 index 0000000000000..c38e3baf5b465 --- /dev/null +++ b/tests/ui/traits/new-solver/coherence/trait_ref_is_knowable-normalization-1.rs @@ -0,0 +1,22 @@ +// compile-flags: -Ztrait-solver=next +// check-pass + +trait Id { + type Assoc; +} +impl Id for T { + type Assoc = T; +} + + +// Coherence should be able to reason that `::Assoc: Copy` +// does not hold. +// +// See https://github.com/rust-lang/trait-system-refactor-initiative/issues/51 +// for more details. +trait Trait {} +impl Trait for T {} +struct LocalTy; +impl Trait for ::Assoc {} + +fn main() {} diff --git a/tests/ui/traits/new-solver/coherence/trait_ref_is_knowable-normalization-2.rs b/tests/ui/traits/new-solver/coherence/trait_ref_is_knowable-normalization-2.rs new file mode 100644 index 0000000000000..2d53266db09d5 --- /dev/null +++ b/tests/ui/traits/new-solver/coherence/trait_ref_is_knowable-normalization-2.rs @@ -0,0 +1,25 @@ +// compile-flags: -Ztrait-solver=next +// check-pass + +use std::future::{Future, IntoFuture}; +use std::pin::Pin; + +// We check that this does not overlap with the following impl from std: +// impl

Future for Pin

where P: DerefMut,

::Target: Future { .. } +// This should fail because we know ` <&mut Value as Deref>::Target: Future` not to hold. +// For this to work we have to normalize in the `trait_ref_is_knowable` check as we +// otherwise add an ambiguous candidate here. +// +// See https://github.com/rust-lang/trait-system-refactor-initiative/issues/51 +// for more details. +struct Value; +impl<'a> IntoFuture for Pin<&'a mut Value> { + type Output = (); + type IntoFuture = Pin + Send>>; + + fn into_future(self) -> Self::IntoFuture { + todo!() + } +} + +fn main() {} diff --git a/tests/ui/traits/new-solver/coherence/trait_ref_is_knowable-normalization-3.rs b/tests/ui/traits/new-solver/coherence/trait_ref_is_knowable-normalization-3.rs new file mode 100644 index 0000000000000..2f27de4e4f4da --- /dev/null +++ b/tests/ui/traits/new-solver/coherence/trait_ref_is_knowable-normalization-3.rs @@ -0,0 +1,24 @@ +// compile-flags: -Ztrait-solver=next +// check-pass + +trait Id { + type Assoc; +} +impl Id for T { + type Assoc = T; +} + + +// Coherence should be able to reason that `(): PartialEq<::Assoc>>` +// does not hold. +// +// See https://github.com/rust-lang/trait-system-refactor-initiative/issues/51 +// for more details. +trait Trait {} +impl Trait for T +where + (): PartialEq {} +struct LocalTy; +impl Trait for ::Assoc {} + +fn main() {} diff --git a/tests/ui/traits/new-solver/cycles/inductive-not-on-stack.rs b/tests/ui/traits/new-solver/cycles/inductive-not-on-stack.rs new file mode 100644 index 0000000000000..f06b98a79cfe3 --- /dev/null +++ b/tests/ui/traits/new-solver/cycles/inductive-not-on-stack.rs @@ -0,0 +1,46 @@ +// compile-flags: -Ztrait-solver=next +#![feature(rustc_attrs, trivial_bounds)] + +// We have to be careful here: +// +// We either have the provisional result of `A -> B -> A` on the +// stack, which is a fully coinductive cycle. Accessing the +// provisional result for `B` as part of the `A -> C -> B -> A` cycle +// has to make sure we don't just use the result of `A -> B -> A` as the +// new cycle is inductive. +// +// Alternatively, if we have `A -> C -> A` first, then `A -> B -> A` has +// a purely inductive stack, so something could also go wrong here. + +#[rustc_coinductive] +trait A {} +#[rustc_coinductive] +trait B {} +trait C {} + +impl A for T {} +impl B for T {} +impl C for T {} + +fn impls_a() {} + +// The same test with reordered where clauses to make sure we're actually testing anything. +#[rustc_coinductive] +trait AR {} +#[rustc_coinductive] +trait BR {} +trait CR {} + +impl AR for T {} +impl BR for T {} +impl CR for T {} + +fn impls_ar() {} + +fn main() { + impls_a::<()>(); + //~^ ERROR overflow evaluating the requirement `(): A` + + impls_ar::<()>(); + //~^ ERROR overflow evaluating the requirement `(): AR` +} diff --git a/tests/ui/traits/new-solver/cycles/inductive-not-on-stack.stderr b/tests/ui/traits/new-solver/cycles/inductive-not-on-stack.stderr new file mode 100644 index 0000000000000..33fac603cbdda --- /dev/null +++ b/tests/ui/traits/new-solver/cycles/inductive-not-on-stack.stderr @@ -0,0 +1,29 @@ +error[E0275]: overflow evaluating the requirement `(): A` + --> $DIR/inductive-not-on-stack.rs:41:5 + | +LL | impls_a::<()>(); + | ^^^^^^^^^^^^^ + | + = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`inductive_not_on_stack`) +note: required by a bound in `impls_a` + --> $DIR/inductive-not-on-stack.rs:25:15 + | +LL | fn impls_a() {} + | ^ required by this bound in `impls_a` + +error[E0275]: overflow evaluating the requirement `(): AR` + --> $DIR/inductive-not-on-stack.rs:44:5 + | +LL | impls_ar::<()>(); + | ^^^^^^^^^^^^^^ + | + = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`inductive_not_on_stack`) +note: required by a bound in `impls_ar` + --> $DIR/inductive-not-on-stack.rs:38:16 + | +LL | fn impls_ar() {} + | ^^ required by this bound in `impls_ar` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0275`.