diff --git a/Cargo.lock b/Cargo.lock index d6d60bd5d3f..5186ca6ec64 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -101,6 +101,7 @@ dependencies = [ "chalk-solve", "diff", "docopt", + "expect-test", "itertools", "pretty_assertions", "regex", @@ -252,6 +253,12 @@ dependencies = [ "winapi", ] +[[package]] +name = "dissimilar" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31ad93652f40969dead8d4bf897a41e9462095152eb21c56e5830537e41179dd" + [[package]] name = "docopt" version = "1.1.1" @@ -279,6 +286,16 @@ dependencies = [ "log", ] +[[package]] +name = "expect-test" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ffc5e8bf4af3ae147a7797c5d0566d9f038e49179213e29f44ddb031aea96c7" +dependencies = [ + "dissimilar", + "once_cell", +] + [[package]] name = "fixedbitset" version = "0.2.0" diff --git a/Cargo.toml b/Cargo.toml index ecb06dea55a..8a09139a3d4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -34,5 +34,6 @@ chalk-integration = { version = "0.76.0-dev.0", path = "chalk-integration" } [dev-dependencies] # used for program_writer test errors diff = "0.1" +expect-test = "1.2.1" pretty_assertions = "0.6.1" regex = "1" diff --git a/chalk-ir/src/debug.rs b/chalk-ir/src/debug.rs index e4c5ab56a51..34774e48e13 100644 --- a/chalk-ir/src/debug.rs +++ b/chalk-ir/src/debug.rs @@ -1,9 +1,23 @@ //! Debug impls for types. -use std::fmt::{Debug, Display, Error, Formatter}; +use std::fmt::{self, Debug, Display, Error, Formatter}; use super::*; +/// Wrapper to allow forwarding to `Display::fmt`, `Debug::fmt`, etc. +pub struct Fmt(pub F) +where + F: Fn(&mut fmt::Formatter<'_>) -> fmt::Result; + +impl fmt::Display for Fmt +where + F: Fn(&mut fmt::Formatter<'_>) -> fmt::Result, +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + (self.0)(f) + } +} + impl Debug for TraitId { fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> { I::debug_trait_id(*self, fmt).unwrap_or_else(|| write!(fmt, "TraitId({:?})", self.0)) @@ -959,14 +973,27 @@ impl Debug for Constraint { } impl Display for ConstrainedSubst { + #[rustfmt::skip] fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> { let ConstrainedSubst { subst, constraints } = self; - write!( - f, - "substitution {}, lifetime constraints {:?}", - subst, constraints, - ) + let mut first = true; + + let subst = format!("{}", Fmt(|f| Display::fmt(subst, f))); + if subst != "[]" { + write!(f, "substitution {}", subst)?; + first = false; + } + + let constraints = format!("{}", Fmt(|f| Debug::fmt(constraints, f))); + if constraints != "[]" { + if !first { write!(f, ", ")?; } + write!(f, "lifetime constraints {}", constraints)?; + first = false; + } + + let _ = first; + Ok(()) } } diff --git a/chalk-solve/src/solve.rs b/chalk-solve/src/solve.rs index 9bf634cd6d3..9a8b87b4606 100644 --- a/chalk-solve/src/solve.rs +++ b/chalk-solve/src/solve.rs @@ -159,12 +159,20 @@ pub struct SolutionDisplay<'a, I: Interner> { } impl<'a, I: Interner> fmt::Display for SolutionDisplay<'a, I> { + #[rustfmt::skip] fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { let SolutionDisplay { solution, interner } = self; match solution { - Solution::Unique(constrained) => { - write!(f, "Unique; {}", constrained.display(*interner)) - } + // If a `Unique` solution has no associated data, omit the trailing semicolon. + // This makes blessed test output nicer to read. + Solution::Unique(Canonical { binders, value: ConstrainedSubst { subst, constraints } } ) + if interner.constraints_data(constraints.interned()).is_empty() + && interner.substitution_data(subst.interned()).is_empty() + && interner.canonical_var_kinds_data(binders.interned()).is_empty() + => write!(f, "Unique"), + + Solution::Unique(constrained) => write!(f, "Unique; {}", constrained.display(*interner)), + Solution::Ambig(Guidance::Definite(subst)) => write!( f, "Ambiguous; definite substitution {}", diff --git a/tests/logging_db/util.rs b/tests/logging_db/util.rs index 758ecb7649c..980fb523d8e 100644 --- a/tests/logging_db/util.rs +++ b/tests/logging_db/util.rs @@ -12,7 +12,9 @@ use chalk_solve::ext::*; use chalk_solve::logging_db::LoggingRustIrDatabase; use chalk_solve::RustIrDatabase; -use crate::test::{assert_result, TestGoal}; +use crate::test::assert_result_str; + +type TestGoal = crate::test::TestGoal<&'static str>; macro_rules! logging_db_output_sufficient { ($($arg:tt)*) => {{ @@ -25,12 +27,16 @@ macro_rules! logging_db_output_sufficient { pub fn logging_db_output_sufficient( program_text: &str, - goals: Vec<(&str, SolverChoice, TestGoal)>, + goals: Vec<(&str, Vec, TestGoal)>, ) { println!("program {}", program_text); assert!(program_text.starts_with("{")); assert!(program_text.ends_with("}")); + let goals = goals + .iter() + .flat_map(|(a, bs, c)| bs.into_iter().map(move |b| (a, b, c))); + let output_text = { let db = ChalkDatabase::with( &program_text[1..program_text.len() - 1], @@ -39,6 +45,7 @@ pub fn logging_db_output_sufficient( let program = db.program_ir().unwrap(); let wrapped = LoggingRustIrDatabase::<_, Program, _>::new(program.clone()); + chalk_integration::tls::set_current_program(&program, || { for (goal_text, solver_choice, expected) in goals.clone() { let mut solver = solver_choice.into_solver(); @@ -59,7 +66,7 @@ pub fn logging_db_output_sufficient( match expected { TestGoal::Aggregated(expected) => { let result = solver.solve(&wrapped, &peeled_goal); - assert_result(result, expected, db.interner()); + assert_result_str(result, expected, db.interner()); } _ => panic!("only aggregated test goals supported for logger goals"), } @@ -101,7 +108,7 @@ pub fn logging_db_output_sufficient( match expected { TestGoal::Aggregated(expected) => { let result = solver.solve(&db, &peeled_goal); - assert_result(result, expected, db.interner()); + assert_result_str(result, expected, db.interner()); } _ => panic!("only aggregated test goals supported for logger goals"), } diff --git a/tests/test/arrays.rs b/tests/test/arrays.rs index b44a61b9620..ff5b8a3e045 100644 --- a/tests/test/arrays.rs +++ b/tests/test/arrays.rs @@ -13,7 +13,7 @@ fn arrays_are_sized() { [u32; N]: Sized } } yields { - "Unique" + expect![["Unique"]] } } @@ -35,7 +35,7 @@ fn arrays_are_copy_if_element_copy() { [Foo; N]: Copy } } yields { - "Unique" + expect![["Unique"]] } } } @@ -55,7 +55,7 @@ fn arrays_are_not_copy_if_element_not_copy() { [Foo; N]: Copy } } yields { - "No possible solution" + expect![["No possible solution"]] } } } @@ -76,7 +76,7 @@ fn arrays_are_clone_if_element_clone() { [Foo; N]: Clone } } yields { - "Unique" + expect![["Unique"]] } } } @@ -96,7 +96,7 @@ fn arrays_are_not_clone_if_element_not_clone() { [Foo; N]: Clone } } yields { - "No possible solution" + expect![["No possible solution"]] } } } @@ -116,7 +116,7 @@ fn arrays_are_well_formed_if_elem_sized() { } } } yields { - "Unique" + expect![["Unique"]] } goal { @@ -124,7 +124,7 @@ fn arrays_are_well_formed_if_elem_sized() { WellFormed([T; N]) } } yields { - "No possible solution" + expect![["No possible solution"]] } goal { @@ -132,7 +132,7 @@ fn arrays_are_well_formed_if_elem_sized() { WellFormed([T; N]) } } yields { - "Ambiguous; no inference guidance" + expect![["Ambiguous; no inference guidance"]] } } } diff --git a/tests/test/auto_traits.rs b/tests/test/auto_traits.rs index d2901360d77..2a3f579fa7a 100644 --- a/tests/test/auto_traits.rs +++ b/tests/test/auto_traits.rs @@ -25,7 +25,7 @@ fn auto_semantics() { List: Send } } yields { - "No possible solution" + expect![["No possible solution"]] } goal { forall { @@ -34,13 +34,13 @@ fn auto_semantics() { } } } yields { - "Unique" + expect![["Unique"]] } goal { List: Send } yields { - "Unique" + expect![["Unique"]] } goal { @@ -48,7 +48,7 @@ fn auto_semantics() { T: Send } } yields { - "Ambiguous" + expect![["Ambiguous; no inference guidance"]] } } } @@ -71,7 +71,7 @@ fn auto_trait_without_impls() { goal { TypeA: Send } yields { - "Unique" + expect![["Unique"]] } // No fields so `Useless` is `Send`. @@ -80,7 +80,7 @@ fn auto_trait_without_impls() { Useless: Send } } yields { - "Unique" + expect![["Unique"]] } goal { @@ -90,7 +90,7 @@ fn auto_trait_without_impls() { } } } yields { - "Unique" + expect![["Unique"]] } } } @@ -112,25 +112,25 @@ fn auto_trait_with_impls() { goal { TypeA: Send } yields { - "No possible solution" + expect![["No possible solution"]] } goal { TypeB: Send } yields { - "Unique" + expect![["Unique"]] } goal { Vec: Send } yields { - "No possible solution" + expect![["No possible solution"]] } goal { Vec: Send } yields { - "Unique" + expect![["Unique"]] } goal { @@ -138,7 +138,7 @@ fn auto_trait_with_impls() { Vec: Send } } yields { - "No possible solution" + expect![["No possible solution"]] } } } @@ -158,7 +158,7 @@ fn auto_traits_flounder() { goal { exists { A: Send } } yields_first[SolverChoice::slg(3, None)] { - "Floundered" + expect![["Floundered"]] } } } @@ -201,19 +201,19 @@ fn enum_auto_trait() { goal { A: Send } yields { - "Unique; substitution [], lifetime constraints []" + expect![["Unique"]] } goal { B: Send } yields { - "No possible solution" + expect![["No possible solution"]] } goal { C: Send } yields { - "No possible solution" + expect![["No possible solution"]] } } } @@ -239,61 +239,61 @@ fn builtin_auto_trait() { // The following types only contain AutoTrait-types, and thus implement AutoTrait themselves. goal { (i32, f32): AutoTrait } - yields { "Unique; substitution [], lifetime constraints []" } + yields { expect![["Unique"]] } goal { [(); 1]: AutoTrait } - yields { "Unique; substitution [], lifetime constraints []" } + yields { expect![["Unique"]] } goal { [()]: AutoTrait } - yields { "Unique; substitution [], lifetime constraints []" } + yields { expect![["Unique"]] } goal { u32: AutoTrait } - yields { "Unique; substitution [], lifetime constraints []" } + yields { expect![["Unique"]] } goal { *const (): AutoTrait } - yields { "Unique; substitution [], lifetime constraints []" } + yields { expect![["Unique"]] } goal { *mut (): AutoTrait } - yields { "Unique; substitution [], lifetime constraints []" } + yields { expect![["Unique"]] } goal { forall<'a> { &'a (): AutoTrait } } - yields { "Unique; substitution [], lifetime constraints []" } + yields { expect![["Unique"]] } goal { forall<'a> { &'a mut (): AutoTrait } } - yields { "Unique; substitution [], lifetime constraints []" } + yields { expect![["Unique"]] } goal { str: AutoTrait } - yields { "Unique; substitution [], lifetime constraints []" } + yields { expect![["Unique"]] } goal { !: AutoTrait } - yields { "Unique; substitution [], lifetime constraints []" } + yields { expect![["Unique"]] } goal { Enum: AutoTrait } - yields { "Unique; substitution [], lifetime constraints []" } + yields { expect![["Unique"]] } goal { func: AutoTrait } - yields { "Unique; substitution [], lifetime constraints []" } + yields { expect![["Unique"]] } goal { good_closure: AutoTrait } - yields { "Unique; substitution [], lifetime constraints []" } + yields { expect![["Unique"]] } goal { fn(Marker) -> Marker: AutoTrait } - yields { "Unique; substitution [], lifetime constraints []" } + yields { expect![["Unique"]] } // foreign types do not implement AutoTraits automatically goal { Ext: AutoTrait } - yields { "No possible solution" } + yields { expect![["No possible solution"]] } // The following types do contain non-AutoTrait types, and thus do not implement AutoTrait. goal { bad_closure: AutoTrait } - yields { "No possible solution" } + yields { expect![["No possible solution"]] } goal { ExtEnum: AutoTrait } - yields { "No possible solution" } + yields { expect![["No possible solution"]] } goal { (Struct, Marker): AutoTrait } - yields { "No possible solution" } + yields { expect![["No possible solution"]] } } } @@ -317,35 +317,35 @@ fn adt_auto_trait() { Yes: AutoTrait } yields { - "Unique; substitution [], lifetime constraints []" + expect![["Unique"]] } goal { No: AutoTrait } yields { - "No possible solution" + expect![["No possible solution"]] } goal { X: AutoTrait } yields { - "Unique; substitution [], lifetime constraints []" + expect![["Unique"]] } goal { WrapperNo: AutoTrait } yields { - "No possible solution" + expect![["No possible solution"]] } goal { WrapperYes: AutoTrait } yields { - "No possible solution" + expect![["No possible solution"]] } } } @@ -364,7 +364,7 @@ fn phantom_auto_trait() { PhantomData: AutoTrait } yields { - "No possible solution" + expect![["No possible solution"]] } } } diff --git a/tests/test/closures.rs b/tests/test/closures.rs index 37fe647fb07..40f8d78f78d 100644 --- a/tests/test/closures.rs +++ b/tests/test/closures.rs @@ -12,17 +12,17 @@ fn closure_is_well_formed() { goal { WellFormed(foo) } yields { - "Unique" + expect![["Unique"]] } goal { WellFormed(bar) } yields { - "Unique" + expect![["Unique"]] } goal { WellFormed(baz) } yields { - "Unique" + expect![["Unique"]] } } } @@ -40,7 +40,7 @@ fn closure_is_sized() { goal { foo: Sized } yields { - "Unique" + expect![["Unique"]] } } } @@ -76,17 +76,17 @@ fn closure_is_copy() { goal { foo: Copy } yields { - "Unique" + expect![["Unique"]] } goal { bar: Copy } yields { - "Unique" + expect![["Unique"]] } goal { baz: Copy } yields { - "Unique" + expect![["Unique"]] } // A closure with non-Copy upvars is not copy @@ -95,7 +95,7 @@ fn closure_is_copy() { foobuzz<'a>: Copy } } yields { - "No possible solution" + expect![["No possible solution"]] } // A closure with only Copy upvars is copy goal { @@ -103,17 +103,17 @@ fn closure_is_copy() { foobar<'a>: Copy } } yields { - "Unique" + expect![["Unique"]] } goal { forall { with_ty: Copy } } yields { - "No possible solution" + expect![["No possible solution"]] } goal { forall { if (T: Copy) { with_ty: Copy } } } yields { - "Unique" + expect![["Unique"]] } } } @@ -132,17 +132,17 @@ fn closure_is_clone() { goal { foo: Clone } yields { - "Unique" + expect![["Unique"]] } goal { bar: Clone } yields { - "Unique" + expect![["Unique"]] } goal { baz: Clone } yields { - "Unique" + expect![["Unique"]] } } } @@ -181,66 +181,66 @@ fn closure_implements_fn_traits() { goal { foo: Fn<()> } yields { - "No possible solution" + expect![["No possible solution"]] } goal { foo: FnMut<()> } yields { - "No possible solution" + expect![["No possible solution"]] } goal { foo: FnOnce<()> } yields { - "Unique" + expect![["Unique"]] } goal { Normalize(>::Output -> ()) } yields { - "Unique" + expect![["Unique"]] } // A closure with kind `Fn` implements all `Fn` traits goal { bar: Fn<()> } yields { - "Unique" + expect![["Unique"]] } goal { bar: FnMut<()> } yields { - "Unique" + expect![["Unique"]] } goal { bar: FnOnce<()> } yields { - "Unique" + expect![["Unique"]] } goal { Normalize(>::Output -> ()) } yields { - "Unique" + expect![["Unique"]] } // A closure with kind `FnMut` implements `FnMut` and `FnOnce` goal { baz: Fn<()> } yields { - "No possible solution" + expect![["No possible solution"]] } goal { baz: FnMut<()> } yields { - "Unique" + expect![["Unique"]] } goal { baz: FnOnce<()> } yields { - "Unique" + expect![["Unique"]] } goal { Normalize(>::Output -> ()) } yields { - "Unique" + expect![["Unique"]] } // A closure also implements the `Fn` traits regardless of upvars goal { @@ -248,35 +248,35 @@ fn closure_implements_fn_traits() { foobar<'a>: FnOnce<(u8, f32)> } } yields { - "Unique" + expect![["Unique"]] } goal { forall<'a> { Normalize( as FnOnce<(u8, f32)>>::Output -> u32) } } yields { - "Unique" + expect![["Unique"]] } goal { forall<'a> { Normalize( as FnOnce<(u8, f32)>>::Output -> u32) } } yields { - "Unique" + expect![["Unique"]] } goal { forall<'a> { foobuzz<'a>: FnOnce<(u8, f32)> } } yields { - "Unique" + expect![["Unique"]] } goal { forall<'a> { Normalize( as FnOnce<(u8, f32)>>::Output -> u32) } } yields { - "Unique" + expect![["Unique"]] } } } diff --git a/tests/test/coherence_goals.rs b/tests/test/coherence_goals.rs index 0cf44f0303c..86cbdb6d868 100644 --- a/tests/test/coherence_goals.rs +++ b/tests/test/coherence_goals.rs @@ -11,11 +11,11 @@ fn local_and_upstream_types() { struct Local { } } - goal { IsLocal(Upstream) } yields { "No possible solution" } - goal { IsUpstream(Upstream) } yields { "Unique" } + goal { IsLocal(Upstream) } yields { expect![["No possible solution"]] } + goal { IsUpstream(Upstream) } yields { expect![["Unique"]] } - goal { IsLocal(Local) } yields { "Unique" } - goal { IsUpstream(Local) } yields { "No possible solution" } + goal { IsLocal(Local) } yields { expect![["Unique"]] } + goal { IsUpstream(Local) } yields { expect![["No possible solution"]] } } test! { @@ -28,11 +28,11 @@ fn local_and_upstream_types() { struct Internal2 { } } - goal { forall { IsLocal(Upstream) } } yields { "No possible solution" } - goal { forall { IsUpstream(Upstream) } } yields { "Unique" } + goal { forall { IsLocal(Upstream) } } yields { expect![["No possible solution"]] } + goal { forall { IsUpstream(Upstream) } } yields { expect![["Unique"]] } - goal { forall { IsLocal(Local) } } yields { "Unique" } - goal { forall { IsUpstream(Local) } } yields { "No possible solution" } + goal { forall { IsLocal(Local) } } yields { expect![["Unique"]] } + goal { forall { IsUpstream(Local) } } yields { expect![["No possible solution"]] } } } @@ -49,10 +49,10 @@ fn is_fully_visible() { struct Box { } } - goal { IsFullyVisible(Upstream) } yields { "Unique" } - goal { IsFullyVisible(Local) } yields { "Unique" } - goal { IsFullyVisible(Box) } yields { "Unique" } - goal { IsFullyVisible(Box) } yields { "Unique" } + goal { IsFullyVisible(Upstream) } yields { expect![["Unique"]] } + goal { IsFullyVisible(Local) } yields { expect![["Unique"]] } + goal { IsFullyVisible(Box) } yields { expect![["Unique"]] } + goal { IsFullyVisible(Box) } yields { expect![["Unique"]] } } // Should be visible regardless of local, fundamental, or upstream @@ -70,25 +70,25 @@ fn is_fully_visible() { } // Unknown type parameters are not fully visible - goal { forall { IsFullyVisible(Box) } } yields { "No possible solution" } - goal { forall { IsFullyVisible(Upstream2) } } yields { "No possible solution" } - goal { forall { IsFullyVisible(Local2) } } yields { "No possible solution" } + goal { forall { IsFullyVisible(Box) } } yields { expect![["No possible solution"]] } + goal { forall { IsFullyVisible(Upstream2) } } yields { expect![["No possible solution"]] } + goal { forall { IsFullyVisible(Local2) } } yields { expect![["No possible solution"]] } // Without any unknown type parameters, local and upstream should not matter - goal { forall { IsFullyVisible(Upstream2) } } yields { "Unique" } - goal { forall { IsFullyVisible(Upstream2) } } yields { "Unique" } - goal { forall { IsFullyVisible(Local2) } } yields { "Unique" } - goal { forall { IsFullyVisible(Local2) } } yields { "Unique" } + goal { forall { IsFullyVisible(Upstream2) } } yields { expect![["Unique"]] } + goal { forall { IsFullyVisible(Upstream2) } } yields { expect![["Unique"]] } + goal { forall { IsFullyVisible(Local2) } } yields { expect![["Unique"]] } + goal { forall { IsFullyVisible(Local2) } } yields { expect![["Unique"]] } // Fundamental anywhere should not change the outcome - goal { forall { IsFullyVisible(Box>) } } yields { "Unique" } - goal { forall { IsFullyVisible(Box>) } } yields { "Unique" } - goal { forall { IsFullyVisible(Box>) } } yields { "Unique" } - goal { forall { IsFullyVisible(Box>) } } yields { "Unique" } - goal { forall { IsFullyVisible(Upstream2>) } } yields { "Unique" } - goal { forall { IsFullyVisible(Upstream2>) } } yields { "Unique" } - goal { forall { IsFullyVisible(Local2>) } } yields { "Unique" } - goal { forall { IsFullyVisible(Local2>) } } yields { "Unique" } + goal { forall { IsFullyVisible(Box>) } } yields { expect![["Unique"]] } + goal { forall { IsFullyVisible(Box>) } } yields { expect![["Unique"]] } + goal { forall { IsFullyVisible(Box>) } } yields { expect![["Unique"]] } + goal { forall { IsFullyVisible(Box>) } } yields { expect![["Unique"]] } + goal { forall { IsFullyVisible(Upstream2>) } } yields { expect![["Unique"]] } + goal { forall { IsFullyVisible(Upstream2>) } } yields { expect![["Unique"]] } + goal { forall { IsFullyVisible(Local2>) } } yields { expect![["Unique"]] } + goal { forall { IsFullyVisible(Local2>) } } yields { expect![["Unique"]] } } } @@ -109,15 +109,15 @@ fn fundamental_types() { } // Without fundamental, Box should behave like a regular upstream type - goal { forall { not { IsLocal(Box) } } } yields { "Unique" } - goal { forall { IsLocal(Box) } } yields { "No possible solution" } - goal { forall { IsUpstream(Box) } } yields { "Unique" } + goal { forall { not { IsLocal(Box) } } } yields { expect![["Unique"]] } + goal { forall { IsLocal(Box) } } yields { expect![["No possible solution"]] } + goal { forall { IsUpstream(Box) } } yields { expect![["Unique"]] } // Without fundamental, Box is upstream regardless of its inner type - goal { IsLocal(Box) } yields { "No possible solution" } - goal { IsLocal(Box) } yields { "No possible solution" } - goal { IsUpstream(Box) } yields { "Unique" } - goal { IsUpstream(Box) } yields { "Unique" } + goal { IsLocal(Box) } yields { expect![["No possible solution"]] } + goal { IsLocal(Box) } yields { expect![["No possible solution"]] } + goal { IsUpstream(Box) } yields { expect![["Unique"]] } + goal { IsUpstream(Box) } yields { expect![["Unique"]] } } test! { @@ -132,16 +132,16 @@ fn fundamental_types() { // With fundamental, Box can be local for certain types, so there is no unique solution // anymore for any of these - goal { forall { not { IsLocal(Box) } } } yields { "Ambiguous" } - goal { forall { IsLocal(Box) } } yields { "No possible solution" } - goal { forall { IsUpstream(Box) } } yields { "No possible solution" } + goal { forall { not { IsLocal(Box) } } } yields { expect![["Ambiguous; no inference guidance"]] } + goal { forall { IsLocal(Box) } } yields { expect![["No possible solution"]] } + goal { forall { IsUpstream(Box) } } yields { expect![["No possible solution"]] } // With fundamental, some of these yield different results -- no longer depends on Box // itself - goal { IsLocal(Box) } yields { "No possible solution" } - goal { IsLocal(Box) } yields { "Unique" } - goal { IsUpstream(Box) } yields { "Unique" } - goal { IsUpstream(Box) } yields { "No possible solution" } + goal { IsLocal(Box) } yields { expect![["No possible solution"]] } + goal { IsLocal(Box) } yields { expect![["Unique"]] } + goal { IsUpstream(Box) } yields { expect![["Unique"]] } + goal { IsUpstream(Box) } yields { expect![["No possible solution"]] } } test! { @@ -159,29 +159,29 @@ fn fundamental_types() { } // Upstream is upstream no matter what, so this should not be local for any T - goal { forall { IsLocal(Box>) } } yields { "No possible solution" } - goal { forall { IsUpstream(Box>) } } yields { "Unique" } + goal { forall { IsLocal(Box>) } } yields { expect![["No possible solution"]] } + goal { forall { IsUpstream(Box>) } } yields { expect![["Unique"]] } // A fundamental type inside an upstream type should not make a difference (i.e. the rules // for the outer, non-fundamental type should apply) - goal { forall { IsLocal(Upstream>) } } yields { "No possible solution" } - goal { forall { IsUpstream(Upstream>) } } yields { "Unique" } + goal { forall { IsLocal(Upstream>) } } yields { expect![["No possible solution"]] } + goal { forall { IsUpstream(Upstream>) } } yields { expect![["Unique"]] } // Make sure internal types within an upstream type do not make a difference - goal { forall { IsLocal(Box>>) } } yields { "No possible solution" } - goal { forall { IsUpstream(Box>>) } } yields { "Unique" } + goal { forall { IsLocal(Box>>) } } yields { expect![["No possible solution"]] } + goal { forall { IsUpstream(Box>>) } } yields { expect![["Unique"]] } // Local is local no matter what, so this should be local for any T - goal { forall { IsLocal(Box>) } } yields { "Unique" } - goal { forall { IsUpstream(Box>) } } yields { "No possible solution" } + goal { forall { IsLocal(Box>) } } yields { expect![["Unique"]] } + goal { forall { IsUpstream(Box>) } } yields { expect![["No possible solution"]] } // A fundamental type inside an internal type should not make a difference - goal { forall { IsLocal(Local>) } } yields { "Unique" } - goal { forall { IsUpstream(Local>) } } yields { "No possible solution" } + goal { forall { IsLocal(Local>) } } yields { expect![["Unique"]] } + goal { forall { IsUpstream(Local>) } } yields { expect![["No possible solution"]] } // Make sure upstream types within an internal type and vice versa do not make a difference - goal { forall { IsLocal(Box>>) } } yields { "Unique" } - goal { forall { IsUpstream(Box>>) } } yields { "Unique" } + goal { forall { IsLocal(Box>>) } } yields { expect![["Unique"]] } + goal { forall { IsUpstream(Box>>) } } yields { expect![["Unique"]] } } // Nested fundamental types should still be local if they can be recursively proven to be local @@ -203,14 +203,14 @@ fn fundamental_types() { struct Internal2 { } } - goal { forall { IsLocal(Ref>) } } yields { "No possible solution" } - goal { forall { IsUpstream(Ref>) } } yields { "No possible solution" } + goal { forall { IsLocal(Ref>) } } yields { expect![["No possible solution"]] } + goal { forall { IsUpstream(Ref>) } } yields { expect![["No possible solution"]] } - goal { IsLocal(Ref>) } yields { "No possible solution" } - goal { IsUpstream(Ref>) } yields { "Unique" } + goal { IsLocal(Ref>) } yields { expect![["No possible solution"]] } + goal { IsUpstream(Ref>) } yields { expect![["Unique"]] } - goal { IsLocal(Ref>) } yields { "Unique" } - goal { IsUpstream(Ref>) } yields { "No possible solution" } + goal { IsLocal(Ref>) } yields { expect![["Unique"]] } + goal { IsUpstream(Ref>) } yields { expect![["No possible solution"]] } } // If a type is not upstream, it is always local regardless of its parameters or #[fundamental] @@ -224,9 +224,9 @@ fn fundamental_types() { struct Local { } } - goal { forall { IsLocal(Box) } } yields { "Unique" } - goal { IsLocal(Box) } yields { "Unique" } - goal { IsLocal(Box) } yields { "Unique" } + goal { forall { IsLocal(Box) } } yields { expect![["Unique"]] } + goal { IsLocal(Box) } yields { expect![["Unique"]] } + goal { IsLocal(Box) } yields { expect![["Unique"]] } } } @@ -242,13 +242,13 @@ fn local_impl_allowed_for_traits() { } // Local traits are always implementable - goal { forall { LocalImplAllowed(T: LocalTrait) } } yields { "Unique" } - goal { LocalImplAllowed(Local: LocalTrait) } yields { "Unique" } - goal { LocalImplAllowed(Upstream: LocalTrait) } yields { "Unique" } - goal { forall { LocalImplAllowed(T: LocalTrait2) } } yields { "Unique" } - goal { forall { LocalImplAllowed(T: LocalTrait2) } } yields { "Unique" } - goal { forall { LocalImplAllowed(Local: LocalTrait2) } } yields { "Unique" } - goal { forall { LocalImplAllowed(Upstream: LocalTrait2) } } yields { "Unique" } + goal { forall { LocalImplAllowed(T: LocalTrait) } } yields { expect![["Unique"]] } + goal { LocalImplAllowed(Local: LocalTrait) } yields { expect![["Unique"]] } + goal { LocalImplAllowed(Upstream: LocalTrait) } yields { expect![["Unique"]] } + goal { forall { LocalImplAllowed(T: LocalTrait2) } } yields { expect![["Unique"]] } + goal { forall { LocalImplAllowed(T: LocalTrait2) } } yields { expect![["Unique"]] } + goal { forall { LocalImplAllowed(Local: LocalTrait2) } } yields { expect![["Unique"]] } + goal { forall { LocalImplAllowed(Upstream: LocalTrait2) } } yields { expect![["Unique"]] } } // Single-type parameter trait refs (Self only) @@ -263,12 +263,12 @@ fn local_impl_allowed_for_traits() { } // No local type - goal { LocalImplAllowed(Upstream: UpstreamTrait) } yields { "No possible solution" } - goal { forall { LocalImplAllowed(T: UpstreamTrait) } } yields { "No possible solution" } + goal { LocalImplAllowed(Upstream: UpstreamTrait) } yields { expect![["No possible solution"]] } + goal { forall { LocalImplAllowed(T: UpstreamTrait) } } yields { expect![["No possible solution"]] } // Local type, not preceded by anything // Notice that the types after the first local type do not matter at all - goal { LocalImplAllowed(Local: UpstreamTrait) } yields { "Unique" } + goal { LocalImplAllowed(Local: UpstreamTrait) } yields { expect![["Unique"]] } } // Multi-type parameter trait refs (Self, T) @@ -284,36 +284,36 @@ fn local_impl_allowed_for_traits() { } // No local type - goal { forall { LocalImplAllowed(T: UpstreamTrait2) } } yields { "No possible solution" } - goal { forall { LocalImplAllowed(T: UpstreamTrait2) } } yields { "No possible solution" } - goal { forall { LocalImplAllowed(Upstream: UpstreamTrait2) } } yields { "No possible solution" } + goal { forall { LocalImplAllowed(T: UpstreamTrait2) } } yields { expect![["No possible solution"]] } + goal { forall { LocalImplAllowed(T: UpstreamTrait2) } } yields { expect![["No possible solution"]] } + goal { forall { LocalImplAllowed(Upstream: UpstreamTrait2) } } yields { expect![["No possible solution"]] } // Local type, but preceded by a type parameter - goal { forall { LocalImplAllowed(T: UpstreamTrait2) } } yields { "No possible solution" } + goal { forall { LocalImplAllowed(T: UpstreamTrait2) } } yields { expect![["No possible solution"]] } // Local type, not preceded by anything // Notice that the types after the first local type do not matter at all - goal { forall { LocalImplAllowed(Local: UpstreamTrait2) } } yields { "Unique" } - goal { LocalImplAllowed(Local: UpstreamTrait2) } yields { "Unique" } - goal { LocalImplAllowed(Local: UpstreamTrait2) } yields { "Unique" } + goal { forall { LocalImplAllowed(Local: UpstreamTrait2) } } yields { expect![["Unique"]] } + goal { LocalImplAllowed(Local: UpstreamTrait2) } yields { expect![["Unique"]] } + goal { LocalImplAllowed(Local: UpstreamTrait2) } yields { expect![["Unique"]] } // Local type, but preceded by a fully visible type (i.e. no placeholder types) - goal { LocalImplAllowed(Upstream: UpstreamTrait2) } yields { "Unique" } - goal { LocalImplAllowed(Upstream2: UpstreamTrait2) } yields { "Unique" } - goal { LocalImplAllowed(Upstream2: UpstreamTrait2) } yields { "Unique" } + goal { LocalImplAllowed(Upstream: UpstreamTrait2) } yields { expect![["Unique"]] } + goal { LocalImplAllowed(Upstream2: UpstreamTrait2) } yields { expect![["Unique"]] } + goal { LocalImplAllowed(Upstream2: UpstreamTrait2) } yields { expect![["Unique"]] } // Type parameter covered by the local type - goal { forall { LocalImplAllowed(Upstream: UpstreamTrait2>) } } yields { "Unique" } - goal { forall { LocalImplAllowed(Upstream2: UpstreamTrait2>) } } yields { "Unique" } - goal { forall { LocalImplAllowed(Upstream2: UpstreamTrait2>) } } yields { "Unique" } + goal { forall { LocalImplAllowed(Upstream: UpstreamTrait2>) } } yields { expect![["Unique"]] } + goal { forall { LocalImplAllowed(Upstream2: UpstreamTrait2>) } } yields { expect![["Unique"]] } + goal { forall { LocalImplAllowed(Upstream2: UpstreamTrait2>) } } yields { expect![["Unique"]] } // Type parameter covered by a deeply nested upstream type // Notice that it does not matter that the T is wrapped in a local type because the outer // type is still upstream - goal { forall { LocalImplAllowed(Upstream2>: UpstreamTrait2>) } } yields { "No possible solution" } + goal { forall { LocalImplAllowed(Upstream2>: UpstreamTrait2>) } } yields { expect![["No possible solution"]] } // Does not matter whether the covered type parameter is eventually covered or not by the // first actually local type found - goal { forall { LocalImplAllowed(Upstream2>: UpstreamTrait2>) } } yields { "No possible solution" } + goal { forall { LocalImplAllowed(Upstream2>: UpstreamTrait2>) } } yields { expect![["No possible solution"]] } } test! { @@ -331,32 +331,32 @@ fn local_impl_allowed_for_traits() { } // Local traits can be implemented regardless of the types involved - goal { forall { LocalImplAllowed(Self: InternalTrait<'a, T, U, V>) } } yields { "Unique" } + goal { forall { LocalImplAllowed(Self: InternalTrait<'a, T, U, V>) } } yields { expect![["Unique"]] } // Upstream traits definitely cannot be implemented for all types - goal { forall { LocalImplAllowed(Self: UpstreamTrait<'a, T, U, V>) } } yields { "No possible solution" } + goal { forall { LocalImplAllowed(Self: UpstreamTrait<'a, T, U, V>) } } yields { expect![["No possible solution"]] } // No local types - goal { forall<'a> { LocalImplAllowed(Upstream2: UpstreamTrait<'a, Upstream, Upstream, Upstream>) } } yields { "No possible solution" } + goal { forall<'a> { LocalImplAllowed(Upstream2: UpstreamTrait<'a, Upstream, Upstream, Upstream>) } } yields { expect![["No possible solution"]] } goal { forall<'a> { LocalImplAllowed(Upstream2: UpstreamTrait< 'a, Upstream2, Upstream2>>, Upstream2> - >) } } yields { "No possible solution" } + >) } } yields { expect![["No possible solution"]] } // Local type, not preceded by anything -- types after the first local type do not matter - goal { forall<'a, T, U, V> { LocalImplAllowed(Local: UpstreamTrait<'a, T, U, V>) } } yields { "Unique" } - goal { forall<'a, U, V> { LocalImplAllowed(Local: UpstreamTrait<'a, Local, U, V>) } } yields { "Unique" } - goal { forall<'a, U, V> { LocalImplAllowed(Local: UpstreamTrait<'a, Upstream, U, V>) } } yields { "Unique" } - goal { forall<'a> { LocalImplAllowed(Local: UpstreamTrait<'a, Upstream, Local, Local>) } } yields { "Unique" } + goal { forall<'a, T, U, V> { LocalImplAllowed(Local: UpstreamTrait<'a, T, U, V>) } } yields { expect![["Unique"]] } + goal { forall<'a, U, V> { LocalImplAllowed(Local: UpstreamTrait<'a, Local, U, V>) } } yields { expect![["Unique"]] } + goal { forall<'a, U, V> { LocalImplAllowed(Local: UpstreamTrait<'a, Upstream, U, V>) } } yields { expect![["Unique"]] } + goal { forall<'a> { LocalImplAllowed(Local: UpstreamTrait<'a, Upstream, Local, Local>) } } yields { expect![["Unique"]] } // Local type preceded by a type that is not fully visible - goal { forall<'a, T> { LocalImplAllowed(T: UpstreamTrait<'a, Upstream, Upstream, Local>) } } yields { "No possible solution" } - goal { forall<'a, T> { LocalImplAllowed(Upstream: UpstreamTrait<'a, T, Upstream, Local>) } } yields { "No possible solution" } - goal { forall<'a, T> { LocalImplAllowed(Upstream: UpstreamTrait<'a, Upstream, T, Local>) } } yields { "No possible solution" } + goal { forall<'a, T> { LocalImplAllowed(T: UpstreamTrait<'a, Upstream, Upstream, Local>) } } yields { expect![["No possible solution"]] } + goal { forall<'a, T> { LocalImplAllowed(Upstream: UpstreamTrait<'a, T, Upstream, Local>) } } yields { expect![["No possible solution"]] } + goal { forall<'a, T> { LocalImplAllowed(Upstream: UpstreamTrait<'a, Upstream, T, Local>) } } yields { expect![["No possible solution"]] } // Once again, types after the first local do not matter - goal { forall<'a, T> { LocalImplAllowed(Upstream: UpstreamTrait<'a, Upstream, Local, T>) } } yields { "Unique" } + goal { forall<'a, T> { LocalImplAllowed(Upstream: UpstreamTrait<'a, Upstream, Local, T>) } } yields { expect![["Unique"]] } } } diff --git a/tests/test/coinduction.rs b/tests/test/coinduction.rs index b469378766d..65bf0f328f2 100644 --- a/tests/test/coinduction.rs +++ b/tests/test/coinduction.rs @@ -20,13 +20,13 @@ fn mixed_semantics() { goal { Bar: Send } yields { - "No possible solution" + expect![["No possible solution"]] } goal { Bar: Foo } yields { - "No possible solution" + expect![["No possible solution"]] } } } @@ -53,7 +53,7 @@ fn coinductive_unification_forall() { goal { forall { T: C1 } } yields { - r"No possible solution" + expect![["No possible solution"]] } } } @@ -80,7 +80,7 @@ fn coinductive_unification_exists() { goal { exists { T: C1 } } yields { - r"No possible solution" + expect![["No possible solution"]] } } } @@ -103,7 +103,7 @@ fn coinductive_nontrivial() { goal { exists { T: C1 } } yields { - r"No possible solution" + expect![["No possible solution"]] } } } @@ -126,7 +126,7 @@ fn coinductive_trivial_variant1() { goal { exists { T: C1 } } yields { - r"Unique; substitution [?0 := X, ?1 := X], lifetime constraints []" + expect![["Unique; substitution [?0 := X, ?1 := X]"]] } } } @@ -150,7 +150,7 @@ fn coinductive_trivial_variant2() { goal { exists { T: C1 } } yields { - r"Unique; substitution [?0 := X, ?1 := X], lifetime constraints []" + expect![["Unique; substitution [?0 := X, ?1 := X]"]] } } } @@ -168,7 +168,7 @@ fn coinductive_trivial_variant3() { goal { exists { T: C1 } } yields { - r"Unique; for { substitution [?0 := ^0.0, ?1 := ^0.1], lifetime constraints [] }" + expect![["Unique; for { substitution [?0 := ^0.0, ?1 := ^0.1] }"]] } } } @@ -214,7 +214,7 @@ fn coinductive_unsound1() { goal { forall { X: C1orC2 } } yields { - "No possible solution" + expect![["No possible solution"]] } } } @@ -256,7 +256,7 @@ fn coinductive_unsound2() { goal { forall { X: C1orC2 } } yields { - "No possible solution" + expect![["No possible solution"]] } } } @@ -305,7 +305,7 @@ fn coinductive_unsound_nested() { goal { forall { X: C1orC2 } } yields { - "No possible solution" + expect![["No possible solution"]] } } } @@ -376,7 +376,7 @@ fn coinductive_unsound_nested2() { goal { forall { X: C1andC2 } } yields { - "No possible solution" + expect![["No possible solution"]] } } } @@ -446,7 +446,7 @@ fn coinductive_unsound_inter_cycle_dependency() { goal { forall { X: C1andC2 } } yields { - "No possible solution" + expect![["No possible solution"]] } } } @@ -494,7 +494,7 @@ fn coinductive_multicycle1() { goal { forall { X: Any } } yields { - "Unique; substitution [], lifetime constraints []" + expect![["Unique"]] } } } @@ -534,7 +534,7 @@ fn coinductive_multicycle2() { goal { forall { X: Any } } yields { - "Unique; substitution [], lifetime constraints []" + expect![["Unique"]] } } } @@ -584,7 +584,7 @@ fn coinductive_multicycle3() { goal { forall { X: Any } } yields { - "No possible solution" + expect![["No possible solution"]] } } } @@ -634,7 +634,7 @@ fn coinductive_multicycle4() { goal { forall { X: Any } } yields { - "No possible solution" + expect![["No possible solution"]] } } } diff --git a/tests/test/constants.rs b/tests/test/constants.rs index 467b8aaf843..2189d14f8c6 100644 --- a/tests/test/constants.rs +++ b/tests/test/constants.rs @@ -18,19 +18,19 @@ fn single_impl() { S: Trait } } yields { - "Unique; substitution [?0 := 3], lifetime constraints []" + expect![["Unique; substitution [?0 := 3]"]] } goal { S<3>: Trait } yields { - "Unique" + expect![["Unique"]] } goal { S<5>: Trait } yields { - "No possible solution" + expect![["No possible solution"]] } @@ -39,7 +39,7 @@ fn single_impl() { S: Trait } } yields { - "No possible solution" + expect![["No possible solution"]] } } @@ -62,7 +62,7 @@ fn multi_impl() { S: Trait } } yields { - "Ambiguous; no inference guidance" + expect![["Ambiguous; no inference guidance"]] } goal { @@ -70,7 +70,7 @@ fn multi_impl() { S: Trait } } yields { - "No possible solution" + expect![["No possible solution"]] } } @@ -92,7 +92,7 @@ fn generic_impl() { S: Trait } } yields { - "Unique; for { substitution [?0 := ^0.0], lifetime constraints [] }" + expect![["Unique; for { substitution [?0 := ^0.0] }"]] } goal { @@ -100,7 +100,7 @@ fn generic_impl() { S: Trait } } yields { - "Unique; substitution [], lifetime constraints []" + expect![["Unique"]] } } } @@ -113,7 +113,7 @@ fn placeholders_eq() { C = D } } yields { - "No possible solution" + expect![["No possible solution"]] } goal { @@ -123,7 +123,7 @@ fn placeholders_eq() { } } } yields { - "No possible solution" + expect![["No possible solution"]] } goal { @@ -133,7 +133,7 @@ fn placeholders_eq() { } } } yields { - "Unique; substitution [?0 := !1_0], lifetime constraints []" + expect![["Unique; substitution [?0 := !1_0]"]] } goal { @@ -143,7 +143,7 @@ fn placeholders_eq() { } } } yields { - "No possible solution" + expect![["No possible solution"]] } } } diff --git a/tests/test/cycle.rs b/tests/test/cycle.rs index bdd6ed6e709..41f6369f8d6 100644 --- a/tests/test/cycle.rs +++ b/tests/test/cycle.rs @@ -31,7 +31,7 @@ fn inner_cycle() { goal { exists { T: A } } yields { - "Ambiguous" + expect![["Ambiguous; no inference guidance"]] } } } @@ -51,7 +51,7 @@ fn cycle_no_solution() { T: Foo } } yields { - "No possible solution" + expect![["No possible solution"]] } } } @@ -73,7 +73,7 @@ fn cycle_many_solutions() { T: Foo } } yields { - "Ambiguous; no inference guidance" + expect![["Ambiguous; no inference guidance"]] } } } @@ -95,7 +95,7 @@ fn cycle_unique_solution() { T: Foo } } yields { - "Unique; substitution [?0 := Zero]" + expect![["Unique; substitution [?0 := Zero]"]] } } } @@ -141,7 +141,7 @@ fn multiple_ambiguous_cycles() { T: WF } } yields { - "Ambig" + expect![["Ambiguous; no inference guidance"]] } } } @@ -164,9 +164,9 @@ fn overflow() { goal { S: Q } yields[SolverChoice::slg(10, None)] { - "Ambiguous; no inference guidance" + expect![["Ambiguous; no inference guidance"]] } yields[SolverChoice::recursive_default()] { - "Ambiguous; no inference guidance" + expect![["Ambiguous; no inference guidance"]] } } } @@ -193,7 +193,7 @@ fn overflow_universe() { // solver means that when we are asked to solve (e.g.) // `!1_1: Bar`, we rewrite that to `!1_0: Bar`, identifying a // cycle. - "No possible solution" + expect![["No possible solution"]] } } } @@ -256,7 +256,7 @@ fn cycle_with_ambiguity() { Rc: From } } yields[SolverChoice::slg_default()] { - "Ambiguous; no inference guidance" + expect![["Ambiguous; no inference guidance"]] } } } diff --git a/tests/test/discriminant_kind.rs b/tests/test/discriminant_kind.rs index 1fcbadd4791..a4e0cd14072 100644 --- a/tests/test/discriminant_kind.rs +++ b/tests/test/discriminant_kind.rs @@ -38,19 +38,19 @@ fn discriminant_kind_impl() { goal { A: DiscriminantKind } yields { - "Unique" + expect![["Unique"]] } goal { i32: DiscriminantKind } yields { - "Unique" + expect![["Unique"]] } goal { (i32, A): DiscriminantKind } yields { - "Unique" + expect![["Unique"]] } goal { @@ -58,7 +58,7 @@ fn discriminant_kind_impl() { dyn Principal + 'a: DiscriminantKind } } yields { - "Unique" + expect![["Unique"]] } } } @@ -99,7 +99,7 @@ fn discriminant_kind_assoc() { goal { Normalize(::Discriminant -> u8) } yields { - "Unique" + expect![["Unique"]] } // Same as above @@ -108,14 +108,14 @@ fn discriminant_kind_assoc() { Normalize(::Discriminant -> u8) } } yields { - "Unique" + expect![["Unique"]] } // Discriminant for enums with unspecified discriminant should be isize goal { Normalize(::Discriminant -> isize) } yields { - "Unique" + expect![["Unique"]] } // Discriminant should be the same as specified in `repr` @@ -123,25 +123,25 @@ fn discriminant_kind_assoc() { goal { Normalize(::Discriminant -> isize) } yields { - "Unique" + expect![["Unique"]] } goal { Normalize(::Discriminant -> i32) } yields { - "Unique" + expect![["Unique"]] } goal { Normalize(::Discriminant -> u32) } yields { - "Unique" + expect![["Unique"]] } goal { Normalize(::Discriminant -> usize) } yields { - "Unique" + expect![["Unique"]] } //-------- @@ -149,7 +149,7 @@ fn discriminant_kind_assoc() { goal { Normalize(::Discriminant -> u32) } yields { - "Unique" + expect![["Unique"]] } // Placeholders don't have a determined discriminant @@ -160,7 +160,7 @@ fn discriminant_kind_assoc() { } } } yields { - "Ambiguous" + expect![["Ambiguous; no inference guidance"]] } } } diff --git a/tests/test/existential_types.rs b/tests/test/existential_types.rs index d1097eebf2a..d6e23d49398 100644 --- a/tests/test/existential_types.rs +++ b/tests/test/existential_types.rs @@ -14,7 +14,7 @@ fn dyn_Clone_is_Clone() { dyn Clone + 's: Clone } } yields { - "Unique; substitution []" + expect![["Unique"]] } } } @@ -32,7 +32,7 @@ fn dyn_Clone_is_not_Send() { dyn Clone + 's: Send } } yields { - "No possible solution" + expect![["No possible solution"]] } } } @@ -50,7 +50,7 @@ fn dyn_Clone_Send_is_Send() { (dyn Clone + Send + 's): Send } } yields { - "Unique; substitution []" + expect![["Unique"]] } } } @@ -70,7 +70,7 @@ fn dyn_Foo_Bar() { dyn Foo + 's: Foo } } yields { - "No possible solution" + expect![["No possible solution"]] } goal { @@ -80,7 +80,7 @@ fn dyn_Foo_Bar() { } } } yields { - "Unique; substitution [?0 := Bar], lifetime constraints []" + expect![["Unique; substitution [?0 := Bar]"]] } } } @@ -101,7 +101,7 @@ fn dyn_super_trait_simple() { dyn Bar + 's: Bar } } yields { - "Unique" + expect![["Unique"]] } goal { @@ -109,7 +109,7 @@ fn dyn_super_trait_simple() { dyn Bar + 's: Foo } } yields { - "Unique" + expect![["Unique"]] } goal { @@ -117,7 +117,7 @@ fn dyn_super_trait_simple() { dyn Bar + 's: Foo } } yields { - "No possible solution" + expect![["No possible solution"]] } goal { @@ -127,7 +127,7 @@ fn dyn_super_trait_simple() { } } } yields { - "Unique; substitution [?0 := B], lifetime constraints []" + expect![["Unique; substitution [?0 := B]"]] } } } @@ -150,7 +150,7 @@ fn dyn_super_trait_cycle() { dyn Bar + 's: Bar } } yields { - "No possible solution" + expect![["No possible solution"]] } } } @@ -172,7 +172,7 @@ fn dyn_super_trait_not_a_cycle() { dyn Bar + 's: Foo } } yields { - "Unique" + expect![["Unique"]] } goal { @@ -180,7 +180,7 @@ fn dyn_super_trait_not_a_cycle() { dyn Bar + 's: Thing } } yields { - "Unique" + expect![["Unique"]] } goal { @@ -188,7 +188,7 @@ fn dyn_super_trait_not_a_cycle() { dyn Bar + 's: Thing } } yields { - "Unique" + expect![["Unique"]] } } } @@ -212,7 +212,7 @@ fn dyn_super_trait_higher_ranked() { } } } yields { - "Unique" + expect![["Unique"]] } goal { @@ -222,7 +222,7 @@ fn dyn_super_trait_higher_ranked() { } } } yields { - "Unique" + expect![["Unique"]] } goal { @@ -230,7 +230,7 @@ fn dyn_super_trait_higher_ranked() { dyn Bar<'y> + 's: Foo<'x> } } yields { - "Unique" + expect![["Unique"]] } } } @@ -251,7 +251,7 @@ fn dyn_super_trait_non_super_trait_clause() { dyn Foo + 's: Foo } } yields { - "Unique" + expect![["Unique"]] } goal { @@ -259,7 +259,7 @@ fn dyn_super_trait_non_super_trait_clause() { dyn Foo + 's: Bar } } yields { - "No possible solution" + expect![["No possible solution"]] } } } @@ -279,7 +279,7 @@ fn dyn_higher_ranked_type_arguments() { dyn forall<'a> Foo> + 's: Foo> } } yields { - "Unique; substitution [], lifetime constraints []" + expect![["Unique"]] } goal { @@ -287,7 +287,7 @@ fn dyn_higher_ranked_type_arguments() { dyn forall<'a> Foo> + Bar + 's: Foo> } } yields { - "Unique; substitution [], lifetime constraints []" + expect![["Unique"]] } goal { @@ -295,7 +295,7 @@ fn dyn_higher_ranked_type_arguments() { dyn forall<'a> Foo> + Bar + 's: Bar } } yields { - "Unique; substitution [], lifetime constraints []" + expect![["Unique"]] } goal { @@ -306,10 +306,7 @@ fn dyn_higher_ranked_type_arguments() { } } yields { // Note that this requires 'a == 's, so it would be resolveable later on. - "Unique; substitution [], lifetime constraints [\ - InEnvironment { environment: Env([]), goal: '!1_0: '!2_0 }, \ - InEnvironment { environment: Env([]), goal: '!2_0: '!1_0 }\ - ]" + expect![["Unique; lifetime constraints [InEnvironment { environment: Env([]), goal: '!1_0: '!2_0 }, InEnvironment { environment: Env([]), goal: '!2_0: '!1_0 }]"]] } } } @@ -336,10 +333,7 @@ fn dyn_binders_reverse() { > } } yields { - "Unique; substitution [], lifetime constraints [\ - InEnvironment { environment: Env([]), goal: '!5_0: '!5_1 }, \ - InEnvironment { environment: Env([]), goal: '!5_1: '!5_0 }\ - ]" + expect![["Unique; lifetime constraints [InEnvironment { environment: Env([]), goal: '!5_0: '!5_1 }, InEnvironment { environment: Env([]), goal: '!5_1: '!5_0 }]"]] } // Note: these constraints are ultimately unresolveable (we @@ -351,10 +345,7 @@ fn dyn_binders_reverse() { > } } yields { - "Unique; substitution [], lifetime constraints [\ - InEnvironment { environment: Env([]), goal: '!3_0: '!3_1 }, \ - InEnvironment { environment: Env([]), goal: '!3_1: '!3_0 }\ - ]" + expect![["Unique; lifetime constraints [InEnvironment { environment: Env([]), goal: '!3_0: '!3_1 }, InEnvironment { environment: Env([]), goal: '!3_1: '!3_0 }]"]] } // Note: ordering of parameters is reversed here, but that's no problem @@ -365,7 +356,7 @@ fn dyn_binders_reverse() { > } } yields { - "Unique; substitution [], lifetime constraints []" + expect![["Unique"]] } } } @@ -388,10 +379,7 @@ fn dyn_lifetime_bound() { } } } yields { - "Unique; substitution [], lifetime constraints [\ - InEnvironment { environment: Env([]), goal: '!1_0: '!2_0 }, \ - InEnvironment { environment: Env([]), goal: '!2_0: '!1_0 }\ - ]" + expect![["Unique; lifetime constraints [InEnvironment { environment: Env([]), goal: '!1_0: '!2_0 }, InEnvironment { environment: Env([]), goal: '!2_0: '!1_0 }]"]] } } } @@ -410,10 +398,10 @@ fn dyn_associated_type_binding() { } } } yields[SolverChoice::recursive_default()] { - "Unique; substitution [?0 := Int(I32)], lifetime constraints []" + expect![["Unique; substitution [?0 := Int(I32)]"]] } yields[SolverChoice::slg_default()] { // #234 - "Ambiguous" + expect![["Ambiguous; no inference guidance"]] } } } @@ -430,7 +418,7 @@ fn dyn_well_formed() { WellFormed(dyn MyTrait + 's) } } yields { - "Unique" + expect![["Unique; for { substitution [?0 := '^0.0] }"]] } } } diff --git a/tests/test/fn_def.rs b/tests/test/fn_def.rs index a96738d1bc4..d4a5d134f44 100644 --- a/tests/test/fn_def.rs +++ b/tests/test/fn_def.rs @@ -9,7 +9,7 @@ fn fn_def_is_well_formed() { goal { WellFormed(foo) } yields { - "Unique" + expect![["Unique"]] } } } @@ -26,7 +26,7 @@ fn fn_def_is_sized() { goal { foo: Sized } yields { - "Unique" + expect![["Unique"]] } } } @@ -43,7 +43,7 @@ fn fn_def_is_copy() { goal { foo: Copy } yields { - "Unique" + expect![["Unique"]] } } } @@ -60,7 +60,7 @@ fn fn_def_is_clone() { goal { foo: Clone } yields { - "Unique" + expect![["Unique"]] } } } @@ -88,37 +88,37 @@ fn fn_def_implements_fn_traits() { goal { foo: Fn<()> } yields { - "Unique" + expect![["Unique"]] } goal { Normalize(>::Output -> ()) } yields { - "Unique" + expect![["Unique"]] } goal { bar: Fn<(i32,)> } yields { - "Unique" + expect![["Unique"]] } goal { Normalize(>::Output -> ()) } yields { - "Unique" + expect![["Unique"]] } goal { baz: Fn<(i32,)> } yields { - "Unique" + expect![["Unique"]] } goal { Normalize(>::Output -> u8) } yields { - "Unique" + expect![["Unique"]] } } } @@ -144,25 +144,25 @@ fn generic_fn_implements_fn_traits() { goal { exists { foo: Fn<(T,)> } } yields { - "Unique" + expect![["Unique; for { substitution [?0 := ^0.0] }"]] } goal { forall { foo: Fn<(T,)> } } yields { - "Unique" + expect![["Unique"]] } goal { exists { Normalize( as FnOnce<(T,)>>::Output -> T) } } yields { - "Unique" + expect![["Unique; for { substitution [?0 := ^0.0] }"]] } goal { forall { Normalize( as FnOnce<(T,)>>::Output -> T) } } yields { - "Unique" + expect![["Unique"]] } } } @@ -187,19 +187,19 @@ fn fn_defs() { goal { WellFormed(baz) } yields { - "No possible solution" + expect![["No possible solution"]] } goal { WellFormed(baz) } yields { - "Unique" + expect![["Unique"]] } goal { WellFormed(garply) } yields { - "Unique" + expect![["Unique"]] } } @@ -221,7 +221,7 @@ fn fn_def_implied_bounds_from_env() { Bar: Foo } } yields { - "Unique" + expect![["Unique"]] } } } diff --git a/tests/test/foreign_types.rs b/tests/test/foreign_types.rs index d525dbd0272..0133730c993 100644 --- a/tests/test/foreign_types.rs +++ b/tests/test/foreign_types.rs @@ -12,7 +12,7 @@ fn foreign_ty_trait_impl() { impl Foo for A {} } - goal { A: Foo } yields { "Unique" } + goal { A: Foo } yields { expect![["Unique"]] } } } @@ -33,7 +33,7 @@ fn foreign_ty_is_well_formed() { extern type A; } - goal { WellFormed(A) } yields { "Unique" } + goal { WellFormed(A) } yields { expect![["Unique"]] } } } @@ -46,7 +46,7 @@ fn foreign_ty_is_not_sized() { extern type A; } - goal { not { A: Sized } } yields { "Unique" } + goal { not { A: Sized } } yields { expect![["Unique"]] } } } @@ -59,7 +59,7 @@ fn foreign_ty_is_not_copy() { extern type A; } - goal { not { A: Copy } } yields { "Unique" } + goal { not { A: Copy } } yields { expect![["Unique"]] } } } @@ -72,6 +72,6 @@ fn foreign_ty_is_not_clone() { extern type A; } - goal { not { A: Clone } } yields { "Unique" } + goal { not { A: Clone } } yields { expect![["Unique"]] } } } diff --git a/tests/test/functions.rs b/tests/test/functions.rs index d1b33ee2007..d68693d8c7f 100644 --- a/tests/test/functions.rs +++ b/tests/test/functions.rs @@ -11,13 +11,13 @@ fn functions_are_sized() { goal { fn(()): Sized } yields { - "Unique; substitution [], lifetime constraints []" + expect![["Unique"]] } goal { fn([u8]): Sized } yields { - "Unique; substitution [], lifetime constraints []" + expect![["Unique"]] } } } @@ -33,13 +33,13 @@ fn functions_are_copy() { goal { fn(()): Copy } yields { - "Unique; substitution [], lifetime constraints []" + expect![["Unique"]] } goal { fn([u8]): Copy } yields { - "Unique; substitution [], lifetime constraints []" + expect![["Unique"]] } } } @@ -73,40 +73,40 @@ fn function_implement_fn_traits() { goal { fn(u8): FnOnce<(u8,)> } yields { - "Unique; substitution [], lifetime constraints []" + expect![["Unique"]] } // Same as above, but for FnMut goal { fn(u8): FnMut<(u8,)> } yields { - "Unique; substitution [], lifetime constraints []" + expect![["Unique"]] } // Same as above, but for Fn goal { fn(u8): Fn<(u8,)> } yields { - "Unique; substitution [], lifetime constraints []" + expect![["Unique"]] } // Make sure unsafe function pointers don't implement FnOnce goal { unsafe fn(u8): FnOnce<(u8,)> } yields { - "No possible solution" + expect![["No possible solution"]] } // Same as above but for FnMut goal { unsafe fn(u8): FnMut<(u8,)> } yields { - "No possible solution" + expect![["No possible solution"]] } // Same as above but for Fn goal { unsafe fn(u8): Fn<(u8,)> } yields { - "No possible solution" + expect![["No possible solution"]] } // Function pointres implicity return `()` when no return @@ -115,14 +115,14 @@ fn function_implement_fn_traits() { goal { Normalize(>::Output -> ()) } yields { - "Unique; substitution [], lifetime constraints []" + expect![["Unique"]] } // Tests normalizing when an explicit return type is used goal { Normalize( bool as FnOnce<(u8,)>>::Output -> bool) } yields { - "Unique; substitution [], lifetime constraints []" + expect![["Unique"]] } // Tests that we fail to normalize when there's a mismatch with @@ -130,7 +130,7 @@ fn function_implement_fn_traits() { goal { Normalize( bool as FnOnce<(u8,)>>::Output -> u8) } yields { - "No possible solution" + expect![["No possible solution"]] } // Ensures that we don't find a solution when doing so would @@ -141,7 +141,7 @@ fn function_implement_fn_traits() { Normalize( T as FnOnce<(u8, V)>>::Output -> V) } } yields { - "No possible solution" + expect![["No possible solution"]] } // Tests that we can normalize a generic function pointer type @@ -152,7 +152,7 @@ fn function_implement_fn_traits() { } } } yields { - "Unique; substitution [?0 := !1_0], lifetime constraints []" + expect![["Unique; substitution [?0 := !1_0]"]] } // Tests that we properly tuple function arguments when constrcting @@ -160,7 +160,7 @@ fn function_implement_fn_traits() { goal { fn(u8, u32): FnOnce<(u8,u32)> } yields { - "Unique; substitution [], lifetime constraints []" + expect![["Unique"]] } // Tests that we don't find a solution when fully monomorphic @@ -168,7 +168,7 @@ fn function_implement_fn_traits() { goal { fn(i32): FnOnce<(bool,)> } yields { - "No possible solution" + expect![["No possible solution"]] } // Tests function pointer types that use the function's binder @@ -179,7 +179,7 @@ fn function_implement_fn_traits() { for<'b> fn(&'b u8): FnOnce<(&'a u8,)> } } yields { - "Unique; substitution [], lifetime constraints []" + expect![["Unique"]] } // Tests that a 'stricter' function (requires lifetimes to be the same) @@ -191,7 +191,7 @@ fn function_implement_fn_traits() { for<'c> fn(&'c u8, &'c i32): FnOnce<(&'a u8, &'b i32)> } } yields { - "Unique; substitution [], lifetime constraints [InEnvironment { environment: Env([]), goal: '!1_0: '!1_1 }, InEnvironment { environment: Env([]), goal: '!1_1: '!1_0 }]" + expect![["Unique; lifetime constraints [InEnvironment { environment: Env([]), goal: '!1_0: '!1_1 }, InEnvironment { environment: Env([]), goal: '!1_1: '!1_0 }]"]] } // Tests the opposite case as the previous test: a 'less strict' function @@ -203,7 +203,7 @@ fn function_implement_fn_traits() { for<'b, 'c> fn(&'b u8, &'c i32): FnOnce<(&'a u8, &'a i32)> } } yields { - "Unique; substitution [], lifetime constraints []" + expect![["Unique"]] } // Similiar to the above test, but for types instead of lifetimes: @@ -215,7 +215,7 @@ fn function_implement_fn_traits() { fn(T, T): FnOnce<(T, U)> } } yields { - "No possible solution" + expect![["No possible solution"]] } // Tests the opposite case as a previous test: a 'less strict' @@ -226,7 +226,7 @@ fn function_implement_fn_traits() { fn(T, U): FnOnce<(T, T)> } } yields { - "No possible solution" + expect![["No possible solution"]] } // Tests that we flounder for inference variables @@ -235,14 +235,14 @@ fn function_implement_fn_traits() { T: FnOnce<()> } } yields_first[SolverChoice::slg(3, None)] { - "Floundered" + expect![["Floundered"]] } // No solution for alias type goal { MyOpaque: FnOnce<()> } yields { - "No possible solution" + expect![["No possible solution"]] } } } diff --git a/tests/test/generators.rs b/tests/test/generators.rs index 331b98fe8d4..3ba9a61b314 100644 --- a/tests/test/generators.rs +++ b/tests/test/generators.rs @@ -51,19 +51,19 @@ fn generator_test() { goal { WellFormed(empty_gen) } yields { - "Unique" + expect![["Unique"]] } goal { empty_gen: Send } yields { - "Unique" + expect![["Unique"]] } goal { empty_gen: Generator<()> } yields { - "Unique" + expect![["Unique"]] } goal { @@ -71,7 +71,7 @@ fn generator_test() { gen_with_types: Generator } } yields { - "Unique" + expect![["Unique"]] } goal { @@ -79,7 +79,7 @@ fn generator_test() { Normalize( as Generator>::Yield -> StructOne) } } yields { - "Unique" + expect![["Unique"]] } goal { @@ -87,7 +87,7 @@ fn generator_test() { Normalize( as Generator>::Return -> NotSend) } } yields { - "Unique" + expect![["Unique"]] } goal { @@ -95,7 +95,7 @@ fn generator_test() { upvar_lifetime_restrict: Send } } yields { - "No possible solution" + expect![["No possible solution"]] } goal { @@ -105,13 +105,13 @@ fn generator_test() { } } } yields { - "Unique; substitution [], lifetime constraints [InEnvironment { environment: Env([]), goal: '!2_0: '!2_1 }, InEnvironment { environment: Env([]), goal: '!2_1: '!2_0 }]" + expect![["Unique; lifetime constraints [InEnvironment { environment: Env([]), goal: '!2_0: '!2_1 }, InEnvironment { environment: Env([]), goal: '!2_1: '!2_0 }]"]] } goal { not_send_resume_yield: Send } yields { - "Unique; substitution [], lifetime constraints []" + expect![["Unique"]] } goal { @@ -121,7 +121,7 @@ fn generator_test() { } } } yields { - "Unique; substitution [], lifetime constraints []" + expect![["Unique"]] } goal { @@ -129,7 +129,7 @@ fn generator_test() { send_any_lifetime: Send } } yields { - "No possible solution" + expect![["No possible solution"]] } } } diff --git a/tests/test/implied_bounds.rs b/tests/test/implied_bounds.rs index bcecd00c7c5..a9f9a90a628 100644 --- a/tests/test/implied_bounds.rs +++ b/tests/test/implied_bounds.rs @@ -18,7 +18,7 @@ fn implied_bounds() { } } } yields { - "Unique; substitution []" + expect![["Unique"]] } } } @@ -39,7 +39,7 @@ fn gat_implied_bounds() { } } } yields { - "Unique; substitution []" + expect![["Unique"]] } } @@ -58,7 +58,7 @@ fn gat_implied_bounds() { } } } yields { - "No possible solution" + expect![["No possible solution"]] } } @@ -82,7 +82,7 @@ fn gat_implied_bounds() { } } } yields { - "Unique" + expect![["Unique"]] } } } @@ -102,7 +102,7 @@ fn implied_from_env() { } } } yields { - "Unique" + expect![["Unique"]] } goal { @@ -112,7 +112,7 @@ fn implied_from_env() { } } } yields { - "No possible solution" + expect![["No possible solution"]] } } } @@ -134,7 +134,7 @@ fn higher_ranked_implied_bounds() { } } } yields { - "Unique" + expect![["Unique"]] } } @@ -153,7 +153,7 @@ fn higher_ranked_implied_bounds() { } } } yields { - "Unique" + expect![["Unique"]] } } } diff --git a/tests/test/impls.rs b/tests/test/impls.rs index 29bd458a98c..5576c1d5900 100644 --- a/tests/test/impls.rs +++ b/tests/test/impls.rs @@ -18,25 +18,25 @@ fn prove_clone() { goal { Vec: Clone } yields { - "Unique; substitution [], lifetime constraints []" + expect![["Unique"]] } goal { Foo: Clone } yields { - "Unique; substitution [], lifetime constraints []" + expect![["Unique"]] } goal { Bar: Clone } yields { - "No possible solution" + expect![["No possible solution"]] } goal { Vec: Clone } yields { - "No possible solution" + expect![["No possible solution"]] } } } @@ -61,19 +61,19 @@ fn prove_infer() { goal { exists { A: Map } } yields { - "Ambiguous; no inference guidance" + expect![["Ambiguous; no inference guidance"]] } goal { exists { A: Map } } yields { - "Unique; substitution [?0 := Foo], lifetime constraints []" + expect![["Unique; substitution [?0 := Foo]"]] } goal { exists { Foo: Map } } yields { - "Unique; substitution [?0 := Bar], lifetime constraints []" + expect![["Unique; substitution [?0 := Bar]"]] } } } @@ -105,26 +105,26 @@ fn prove_forall() { goal { forall { T: Marker } } yields { - "No possible solution" + expect![["No possible solution"]] } goal { forall { not { T: Marker } } } yields { - "No" + expect![["No possible solution"]] } goal { not { forall { T: Marker } } } yields { - "Unique" + expect![["Unique"]] } // If we assume `T: Marker`, then obviously `T: Marker`. goal { forall { if (T: Marker) { T: Marker } } } yields { - "Unique; substitution [], lifetime constraints []" + expect![["Unique"]] } // We don't have to know anything about `T` to know that @@ -132,7 +132,7 @@ fn prove_forall() { goal { forall { Vec: Marker } } yields { - "Unique; substitution [], lifetime constraints []" + expect![["Unique"]] } // Here, we don't know that `T: Clone`, so we can't prove that @@ -140,7 +140,7 @@ fn prove_forall() { goal { forall { Vec: Clone } } yields { - "No possible solution" + expect![["No possible solution"]] } // Here, we do know that `T: Clone`, so we can. @@ -151,7 +151,7 @@ fn prove_forall() { } } } yields { - "Unique; substitution [], lifetime constraints []" + expect![["Unique"]] } } } @@ -173,7 +173,7 @@ fn higher_ranked() { } } } yields { - "Unique; substitution [?0 := BestType], lifetime constraints []" + expect![["Unique; substitution [?0 := BestType]"]] } } } @@ -193,7 +193,7 @@ fn ordering() { } } } yields { - "No possible solution" + expect![["No possible solution"]] } } } @@ -216,7 +216,7 @@ fn normalize_rev_infer() { T: Identity } } yields { - "Unique; substitution [?0 := A]" + expect![["Unique; substitution [?0 := A]"]] } } } @@ -241,7 +241,7 @@ fn normalize_rev_infer_gat() { } } yields { // T is ?1 and U is ?0, so this is surprising, but correct! (See #126.) - "Unique; substitution [?0 := B, ?1 := A]" + expect![["Unique; substitution [?0 := B, ?1 := A]"]] } } } @@ -262,19 +262,19 @@ fn generic_trait() { goal { Int: Eq } yields { - "Unique; substitution [], lifetime constraints []" + expect![["Unique"]] } goal { Uint: Eq } yields { - "Unique; substitution [], lifetime constraints []" + expect![["Unique"]] } goal { Int: Eq } yields { - "No possible solution" + expect![["No possible solution"]] } } } @@ -295,13 +295,13 @@ fn deep_failure() { goal { exists { T: Baz } } yields { - "No possible solution" + expect![["No possible solution"]] } goal { exists { Foo: Bar } } yields { - "No possible solution" + expect![["No possible solution"]] } } } @@ -324,7 +324,7 @@ fn deep_success() { goal { exists { Foo: Bar } } yields { - "Unique; substitution [?0 := ImplsBaz]" + expect![["Unique; substitution [?0 := ImplsBaz]"]] } } } @@ -350,7 +350,7 @@ fn definite_guidance() { T: Debug } } yields { - "Ambiguous; definite substitution for { [?0 := Foo<^0.0>] }" + expect![["Ambiguous; definite substitution for { [?0 := Foo<^0.0>] }"]] } } } @@ -374,7 +374,7 @@ fn suggested_subst() { Foo: SomeTrait } } yields { - "Unique; substitution [?0 := Baz]" + expect![["Unique; substitution [?0 := Baz]"]] } goal { @@ -384,7 +384,7 @@ fn suggested_subst() { } } } yields { - "Unique; substitution [?0 := Qux]" + expect![["Unique; substitution [?0 := Qux]"]] } goal { @@ -394,7 +394,7 @@ fn suggested_subst() { } } } yields { - "Unique; substitution [?0 := Baz]" + expect![["Unique; substitution [?0 := Baz]"]] } goal { @@ -404,7 +404,7 @@ fn suggested_subst() { } } } yields { - "Unique; substitution [?0 := Baz]" + expect![["Unique; substitution [?0 := Baz]"]] } goal { @@ -416,7 +416,7 @@ fn suggested_subst() { } yields { // FIXME: we need to rework the "favor environment" heuristic. // Should be: "Ambiguous; suggested substitution [?0 := bool]" - "Ambiguous; no inference guidance" + expect![["Ambiguous; no inference guidance"]] } goal { @@ -428,7 +428,7 @@ fn suggested_subst() { } } } yields { - "Ambiguous; no inference guidance" + expect![["Ambiguous; no inference guidance"]] } goal { @@ -436,7 +436,7 @@ fn suggested_subst() { Bar: SomeTrait } } yields { - "Ambiguous; no inference guidance" + expect![["Ambiguous; no inference guidance"]] } goal { @@ -446,8 +446,8 @@ fn suggested_subst() { } } } yields { - // FIXME: same as above, should be: "Ambiguous; suggested substitution [?0 := bool]" - "Ambiguous; no inference guidance" + // FIXME: same as above, should be: expect![["Ambiguous; suggested substitution [?0 := bool]"]] + expect![["Ambiguous; no inference guidance"]] } goal { @@ -459,7 +459,7 @@ fn suggested_subst() { } } } yields { - "Ambiguous; no inference guidance" + expect![["Ambiguous; no inference guidance"]] } } } @@ -481,7 +481,7 @@ fn where_clause_trumps() { } } } yields { - "Unique" + expect![["Unique"]] } } } @@ -507,7 +507,7 @@ fn inapplicable_assumption_does_not_shadow() { } } } yields { - "Unique" + expect![["Unique; substitution [?0 := A]"]] } } } @@ -534,7 +534,7 @@ fn partial_overlap_2() { } } } yields { - "Ambiguous" + expect![["Ambiguous; no inference guidance"]] } goal { @@ -544,7 +544,7 @@ fn partial_overlap_2() { } } } yields { - "Unique" + expect![["Unique"]] } goal { @@ -554,7 +554,7 @@ fn partial_overlap_2() { } } } yields { - "Unique" + expect![["Unique"]] } } } @@ -580,13 +580,13 @@ fn partial_overlap_3() { if (T: Foo; T: Bar) { T: Marker } } } yields { - "Unique" + expect![["Unique"]] } goal { Struct: Marker } yields { - "Unique" + expect![["Unique"]] } } } @@ -605,7 +605,7 @@ fn clauses_in_if_goals() { forall { T: Foo } } } yields { - "Unique" + expect![["Unique"]] } goal { @@ -617,7 +617,7 @@ fn clauses_in_if_goals() { } } } yields { - "Unique" + expect![["Unique"]] } goal { @@ -627,7 +627,7 @@ fn clauses_in_if_goals() { } } } yields { - "Unique" + expect![["Unique"]] } goal { @@ -635,7 +635,7 @@ fn clauses_in_if_goals() { Vec: Foo } } yields { - "No possible solution" + expect![["No possible solution"]] } } } @@ -654,7 +654,7 @@ fn unify_types_in_ambiguous_impl() { goal { exists { A: Trait } } yields { - "Ambiguous; definite substitution for { [?0 := ^0.0, ?1 := ^0.0] }" + expect![["Ambiguous; definite substitution for { [?0 := ^0.0, ?1 := ^0.0] }"]] } } } @@ -673,7 +673,7 @@ fn unify_types_in_impl() { goal { exists { A: Trait } } yields { - "Unique; for { substitution [?0 := ^0.0, ?1 := ^0.0], lifetime constraints [] }" + expect![["Unique; for { substitution [?0 := ^0.0, ?1 := ^0.0] }"]] } } } diff --git a/tests/test/lifetimes.rs b/tests/test/lifetimes.rs index 422db6613af..0d91a2a3599 100644 --- a/tests/test/lifetimes.rs +++ b/tests/test/lifetimes.rs @@ -50,7 +50,7 @@ fn static_outlives() { Bar: Foo<'a> } } yields { - "Unique; for { substitution [?0 := '^0.0], lifetime constraints [InEnvironment { environment: Env([]), goal: '^0.0: 'static }] }" + expect![["Unique; for { substitution [?0 := '^0.0], lifetime constraints [InEnvironment { environment: Env([]), goal: '^0.0: 'static }] }"]] } goal { @@ -58,7 +58,7 @@ fn static_outlives() { Bar: Foo<'a> } } yields { - "Unique; substitution [], lifetime constraints [InEnvironment { environment: Env([]), goal: '!1_0: 'static }]" + expect![["Unique; lifetime constraints [InEnvironment { environment: Env([]), goal: '!1_0: 'static }]"]] } } } @@ -78,7 +78,7 @@ fn empty_outlives() { Bar: Foo<'a> } } yields { - "Unique; for { substitution [?0 := '^0.0], lifetime constraints [InEnvironment { environment: Env([]), goal: '^0.0: ' }] }" + expect![["Unique; for { substitution [?0 := '^0.0], lifetime constraints [InEnvironment { environment: Env([]), goal: '^0.0: ' }] }"]] } goal { @@ -86,7 +86,7 @@ fn empty_outlives() { Bar: Foo<'a> } } yields { - "Unique; substitution [], lifetime constraints [InEnvironment { environment: Env([]), goal: '!1_0: ' }]" + expect![["Unique; lifetime constraints [InEnvironment { environment: Env([]), goal: '!1_0: ' }]"]] } } } @@ -106,7 +106,7 @@ fn erased_outlives() { Bar: Foo<'a> } } yields { - "Unique; for { substitution [?0 := '^0.0], lifetime constraints [InEnvironment { environment: Env([]), goal: '^0.0: ' }] }" + expect![["Unique; for { substitution [?0 := '^0.0], lifetime constraints [InEnvironment { environment: Env([]), goal: '^0.0: ' }] }"]] } goal { @@ -114,7 +114,7 @@ fn erased_outlives() { Bar: Foo<'a> } } yields { - "Unique; substitution [], lifetime constraints [InEnvironment { environment: Env([]), goal: '!1_0: ' }]" + expect![["Unique; lifetime constraints [InEnvironment { environment: Env([]), goal: '!1_0: ' }]"]] } } } @@ -131,19 +131,19 @@ fn static_impls() { goal { &'static Foo: Bar } yields { - "Unique; substitution [], lifetime constraints []" + expect![["Unique"]] } goal { forall<'a> { &'a Foo: Bar } } yields { - "Unique; substitution [], lifetime constraints []" + expect![["Unique"]] } goal { exists<'a> { &'a Foo: Bar } } yields { - "Unique; for { substitution [?0 := '^0.0], lifetime constraints [] }" + expect![["Unique; for { substitution [?0 := '^0.0] }"]] } } } @@ -160,7 +160,7 @@ fn erased_impls() { goal { &'erased Foo: Bar } yields { - "Unique; substitution [], lifetime constraints []" + expect![["Unique"]] } } } @@ -177,7 +177,7 @@ fn empty_impls() { goal { &'empty Foo: Bar } yields { - "Unique; substitution [], lifetime constraints []" + expect![["Unique"]] } } } diff --git a/tests/test/misc.rs b/tests/test/misc.rs index 0388bf58865..1efe8d46b4c 100644 --- a/tests/test/misc.rs +++ b/tests/test/misc.rs @@ -36,7 +36,7 @@ fn futures_ambiguity() { goal { forall { if (T: FutureResult) { exists { T: Future> } } } } yields { - r"Unique; substitution [?0 := (FutureResult::Item), ?1 := (FutureResult::Error)], lifetime constraints []" + expect![["Unique; substitution [?0 := (FutureResult::Item), ?1 := (FutureResult::Error)]"]] } } } @@ -54,7 +54,7 @@ fn basic() { goal { forall { if (T: Sized) { T: Sized } } } yields_all[SolverChoice::slg(10, None)] { - "substitution [], lifetime constraints []" + expect![[""]] } } } @@ -73,7 +73,7 @@ fn subgoal_abstraction() { goal { exists { T: Foo } } yields_first[SolverChoice::slg(50, None)] { - "Floundered" + expect![["Floundered"]] } } } @@ -91,7 +91,7 @@ fn flounder() { goal { exists { not { T: A } } } yields_first[SolverChoice::slg(10, None)] { - "Floundered" + expect![["Floundered"]] } } } @@ -119,19 +119,19 @@ fn only_draw_so_many() { goal { exists { T: Sized } } yields_first[SolverChoice::slg(10, None)] { - "substitution [?0 := Foo], lifetime constraints []", - "substitution [?0 := Slice], lifetime constraints []", - "substitution [?0 := Vec], lifetime constraints []", - "substitution [?0 := Slice>], lifetime constraints []", - "substitution [?0 := Vec>], lifetime constraints []" + expect![["substitution [?0 := Foo]"]], + expect![["substitution [?0 := Slice]"]], + expect![["substitution [?0 := Vec]"]], + expect![["substitution [?0 := Slice>]"]], + expect![["substitution [?0 := Vec>]"]] } goal { exists { T: Sized } } yields[SolverChoice::slg(10, Some(2))] { - "Ambiguous; no inference guidance" + expect![["Ambiguous; no inference guidance"]] } yields[SolverChoice::recursive_default()] { - "Ambiguous; no inference guidance" + expect![["Ambiguous; no inference guidance"]] } } } @@ -157,9 +157,9 @@ fn only_draw_so_many_blow_up() { goal { exists { T: Foo } } yields[SolverChoice::slg(10, Some(2))] { - "Ambiguous; definite substitution for { [?0 := Vec<^0.0>] }" + expect![["Ambiguous; definite substitution for { [?0 := Vec<^0.0>] }"]] } yields[SolverChoice::recursive_default()] { - "Ambiguous; definite substitution for { [?0 := Vec<^0.0>] }" + expect![["Ambiguous; definite substitution for { [?0 := Vec<^0.0>] }"]] } } } @@ -180,21 +180,21 @@ fn subgoal_cycle_uninhabited() { goal { exists { T: Foo } } yields_first[SolverChoice::slg(2, None)] { - "Ambiguous(for { substitution [?0 := Box<^0.0>], lifetime constraints [] })" + expect![["Ambiguous(for { substitution [?0 := Box<^0.0>] })"]] } // Unsurprisingly, applying negation also flounders. goal { not { exists { T: Foo } } } yields_first[SolverChoice::slg(2, None)] { - "Floundered" + expect![["Floundered"]] } // Equivalent to the previous. goal { forall { not { T: Foo } } } yields_first[SolverChoice::slg(2, None)] { - "Floundered" + expect![["Floundered"]] } // However, if we come across a negative goal that exceeds our @@ -202,22 +202,22 @@ fn subgoal_cycle_uninhabited() { goal { exists { T = Vec, not { Vec>: Foo } } } yields_first[SolverChoice::slg(2, None)] { - "Ambiguous(substitution [?0 := Vec], lifetime constraints [])" + expect![["Ambiguous(substitution [?0 := Vec])"]] } // Same query with larger threshold works fine, though. goal { exists { T = Vec, not { Vec>: Foo } } } yields_all[SolverChoice::slg(4, None)] { - "substitution [?0 := Vec], lifetime constraints []" + expect![["substitution [?0 := Vec]"]] } // Here, due to the hypothesis, there does indeed exist a suitable T, `U`. goal { forall { if (U: Foo) { exists { T: Foo } } } } yields_first[SolverChoice::slg(2, None)] { - "substitution [?0 := !1_0], lifetime constraints []", - "Ambiguous(for { substitution [?0 := Box<^0.0>], lifetime constraints [] })" + expect![["substitution [?0 := !1_0]"]], + expect![["Ambiguous(for { substitution [?0 := Box<^0.0>] })"]] } } } @@ -239,8 +239,8 @@ fn subgoal_cycle_inhabited() { goal { exists { T: Foo } } yields_first[SolverChoice::slg(3, None)] { - "substitution [?0 := Alice], lifetime constraints []", - "Ambiguous(for { substitution [?0 := Box<^0.0>], lifetime constraints [] })" + expect![["substitution [?0 := Alice]"]], + expect![["Ambiguous(for { substitution [?0 := Box<^0.0>] })"]] } } } @@ -258,10 +258,7 @@ fn basic_region_constraint_from_positive_impl() { goal { forall<'a, 'b, T> { Ref<'a, 'b, T>: Foo } } yields_all[SolverChoice::slg(3, None)] { - "substitution [], lifetime constraints [\ - InEnvironment { environment: Env([]), goal: '!1_0: '!1_1 }, \ - InEnvironment { environment: Env([]), goal: '!1_1: '!1_0 } \ - ]" + expect![["lifetime constraints [InEnvironment { environment: Env([]), goal: '!1_0: '!1_1 }, InEnvironment { environment: Env([]), goal: '!1_1: '!1_0 }]"]] } } } @@ -287,9 +284,9 @@ fn example_2_1_EWFS() { goal { exists { a: TransitiveClosure } } yields_all[SolverChoice::slg(3, None)] { - "substitution [?0 := b], lifetime constraints []", - "substitution [?0 := c], lifetime constraints []", - "substitution [?0 := a], lifetime constraints []" + expect![["substitution [?0 := b]"]], + expect![["substitution [?0 := c]"]], + expect![["substitution [?0 := a]"]] } } } @@ -323,11 +320,11 @@ fn cached_answers_1() { goal { exists { T: Sour } } yields_first[SolverChoice::slg(2, None)] { - "substitution [?0 := Lemon], lifetime constraints []", - "substitution [?0 := Vinegar], lifetime constraints []", - "substitution [?0 := HotSauce], lifetime constraints []", - "substitution [?0 := HotSauce], lifetime constraints []", - "Floundered" + expect![["substitution [?0 := Lemon]"]], + expect![["substitution [?0 := Vinegar]"]], + expect![["substitution [?0 := HotSauce]"]], + expect![["substitution [?0 := HotSauce]"]], + expect![["Floundered"]] } } } @@ -350,11 +347,11 @@ fn cached_answers_2() { goal { exists { T: Sour } } yields_first[SolverChoice::slg(2, None)] { - "substitution [?0 := Lemon], lifetime constraints []", - "substitution [?0 := Vinegar], lifetime constraints []", - "substitution [?0 := HotSauce], lifetime constraints []", - "substitution [?0 := HotSauce], lifetime constraints []", - "Floundered" + expect![["substitution [?0 := Lemon]"]], + expect![["substitution [?0 := Vinegar]"]], + expect![["substitution [?0 := HotSauce]"]], + expect![["substitution [?0 := HotSauce]"]], + expect![["Floundered"]] } } } @@ -377,10 +374,10 @@ fn cached_answers_3() { goal { exists { T: Sour } } yields_first[SolverChoice::slg(2, None)] { - "substitution [?0 := Lemon], lifetime constraints []", - "substitution [?0 := HotSauce], lifetime constraints []", - "substitution [?0 := Vinegar], lifetime constraints []", - "Floundered" + expect![["substitution [?0 := Lemon]"]], + expect![["substitution [?0 := HotSauce]"]], + expect![["substitution [?0 := Vinegar]"]], + expect![["Floundered"]] } } } @@ -405,20 +402,20 @@ fn non_enumerable_traits_direct() { goal { exists { A: NonEnumerable } } yields_first[SolverChoice::slg(3, None)] { - "Floundered" + expect![["Floundered"]] } goal { exists { A: Enumerable } } yields_all[SolverChoice::slg(3, None)] { - "substitution [?0 := Foo], lifetime constraints []", - "substitution [?0 := Bar], lifetime constraints []" + expect![["substitution [?0 := Foo]"]], + expect![["substitution [?0 := Bar]"]] } goal { Foo: NonEnumerable } yields_all[SolverChoice::slg(3, None)] { - "substitution [], lifetime constraints []" + expect![[""]] } } } @@ -442,7 +439,7 @@ fn non_enumerable_traits_indirect() { goal { exists { A: Debug } } yields_first[SolverChoice::slg(3, None)] { - "Floundered" + expect![["Floundered"]] } } } @@ -471,7 +468,7 @@ fn non_enumerable_traits_double() { goal { exists { A: Debug } } yields_first[SolverChoice::slg(3, None)] { - "Floundered" + expect![["Floundered"]] } } } @@ -506,14 +503,14 @@ fn non_enumerable_traits_reorder() { goal { exists { A: Debug1 } } yields_all[SolverChoice::slg(3, None)] { - "substitution [?0 := Foo], lifetime constraints []" + expect![["substitution [?0 := Foo]"]] } goal { exists { A: Debug2 } } yields_all[SolverChoice::slg(3, None)] { - "substitution [?0 := Foo], lifetime constraints []" + expect![["substitution [?0 := Foo]"]] } } } @@ -538,19 +535,19 @@ fn builtin_impl_enumeration() { goal { exists { T: Copy } } yields { - "Ambiguous; no inference guidance" + expect![["Ambiguous; no inference guidance"]] } goal { exists { T: Clone } } yields { - "Ambiguous; no inference guidance" + expect![["Ambiguous; no inference guidance"]] } goal { exists { T: Sized } } yields { - "Ambiguous; no inference guidance" + expect![["Ambiguous; no inference guidance"]] } } } @@ -574,7 +571,7 @@ fn flounder_ambiguous() { goal { exists { Ref: IntoIterator } } yields { - "Ambiguous; no inference guidance" + expect![["Ambiguous; no inference guidance"]] } } } @@ -605,7 +602,7 @@ fn normalize_ambiguous() { Normalize( as IntoIterator>::Item -> U) } } yields { - "Ambiguous; no inference guidance" + expect![["Ambiguous; no inference guidance"]] } } } @@ -625,7 +622,7 @@ fn lifetime_outlives_constraints() { Bar: Foo<'a, 'b> } } yields { - "Unique; for { substitution [?0 := '^0.0, ?1 := '^0.1], lifetime constraints [InEnvironment { environment: Env([]), goal: '^0.0: '^0.1 }] }" + expect![["Unique; for { substitution [?0 := '^0.0, ?1 := '^0.1], lifetime constraints [InEnvironment { environment: Env([]), goal: '^0.0: '^0.1 }] }"]] } goal { @@ -635,7 +632,7 @@ fn lifetime_outlives_constraints() { } } } yields { - "Unique; for { substitution [?0 := '^0.0], lifetime constraints [InEnvironment { environment: Env([]), goal: '!1_0: '^0.0 }] }" + expect![["Unique; for { substitution [?0 := '^0.0], lifetime constraints [InEnvironment { environment: Env([]), goal: '!1_0: '^0.0 }] }"]] } } } @@ -654,7 +651,7 @@ fn type_outlives_constraints() { Bar: Foo<'a, T> } } yields { - "Unique; for { substitution [?0 := '^0.0, ?1 := ^0.1], lifetime constraints [InEnvironment { environment: Env([]), goal: ^0.1: '^0.0 }] }" + expect![["Unique; for { substitution [?0 := '^0.0, ?1 := ^0.1], lifetime constraints [InEnvironment { environment: Env([]), goal: ^0.1: '^0.0 }] }"]] } goal { @@ -664,7 +661,7 @@ fn type_outlives_constraints() { } } } yields { - "Unique; for { substitution [?0 := '^0.0], lifetime constraints [InEnvironment { environment: Env([]), goal: !1_0: '^0.0 }] }" + expect![["Unique; for { substitution [?0 := '^0.0], lifetime constraints [InEnvironment { environment: Env([]), goal: !1_0: '^0.0 }] }"]] } } } @@ -692,9 +689,9 @@ fn not_really_ambig() { goal { exists { Vec: A } } yields[SolverChoice::slg_default()] { - "Unique; substitution [?0 := Uint(U32)], lifetime constraints []" + expect![["Unique; substitution [?0 := Uint(U32)]"]] } yields[SolverChoice::recursive_default()] { - "Ambiguous; no inference guidance" + expect![["Ambiguous; no inference guidance"]] } } } @@ -720,7 +717,7 @@ fn canonicalization_regression() { } } } yields { - "Unique; substitution [?0 := !2_0], lifetime constraints []" + expect![["Unique; substitution [?0 := !2_0]"]] } } } @@ -750,9 +747,9 @@ fn empty_definite_guidance() { // isn't that important -- this is mainly a regression test for a // recursive solver infinite loop. } yields[SolverChoice::slg_default()] { - "Unique" + expect![["Unique"]] } yields[SolverChoice::recursive_default()] { - "Ambiguous" + expect![["Ambiguous; suggested substitution []"]] } } } @@ -774,8 +771,10 @@ fn ambiguous_unification_in_fn() { exists { MyClosure ()>: FnOnce<(&'static T,)> } - } yields { - "Unique" + } yields[SolverChoice::slg_default()] { + expect![["Unique; for { substitution [?0 := ^0.0, ?1 := ^0.0], lifetime constraints [InEnvironment { environment: Env([]), goal: 'static: 'static }, InEnvironment { environment: Env([]), goal: 'static: 'static }] }"]] + } yields[SolverChoice::recursive_default()] { + expect![["Unique; for { substitution [?0 := ^0.0, ?1 := ^0.0], lifetime constraints [InEnvironment { environment: Env([]), goal: 'static: 'static }] }"]] } } } @@ -799,7 +798,7 @@ fn endless_loop() { T> as FnOnce>::Output = T } } yields { - "Unique; for { substitution [?0 := ^0.0], lifetime constraints [] }" + expect![["Unique; for { substitution [?0 := ^0.0] }"]] } } } @@ -814,7 +813,7 @@ fn env_bound_vars() { } } } yields { - "Ambiguous; definite substitution for { [?0 := '^0.0] }" + expect![["Ambiguous; definite substitution for { [?0 := '^0.0] }"]] } goal { exists<'a> { @@ -823,7 +822,7 @@ fn env_bound_vars() { } } } yields { - "Unique" + expect![["Unique; for { substitution [?0 := '^0.0], lifetime constraints [InEnvironment { environment: Env([]), goal: 0: '^0.0 }] }"]] } } } diff --git a/tests/test/mod.rs b/tests/test/mod.rs index 4a0b1e80e84..23d5c2d6f9e 100644 --- a/tests/test/mod.rs +++ b/tests/test/mod.rs @@ -1,5 +1,10 @@ #![allow(non_snake_case)] +use std::sync::Arc; + +use chalk_integration::program::Program; +use expect_test::{expect, Expect}; + use crate::test_util::assert_same; use chalk_integration::db::ChalkDatabase; use chalk_integration::interner::ChalkIr; @@ -17,7 +22,7 @@ mod bench; mod coherence; mod wf_lowering; -pub fn assert_result(mut result: Option>, expected: &str, interner: ChalkIr) { +fn format_solution(mut result: Option>, interner: ChalkIr) -> String { // sort constraints, since the different solvers may output them in different order match &mut result { Some(Solution::Unique(solution)) => { @@ -27,23 +32,31 @@ pub fn assert_result(mut result: Option>, expected: &str, inte } _ => {} } - let result = match result { + match result { Some(v) => format!("{}", v.display(ChalkIr)), None => format!("No possible solution"), - }; + } +} +pub fn assert_result(result: Option>, expected: &Expect, interner: ChalkIr) { + let result = format_solution(result, interner); + expected.assert_eq(&result); +} + +pub fn assert_result_str(result: Option>, expected: &str, interner: ChalkIr) { + let result = format_solution(result, interner); assert_same(&result, expected); } // different goals #[derive(Clone)] -pub enum TestGoal { +pub enum TestGoal { // solver should produce same aggregated single solution - Aggregated(&'static str), + Aggregated(T), // solver should produce exactly multiple solutions - All(Vec<&'static str>), + All(Vec), // solver should produce first same multiple solutions - First(Vec<&'static str>), + First(Vec), } macro_rules! test { @@ -81,8 +94,7 @@ macro_rules! parse_test_data { parse_test_data!(@program[$program] @parsed_goals[ $($parsed_goals)* - (stringify!($goal), SolverChoice::slg_default(), TestGoal::Aggregated($expected)) - (stringify!($goal), SolverChoice::recursive_default(), TestGoal::Aggregated($expected)) + (stringify!($goal), vec![SolverChoice::slg_default(), SolverChoice::recursive_default()], TestGoal::Aggregated($expected)) ] @unparsed_goals[$($unparsed_goals)*]) }; @@ -97,7 +109,7 @@ macro_rules! parse_test_data { parse_test_data!(@program[$program] @parsed_goals[ $($parsed_goals)* - (stringify!($goal), SolverChoice::slg_default(), TestGoal::All(vec![$($expected),*])) + (stringify!($goal), vec![SolverChoice::slg_default()], TestGoal::All(vec![$($expected),*])) ] @unparsed_goals[$($unparsed_goals)*]) }; @@ -111,7 +123,7 @@ macro_rules! parse_test_data { parse_test_data!(@program[$program] @parsed_goals[ $($parsed_goals)* - (stringify!($goal), SolverChoice::default(), TestGoal::First(vec![$($expected),*])) + (stringify!($goal), vec![SolverChoice::default()], TestGoal::First(vec![$($expected),*])) ] @unparsed_goals[$($unparsed_goals)*]) }; @@ -130,7 +142,7 @@ macro_rules! parse_test_data { parse_test_data!(@program[$program] @parsed_goals[ $($parsed_goals)* - (stringify!($goal), $C, TestGoal::Aggregated($expected)) + (stringify!($goal), vec![$C], TestGoal::Aggregated($expected)) ] @unparsed_goals[goal $($unparsed_goals)*]) }; @@ -144,7 +156,7 @@ macro_rules! parse_test_data { parse_test_data!(@program[$program] @parsed_goals[ $($parsed_goals)* - (stringify!($goal), $C, TestGoal::Aggregated($expected)) + (stringify!($goal), vec![$C], TestGoal::Aggregated($expected)) ] @unparsed_goals[goal $goal yields $($unparsed_tail)*]) }; @@ -156,7 +168,7 @@ macro_rules! parse_test_data { parse_test_data!(@program[$program] @parsed_goals[ $($parsed_goals)* - (stringify!($goal), $C, TestGoal::Aggregated($expected)) + (stringify!($goal), vec![$C], TestGoal::Aggregated($expected)) ] @unparsed_goals[]) }; @@ -175,7 +187,7 @@ macro_rules! parse_test_data { parse_test_data!(@program[$program] @parsed_goals[ $($parsed_goals)* - (stringify!($goal), $C, TestGoal::All(vec![$($expected),*])) + (stringify!($goal), vec![$C], TestGoal::All(vec![$($expected),*])) ] @unparsed_goals[goal $($unparsed_goals)*]) }; @@ -187,7 +199,7 @@ macro_rules! parse_test_data { parse_test_data!(@program[$program] @parsed_goals[ $($parsed_goals)* - (stringify!($goal), $C, TestGoal::All(vec![$($expected),*])) + (stringify!($goal), vec![$C], TestGoal::All(vec![$($expected),*])) ] @unparsed_goals[]) }; @@ -206,7 +218,7 @@ macro_rules! parse_test_data { parse_test_data!(@program[$program] @parsed_goals[ $($parsed_goals)* - (stringify!($goal), $C, TestGoal::First(vec![$($expected),*])) + (stringify!($goal), vec![$C], TestGoal::First(vec![$($expected),*])) ] @unparsed_goals[goal $($unparsed_goals)*]) }; @@ -218,13 +230,17 @@ macro_rules! parse_test_data { parse_test_data!(@program[$program] @parsed_goals[ $($parsed_goals)* - (stringify!($goal), $C, TestGoal::First(vec![$($expected),*])) + (stringify!($goal), vec![$C], TestGoal::First(vec![$($expected),*])) ] @unparsed_goals[]) }; } -fn solve_goal(program_text: &str, goals: Vec<(&str, SolverChoice, TestGoal)>, coherence: bool) { +fn solve_goal( + program_text: &str, + goals: Vec<(&str, Vec, TestGoal)>, + coherence: bool, +) { with_tracing_logs(|| { println!("program {}", program_text); assert!(program_text.starts_with("{")); @@ -241,7 +257,28 @@ fn solve_goal(program_text: &str, goals: Vec<(&str, SolverChoice, TestGoal)>, co db.program_ir().unwrap() }; - for (goal_text, solver_choice, expected) in goals { + for (goal_text, solver_choices, expected) in goals { + let solver_choices = &*solver_choices; + let solver_choice = match solver_choices { + [] => panic!("No solvers?"), + [x] => *x, + _ => { + let expected = match expected { + TestGoal::Aggregated(x) => x, + _ => todo!("solver comparison only supported for `Aggregated` goals"), + }; + + solve_aggregated( + &mut db, + program.clone(), + goal_text, + solver_choices, + expected, + ); + continue; + } + }; + match (&solver_choice, &expected) { (SolverChoice::Recursive { .. }, TestGoal::All(_)) | (SolverChoice::Recursive { .. }, TestGoal::First(_)) => { @@ -267,7 +304,7 @@ fn solve_goal(program_text: &str, goals: Vec<(&str, SolverChoice, TestGoal)>, co println!("using solver: {:?}", solver_choice); let peeled_goal = goal.into_peeled_goal(db.interner()); - match expected { + match &expected { TestGoal::Aggregated(expected) => { let result = db.solve(&peeled_goal); assert_result(result, expected, db.interner()); @@ -278,13 +315,11 @@ fn solve_goal(program_text: &str, goals: Vec<(&str, SolverChoice, TestGoal)>, co db.solve_multiple(&peeled_goal, &mut |result, next_result| { match expected.next() { Some(expected) => { - assert_same( - &format!( - "{}", - result.as_ref().map(|v| v.display(ChalkIr)) - ), - expected, + let actual = format!( + "{}", + result.as_ref().map(|v| v.display(ChalkIr)) ); + expected.assert_eq(&actual) } None => { assert!(!next_result, "Unexpected next solution"); @@ -304,10 +339,9 @@ fn solve_goal(program_text: &str, goals: Vec<(&str, SolverChoice, TestGoal)>, co .next() { Some(solution) => { - assert_same( - &format!("{}", result.as_ref().map(|v| v.display(ChalkIr))), - solution, - ); + let actual = + format!("{}", result.as_ref().map(|v| v.display(ChalkIr))); + solution.assert_eq(&actual); if !next_result { assert!( expected.next().is_none(), @@ -326,6 +360,53 @@ fn solve_goal(program_text: &str, goals: Vec<(&str, SolverChoice, TestGoal)>, co }) } +fn solve_aggregated( + db: &mut ChalkDatabase, + program: Arc, + goal_text: &str, + choices: &[SolverChoice], + expected: Expect, +) { + let mut solutions = vec![]; + + for solver_choice in choices.iter().copied() { + if db.solver_choice() != solver_choice { + db.set_solver_choice(solver_choice); + } + + chalk_integration::tls::set_current_program(&program, || { + println!("----------------------------------------------------------------------"); + println!("goal {}", goal_text); + assert!(goal_text.starts_with("{")); + assert!(goal_text.ends_with("}")); + let goal = lower_goal( + &*chalk_parse::parse_goal(&goal_text[1..goal_text.len() - 1]).unwrap(), + &*program, + ) + .unwrap(); + + println!("using solver: {:?}", solver_choice); + let peeled_goal = goal.into_peeled_goal(db.interner()); + let result = db.solve(&peeled_goal); + solutions.push(format_solution(result, db.interner())); + }); + } + + let (head, tail) = solutions + .split_first() + .expect("Test requires at least one solver"); + for (i, other) in tail.iter().enumerate() { + println!( + "\ncomparing solvers:\n\tleft: {:?}\n\tright: {:?}\n", + &choices[0], + &choices[i + 1] + ); + assert_same(head, other); + } + + expected.assert_eq(head); +} + mod arrays; mod auto_traits; mod closures; diff --git a/tests/test/negation.rs b/tests/test/negation.rs index bd1a0b7461f..708b959bcc7 100644 --- a/tests/test/negation.rs +++ b/tests/test/negation.rs @@ -13,7 +13,7 @@ fn simple_negation() { goal { not { Bar: Foo } } yields { - "Unique" + expect![["Unique"]] } goal { @@ -21,7 +21,7 @@ fn simple_negation() { not { Bar: Foo } } } yields { - "No" + expect![["No possible solution"]] } goal { @@ -31,7 +31,7 @@ fn simple_negation() { } } } yields { - "Unique" + expect![["Unique"]] } goal { @@ -39,7 +39,7 @@ fn simple_negation() { not { T: Foo } } } yields { - "Ambig" + expect![["Ambiguous; no inference guidance"]] } goal { @@ -47,7 +47,7 @@ fn simple_negation() { not { T: Foo } } } yields { - "Unique" + expect![["Unique"]] } goal { @@ -55,7 +55,7 @@ fn simple_negation() { exists { T: Foo } } } yields { - "Unique" + expect![["Unique"]] } goal { @@ -63,7 +63,7 @@ fn simple_negation() { forall { T: Foo } } } yields { - "Unique" + expect![["Unique"]] } } } @@ -84,7 +84,7 @@ fn deep_negation() { exists { T: Baz } } } yields { - "Unique" + expect![["Unique"]] } goal { @@ -92,7 +92,7 @@ fn deep_negation() { exists { Foo: Bar } } } yields { - "Unique" + expect![["Unique"]] } } } @@ -112,7 +112,7 @@ fn negation_quantifiers() { } } } yields { - "Unique" + expect![["Unique"]] } goal { @@ -122,7 +122,7 @@ fn negation_quantifiers() { } } } yields { - "No" + expect![["No possible solution"]] } goal { @@ -132,7 +132,7 @@ fn negation_quantifiers() { } } } yields { - "No" + expect![["No possible solution"]] } } } @@ -153,7 +153,7 @@ fn negation_free_vars() { not { Vec: Foo } } } yields { - "Ambig" + expect![["Ambiguous; no inference guidance"]] } } } @@ -176,7 +176,7 @@ fn negative_loop() { Alice: P } yields_all[SolverChoice::slg(10, None)] { // Negative cycle -> panic - "" + expect![[""]] } } } @@ -204,7 +204,7 @@ fn example_2_2_EWFS() { goal { c: M } yields_all[SolverChoice::slg(3, None)] { - "substitution [], lifetime constraints []" + expect![[""]] } } } @@ -234,7 +234,7 @@ fn example_2_3_EWFS() { a: W } yields_all[SolverChoice::slg(3, None)] { // Negative cycle -> panic - "" + expect![[""]] } } } @@ -260,7 +260,7 @@ fn example_3_3_EWFS() { a: S } yields_all[SolverChoice::slg(3, None)] { // Negative cycle -> panic - "" + expect![[""]] } } } @@ -282,7 +282,7 @@ fn contradiction() { Alice: P } yields_all[SolverChoice::slg(3, None)] { // Negative cycle -> panic - "" + expect![[""]] } } } @@ -305,7 +305,7 @@ fn negative_answer_ambiguous() { Alice: P } yields_all[SolverChoice::slg(3, None)] { // Negative cycle -> panic - "" + expect![[""]] } } } @@ -343,14 +343,14 @@ fn negative_reorder() { goal { exists { A: Debug1 } } yields_all[SolverChoice::slg(3, None)] { - "substitution [?0 := Bar], lifetime constraints []" + expect![["substitution [?0 := Bar]"]] } goal { exists { A: Debug2 } } yields_all[SolverChoice::slg(3, None)] { - "substitution [?0 := Bar], lifetime constraints []" + expect![["substitution [?0 := Bar]"]] } } } diff --git a/tests/test/never.rs b/tests/test/never.rs index 3a78d441100..ffd39b57243 100644 --- a/tests/test/never.rs +++ b/tests/test/never.rs @@ -6,7 +6,7 @@ fn never_is_well_formed() { goal { WellFormed(!) } yields { - "Unique" + expect![["Unique"]] } } } @@ -21,7 +21,7 @@ fn never_is_sized() { goal { !: Sized } yields { - "Unique" + expect![["Unique"]] } } } diff --git a/tests/test/numerics.rs b/tests/test/numerics.rs index 42e938b1d90..688cb47ba02 100644 --- a/tests/test/numerics.rs +++ b/tests/test/numerics.rs @@ -28,7 +28,7 @@ fn integer_index() { Slice: Index } } yields { - "Unique; substitution [?0 := Uint(Usize)]" + expect![["Unique; substitution [?0 := Uint(Usize)]"]] } } } @@ -54,7 +54,7 @@ fn integer_kind_trait() { N: Foo } } yields { - "Unique; substitution [?0 := Uint(Usize)]" + expect![["Unique; substitution [?0 := Uint(Usize)]"]] } } } @@ -77,7 +77,7 @@ fn float_kind_trait() { N: Foo } } yields { - "Unique; substitution [?0 := Float(F32)]" + expect![["Unique; substitution [?0 := Float(F32)]"]] } } } @@ -98,7 +98,7 @@ fn integer_ambiguity() { N: Foo } } yields { - "Ambiguous; no inference guidance" + expect![["Ambiguous; no inference guidance"]] } } } @@ -119,7 +119,7 @@ fn float_ambiguity() { N: Foo } } yields { - "Ambiguous; no inference guidance" + expect![["Ambiguous; no inference guidance"]] } } } @@ -134,7 +134,7 @@ fn integer_and_float_are_specialized_ty_kinds() { T = N, N = usize } } yields { - "Unique; substitution [?0 := Uint(Usize), ?1 := Uint(Usize)], lifetime constraints []" + expect![["Unique; substitution [?0 := Uint(Usize), ?1 := Uint(Usize)]"]] } goal { @@ -142,7 +142,7 @@ fn integer_and_float_are_specialized_ty_kinds() { T = N, N = f32 } } yields { - "Unique; substitution [?0 := Float(F32), ?1 := Float(F32)], lifetime constraints []" + expect![["Unique; substitution [?0 := Float(F32), ?1 := Float(F32)]"]] } } } @@ -157,7 +157,7 @@ fn general_ty_kind_becomes_specific() { T = N, T = char } } yields { - "No possible solution" + expect![["No possible solution"]] } goal { @@ -165,7 +165,7 @@ fn general_ty_kind_becomes_specific() { T = N, T = char } } yields { - "No possible solution" + expect![["No possible solution"]] } } } @@ -179,7 +179,7 @@ fn integers_are_not_floats() { I = F } } yields { - "No possible solution" + expect![["No possible solution"]] } } } @@ -197,7 +197,7 @@ fn integers_are_copy() { I: Copy } } yields { - "Unique" + expect![["Unique; for { substitution [?0 := ^0.0] }"]] } } } @@ -215,7 +215,7 @@ fn integers_are_sized() { I: Sized } } yields { - "Unique" + expect![["Unique; for { substitution [?0 := ^0.0] }"]] } } } @@ -238,7 +238,7 @@ fn ambiguous_add() { >::Output = V } } yields { - "Ambiguous; no inference guidance" + expect![["Ambiguous; no inference guidance"]] } } } @@ -260,8 +260,10 @@ fn shl_ice() { exists { u32: Shl } - } yields { - "Ambiguous" + } yields[SolverChoice::slg_default()] { + expect![["Ambiguous; definite substitution for { [?0 := (&'^0.0 ^0.1)] }"]] + } yields[SolverChoice::recursive_default()] { + expect![["Ambiguous; no inference guidance"]] } } } @@ -284,7 +286,7 @@ fn unify_general_then_specific_ty() { Bar<(N, T, T, T)>: Foo } } yields { - "Unique" + expect![["Unique; substitution [?0 := Int(I32), ?1 := Int(I32)]"]] } } } diff --git a/tests/test/object_safe.rs b/tests/test/object_safe.rs index 49839fdfe55..52839a7c2fb 100644 --- a/tests/test/object_safe.rs +++ b/tests/test/object_safe.rs @@ -9,7 +9,7 @@ fn object_safe_flag() { trait Bar {} } - goal { ObjectSafe(Foo) } yields { "Unique" } - goal { not { ObjectSafe(Bar) } } yields { "Unique" } + goal { ObjectSafe(Foo) } yields { expect![["Unique"]] } + goal { not { ObjectSafe(Bar) } } yields { expect![["Unique"]] } } } diff --git a/tests/test/opaque_types.rs b/tests/test/opaque_types.rs index fe028313ed6..767db8c8a15 100644 --- a/tests/test/opaque_types.rs +++ b/tests/test/opaque_types.rs @@ -16,7 +16,7 @@ fn opaque_bounds() { goal { T: Clone } yields { - "Unique; substitution []" + expect![["Unique"]] } } } @@ -39,13 +39,13 @@ fn opaque_reveal() { T: Trait } } yields { - "Unique; substitution []" + expect![["Unique"]] } goal { T: Trait } yields { - "No possible solution" + expect![["No possible solution"]] } } } @@ -77,13 +77,13 @@ fn opaque_where_clause() { WellFormed(T) } } yields { - "Unique; substitution []" + expect![["Unique"]] } goal { WellFormed(T) } yields { - "No possible solution" + expect![["No possible solution"]] } goal { @@ -93,7 +93,7 @@ fn opaque_where_clause() { } } } yields { - "Unique; substitution []" + expect![["Unique"]] } goal { @@ -101,7 +101,7 @@ fn opaque_where_clause() { WellFormed(S) } } yields { - "No possible solution" + expect![["No possible solution"]] } } } @@ -124,7 +124,7 @@ fn opaque_generics_simple() { goal { Foo: Iterator } yields { - "Unique; substitution []" + expect![["Unique"]] } } @@ -149,7 +149,7 @@ fn opaque_generics() { goal { Foo: Iterator } yields { - "Unique; substitution []" + expect![["Unique"]] } goal { @@ -157,7 +157,7 @@ fn opaque_generics() { Foo: Iterator } } yields { - "Unique; substitution []" + expect![["Unique"]] } goal { @@ -165,9 +165,9 @@ fn opaque_generics() { as Iterator>::Item = T } } yields[SolverChoice::slg_default()] { - "Ambiguous" // #234 + expect![["Ambiguous; no inference guidance"]] // #234 } yields[SolverChoice::recursive_default()] { - "Unique; substitution [?0 := Bar], lifetime constraints []" + expect![["Unique; substitution [?0 := Bar]"]] } } } @@ -188,7 +188,7 @@ fn opaque_trait_generic() { Bar: Trait } } yields { - "Unique; substitution [?0 := Uint(U32)]" + expect![["Unique; substitution [?0 := Uint(U32)]"]] } } } @@ -216,13 +216,13 @@ fn opaque_auto_traits() { goal { Opaque1: Send } yields { - "Unique" + expect![["Unique"]] } goal { Opaque2: Send } yields { - "No possible solution" + expect![["No possible solution"]] } } } @@ -253,13 +253,13 @@ fn opaque_auto_traits_indirect() { goal { Opaque1: SendDerived } yields { - "Unique" + expect![["Unique"]] } goal { Opaque2: SendDerived } yields { - "No possible solution" + expect![["No possible solution"]] } } } @@ -279,7 +279,7 @@ fn opaque_super_trait() { goal { Opaque: Base } yields { - "Unique" + expect![["Unique"]] } } } diff --git a/tests/test/projection.rs b/tests/test/projection.rs index 7df12fb9b25..aaddd17ffa8 100644 --- a/tests/test/projection.rs +++ b/tests/test/projection.rs @@ -21,7 +21,7 @@ fn normalize_basic() { } } } yields { - "Unique; substitution [?0 := !1_0], lifetime constraints []" + expect![["Unique; substitution [?0 := !1_0]"]] } goal { @@ -29,7 +29,7 @@ fn normalize_basic() { Vec: Iterator } } yields { - "Unique; substitution [], lifetime constraints []" + expect![["Unique"]] } goal { @@ -39,7 +39,7 @@ fn normalize_basic() { } } } yields { - "Unique; substitution []" + expect![["Unique"]] } goal { @@ -51,7 +51,7 @@ fn normalize_basic() { } } } yields { - "Unique; substitution [?0 := (Iterator::Item)]" + expect![["Unique; substitution [?0 := (Iterator::Item)]"]] } goal { @@ -63,7 +63,7 @@ fn normalize_basic() { } } } yields { - "Unique; substitution [?0 := (Iterator::Item)]" + expect![["Unique; substitution [?0 := (Iterator::Item)]"]] } goal { @@ -73,7 +73,7 @@ fn normalize_basic() { } } } yields { - "Unique" + expect![["Unique"]] } goal { @@ -86,7 +86,7 @@ fn normalize_basic() { } } yields { // True for `U = T`, of course, but also true for `U = Vec<::Item>`. - "Ambiguous" + expect![["Ambiguous; no inference guidance"]] } } } @@ -114,7 +114,7 @@ fn normalize_into_iterator() { } } } yields { - "Unique" + expect![["Unique; substitution [?0 := !1_0]"]] } } } @@ -141,9 +141,9 @@ fn projection_equality() { } } yields[SolverChoice::slg_default()] { // this is wrong, chalk#234 - "Ambiguous" + expect![["Ambiguous; no inference guidance"]] } yields[SolverChoice::recursive_default()] { - "Unique; substitution [?0 := Uint(U32)]" + expect![["Unique; substitution [?0 := Uint(U32)]"]] } goal { @@ -152,9 +152,9 @@ fn projection_equality() { } } yields[SolverChoice::slg_default()] { // this is wrong, chalk#234 - "Ambiguous" + expect![["Ambiguous; no inference guidance"]] } yields[SolverChoice::recursive_default()] { - "Unique; substitution [?0 := Uint(U32)]" + expect![["Unique; substitution [?0 := Uint(U32)]"]] } } } @@ -182,7 +182,7 @@ fn projection_equality_priority1() { } } yields[SolverChoice::slg_default()] { // this is wrong, chalk#234 - "Ambiguous" + expect![["Ambiguous; definite substitution for { [?0 := S2, ?1 := ^0.0] }"]] } yields[SolverChoice::recursive_default()] { // This is.. interesting, but not necessarily wrong. // It's certainly true that based on the impls we see @@ -194,7 +194,7 @@ fn projection_equality_priority1() { // constrained `T` at all? I can't come up with // an example where that's the case, so maybe // not. -Niko - "Unique; substitution [?0 := S2, ?1 := Uint(U32)]" + expect![["Unique; substitution [?0 := S2, ?1 := Uint(U32)]"]] } } } @@ -226,7 +226,7 @@ fn projection_equality_priority2() { } } yields { // Correct: Ambiguous because Out1 = Y and Out1 = S1 are both value. - "Ambiguous; no inference guidance" + expect![["Ambiguous; no inference guidance"]] } goal { @@ -240,7 +240,7 @@ fn projection_equality_priority2() { } } yields { // Constraining Out1 = Y gives us only one choice. - "Unique; substitution [?0 := !1_1, ?1 := (Trait1::Type)], lifetime constraints []" + expect![["Unique; substitution [?0 := !1_1, ?1 := (Trait1::Type)]"]] } goal { @@ -254,7 +254,7 @@ fn projection_equality_priority2() { } } yields { // Constraining Out1 = Y gives us only one choice. - "Unique; substitution [?0 := !1_1, ?1 := (Trait1::Type)], lifetime constraints []" + expect![["Unique; substitution [?0 := !1_1, ?1 := (Trait1::Type)]"]] } goal { @@ -270,11 +270,11 @@ fn projection_equality_priority2() { // chalk#234: Constraining Out1 = S1 gives us only the choice to // use the impl, but the SLG solver can't decide between // the placeholder and the normalized form. - "Ambiguous; definite substitution for { [?0 := S1, ?1 := ^0.0] }" + expect![["Ambiguous; definite substitution for { [?0 := S1, ?1 := ^0.0] }"]] } yields[SolverChoice::recursive_default()] { // Constraining Out1 = S1 gives us only one choice, use the impl, // and the recursive solver prefers the normalized form. - "Unique; substitution [?0 := S1, ?1 := Uint(U32)], lifetime constraints []" + expect![["Unique; substitution [?0 := S1, ?1 := Uint(U32)]"]] } } } @@ -297,9 +297,9 @@ fn projection_equality_from_env() { } } yields[SolverChoice::slg_default()] { // this is wrong, chalk#234 - "Ambiguous" + expect![["Ambiguous; no inference guidance"]] } yields[SolverChoice::recursive_default()] { - "Unique; substitution [?0 := Uint(U32)]" + expect![["Unique; substitution [?0 := Uint(U32)]"]] } } } @@ -325,9 +325,9 @@ fn projection_equality_nested() { } } yields[SolverChoice::slg_default()] { // this is wrong, chalk#234 - "Ambiguous" + expect![["Ambiguous; no inference guidance"]] } yields[SolverChoice::recursive_default()] { - "Unique; substitution [?0 := Uint(U32)]" + expect![["Unique; substitution [?0 := Uint(U32)]"]] } } } @@ -367,9 +367,9 @@ fn iterator_flatten() { } } yields[SolverChoice::slg_default()] { // this is wrong, chalk#234 - "Ambiguous" + expect![["Ambiguous; no inference guidance"]] } yields[SolverChoice::recursive_default()] { - "Unique; substitution [?0 := Uint(U32)]" + expect![["Unique; substitution [?0 := Uint(U32)]"]] } } } @@ -409,7 +409,7 @@ fn normalize_gat1() { } } } yields { - "Unique; substitution [?0 := Iter<'!2_0, !1_0>], lifetime constraints []" + expect![["Unique; substitution [?0 := Iter<'!2_0, !1_0>]"]] } } } @@ -434,7 +434,7 @@ fn normalize_gat2() { } } } yields { - "Unique; substitution [?0 := Span<'!1_0, !1_1>], lifetime constraints []" + expect![["Unique; substitution [?0 := Span<'!1_0, !1_1>]"]] } goal { @@ -442,7 +442,7 @@ fn normalize_gat2() { as StreamingIterator>::Item<'a> = Span<'a, T> } } yields { - "Unique; substitution [], lifetime constraints []" + expect![["Unique"]] } goal { @@ -452,7 +452,7 @@ fn normalize_gat2() { } } } yields { - "Unique; substitution [], lifetime constraints []" + expect![["Unique"]] } } } @@ -476,7 +476,7 @@ fn normalize_gat_const() { } } } yields { - "Unique; substitution [?0 := Span], lifetime constraints []" + expect![["Unique; substitution [?0 := Span]"]] } goal { @@ -484,7 +484,7 @@ fn normalize_gat_const() { as StreamingIterator>::Item = Span } } yields { - "Unique; substitution [], lifetime constraints []" + expect![["Unique"]] } goal { @@ -494,7 +494,7 @@ fn normalize_gat_const() { } } } yields { - "Unique; substitution [], lifetime constraints []" + expect![["Unique"]] } } } @@ -522,7 +522,7 @@ fn normalize_gat_with_where_clause() { } } } yields { - "No possible solution" + expect![["No possible solution"]] } goal { @@ -534,7 +534,7 @@ fn normalize_gat_with_where_clause() { } } } yields { - "Unique; substitution [?0 := Value]" + expect![["Unique; substitution [?0 := Value]"]] } } } @@ -561,7 +561,7 @@ fn normalize_gat_with_where_clause2() { } } } yields { - "No possible solution" + expect![["No possible solution"]] } goal { @@ -573,7 +573,7 @@ fn normalize_gat_with_where_clause2() { } } } yields { - "Unique; substitution [?0 := !1_1]" + expect![["Unique; substitution [?0 := !1_1]"]] } } } @@ -604,7 +604,7 @@ fn normalize_gat_with_higher_ranked_trait_bound() { } } } yields { - "Unique; substitution [?0 := Baz], lifetime constraints []" + expect![["Unique; substitution [?0 := Baz]"]] } } } @@ -626,7 +626,7 @@ fn forall_projection() { goal { for<'a> fn(>::Item): Eq } yields { - "Unique; substitution [], lifetime constraints []" + expect![["Unique"]] } } } @@ -654,7 +654,7 @@ fn forall_projection_gat() { for<'a> fn(>::Item): Eq } } yields { - "No possible solution" + expect![["No possible solution"]] } goal { @@ -664,7 +664,7 @@ fn forall_projection_gat() { } } } yields { - "Unique; substitution [], lifetime constraints []" + expect![["Unique"]] } goal { @@ -672,7 +672,7 @@ fn forall_projection_gat() { WellFormed(>::Item) } } yields { - "No possible solution" + expect![["No possible solution"]] } goal { @@ -682,7 +682,7 @@ fn forall_projection_gat() { } } } yields { - "Unique; substitution [], lifetime constraints []" + expect![["Unique"]] } } } @@ -719,9 +719,9 @@ fn normalize_under_binder() { } } yields[SolverChoice::slg_default()] { // chalk#234, I think - "Ambiguous" + expect![["Ambiguous; no inference guidance"]] } yields[SolverChoice::recursive_default()] { - "Unique; substitution [?0 := I32], lifetime constraints []" + expect![["Unique; substitution [?0 := I32]"]] } goal { @@ -731,7 +731,7 @@ fn normalize_under_binder() { } } } yields { - "Unique; substitution [?0 := I32], lifetime constraints []" + expect![["Unique; substitution [?0 := I32]"]] } goal { @@ -742,9 +742,9 @@ fn normalize_under_binder() { } } yields[SolverChoice::slg_default()] { // chalk#234, I think - "Ambiguous" + expect![["Ambiguous; no inference guidance"]] } yields[SolverChoice::recursive_default()] { - "Unique; substitution [?0 := Ref<'!1_0, I32>], lifetime constraints []" + expect![["Unique; substitution [?0 := Ref<'!1_0, I32>]"]] } goal { @@ -754,7 +754,7 @@ fn normalize_under_binder() { } } } yields { - "Unique; substitution [?0 := Ref<'!1_0, I32>], lifetime constraints []" + expect![["Unique; substitution [?0 := Ref<'!1_0, I32>]"]] } goal { @@ -764,12 +764,12 @@ fn normalize_under_binder() { } } } yields { - "Unique; for { \ + expect![["Unique; for { \ substitution [?0 := Ref<'^0.0, I32>], \ lifetime constraints [\ InEnvironment { environment: Env([]), goal: '!1_0: '^0.0 }, \ InEnvironment { environment: Env([]), goal: '^0.0: '!1_0 }] \ - }" + }"]] } } } @@ -797,12 +797,12 @@ fn normalize_under_binder_multi() { } } } yields_all { - "substitution [?0 := I32], lifetime constraints []", - "for { substitution [?0 := (Deref::Item), '^0.1>], lifetime constraints [\ + expect![["substitution [?0 := I32]"]], + expect![["for { substitution [?0 := (Deref::Item), '^0.1>], lifetime constraints [\ InEnvironment { environment: Env([]), goal: '!1_0: '^0.1 }, \ InEnvironment { environment: Env([]), goal: '^0.1: '!1_0 }, \ InEnvironment { environment: Env([]), goal: '!1_0: '^0.0 }, \ - InEnvironment { environment: Env([]), goal: '^0.0: '!1_0 }] }" + InEnvironment { environment: Env([]), goal: '^0.0: '!1_0 }] }"]] } goal { @@ -812,7 +812,7 @@ fn normalize_under_binder_multi() { } } } yields_first { - "substitution [?0 := I32], lifetime constraints []" + expect![["substitution [?0 := I32]"]] } } } @@ -846,7 +846,7 @@ fn projection_from_env_a() { } } } yields { - "Unique" + expect![["Unique"]] } } } @@ -901,7 +901,7 @@ fn projection_from_env_slow() { } } } yields { - "Unique" + expect![["Unique"]] } } } @@ -934,7 +934,7 @@ fn gat_unify_with_implied_wc() { } } } yields { - "Unique" + expect![["Unique"]] } goal { @@ -942,7 +942,7 @@ fn gat_unify_with_implied_wc() { T: Cast } } yields { - "No possible solution" + expect![["No possible solution"]] } } } @@ -992,7 +992,7 @@ fn rust_analyzer_regression() { } } } yields_first[SolverChoice::slg(4, None)] { - "Floundered" + expect![["Floundered"]] } } } @@ -1012,7 +1012,7 @@ fn issue_144_regression() { } } } yields { - "Unique" + expect![["Unique"]] } } } @@ -1039,7 +1039,7 @@ fn guidance_for_projection_on_flounder() { } } } yields[SolverChoice::recursive_default()] { - "Ambiguous; definite substitution for { [?0 := ^0.0, ?1 := ^0.0] }" + expect![["Ambiguous; definite substitution for { [?0 := ^0.0, ?1 := ^0.0] }"]] } } } @@ -1063,7 +1063,7 @@ fn projection_to_dyn() { goal { <() as AsDyn>::Dyn: Debug } yields { - "Unique; substitution [], lifetime constraints []" + expect![["Unique"]] } } } @@ -1097,13 +1097,13 @@ fn projection_to_opaque() { goal { ::Proj: Debug } yields { - "Unique; substitution [], lifetime constraints []" + expect![["Unique"]] } goal { <::Proj as Debug>::Output = () } yields { - "Unique; substitution [], lifetime constraints []" + expect![["Unique"]] } } } diff --git a/tests/test/refs.rs b/tests/test/refs.rs index 8654f58b2c1..c8933071890 100644 --- a/tests/test/refs.rs +++ b/tests/test/refs.rs @@ -12,7 +12,7 @@ fn immut_refs_are_well_formed() { WellFormed(&'a T) } } yields { - "Unique; substitution [], lifetime constraints [InEnvironment { environment: Env([]), goal: !1_1: '!1_0 }]" + expect![["Unique; lifetime constraints [InEnvironment { environment: Env([]), goal: !1_1: '!1_0 }]"]] } goal { @@ -20,7 +20,7 @@ fn immut_refs_are_well_formed() { WellFormed(&'a A) } } yields { - "Unique; for { substitution [?0 := '^0.0], lifetime constraints [InEnvironment { environment: Env([]), goal: A: '^0.0 }] }" + expect![["Unique; for { substitution [?0 := '^0.0], lifetime constraints [InEnvironment { environment: Env([]), goal: A: '^0.0 }] }"]] } } } @@ -36,7 +36,7 @@ fn immut_refs_are_sized() { goal { forall<'a, T> { &'a T: Sized } } yields { - "Unique; substitution [], lifetime constraints []" + expect![["Unique"]] } } } @@ -47,7 +47,7 @@ fn mut_refs_are_well_formed() { goal { forall<'a, T> { WellFormed(&'a mut T) } } yields { - "Unique; substitution [], lifetime constraints [InEnvironment { environment: Env([]), goal: !1_1: '!1_0 }]" + expect![["Unique; lifetime constraints [InEnvironment { environment: Env([]), goal: !1_1: '!1_0 }]"]] } } } @@ -63,7 +63,7 @@ fn mut_refs_are_sized() { goal { forall<'a, T> { &'a mut T: Sized } } yields { - "Unique; substitution [], lifetime constraints []" + expect![["Unique"]] } } } diff --git a/tests/test/scalars.rs b/tests/test/scalars.rs index 52196261528..3513c158924 100644 --- a/tests/test/scalars.rs +++ b/tests/test/scalars.rs @@ -14,31 +14,31 @@ fn scalar_in_tuple_trait_impl() { goal { (usize, usize): Foo } yields { - "Unique" + expect![["Unique"]] } goal { (usize, isize): Foo } yields { - "Unique" + expect![["Unique"]] } goal { (usize, bool): Foo } yields { - "No possible solution" + expect![["No possible solution"]] } goal { (usize, usize, usize): Foo } yields { - "Unique" + expect![["Unique"]] } goal { (char, u8, i8): Foo } yields { - "No possible solution" + expect![["No possible solution"]] } } } @@ -76,39 +76,39 @@ fn scalar_trait_impl() { } - goal { i8: Foo } yields { "Unique" } - goal { i16: Foo } yields { "Unique" } - goal { i32: Foo } yields { "Unique" } - goal { i64: Foo } yields { "Unique" } - goal { i128: Foo } yields { "Unique" } - goal { isize: Foo } yields { "Unique" } - goal { u8: Foo } yields { "Unique" } - goal { u16: Foo } yields { "Unique" } - goal { u32: Foo } yields { "Unique" } - goal { u64: Foo } yields { "Unique" } - goal { u128: Foo } yields { "Unique" } - goal { usize: Foo } yields { "Unique" } - goal { f32: Foo } yields { "Unique" } - goal { f64: Foo } yields { "Unique" } - goal { bool: Foo } yields { "Unique" } - goal { char: Foo } yields { "Unique" } - - goal { i8: UnsignedFoo } yields { "No possible solution" } - goal { i16: UnsignedFoo } yields { "No possible solution" } - goal { i32: UnsignedFoo } yields { "No possible solution" } - goal { i64: UnsignedFoo } yields { "No possible solution" } - goal { i128: UnsignedFoo } yields { "No possible solution" } - goal { isize: UnsignedFoo } yields { "No possible solution" } - goal { u8: UnsignedFoo } yields { "Unique" } - goal { u16: UnsignedFoo } yields { "Unique" } - goal { u32: UnsignedFoo } yields { "Unique" } - goal { u64: UnsignedFoo } yields { "Unique" } - goal { u128: UnsignedFoo } yields { "Unique" } - goal { usize: UnsignedFoo } yields { "Unique" } - goal { f32: UnsignedFoo } yields { "No possible solution" } - goal { f64: UnsignedFoo } yields { "No possible solution" } - goal { bool: UnsignedFoo } yields { "No possible solution" } - goal { char: UnsignedFoo } yields { "No possible solution" } + goal { i8: Foo } yields { expect![["Unique"]] } + goal { i16: Foo } yields { expect![["Unique"]] } + goal { i32: Foo } yields { expect![["Unique"]] } + goal { i64: Foo } yields { expect![["Unique"]] } + goal { i128: Foo } yields { expect![["Unique"]] } + goal { isize: Foo } yields { expect![["Unique"]] } + goal { u8: Foo } yields { expect![["Unique"]] } + goal { u16: Foo } yields { expect![["Unique"]] } + goal { u32: Foo } yields { expect![["Unique"]] } + goal { u64: Foo } yields { expect![["Unique"]] } + goal { u128: Foo } yields { expect![["Unique"]] } + goal { usize: Foo } yields { expect![["Unique"]] } + goal { f32: Foo } yields { expect![["Unique"]] } + goal { f64: Foo } yields { expect![["Unique"]] } + goal { bool: Foo } yields { expect![["Unique"]] } + goal { char: Foo } yields { expect![["Unique"]] } + + goal { i8: UnsignedFoo } yields { expect![["No possible solution"]] } + goal { i16: UnsignedFoo } yields { expect![["No possible solution"]] } + goal { i32: UnsignedFoo } yields { expect![["No possible solution"]] } + goal { i64: UnsignedFoo } yields { expect![["No possible solution"]] } + goal { i128: UnsignedFoo } yields { expect![["No possible solution"]] } + goal { isize: UnsignedFoo } yields { expect![["No possible solution"]] } + goal { u8: UnsignedFoo } yields { expect![["Unique"]] } + goal { u16: UnsignedFoo } yields { expect![["Unique"]] } + goal { u32: UnsignedFoo } yields { expect![["Unique"]] } + goal { u64: UnsignedFoo } yields { expect![["Unique"]] } + goal { u128: UnsignedFoo } yields { expect![["Unique"]] } + goal { usize: UnsignedFoo } yields { expect![["Unique"]] } + goal { f32: UnsignedFoo } yields { expect![["No possible solution"]] } + goal { f64: UnsignedFoo } yields { expect![["No possible solution"]] } + goal { bool: UnsignedFoo } yields { expect![["No possible solution"]] } + goal { char: UnsignedFoo } yields { expect![["No possible solution"]] } } } @@ -116,22 +116,22 @@ fn scalar_trait_impl() { #[test] fn scalars_are_well_formed() { test! { - goal { WellFormed(i8) } yields { "Unique" } - goal { WellFormed(i16) } yields { "Unique" } - goal { WellFormed(i32) } yields { "Unique" } - goal { WellFormed(i64) } yields { "Unique" } - goal { WellFormed(i128) } yields { "Unique" } - goal { WellFormed(isize) } yields { "Unique" } - goal { WellFormed(u8) } yields { "Unique" } - goal { WellFormed(u16) } yields { "Unique" } - goal { WellFormed(u32) } yields { "Unique" } - goal { WellFormed(u64) } yields { "Unique" } - goal { WellFormed(u128) } yields { "Unique" } - goal { WellFormed(usize) } yields { "Unique" } - goal { WellFormed(f32) } yields { "Unique" } - goal { WellFormed(f64) } yields { "Unique" } - goal { WellFormed(bool) } yields { "Unique" } - goal { WellFormed(char) } yields { "Unique" } + goal { WellFormed(i8) } yields { expect![["Unique"]] } + goal { WellFormed(i16) } yields { expect![["Unique"]] } + goal { WellFormed(i32) } yields { expect![["Unique"]] } + goal { WellFormed(i64) } yields { expect![["Unique"]] } + goal { WellFormed(i128) } yields { expect![["Unique"]] } + goal { WellFormed(isize) } yields { expect![["Unique"]] } + goal { WellFormed(u8) } yields { expect![["Unique"]] } + goal { WellFormed(u16) } yields { expect![["Unique"]] } + goal { WellFormed(u32) } yields { expect![["Unique"]] } + goal { WellFormed(u64) } yields { expect![["Unique"]] } + goal { WellFormed(u128) } yields { expect![["Unique"]] } + goal { WellFormed(usize) } yields { expect![["Unique"]] } + goal { WellFormed(f32) } yields { expect![["Unique"]] } + goal { WellFormed(f64) } yields { expect![["Unique"]] } + goal { WellFormed(bool) } yields { expect![["Unique"]] } + goal { WellFormed(char) } yields { expect![["Unique"]] } } } @@ -142,21 +142,21 @@ fn scalars_are_sized() { #[lang(sized)] trait Sized { } } - goal { i8: Sized } yields { "Unique" } - goal { i16: Sized } yields { "Unique" } - goal { i32: Sized } yields { "Unique" } - goal { i64: Sized } yields { "Unique" } - goal { i128: Sized } yields { "Unique" } - goal { isize: Sized } yields { "Unique" } - goal { u8: Sized } yields { "Unique" } - goal { u16: Sized } yields { "Unique" } - goal { u32: Sized } yields { "Unique" } - goal { u64: Sized } yields { "Unique" } - goal { u128: Sized } yields { "Unique" } - goal { usize: Sized } yields { "Unique" } - goal { f32: Sized } yields { "Unique" } - goal { f64: Sized } yields { "Unique" } - goal { bool: Sized } yields { "Unique" } - goal { char: Sized } yields { "Unique" } + goal { i8: Sized } yields { expect![["Unique"]] } + goal { i16: Sized } yields { expect![["Unique"]] } + goal { i32: Sized } yields { expect![["Unique"]] } + goal { i64: Sized } yields { expect![["Unique"]] } + goal { i128: Sized } yields { expect![["Unique"]] } + goal { isize: Sized } yields { expect![["Unique"]] } + goal { u8: Sized } yields { expect![["Unique"]] } + goal { u16: Sized } yields { expect![["Unique"]] } + goal { u32: Sized } yields { expect![["Unique"]] } + goal { u64: Sized } yields { expect![["Unique"]] } + goal { u128: Sized } yields { expect![["Unique"]] } + goal { usize: Sized } yields { expect![["Unique"]] } + goal { f32: Sized } yields { expect![["Unique"]] } + goal { f64: Sized } yields { expect![["Unique"]] } + goal { bool: Sized } yields { expect![["Unique"]] } + goal { char: Sized } yields { expect![["Unique"]] } } } diff --git a/tests/test/slices.rs b/tests/test/slices.rs index ea32740b72b..90d4b348ec0 100644 --- a/tests/test/slices.rs +++ b/tests/test/slices.rs @@ -11,7 +11,7 @@ fn slices_are_not_sized() { goal { forall { not { [T]: Sized } } } yields { - "Unique; substitution [], lifetime constraints []" + expect![["Unique"]] } } } @@ -27,13 +27,13 @@ fn slices_are_well_formed_if_elem_sized() { goal { forall { if (T: Sized) { WellFormed([T]) } } } yields { - "Unique; substitution [], lifetime constraints []" + expect![["Unique"]] } goal { forall { WellFormed([T]) } } yields { - "No possible solution" + expect![["No possible solution"]] } } } @@ -49,7 +49,7 @@ fn slices_are_not_copy() { goal { forall { not { [T]: Copy } } } yields { - "Unique; substitution [], lifetime constraints []" + expect![["Unique"]] } } } @@ -65,7 +65,7 @@ fn slices_are_not_clone() { goal { forall { not { [T]: Clone } } } yields { - "Unique; substitution [], lifetime constraints []" + expect![["Unique"]] } } } diff --git a/tests/test/string.rs b/tests/test/string.rs index 6833f216e16..355a0af60e0 100644 --- a/tests/test/string.rs +++ b/tests/test/string.rs @@ -8,14 +8,14 @@ fn str_trait_impl() { impl Foo for str {} } - goal { str: Foo } yields { "Unique" } + goal { str: Foo } yields { expect![["Unique"]] } } } #[test] fn str_is_well_formed() { test! { - goal { WellFormed(str) } yields { "Unique" } + goal { WellFormed(str) } yields { expect![["Unique"]] } } } @@ -26,7 +26,7 @@ fn str_is_not_sized() { #[lang(sized)] trait Sized {} } - goal { not { str: Sized } } yields { "Unique" } + goal { not { str: Sized } } yields { expect![["Unique"]] } } } @@ -37,7 +37,7 @@ fn str_is_not_copy() { #[lang(copy)] trait Copy {} } - goal { not { str: Copy } } yields { "Unique" } + goal { not { str: Copy } } yields { expect![["Unique"]] } } } @@ -48,6 +48,6 @@ fn str_is_not_clone() { #[lang(clone)] trait Clone {} } - goal { not { str: Clone } } yields { "Unique" } + goal { not { str: Clone } } yields { expect![["Unique"]] } } } diff --git a/tests/test/subtype.rs b/tests/test/subtype.rs index 7403f34d7d3..815fd111760 100644 --- a/tests/test/subtype.rs +++ b/tests/test/subtype.rs @@ -24,7 +24,7 @@ fn subtype_simple() { goal { Subtype(Foo, Foo) } yields { - "Unique" + expect![["Unique"]] } } } @@ -44,9 +44,7 @@ fn struct_lifetime_variance() { Subtype(Foo<'a>, Foo<'b>) } } yields { - "Unique; substitution [], lifetime constraints [\ - InEnvironment { environment: Env([]), goal: '!1_1: '!1_0 } \ - ]" + expect![["Unique; lifetime constraints [InEnvironment { environment: Env([]), goal: '!1_1: '!1_0 }]"]] } } } @@ -61,9 +59,7 @@ fn ref_lifetime_variance() { } } yields { // Seems good! - "Unique; substitution [], lifetime constraints [\ - InEnvironment { environment: Env([]), goal: '!1_0: '!1_1 } \ - ]" + expect![["Unique; lifetime constraints [InEnvironment { environment: Env([]), goal: '!1_0: '!1_1 }]"]] } } } @@ -74,19 +70,9 @@ fn fn_lifetime_variance_args() { goal { for<'a, 'b> fn(&'a u32, &'b u32) = for<'a> fn(&'a u32, &'a u32) } yields[SolverChoice::recursive_default()] { - "Unique; for { substitution [], lifetime constraints [\ - InEnvironment { environment: Env([]), goal: '!1_0: '^0.0 }, \ - InEnvironment { environment: Env([]), goal: '!1_1: '^0.0 }, \ - InEnvironment { environment: Env([]), goal: '!2_0: '^0.1 }, \ - InEnvironment { environment: Env([]), goal: '!2_0: '^0.2 }\ - ] }" + expect![["Unique; for { lifetime constraints [InEnvironment { environment: Env([]), goal: '!1_0: '^0.0 }, InEnvironment { environment: Env([]), goal: '!1_1: '^0.0 }, InEnvironment { environment: Env([]), goal: '!2_0: '^0.1 }, InEnvironment { environment: Env([]), goal: '!2_0: '^0.2 }] }"]] } yields[SolverChoice::slg_default()] { - "Unique; for { substitution [], lifetime constraints [\ - InEnvironment { environment: Env([]), goal: '!1_0: '^0.2 }, \ - InEnvironment { environment: Env([]), goal: '!1_1: '^0.2 }, \ - InEnvironment { environment: Env([]), goal: '!2_0: '^0.0 }, \ - InEnvironment { environment: Env([]), goal: '!2_0: '^0.1 }\ - ] }" + expect![["Unique; for { lifetime constraints [InEnvironment { environment: Env([]), goal: '!1_0: '^0.2 }, InEnvironment { environment: Env([]), goal: '!1_1: '^0.2 }, InEnvironment { environment: Env([]), goal: '!2_0: '^0.0 }, InEnvironment { environment: Env([]), goal: '!2_0: '^0.1 }] }"]] } } } @@ -98,20 +84,12 @@ fn fn_lifetime_variance_with_return_type() { Subtype(for<'a, 'b> fn(&'a u32, &'b u32) -> &'a u32, for<'a> fn(&'a u32, &'a u32) -> &'a u32) } yields { // TODO: are these results actually correct? - "Unique; for { substitution [], lifetime constraints [\ - InEnvironment { environment: Env([]), goal: '!1_0: '^0.0 }, \ - InEnvironment { environment: Env([]), goal: '!1_0: '^0.1 }, \ - InEnvironment { environment: Env([]), goal: '^0.0: '!1_0 } \ - ]}" + expect![["Unique; for { lifetime constraints [InEnvironment { environment: Env([]), goal: '!1_0: '^0.0 }, InEnvironment { environment: Env([]), goal: '!1_0: '^0.1 }, InEnvironment { environment: Env([]), goal: '^0.0: '!1_0 }] }"]] } goal { Subtype(for<'a> fn(&'a u32, &'a u32) -> &'a u32, for<'a, 'b> fn(&'a u32, &'b u32) -> &'a u32) } yields { - "Unique; for { substitution [], lifetime constraints [\ - InEnvironment { environment: Env([]), goal: '!1_0: '^0.0 }, \ - InEnvironment { environment: Env([]), goal: '!1_1: '^0.0 }, \ - InEnvironment { environment: Env([]), goal: '^0.0: '!1_0 } \ - ] }" + expect![["Unique; for { lifetime constraints [InEnvironment { environment: Env([]), goal: '!1_0: '^0.0 }, InEnvironment { environment: Env([]), goal: '!1_1: '^0.0 }, InEnvironment { environment: Env([]), goal: '^0.0: '!1_0 }] }"]] } } } @@ -133,7 +111,7 @@ fn generalize() { // If this is invariant, then the generalizer might be doing // the right thing here by creating the general form of `&'a u32` equal to // just `&'a u32` - "Unique; substitution [?0 := (&'!1_0 Uint(U32))], lifetime constraints []" + expect![["Unique; substitution [?0 := (&'!1_0 Uint(U32))]"]] } } } @@ -152,17 +130,14 @@ fn multi_lifetime() { } yields { // Without the generalizer, we would yield a result like this: // - // "Unique; substitution [?0 := (&'!1_1 Uint(U32))], lifetime + // expect![["Unique; substitution [?0 := (&'!1_1 Uint(U32))], lifetime // constraints [InEnvironment { environment: Env([]), goal: '!1_1: '!1_0 - // }]" + // }]"]] // // This is incorrect, as we shouldn't be requiring 'a and 'b to be // related to eachother. Instead, U should be &'?1 u32, with constraints // ?1 : 'a, ?1: 'b. - "Unique; for { substitution [?0 := (&'^0.0 Uint(U32))], lifetime constraints [\ - InEnvironment { environment: Env([]), goal: '!1_0: '^0.0 }, \ - InEnvironment { environment: Env([]), goal: '!1_1: '^0.0 } \ - ]}" + expect![["Unique; for { substitution [?0 := (&'^0.0 Uint(U32))], lifetime constraints [InEnvironment { environment: Env([]), goal: '!1_0: '^0.0 }, InEnvironment { environment: Env([]), goal: '!1_1: '^0.0 }] }"]] } } } @@ -189,10 +164,7 @@ fn multi_lifetime_inverted() { // This is incorrect, as we shouldn't be requiring 'a and 'b to be // related to eachother. Instead, U should be &'?1 u32, with constraints // ?1 : 'a, ?1: 'b. - "Unique; for { substitution [?0 := (&'^0.0 Uint(U32))], lifetime constraints [\ - InEnvironment { environment: Env([]), goal: '^0.0: '!1_0 }, \ - InEnvironment { environment: Env([]), goal: '^0.0: '!1_1 } \ - ]}" + expect![["Unique; for { substitution [?0 := (&'^0.0 Uint(U32))], lifetime constraints [InEnvironment { environment: Env([]), goal: '^0.0: '!1_0 }, InEnvironment { environment: Env([]), goal: '^0.0: '!1_1 }] }"]] } } } @@ -215,10 +187,7 @@ fn multi_lifetime_covariant_struct() { } } yields { // Result should be identical to multi_lifetime result. - "Unique; for { substitution [?0 := (&'^0.0 Uint(U32))], lifetime constraints [\ - InEnvironment { environment: Env([]), goal: '!1_0: '^0.0 }, \ - InEnvironment { environment: Env([]), goal: '!1_1: '^0.0 } \ - ]}" + expect![["Unique; for { substitution [?0 := (&'^0.0 Uint(U32))], lifetime constraints [InEnvironment { environment: Env([]), goal: '!1_0: '^0.0 }, InEnvironment { environment: Env([]), goal: '!1_1: '^0.0 }] }"]] } goal { forall<'a, 'b> { @@ -229,10 +198,7 @@ fn multi_lifetime_covariant_struct() { } } yields { // Result should be identical to multi_lifetime result. - "Unique; for { substitution [?0 := (&'^0.0 Uint(U32))], lifetime constraints [\ - InEnvironment { environment: Env([]), goal: '^0.0: '!1_0 }, \ - InEnvironment { environment: Env([]), goal: '^0.0: '!1_1 } \ - ]}" + expect![["Unique; for { substitution [?0 := (&'^0.0 Uint(U32))], lifetime constraints [InEnvironment { environment: Env([]), goal: '^0.0: '!1_0 }, InEnvironment { environment: Env([]), goal: '^0.0: '!1_1 }] }"]] } } } @@ -255,10 +221,7 @@ fn multi_lifetime_contravariant_struct() { } } yields { // Result should be opposite multi_lifetime result. - "Unique; for { substitution [?0 := (&'^0.0 Uint(U32))], lifetime constraints [\ - InEnvironment { environment: Env([]), goal: '^0.0: '!1_0 }, \ - InEnvironment { environment: Env([]), goal: '^0.0: '!1_1 } \ - ]}" + expect![["Unique; for { substitution [?0 := (&'^0.0 Uint(U32))], lifetime constraints [InEnvironment { environment: Env([]), goal: '^0.0: '!1_0 }, InEnvironment { environment: Env([]), goal: '^0.0: '!1_1 }] }"]] } goal { forall<'a, 'b> { @@ -269,10 +232,7 @@ fn multi_lifetime_contravariant_struct() { } } yields { // Result should be opposite multi_lifetime result. - "Unique; for { substitution [?0 := (&'^0.0 Uint(U32))], lifetime constraints [\ - InEnvironment { environment: Env([]), goal: '!1_0: '^0.0 }, \ - InEnvironment { environment: Env([]), goal: '!1_1: '^0.0 } \ - ]}" + expect![["Unique; for { substitution [?0 := (&'^0.0 Uint(U32))], lifetime constraints [InEnvironment { environment: Env([]), goal: '!1_0: '^0.0 }, InEnvironment { environment: Env([]), goal: '!1_1: '^0.0 }] }"]] } } } @@ -295,16 +255,10 @@ fn multi_lifetime_invariant_struct() { } } yields[SolverChoice::recursive_default()] { // Because A is invariant, we require the lifetimes to be equal - "Unique; substitution [?0 := (&'!1_0 Uint(U32))], lifetime constraints [\ - InEnvironment { environment: Env([]), goal: '!1_0: '!1_1 }, \ - InEnvironment { environment: Env([]), goal: '!1_1: '!1_0 } \ - ]" + expect![["Unique; substitution [?0 := (&'!1_0 Uint(U32))], lifetime constraints [InEnvironment { environment: Env([]), goal: '!1_0: '!1_1 }, InEnvironment { environment: Env([]), goal: '!1_1: '!1_0 }]"]] } yields[SolverChoice::slg_default()] { // Because A is invariant, we require the lifetimes to be equal - "Unique; substitution [?0 := (&'!1_1 Uint(U32))], lifetime constraints [\ - InEnvironment { environment: Env([]), goal: '!1_0: '!1_1 }, \ - InEnvironment { environment: Env([]), goal: '!1_1: '!1_0 } \ - ]" + expect![["Unique; substitution [?0 := (&'!1_1 Uint(U32))], lifetime constraints [InEnvironment { environment: Env([]), goal: '!1_0: '!1_1 }, InEnvironment { environment: Env([]), goal: '!1_1: '!1_0 }]"]] } goal { @@ -316,16 +270,10 @@ fn multi_lifetime_invariant_struct() { } } yields[SolverChoice::recursive_default()] { // Because A is invariant, we require the lifetimes to be equal - "Unique; substitution [?0 := (&'!1_0 Uint(U32))], lifetime constraints [\ - InEnvironment { environment: Env([]), goal: '!1_0: '!1_1 }, \ - InEnvironment { environment: Env([]), goal: '!1_1: '!1_0 } \ - ]" + expect![["Unique; substitution [?0 := (&'!1_0 Uint(U32))], lifetime constraints [InEnvironment { environment: Env([]), goal: '!1_0: '!1_1 }, InEnvironment { environment: Env([]), goal: '!1_1: '!1_0 }]"]] } yields[SolverChoice::slg_default()] { // Because A is invariant, we require the lifetimes to be equal - "Unique; substitution [?0 := (&'!1_1 Uint(U32))], lifetime constraints [\ - InEnvironment { environment: Env([]), goal: '!1_0: '!1_1 }, \ - InEnvironment { environment: Env([]), goal: '!1_1: '!1_0 } \ - ]" + expect![["Unique; substitution [?0 := (&'!1_1 Uint(U32))], lifetime constraints [InEnvironment { environment: Env([]), goal: '!1_0: '!1_1 }, InEnvironment { environment: Env([]), goal: '!1_1: '!1_0 }]"]] } } } @@ -343,10 +291,7 @@ fn multi_lifetime_slice() { } } yields { // Result should be identical to multi_lifetime result. - "Unique; for { substitution [?0 := (&'^0.0 Uint(U32))], lifetime constraints [\ - InEnvironment { environment: Env([]), goal: '!1_0: '^0.0 }, \ - InEnvironment { environment: Env([]), goal: '!1_1: '^0.0 } \ - ]}" + expect![["Unique; for { substitution [?0 := (&'^0.0 Uint(U32))], lifetime constraints [InEnvironment { environment: Env([]), goal: '!1_0: '^0.0 }, InEnvironment { environment: Env([]), goal: '!1_1: '^0.0 }] }"]] } goal { forall<'a, 'b> { @@ -357,10 +302,7 @@ fn multi_lifetime_slice() { } } yields { // Result should be identical to multi_lifetime result. - "Unique; for { substitution [?0 := (&'^0.0 Uint(U32))], lifetime constraints [\ - InEnvironment { environment: Env([]), goal: '^0.0: '!1_0 }, \ - InEnvironment { environment: Env([]), goal: '^0.0: '!1_1 } \ - ]}" + expect![["Unique; for { substitution [?0 := (&'^0.0 Uint(U32))], lifetime constraints [InEnvironment { environment: Env([]), goal: '^0.0: '!1_0 }, InEnvironment { environment: Env([]), goal: '^0.0: '!1_1 }] }"]] } } } @@ -378,10 +320,7 @@ fn multi_lifetime_tuple() { } } yields { // Result should be identical to multi_lifetime result. - "Unique; for { substitution [?0 := (&'^0.0 Uint(U32))], lifetime constraints [\ - InEnvironment { environment: Env([]), goal: '!1_0: '^0.0 }, \ - InEnvironment { environment: Env([]), goal: '!1_1: '^0.0 } \ - ]}" + expect![["Unique; for { substitution [?0 := (&'^0.0 Uint(U32))], lifetime constraints [InEnvironment { environment: Env([]), goal: '!1_0: '^0.0 }, InEnvironment { environment: Env([]), goal: '!1_1: '^0.0 }] }"]] } goal { forall<'a, 'b> { @@ -392,10 +331,7 @@ fn multi_lifetime_tuple() { } } yields { // Result should be identical to multi_lifetime result. - "Unique; for { substitution [?0 := (&'^0.0 Uint(U32))], lifetime constraints [\ - InEnvironment { environment: Env([]), goal: '^0.0: '!1_0 }, \ - InEnvironment { environment: Env([]), goal: '^0.0: '!1_1 } \ - ]}" + expect![["Unique; for { substitution [?0 := (&'^0.0 Uint(U32))], lifetime constraints [InEnvironment { environment: Env([]), goal: '^0.0: '!1_0 }, InEnvironment { environment: Env([]), goal: '^0.0: '!1_1 }] }"]] } } } @@ -413,10 +349,7 @@ fn multi_lifetime_array() { } } yields { // Result should be identical to multi_lifetime result. - "Unique; for { substitution [?0 := (&'^0.0 Uint(U32))], lifetime constraints [\ - InEnvironment { environment: Env([]), goal: '!1_0: '^0.0 }, \ - InEnvironment { environment: Env([]), goal: '!1_1: '^0.0 } \ - ]}" + expect![["Unique; for { substitution [?0 := (&'^0.0 Uint(U32))], lifetime constraints [InEnvironment { environment: Env([]), goal: '!1_0: '^0.0 }, InEnvironment { environment: Env([]), goal: '!1_1: '^0.0 }] }"]] } goal { forall<'a, 'b> { @@ -427,10 +360,7 @@ fn multi_lifetime_array() { } } yields { // Result should be identical to multi_lifetime result. - "Unique; for { substitution [?0 := (&'^0.0 Uint(U32))], lifetime constraints [\ - InEnvironment { environment: Env([]), goal: '^0.0: '!1_0 }, \ - InEnvironment { environment: Env([]), goal: '^0.0: '!1_1 } \ - ]}" + expect![["Unique; for { substitution [?0 := (&'^0.0 Uint(U32))], lifetime constraints [InEnvironment { environment: Env([]), goal: '^0.0: '!1_0 }, InEnvironment { environment: Env([]), goal: '^0.0: '!1_1 }] }"]] } } } @@ -452,10 +382,7 @@ fn generalize_covariant_struct() { } } } yields { - "Unique; for { substitution [?0 := Foo<(&'^0.0 Uint(U32))>], lifetime constraints [\ - InEnvironment { environment: Env([]), goal: '!1_0: '^0.0 }, \ - InEnvironment { environment: Env([]), goal: '!1_1: '^0.0 } \ - ] }" + expect![["Unique; for { substitution [?0 := Foo<(&'^0.0 Uint(U32))>], lifetime constraints [InEnvironment { environment: Env([]), goal: '!1_0: '^0.0 }, InEnvironment { environment: Env([]), goal: '!1_1: '^0.0 }] }"]] } } } @@ -478,10 +405,7 @@ fn generalize_contravariant_struct() { } } yields { // Result should be opposite generalize_covariant_struct result. - "Unique; for { substitution [?0 := Foo<(&'^0.0 Uint(U32))>], lifetime constraints [\ - InEnvironment { environment: Env([]), goal: '^0.0: '!1_0 }, \ - InEnvironment { environment: Env([]), goal: '^0.0: '!1_1 } \ - ] }" + expect![["Unique; for { substitution [?0 := Foo<(&'^0.0 Uint(U32))>], lifetime constraints [InEnvironment { environment: Env([]), goal: '^0.0: '!1_0 }, InEnvironment { environment: Env([]), goal: '^0.0: '!1_1 }] }"]] } } } @@ -504,15 +428,9 @@ fn generalize_invariant_struct() { } } yields[SolverChoice::recursive_default()] { // Because A is invariant, we require the lifetimes to be equal - "Unique; substitution [?0 := Foo<(&'!1_0 Uint(U32))>], lifetime constraints [ \ - InEnvironment { environment: Env([]), goal: '!1_0: '!1_1 }, \ - InEnvironment { environment: Env([]), goal: '!1_1: '!1_0 } \ - ]" + expect![["Unique; substitution [?0 := Foo<(&'!1_0 Uint(U32))>], lifetime constraints [InEnvironment { environment: Env([]), goal: '!1_0: '!1_1 }, InEnvironment { environment: Env([]), goal: '!1_1: '!1_0 }]"]] } yields[SolverChoice::slg_default()] { - "Unique; substitution [?0 := Foo<(&'!1_1 Uint(U32))>], lifetime constraints [ \ - InEnvironment { environment: Env([]), goal: '!1_0: '!1_1 }, \ - InEnvironment { environment: Env([]), goal: '!1_1: '!1_0 } \ - ]" + expect![["Unique; substitution [?0 := Foo<(&'!1_1 Uint(U32))>], lifetime constraints [InEnvironment { environment: Env([]), goal: '!1_0: '!1_1 }, InEnvironment { environment: Env([]), goal: '!1_1: '!1_0 }]"]] } } } @@ -530,10 +448,7 @@ fn generalize_slice() { } } yields { // Result should be identical to generalize_covariant_struct result. - "Unique; for { substitution [?0 := [(&'^0.0 Uint(U32))]], lifetime constraints [\ - InEnvironment { environment: Env([]), goal: '!1_0: '^0.0 }, \ - InEnvironment { environment: Env([]), goal: '!1_1: '^0.0 } \ - ] }" + expect![["Unique; for { substitution [?0 := [(&'^0.0 Uint(U32))]], lifetime constraints [InEnvironment { environment: Env([]), goal: '!1_0: '^0.0 }, InEnvironment { environment: Env([]), goal: '!1_1: '^0.0 }] }"]] } goal { forall<'a, 'b> { @@ -544,10 +459,7 @@ fn generalize_slice() { } } yields { // Result should be identical to generalize_covariant_struct result. - "Unique; for { substitution [?0 := [(&'^0.0 Uint(U32))]], lifetime constraints [\ - InEnvironment { environment: Env([]), goal: '^0.0: '!1_0 }, \ - InEnvironment { environment: Env([]), goal: '^0.0: '!1_1 } \ - ] }" + expect![["Unique; for { substitution [?0 := [(&'^0.0 Uint(U32))]], lifetime constraints [InEnvironment { environment: Env([]), goal: '^0.0: '!1_0 }, InEnvironment { environment: Env([]), goal: '^0.0: '!1_1 }] }"]] } } } @@ -565,10 +477,7 @@ fn generalize_tuple() { } } yields { // Result should be identical to generalize_covariant_struct result. - "Unique; for { substitution [?0 := 1<(&'^0.0 Uint(U32))>], lifetime constraints [\ - InEnvironment { environment: Env([]), goal: '!1_0: '^0.0 }, \ - InEnvironment { environment: Env([]), goal: '!1_1: '^0.0 } \ - ] }" + expect![["Unique; for { substitution [?0 := 1<(&'^0.0 Uint(U32))>], lifetime constraints [InEnvironment { environment: Env([]), goal: '!1_0: '^0.0 }, InEnvironment { environment: Env([]), goal: '!1_1: '^0.0 }] }"]] } goal { forall<'a, 'b> { @@ -579,10 +488,7 @@ fn generalize_tuple() { } } yields { // Result should be identical to generalize_covariant_struct result. - "Unique; for { substitution [?0 := 1<(&'^0.0 Uint(U32))>], lifetime constraints [\ - InEnvironment { environment: Env([]), goal: '^0.0: '!1_0 }, \ - InEnvironment { environment: Env([]), goal: '^0.0: '!1_1 } \ - ] }" + expect![["Unique; for { substitution [?0 := 1<(&'^0.0 Uint(U32))>], lifetime constraints [InEnvironment { environment: Env([]), goal: '^0.0: '!1_0 }, InEnvironment { environment: Env([]), goal: '^0.0: '!1_1 }] }"]] } } } @@ -599,12 +505,7 @@ fn generalize_2tuple() { } } } yields { - "Unique; for { substitution [?0 := 2<(&'^0.0 Uint(U32)), (&'^0.1 Uint(U32))>], lifetime constraints [\ - InEnvironment { environment: Env([]), goal: '!1_0: '^0.0 }, \ - InEnvironment { environment: Env([]), goal: '!1_1: '^0.0 }, \ - InEnvironment { environment: Env([]), goal: '!1_2: '^0.1 }, \ - InEnvironment { environment: Env([]), goal: '!1_3: '^0.1 } \ - ] }" + expect![["Unique; for { substitution [?0 := 2<(&'^0.0 Uint(U32)), (&'^0.1 Uint(U32))>], lifetime constraints [InEnvironment { environment: Env([]), goal: '!1_0: '^0.0 }, InEnvironment { environment: Env([]), goal: '!1_1: '^0.0 }, InEnvironment { environment: Env([]), goal: '!1_2: '^0.1 }, InEnvironment { environment: Env([]), goal: '!1_3: '^0.1 }] }"]] } goal { forall<'a, 'b, 'c, 'd> { @@ -614,12 +515,7 @@ fn generalize_2tuple() { } } } yields { - "Unique; for { substitution [?0 := 2<(&'^0.0 Uint(U32)), (&'^0.1 Uint(U32))>], lifetime constraints [\ - InEnvironment { environment: Env([]), goal: '^0.0: '!1_0 }, \ - InEnvironment { environment: Env([]), goal: '^0.0: '!1_1 }, \ - InEnvironment { environment: Env([]), goal: '^0.1: '!1_2 }, \ - InEnvironment { environment: Env([]), goal: '^0.1: '!1_3 } \ - ] }" + expect![["Unique; for { substitution [?0 := 2<(&'^0.0 Uint(U32)), (&'^0.1 Uint(U32))>], lifetime constraints [InEnvironment { environment: Env([]), goal: '^0.0: '!1_0 }, InEnvironment { environment: Env([]), goal: '^0.0: '!1_1 }, InEnvironment { environment: Env([]), goal: '^0.1: '!1_2 }, InEnvironment { environment: Env([]), goal: '^0.1: '!1_3 }] }"]] } } } @@ -637,10 +533,7 @@ fn generalize_array() { } } yields { // Result should be identical to generalize_covariant_struct result. - "Unique; for { substitution [?0 := [(&'^0.0 Uint(U32)); 16]], lifetime constraints [\ - InEnvironment { environment: Env([]), goal: '!1_0: '^0.0 }, \ - InEnvironment { environment: Env([]), goal: '!1_1: '^0.0 } \ - ] }" + expect![["Unique; for { substitution [?0 := [(&'^0.0 Uint(U32)); 16]], lifetime constraints [InEnvironment { environment: Env([]), goal: '!1_0: '^0.0 }, InEnvironment { environment: Env([]), goal: '!1_1: '^0.0 }] }"]] } goal { @@ -652,10 +545,7 @@ fn generalize_array() { } } yields { // Result should be identical to generalize_covariant_struct result. - "Unique; for { substitution [?0 := [(&'^0.0 Uint(U32)); 16]], lifetime constraints [\ - InEnvironment { environment: Env([]), goal: '^0.0: '!1_0 }, \ - InEnvironment { environment: Env([]), goal: '^0.0: '!1_1 } \ - ] }" + expect![["Unique; for { substitution [?0 := [(&'^0.0 Uint(U32)); 16]], lifetime constraints [InEnvironment { environment: Env([]), goal: '^0.0: '!1_0 }, InEnvironment { environment: Env([]), goal: '^0.0: '!1_1 }] }"]] } } } diff --git a/tests/test/tuples.rs b/tests/test/tuples.rs index dd843c64228..9f087a979e1 100644 --- a/tests/test/tuples.rs +++ b/tests/test/tuples.rs @@ -12,13 +12,13 @@ fn tuple_trait_impl() { goal { (S1, S1): Foo } yields { - "Unique" + expect![["Unique"]] } goal { (): Foo } yields { - "Unique" + expect![["Unique"]] } } test! { @@ -30,7 +30,7 @@ fn tuple_trait_impl() { goal { (i32, i32, (i32, )): Foo } yields { - "Unique" + expect![["Unique"]] } } } @@ -50,49 +50,49 @@ fn tuples_are_copy() { goal { ([u8],): Copy } yields { - "No possible solution" + expect![["No possible solution"]] } goal { (u8, [u8]): Copy } yields { - "No possible solution" + expect![["No possible solution"]] } goal { ([u8], u8): Copy } yields { - "No possible solution" + expect![["No possible solution"]] } goal { (): Copy } yields { - "Unique; substitution [], lifetime constraints []" + expect![["Unique"]] } goal { (u8,): Copy } yields { - "Unique; substitution [], lifetime constraints []" + expect![["Unique"]] } goal { (u8, u8): Copy } yields { - "Unique; substitution [], lifetime constraints []" + expect![["Unique"]] } goal { exists { (T, u8): Copy } } yields { - "Ambiguous" + expect![["Ambiguous; no inference guidance"]] } goal { forall { if (T: Copy) { (T, u8): Copy } } } yields { - "Unique; substitution [], lifetime constraints []" + expect![["Unique"]] } } } @@ -108,13 +108,13 @@ fn tuples_are_sized() { goal { ([u8],): Sized } yields { - "No possible solution" + expect![["No possible solution"]] } goal { (u8, [u8]): Sized } yields { - "No possible solution" + expect![["No possible solution"]] } // It should not be well-formed because for tuples, only @@ -122,49 +122,49 @@ fn tuples_are_sized() { goal { ([u8], u8): Sized } yields { - "Unique; substitution [], lifetime constraints []" + expect![["Unique"]] } goal { (): Sized } yields { - "Unique; substitution [], lifetime constraints []" + expect![["Unique"]] } goal { (u8,): Sized } yields { - "Unique; substitution [], lifetime constraints []" + expect![["Unique"]] } goal { (u8, u8): Sized } yields { - "Unique; substitution [], lifetime constraints []" + expect![["Unique"]] } goal { exists { (T, u8): Sized } } yields { - "Unique; for { substitution [?0 := ^0.0], lifetime constraints [] }" + expect![["Unique; for { substitution [?0 := ^0.0] }"]] } goal { forall { (T, u8): Sized } } yields { - "Unique; substitution [], lifetime constraints []" + expect![["Unique"]] } goal { forall { (u8, T): Sized } } yields { - "No possible solution" + expect![["No possible solution"]] } goal { forall { if (T: Sized) { (u8, T): Sized } } } yields { - "Unique; substitution [], lifetime constraints []" + expect![["Unique"]] } } } @@ -184,49 +184,49 @@ fn tuples_are_clone() { goal { ([u8],): Clone } yields { - "No possible solution" + expect![["No possible solution"]] } goal { (u8, [u8]): Clone } yields { - "No possible solution" + expect![["No possible solution"]] } goal { ([u8], u8): Clone } yields { - "No possible solution" + expect![["No possible solution"]] } goal { (): Clone } yields { - "Unique; substitution [], lifetime constraints []" + expect![["Unique"]] } goal { (u8,): Clone } yields { - "Unique; substitution [], lifetime constraints []" + expect![["Unique"]] } goal { (u8, u8): Clone } yields { - "Unique; substitution [], lifetime constraints []" + expect![["Unique"]] } goal { exists { (T, u8): Clone } } yields { - "Ambiguous" + expect![["Ambiguous; no inference guidance"]] } goal { forall { if (T: Clone) { (T, u8): Clone } } } yields { - "Unique; substitution [], lifetime constraints []" + expect![["Unique"]] } } } @@ -242,55 +242,55 @@ fn tuples_are_wf() { goal { WellFormed(()) } yields { - "Unique; substitution [], lifetime constraints []" + expect![["Unique"]] } goal { WellFormed((u8,)) } yields { - "Unique; substitution [], lifetime constraints []" + expect![["Unique"]] } goal { WellFormed((u8, u8)) } yields { - "Unique; substitution [], lifetime constraints []" + expect![["Unique"]] } goal { WellFormed(([u8],)) } yields { - "Unique; substitution [], lifetime constraints []" + expect![["Unique"]] } goal { WellFormed((u8, [u8])) } yields { - "Unique; substitution [], lifetime constraints []" + expect![["Unique"]] } goal { WellFormed(([u8], u8)) } yields { - "No possible solution" + expect![["No possible solution"]] } goal { exists { WellFormed((T, u8)) } } yields { - "Ambiguous; no inference guidance" + expect![["Ambiguous; no inference guidance"]] } goal { forall { WellFormed((T, u8)) } } yields { - "No possible solution" + expect![["No possible solution"]] } goal { forall { if (T: Sized) { WellFormed((T, u8)) } } } yields { - "Unique; substitution [], lifetime constraints []" + expect![["Unique"]] } } } diff --git a/tests/test/unify.rs b/tests/test/unify.rs index c77faa6d4f0..f0e8e662851 100644 --- a/tests/test/unify.rs +++ b/tests/test/unify.rs @@ -21,11 +21,7 @@ fn region_equality() { Ref<'a, Unit>: Eq> } } yields { - "Unique; substitution [], - lifetime constraints \ - [InEnvironment { environment: Env([]), goal: '!1_0: '!1_1 }, \ - InEnvironment { environment: Env([]), goal: '!1_1: '!1_0 }] - " + expect![["Unique; lifetime constraints [InEnvironment { environment: Env([]), goal: '!1_0: '!1_1 }, InEnvironment { environment: Env([]), goal: '!1_1: '!1_0 }]"]] } goal { @@ -35,7 +31,7 @@ fn region_equality() { } } } yields { - "Unique; substitution [?0 := '!1_0], lifetime constraints []" + expect![["Unique; substitution [?0 := '!1_0]"]] } } } @@ -59,7 +55,7 @@ fn forall_equality_solveable_simple() { // all in a valid universe to do so (universe 4). for<'a> fn(Ref<'a, Unit>): Eq fn(Ref<'c, Unit>)> } yields { - "Unique; substitution [], lifetime constraints []" + expect![["Unique"]] } } } @@ -85,11 +81,7 @@ fn forall_equality_unsolveable_simple() { for<'a, 'b> fn(Ref<'a, Ref<'b, Ref<'a, Unit>>>): Eq< for<'c, 'd> fn(Ref<'c, Ref<'d, Ref<'d, Unit>>>)> } yields { - "Unique; substitution [], lifetime constraints [\ - InEnvironment { environment: Env([]), goal: '!1_0: '!1_1 }, \ - InEnvironment { environment: Env([]), goal: '!1_1: '!1_0 }, \ - InEnvironment { environment: Env([]), goal: '!2_0: '!2_1 }, \ - InEnvironment { environment: Env([]), goal: '!2_1: '!2_0 }]" + expect![["Unique; lifetime constraints [InEnvironment { environment: Env([]), goal: '!1_0: '!1_1 }, InEnvironment { environment: Env([]), goal: '!1_1: '!1_0 }, InEnvironment { environment: Env([]), goal: '!2_0: '!2_1 }, InEnvironment { environment: Env([]), goal: '!2_1: '!2_0 }]"]] } } } @@ -114,7 +106,7 @@ fn forall_equality() { // all in a valid universe to do so (universe 4). for<'a, 'b> fn(Ref<'a, Ref<'b, Unit>>): Eq fn(Ref<'c, Ref<'d, Unit>>)> } yields { - "Unique; substitution [], lifetime constraints []" + expect![["Unique"]] } goal { @@ -126,53 +118,49 @@ fn forall_equality() { for<'a, 'b> fn(Ref<'a, Ref<'b, Ref<'a, Unit>>>): Eq< for<'c, 'd> fn(Ref<'c, Ref<'d, Ref<'d, Unit>>>)> } yields { - "Unique; substitution [], lifetime constraints [\ - InEnvironment { environment: Env([]), goal: '!1_0: '!1_1 }, \ - InEnvironment { environment: Env([]), goal: '!1_1: '!1_0 }, \ - InEnvironment { environment: Env([]), goal: '!2_0: '!2_1 }, \ - InEnvironment { environment: Env([]), goal: '!2_1: '!2_0 }]" + expect![["Unique; lifetime constraints [InEnvironment { environment: Env([]), goal: '!1_0: '!1_1 }, InEnvironment { environment: Env([]), goal: '!1_1: '!1_0 }, InEnvironment { environment: Env([]), goal: '!2_0: '!2_1 }, InEnvironment { environment: Env([]), goal: '!2_1: '!2_0 }]"]] } goal { // Function pointers with different ABIs should not be equal. extern "Rust" fn(): Eq } yields { - "No possible solution" + expect![["No possible solution"]] } goal { // Function pointers with identical ABIs should be equal. extern "Rust" fn(): Eq } yields { - "Unique; substitution [], lifetime constraints []" + expect![["Unique"]] } goal { // Function pointers with different safety should not be equal. unsafe fn(): Eq } yields { - "No possible solution" + expect![["No possible solution"]] } goal { // Function pointers with identical safety should be equal. unsafe fn(): Eq } yields { - "Unique; substitution [], lifetime constraints []" + expect![["Unique"]] } goal { // Variadic function pointers should not be equal to non-variadic fn pointers. fn(u8, ...): Eq } yields { - "No possible solution" + expect![["No possible solution"]] } goal { // Variadic function pointers should be equal to variadic fn pointers. fn(u8, ...): Eq } yields { - "Unique; substitution [], lifetime constraints []" + expect![["Unique"]] } } } @@ -190,13 +178,13 @@ fn unify_quantified_lifetimes() { } } } yields { - "Unique; for { \ + expect![["Unique; for { \ substitution [?0 := '^0.0], \ lifetime constraints [\ InEnvironment { environment: Env([]), goal: '!1_0: '^0.0 }, \ InEnvironment { environment: Env([]), goal: '^0.0: '!1_0 }\ ] \ - }" + }"]] } // Similar to the previous test, but indirect. @@ -210,22 +198,22 @@ fn unify_quantified_lifetimes() { } } } yields[SolverChoice::slg(10, None)] { - "Unique; for { \ + expect![["Unique; for { \ substitution [?0 := '^0.0, ?1 := '!1_0], \ lifetime constraints [\ InEnvironment { environment: Env([]), goal: '!1_0: '^0.0 }, \ InEnvironment { environment: Env([]), goal: '^0.0: '!1_0 }\ ] \ - }" + }"]] } yields[SolverChoice::recursive_default()] { // only difference is in the value of ?1, which is equivalent - "Unique; for { \ + expect![["Unique; for { \ substitution [?0 := '^0.0, ?1 := '^0.0], \ lifetime constraints [\ InEnvironment { environment: Env([]), goal: '!1_0: '^0.0 }, \ InEnvironment { environment: Env([]), goal: '^0.0: '!1_0 }\ ] \ - }" + }"]] } } } @@ -247,13 +235,13 @@ fn equality_binder() { } } } yields { - "Unique; for { \ + expect![["Unique; for { \ substitution [?0 := '^0.0], \ lifetime constraints [\ InEnvironment { environment: Env([]), goal: '!2_0: '^0.0 }, \ InEnvironment { environment: Env([]), goal: '^0.0: '!2_0 }\ ] \ - }" + }"]] } } } @@ -268,19 +256,13 @@ fn equality_binder2() { goal { for<'b, 'c> fn(Ref<'b, 'c>) = for<'a> fn(Ref<'a, 'a>) } yields { - "Unique; substitution [], lifetime constraints [\ - InEnvironment { environment: Env([]), goal: '!1_0: '!1_1 }, \ - InEnvironment { environment: Env([]), goal: '!1_1: '!1_0 }\ - ]" + expect![["Unique; lifetime constraints [InEnvironment { environment: Env([]), goal: '!1_0: '!1_1 }, InEnvironment { environment: Env([]), goal: '!1_1: '!1_0 }]"]] } goal { for<'a> fn(Ref<'a, 'a>) = for<'b, 'c> fn(Ref<'b, 'c>) } yields { - "Unique; substitution [], lifetime constraints [\ - InEnvironment { environment: Env([]), goal: '!2_0: '!2_1 }, \ - InEnvironment { environment: Env([]), goal: '!2_1: '!2_0 }\ - ]" + expect![["Unique; lifetime constraints [InEnvironment { environment: Env([]), goal: '!2_0: '!2_1 }, InEnvironment { environment: Env([]), goal: '!2_1: '!2_0 }]"]] } } } @@ -301,10 +283,7 @@ fn mixed_indices_unify() { } } } yields { - "Unique; for { \ - substitution [?0 := '^0.0, ?1 := ^0.1, ?2 := ^0.1], \ - lifetime constraints []\ - }" + expect![["Unique; for { substitution [?0 := '^0.0, ?1 := ^0.1, ?2 := ^0.1] }"]] } } } @@ -328,10 +307,7 @@ fn mixed_indices_match_program() { } } } yields { - "Unique; for { \ - substitution [?0 := '^0.0, ?1 := S, ?2 := S], \ - lifetime constraints [] \ - }" + expect![["Unique; for { substitution [?0 := '^0.0, ?1 := S, ?2 := S] }"]] } } } @@ -359,7 +335,7 @@ fn mixed_indices_normalize_application() { } } } yields { - "Unique; for { substitution [?0 := '^0.0, ?1 := ^0.1, ?2 := ^0.1], " + expect![["Unique; for { substitution [?0 := '^0.0, ?1 := ^0.1, ?2 := ^0.1] }"]] } } } @@ -386,8 +362,7 @@ fn mixed_indices_normalize_gat_application() { } yields { // Our GAT parameter is mapped to ?0; all others appear left to right // in our Normalize(...) goal. - "Unique; for { \ - substitution [?0 := ^0.0, ?1 := '^0.1, ?2 := ^0.2, ?3 := ^0.0, ?4 := ^0.2], " + expect![["Unique; for { substitution [?0 := ^0.0, ?1 := '^0.1, ?2 := ^0.2, ?3 := ^0.0, ?4 := ^0.2] }"]] } } } @@ -405,22 +380,20 @@ fn quantified_types() { goal { for<'a> fn(fn1<'a>): Foo } yields { - "Unique" + expect![["Unique"]] } goal { for<'a, 'b> fn(fn2<'a, 'b>) = for<'b, 'a> fn(fn2<'a, 'b>) } yields { - "Unique" + expect![["Unique"]] } goal { forall<'a> { fn(fn1<'a>): Foo } } yields { // Lifetime constraints are unsatisfiable - "Unique; substitution [], lifetime constraints [\ - InEnvironment { environment: Env([]), goal: '!1_0: '!2_0 }, \ - InEnvironment { environment: Env([]), goal: '!2_0: '!1_0 }]" + expect![["Unique; lifetime constraints [InEnvironment { environment: Env([]), goal: '!1_0: '!2_0 }, InEnvironment { environment: Env([]), goal: '!2_0: '!1_0 }]"]] } } } diff --git a/tests/test/unpin.rs b/tests/test/unpin.rs index 63122a65bfe..e113889208e 100644 --- a/tests/test/unpin.rs +++ b/tests/test/unpin.rs @@ -26,7 +26,7 @@ fn unpin_auto_trait() { goal { A: Unpin } yields { - "Unique" + expect![["Unique"]] } } } @@ -43,7 +43,7 @@ fn unpin_negative() { goal { A: Unpin } yields { - "No possible solution" + expect![["No possible solution"]] } } } @@ -61,7 +61,7 @@ fn unpin_inherit_negative() { goal { B: Unpin } yields { - "No possible solution" + expect![["No possible solution"]] } } } @@ -80,7 +80,7 @@ fn unpin_overwrite() { goal { B: Unpin } yields { - "Unique" + expect![["Unique"]] } } } @@ -112,19 +112,19 @@ fn generator_unpin() { goal { static_gen: Unpin } yields { - "No possible solution" + expect![["No possible solution"]] } goal { movable_gen: Unpin } yields { - "Unique" + expect![["Unique"]] } goal { movable_with_pin: Unpin } yields { - "Unique" + expect![["Unique"]] } } } diff --git a/tests/test/unsize.rs b/tests/test/unsize.rs index a0f1c9729f8..21dd0c62ef9 100644 --- a/tests/test/unsize.rs +++ b/tests/test/unsize.rs @@ -37,7 +37,7 @@ fn dyn_to_dyn_unsizing() { } } } yields { - "Unique; substitution [], lifetime constraints [InEnvironment { environment: Env([]), goal: '!1_0: '!2_0 }]" + expect![["Unique; lifetime constraints [InEnvironment { environment: Env([]), goal: '!1_0: '!2_0 }]"]] } goal { @@ -47,7 +47,7 @@ fn dyn_to_dyn_unsizing() { } } } yields { - "Unique; substitution [], lifetime constraints [InEnvironment { environment: Env([]), goal: '!1_0: '!2_0 }]" + expect![["Unique; lifetime constraints [InEnvironment { environment: Env([]), goal: '!1_0: '!2_0 }]"]] } // Target has a subset of source auto traits @@ -56,7 +56,7 @@ fn dyn_to_dyn_unsizing() { dyn Principal + Auto1 + Auto2 + 'a: Unsize } } yields { - "Unique; substitution [], lifetime constraints [InEnvironment { environment: Env([]), goal: '!1_0: '!1_0 }]" + expect![["Unique; lifetime constraints [InEnvironment { environment: Env([]), goal: '!1_0: '!1_0 }]"]] } // Both target and source don't have principal as their first trait @@ -65,7 +65,7 @@ fn dyn_to_dyn_unsizing() { dyn Auto1 + Principal + 'a: Unsize } } yields { - "Unique; substitution [], lifetime constraints [InEnvironment { environment: Env([]), goal: '!1_0: '!1_0 }]" + expect![["Unique; lifetime constraints [InEnvironment { environment: Env([]), goal: '!1_0: '!1_0 }]"]] } // Different order of traits in target and source @@ -74,7 +74,7 @@ fn dyn_to_dyn_unsizing() { dyn Principal + Auto1 + 'a: Unsize } } yields { - "Unique; substitution [], lifetime constraints [InEnvironment { environment: Env([]), goal: '!1_0: '!1_0 }]" + expect![["Unique; lifetime constraints [InEnvironment { environment: Env([]), goal: '!1_0: '!1_0 }]"]] } // See above @@ -83,7 +83,7 @@ fn dyn_to_dyn_unsizing() { dyn Principal + Auto2 + Auto1 + 'a: Unsize } } yields { - "Unique; substitution [], lifetime constraints [InEnvironment { environment: Env([]), goal: '!1_0: '!1_0 }]" + expect![["Unique; lifetime constraints [InEnvironment { environment: Env([]), goal: '!1_0: '!1_0 }]"]] } // Source has a subset of auto traits of target @@ -92,7 +92,7 @@ fn dyn_to_dyn_unsizing() { dyn Principal + Auto2 + 'a: Unsize } } yields { - "No possible solution" + expect![["No possible solution"]] } // Source and target have different set of auto traits @@ -101,7 +101,7 @@ fn dyn_to_dyn_unsizing() { dyn Principal + Auto1 + Auto2 + 'a: Unsize } } yields { - "No possible solution" + expect![["No possible solution"]] } // Source has a principal trait, while target doesnt, both have the same auto traits. @@ -110,7 +110,7 @@ fn dyn_to_dyn_unsizing() { dyn Principal + Auto1 + 'a: Unsize } } yields { - "No possible solution" + expect![["No possible solution"]] } // Non-matching principal traits @@ -119,7 +119,7 @@ fn dyn_to_dyn_unsizing() { dyn Principal + 'a: Unsize } } yields { - "No possible solution" + expect![["No possible solution"]] } // Matching generic principal traits @@ -128,7 +128,7 @@ fn dyn_to_dyn_unsizing() { dyn GenericPrincipal + 'a: Unsize + 'a> } } yields { - "Unique; substitution [], lifetime constraints [InEnvironment { environment: Env([]), goal: '!1_0: '!1_0 }]" + expect![["Unique; lifetime constraints [InEnvironment { environment: Env([]), goal: '!1_0: '!1_0 }]"]] } // Non-matching generic principal traits @@ -137,7 +137,7 @@ fn dyn_to_dyn_unsizing() { dyn GenericPrincipal + 'a: Unsize + 'a> } } yields { - "No possible solution" + expect![["No possible solution"]] } } } @@ -192,7 +192,7 @@ fn ty_to_dyn_unsizing() { Foo: Unsize } } yields { - "Unique; substitution [], lifetime constraints [InEnvironment { environment: Env([]), goal: Foo: '!1_0 }]" + expect![["Unique; lifetime constraints [InEnvironment { environment: Env([]), goal: Foo: '!1_0 }]"]] } // Principal is not the first trait @@ -201,7 +201,7 @@ fn ty_to_dyn_unsizing() { Foo: Unsize } } yields { - "Unique; substitution [], lifetime constraints [InEnvironment { environment: Env([]), goal: Foo: '!1_0 }]" + expect![["Unique; lifetime constraints [InEnvironment { environment: Env([]), goal: Foo: '!1_0 }]"]] } // Auto-only trait object @@ -210,7 +210,7 @@ fn ty_to_dyn_unsizing() { Foo: Unsize } } yields { - "Unique; substitution [], lifetime constraints [InEnvironment { environment: Env([]), goal: Foo: '!1_0 }]" + expect![["Unique; lifetime constraints [InEnvironment { environment: Env([]), goal: Foo: '!1_0 }]"]] } // TypeOutlives test @@ -219,7 +219,7 @@ fn ty_to_dyn_unsizing() { FooLifetime<'a>: Unsize } } yields { - "Unique; substitution [], lifetime constraints [InEnvironment { environment: Env([]), goal: FooLifetime<'!1_0>: '!1_0 }]" + expect![["Unique; lifetime constraints [InEnvironment { environment: Env([]), goal: FooLifetime<'!1_0>: '!1_0 }]"]] } // See above @@ -230,7 +230,7 @@ fn ty_to_dyn_unsizing() { } } } yields { - "Unique; for { substitution [?0 := '^0.0], lifetime constraints [InEnvironment { environment: Env([]), goal: FooLifetime<'!1_0>: '^0.0 }] }" + expect![["Unique; for { substitution [?0 := '^0.0], lifetime constraints [InEnvironment { environment: Env([]), goal: FooLifetime<'!1_0>: '^0.0 }] }"]] } // Source does not implement auto trait (with principal) @@ -239,7 +239,7 @@ fn ty_to_dyn_unsizing() { Bar: Unsize } } yields { - "No possible solution" + expect![["No possible solution"]] } // Source does not implement auto trait (without principal) @@ -248,7 +248,7 @@ fn ty_to_dyn_unsizing() { Bar: Unsize } } yields { - "No possible solution" + expect![["No possible solution"]] } // Source does not implement principal @@ -257,7 +257,7 @@ fn ty_to_dyn_unsizing() { Baz: Unsize } } yields { - "No possible solution" + expect![["No possible solution"]] } // Implemeted generic principal @@ -266,7 +266,7 @@ fn ty_to_dyn_unsizing() { Foo: Unsize + 'a> } } yields { - "Unique; substitution [], lifetime constraints [InEnvironment { environment: Env([]), goal: Foo: '!1_0 }]" + expect![["Unique; lifetime constraints [InEnvironment { environment: Env([]), goal: Foo: '!1_0 }]"]] } @@ -276,7 +276,7 @@ fn ty_to_dyn_unsizing() { Foo: Unsize + 'a> } } yields { - "No possible solution" + expect![["No possible solution"]] } // Not object-safe principal trait @@ -285,7 +285,7 @@ fn ty_to_dyn_unsizing() { Foo: Unsize } } yields { - "No possible solution" + expect![["No possible solution"]] } // Source ty is not Sized @@ -296,7 +296,7 @@ fn ty_to_dyn_unsizing() { } } } yields { - "No possible solution" + expect![["No possible solution"]] } // Sized counterpart for the previous test @@ -309,7 +309,7 @@ fn ty_to_dyn_unsizing() { } } } yields { - "Unique; substitution [], lifetime constraints [InEnvironment { environment: Env([]), goal: FooNotSized: '!1_0 }]" + expect![["Unique; lifetime constraints [InEnvironment { environment: Env([]), goal: FooNotSized: '!1_0 }]"]] } } } @@ -336,13 +336,13 @@ fn tuple_unsizing() { goal { (): Unsize<()> } yields { - "No possible solution" + expect![["No possible solution"]] } goal { (u32, u32): Unsize<(u32, u32)> } yields { - "No possible solution" + expect![["No possible solution"]] } goal { @@ -350,7 +350,7 @@ fn tuple_unsizing() { (u32, Foo): Unsize<(u32, dyn Principal + 'a)> } } yields { - "Unique; substitution [], lifetime constraints [InEnvironment { environment: Env([]), goal: Foo: '!1_0 }]" + expect![["Unique; lifetime constraints [InEnvironment { environment: Env([]), goal: Foo: '!1_0 }]"]] } // Last field does not implement `Unsize` @@ -359,7 +359,7 @@ fn tuple_unsizing() { (u32, Foo): Unsize<(u32, dyn OtherPrincipal + 'a)> } } yields { - "No possible solution" + expect![["No possible solution"]] } // Mismatch of head fields @@ -368,7 +368,7 @@ fn tuple_unsizing() { (u32, Foo): Unsize<(u64, dyn Principal + 'a)> } } yields { - "No possible solution" + expect![["No possible solution"]] } // Tuple length mismatch @@ -377,7 +377,7 @@ fn tuple_unsizing() { (u32, u32, Foo): Unsize<(u32, dyn Principal + 'a)> } } yields { - "No possible solution" + expect![["No possible solution"]] } // Multilevel tuple test @@ -386,7 +386,7 @@ fn tuple_unsizing() { (u32, (u32, Foo)): Unsize<(u32, (u32, dyn Principal + 'a))> } } yields { - "Unique; substitution [], lifetime constraints [InEnvironment { environment: Env([]), goal: Foo: '!1_0 }]" + expect![["Unique; lifetime constraints [InEnvironment { environment: Env([]), goal: Foo: '!1_0 }]"]] } } } @@ -404,13 +404,13 @@ fn array_unsizing() { goal { [Foo; 2]: Unsize<[Foo]> } yields { - "Unique" + expect![["Unique"]] } goal { [Foo; 5]: Unsize<[Foo]> } yields { - "No possible solution" + expect![["No possible solution"]] } } } @@ -489,7 +489,7 @@ fn struct_unsizing() { goal { Foo: Unsize } yields { - "No possible solution" + expect![["No possible solution"]] } goal { @@ -497,7 +497,7 @@ fn struct_unsizing() { S1: Unsize> } } yields { - "Unique; substitution [], lifetime constraints [InEnvironment { environment: Env([]), goal: Foo: '!1_0 }]" + expect![["Unique; lifetime constraints [InEnvironment { environment: Env([]), goal: Foo: '!1_0 }]"]] } goal { @@ -505,7 +505,7 @@ fn struct_unsizing() { S1: Unsize> } } yields { - "No possible solution" + expect![["No possible solution"]] } // Unsizing parameter is used in head fields @@ -515,7 +515,7 @@ fn struct_unsizing() { Unsize> } } yields { - "No possible solution" + expect![["No possible solution"]] } // Two-field struct test @@ -524,7 +524,7 @@ fn struct_unsizing() { S12: Unsize> } } yields { - "Unique; substitution [], lifetime constraints [InEnvironment { environment: Env([]), goal: Foo: '!1_0 }]" + expect![["Unique; lifetime constraints [InEnvironment { environment: Env([]), goal: Foo: '!1_0 }]"]] } // Test for the unsizing parameters collector @@ -534,7 +534,7 @@ fn struct_unsizing() { SWithBinders: Unsize> } } yields { - "Unique; substitution [], lifetime constraints [InEnvironment { environment: Env([]), goal: Foo: '!1_0 }]" + expect![["Unique; lifetime constraints [InEnvironment { environment: Env([]), goal: Foo: '!1_0 }]"]] } // Non-trivial unsizing of the last field @@ -543,7 +543,7 @@ fn struct_unsizing() { SNested, Foo>: Unsize, dyn Principal + 'a>> } } yields { - "Unique; substitution [], lifetime constraints [InEnvironment { environment: Env([]), goal: Foo: '!1_0 }]" + expect![["Unique; lifetime constraints [InEnvironment { environment: Env([]), goal: Foo: '!1_0 }]"]] } goal { @@ -551,7 +551,7 @@ fn struct_unsizing() { SBad: Unsize> } } yields { - "No possible solution" + expect![["No possible solution"]] } // Check that lifetimes can't be used as unsizing parameters @@ -560,14 +560,14 @@ fn struct_unsizing() { SLifetime<'a, Foo>: Unsize> } } yields { - "Unique; substitution [], lifetime constraints [InEnvironment { environment: Env([]), goal: Foo: '!1_0 }]" + expect![["Unique; lifetime constraints [InEnvironment { environment: Env([]), goal: Foo: '!1_0 }]"]] } // Tests with constant as an unsizing parameter goal { SGoodConst<5, [u32; 2]>: Unsize> } yields { - "Unique; substitution [], lifetime constraints []" + expect![["Unique"]] } @@ -575,14 +575,14 @@ fn struct_unsizing() { goal { SGoodConst<4, [u32; 2]>: Unsize> } yields { - "No possible solution" + expect![["No possible solution"]] } // Unsizing parameter is used in head fields goal { SBadConst<5, [u32; 2]>: Unsize> } yields { - "No possible solution" + expect![["No possible solution"]] } } } diff --git a/tests/test/wf_goals.rs b/tests/test/wf_goals.rs index 47681821acb..08436ed331a 100644 --- a/tests/test/wf_goals.rs +++ b/tests/test/wf_goals.rs @@ -19,19 +19,19 @@ fn struct_wf() { goal { WellFormed(Foo) } yields { - "No possible solution" + expect![["No possible solution"]] } goal { WellFormed(Foo) } yields { - "Unique; substitution [], lifetime constraints []" + expect![["Unique"]] } goal { WellFormed(Foo>) } yields { - "Unique; substitution [], lifetime constraints []" + expect![["Unique"]] } } } @@ -53,19 +53,19 @@ fn enum_wf() { goal { WellFormed(Foo) } yields { - "No possible solution" + expect![["No possible solution"]] } goal { WellFormed(Foo) } yields { - "Unique; substitution [], lifetime constraints []" + expect![["Unique"]] } goal { WellFormed(Foo>) } yields { - "Unique; substitution [], lifetime constraints []" + expect![["Unique"]] } } } @@ -85,7 +85,7 @@ fn recursive_where_clause_on_type() { goal { WellFormed(S) } yields { - "No possible solution" + expect![["No possible solution"]] } } } @@ -103,7 +103,7 @@ fn drop_compatible() { goal { compatible { not { exists { S: Drop } } } } yields { - "Unique; substitution [], lifetime constraints []" + expect![["Unique"]] } } } @@ -114,7 +114,7 @@ fn placeholder_wf() { goal { forall { WellFormed(T) } } yields { - "Unique; substitution [], lifetime constraints []" + expect![["Unique"]] } } }