diff options
Diffstat (limited to 'tests')
57 files changed, 808 insertions, 310 deletions
diff --git a/tests/mir-opt/sroa.constant.ScalarReplacementOfAggregates.diff b/tests/mir-opt/sroa.constant.ScalarReplacementOfAggregates.diff new file mode 100644 index 00000000000..9e33215f2b5 --- /dev/null +++ b/tests/mir-opt/sroa.constant.ScalarReplacementOfAggregates.diff @@ -0,0 +1,46 @@ +- // MIR for `constant` before ScalarReplacementOfAggregates ++ // MIR for `constant` after ScalarReplacementOfAggregates + + fn constant() -> () { + let mut _0: (); // return place in scope 0 at $DIR/sroa.rs:+0:15: +0:15 + let _1: (usize, u8); // in scope 0 at $DIR/sroa.rs:+2:9: +2:10 ++ let _4: usize; // in scope 0 at $DIR/sroa.rs:+2:9: +2:10 ++ let _5: u8; // in scope 0 at $DIR/sroa.rs:+2:9: +2:10 + scope 1 { +- debug y => _1; // in scope 1 at $DIR/sroa.rs:+2:9: +2:10 ++ debug y => (usize, u8){ .0 => _4, .1 => _5, }; // in scope 1 at $DIR/sroa.rs:+2:9: +2:10 + let _2: usize; // in scope 1 at $DIR/sroa.rs:+3:9: +3:10 + scope 2 { + debug t => _2; // in scope 2 at $DIR/sroa.rs:+3:9: +3:10 + let _3: u8; // in scope 2 at $DIR/sroa.rs:+4:9: +4:10 + scope 3 { + debug u => _3; // in scope 3 at $DIR/sroa.rs:+4:9: +4:10 + } + } + } + + bb0: { +- StorageLive(_1); // scope 0 at $DIR/sroa.rs:+2:9: +2:10 ++ StorageLive(_4); // scope 0 at $DIR/sroa.rs:+2:9: +2:10 ++ StorageLive(_5); // scope 0 at $DIR/sroa.rs:+2:9: +2:10 ++ nop; // scope 0 at $DIR/sroa.rs:+2:9: +2:10 + _1 = const _; // scope 0 at $DIR/sroa.rs:+2:13: +2:14 ++ _4 = move (_1.0: usize); // scope 1 at $DIR/sroa.rs:+3:9: +3:10 ++ _5 = move (_1.1: u8); // scope 1 at $DIR/sroa.rs:+3:9: +3:10 + StorageLive(_2); // scope 1 at $DIR/sroa.rs:+3:9: +3:10 +- _2 = (_1.0: usize); // scope 1 at $DIR/sroa.rs:+3:13: +3:16 ++ _2 = _4; // scope 1 at $DIR/sroa.rs:+3:13: +3:16 + StorageLive(_3); // scope 2 at $DIR/sroa.rs:+4:9: +4:10 +- _3 = (_1.1: u8); // scope 2 at $DIR/sroa.rs:+4:13: +4:16 ++ _3 = _5; // scope 2 at $DIR/sroa.rs:+4:13: +4:16 + _0 = const (); // scope 0 at $DIR/sroa.rs:+0:15: +5:2 + StorageDead(_3); // scope 2 at $DIR/sroa.rs:+5:1: +5:2 + StorageDead(_2); // scope 1 at $DIR/sroa.rs:+5:1: +5:2 +- StorageDead(_1); // scope 0 at $DIR/sroa.rs:+5:1: +5:2 ++ StorageDead(_4); // scope 0 at $DIR/sroa.rs:+5:1: +5:2 ++ StorageDead(_5); // scope 0 at $DIR/sroa.rs:+5:1: +5:2 ++ nop; // scope 0 at $DIR/sroa.rs:+5:1: +5:2 + return; // scope 0 at $DIR/sroa.rs:+5:2: +5:2 + } + } + diff --git a/tests/mir-opt/sroa.rs b/tests/mir-opt/sroa.rs index 471aac9f9d8..b69de2e124e 100644 --- a/tests/mir-opt/sroa.rs +++ b/tests/mir-opt/sroa.rs @@ -87,6 +87,13 @@ fn ref_copies(x: &Foo) { let u = y.c; } +fn constant() { + const U: (usize, u8) = (5, 9); + let y = U; + let t = y.0; + let u = y.1; +} + fn main() { dropping(); enums(5); @@ -96,6 +103,7 @@ fn main() { escaping(); copies(Foo { a: 5, b: (), c: "a", d: Some(-4) }); ref_copies(&Foo { a: 5, b: (), c: "a", d: Some(-4) }); + constant(); } // EMIT_MIR sroa.dropping.ScalarReplacementOfAggregates.diff @@ -106,3 +114,4 @@ fn main() { // EMIT_MIR sroa.escaping.ScalarReplacementOfAggregates.diff // EMIT_MIR sroa.copies.ScalarReplacementOfAggregates.diff // EMIT_MIR sroa.ref_copies.ScalarReplacementOfAggregates.diff +// EMIT_MIR sroa.constant.ScalarReplacementOfAggregates.diff diff --git a/tests/run-make/rlib-format-packed-bundled-libs-3/Makefile b/tests/run-make/rlib-format-packed-bundled-libs-3/Makefile new file mode 100644 index 00000000000..62dc1b5f606 --- /dev/null +++ b/tests/run-make/rlib-format-packed-bundled-libs-3/Makefile @@ -0,0 +1,35 @@ +-include ../../run-make-fulldeps/tools.mk + +# ignore-cross-compile +# only-linux + +# Make sure -Zpacked_bundled_libs-like behavior activates with whole-archive. + +# We're using the llvm-nm instead of the system nm to ensure it is compatible +# with the LLVM bitcode generated by rustc. +NM = "$(LLVM_BIN_DIR)"/llvm-nm + +all: $(call NATIVE_STATICLIB,native_dep_1) $(call NATIVE_STATICLIB,native_dep_2) $(call NATIVE_STATICLIB,native_dep_3) $(call NATIVE_STATICLIB,native_dep_4) + # test cfg with packed bundle + $(RUSTC) rust_dep_cfg.rs --crate-type=rlib -Zpacked_bundled_libs + $(RUSTC) main.rs --extern rust_dep=$(TMPDIR)/librust_dep_cfg.rlib --crate-type=staticlib --cfg should_add + $(AR) t $(TMPDIR)/librust_dep_cfg.rlib | $(CGREP) -e "libnative_dep_1.a" + $(AR) t $(TMPDIR)/librust_dep_cfg.rlib | $(CGREP) -e "libnative_dep_2.a" + $(AR) t $(TMPDIR)/libmain.a | $(CGREP) -e "libnative_dep_1.o" + $(AR) t $(TMPDIR)/libmain.a | $(CGREP) -ev "libnative_dep_2.o" + + + # test bundle with whole_archive + $(RUSTC) rust_dep.rs --crate-type=rlib + $(AR) t $(TMPDIR)/librust_dep.rlib | $(CGREP) -e "native_dep_1" + $(AR) t $(TMPDIR)/librust_dep.rlib | $(CGREP) -e "native_dep_3" + $(AR) t $(TMPDIR)/librust_dep.rlib | $(CGREP) -ev "native_dep_2" + $(AR) t $(TMPDIR)/librust_dep.rlib | $(CGREP) -ev "native_dep_4" + + # Make sure compiler doesn't use files, that it shouldn't know about. + rm $(TMPDIR)/libnative_dep_1.a + rm $(TMPDIR)/libnative_dep_3.a + + $(RUSTC) main.rs --extern rust_dep=$(TMPDIR)/librust_dep.rlib --print link-args > $(TMPDIR)/link_args + cat $(TMPDIR)/link_args | $(CGREP) -ev "native_dep_3" + cat $(TMPDIR)/link_args | $(CGREP) -e "--whole-archive.*native_dep_1.*--whole-archive.*lnative_dep_2.*no-whole-archive.*lnative_dep_4" diff --git a/tests/run-make/rlib-format-packed-bundled-libs-3/main.rs b/tests/run-make/rlib-format-packed-bundled-libs-3/main.rs new file mode 100644 index 00000000000..8d2b8a2859c --- /dev/null +++ b/tests/run-make/rlib-format-packed-bundled-libs-3/main.rs @@ -0,0 +1,5 @@ +extern crate rust_dep; + +pub fn main() { + rust_dep::rust_dep(); +} diff --git a/tests/run-make/rlib-format-packed-bundled-libs-3/native_dep_1.c b/tests/run-make/rlib-format-packed-bundled-libs-3/native_dep_1.c new file mode 100644 index 00000000000..07be8562c92 --- /dev/null +++ b/tests/run-make/rlib-format-packed-bundled-libs-3/native_dep_1.c @@ -0,0 +1 @@ +int native_f1() { return 1; } diff --git a/tests/run-make/rlib-format-packed-bundled-libs-3/native_dep_2.c b/tests/run-make/rlib-format-packed-bundled-libs-3/native_dep_2.c new file mode 100644 index 00000000000..a1b94e40dc0 --- /dev/null +++ b/tests/run-make/rlib-format-packed-bundled-libs-3/native_dep_2.c @@ -0,0 +1 @@ +int native_f2() { return 2; } diff --git a/tests/run-make/rlib-format-packed-bundled-libs-3/native_dep_3.c b/tests/run-make/rlib-format-packed-bundled-libs-3/native_dep_3.c new file mode 100644 index 00000000000..f81f397a4b1 --- /dev/null +++ b/tests/run-make/rlib-format-packed-bundled-libs-3/native_dep_3.c @@ -0,0 +1 @@ +int native_f3() { return 3; } diff --git a/tests/run-make/rlib-format-packed-bundled-libs-3/native_dep_4.c b/tests/run-make/rlib-format-packed-bundled-libs-3/native_dep_4.c new file mode 100644 index 00000000000..14d41d60b1f --- /dev/null +++ b/tests/run-make/rlib-format-packed-bundled-libs-3/native_dep_4.c @@ -0,0 +1 @@ +int native_f4() { return 4; } diff --git a/tests/run-make/rlib-format-packed-bundled-libs-3/rust_dep.rs b/tests/run-make/rlib-format-packed-bundled-libs-3/rust_dep.rs new file mode 100644 index 00000000000..abd846b6862 --- /dev/null +++ b/tests/run-make/rlib-format-packed-bundled-libs-3/rust_dep.rs @@ -0,0 +1,16 @@ +#![feature(packed_bundled_libs)] + +#[link(name = "native_dep_1", kind = "static", modifiers = "+whole-archive,+bundle")] +extern "C" {} + +#[link(name = "native_dep_2", kind = "static", modifiers = "+whole-archive,-bundle")] +extern "C" {} + +#[link(name = "native_dep_3", kind = "static", modifiers = "+bundle")] +extern "C" {} + +#[link(name = "native_dep_4", kind = "static", modifiers = "-bundle")] +extern "C" {} + +#[no_mangle] +pub fn rust_dep() {} diff --git a/tests/run-make/rlib-format-packed-bundled-libs-3/rust_dep_cfg.rs b/tests/run-make/rlib-format-packed-bundled-libs-3/rust_dep_cfg.rs new file mode 100644 index 00000000000..506ca62a8a6 --- /dev/null +++ b/tests/run-make/rlib-format-packed-bundled-libs-3/rust_dep_cfg.rs @@ -0,0 +1,10 @@ +#![feature(link_cfg)] + +#[link(name = "native_dep_1", kind = "static", cfg(should_add))] +extern "C" {} + +#[link(name = "native_dep_2", kind = "static", cfg(should_not_add))] +extern "C" {} + +#[no_mangle] +pub fn rust_dep() {} diff --git a/tests/rustdoc-gui/codeblock-tooltip.goml b/tests/rustdoc-gui/codeblock-tooltip.goml index a3ef4e77b54..36b67073a03 100644 --- a/tests/rustdoc-gui/codeblock-tooltip.goml +++ b/tests/rustdoc-gui/codeblock-tooltip.goml @@ -30,24 +30,16 @@ define-function: ( ".docblock .example-wrap.compile_fail", {"border-left": "2px solid rgb(255, 0, 0)"}, ) - assert-css: ( - ".docblock .example-wrap.compile_fail .tooltip::after", - { - "content": '"This example deliberately fails to compile"', - "padding": "5px 3px 3px", - "background-color": |background|, - "color": |color|, - "border": "1px solid " + |border|, - }, - ) - assert-css: ( - ".docblock .example-wrap.compile_fail .tooltip::before", - { - "border-width": "5px", - "border-style": "solid", - "border-color": "rgba(0, 0, 0, 0) " + |background| + " rgba(0, 0, 0, 0) rgba(0, 0, 0, 0)", - }, - ) + click: ".docblock .example-wrap.compile_fail .tooltip" + assert-text: ( + ".popover.tooltip", + "This example deliberately fails to compile" + ) + assert-css: (".popover.tooltip", { + "color": |color|, + "background-color": |background|, + "border-color": |border|, + }) // should_panic block assert-css: ( @@ -69,24 +61,16 @@ define-function: ( ".docblock .example-wrap.should_panic", {"border-left": "2px solid rgb(255, 0, 0)"}, ) - assert-css: ( - ".docblock .example-wrap.should_panic .tooltip::after", - { - "content": '"This example panics"', - "padding": "5px 3px 3px", - "background-color": |background|, - "color": |color|, - "border": "1px solid " + |border|, - }, - ) - assert-css: ( - ".docblock .example-wrap.should_panic .tooltip::before", - { - "border-width": "5px", - "border-style": "solid", - "border-color": "rgba(0, 0, 0, 0) " + |background| + " rgba(0, 0, 0, 0) rgba(0, 0, 0, 0)", - }, + click: ".docblock .example-wrap.should_panic .tooltip" + assert-text: ( + ".popover.tooltip", + "This example panics" ) + assert-css: (".popover.tooltip", { + "color": |color|, + "background-color": |background|, + "border-color": |border|, + }) // ignore block assert-css: ( @@ -108,42 +92,36 @@ define-function: ( ".docblock .example-wrap.ignore", {"border-left": "2px solid rgb(255, 142, 0)"}, ) - assert-css: ( - ".docblock .example-wrap.ignore .tooltip::after", - { - "content": '"This example is not tested"', - "padding": "5px 3px 3px", - "background-color": |background|, - "color": |color|, - "border": "1px solid " + |border|, - }, - ) - assert-css: ( - ".docblock .example-wrap.ignore .tooltip::before", - { - "border-width": "5px", - "border-style": "solid", - "border-color": "rgba(0, 0, 0, 0) " + |background| + " rgba(0, 0, 0, 0) rgba(0, 0, 0, 0)", - }, - ) + click: ".docblock .example-wrap.ignore .tooltip" + assert-text: ( + ".popover.tooltip", + "This example is not tested" + ) + assert-css: (".popover.tooltip", { + "color": |color|, + "background-color": |background|, + "border-color": |border|, + }) + click: ".docblock .example-wrap.ignore .tooltip" + assert-false: ".popover.tooltip" }, ) call-function: ("check-colors", { "theme": "ayu", - "background": "rgb(49, 69, 89)", + "background": "rgb(15, 20, 25)", "color": "rgb(197, 197, 197)", "border": "rgb(92, 103, 115)", }) call-function: ("check-colors", { "theme": "dark", - "background": "rgb(0, 0, 0)", - "color": "rgb(255, 255, 255)", + "background": "rgb(53, 53, 53)", + "color": "rgb(221, 221, 221)", "border": "rgb(224, 224, 224)", }) call-function: ("check-colors", { "theme": "light", - "background": "rgb(0, 0, 0)", - "color": "rgb(255, 255, 255)", + "background": "rgb(255, 255, 255)", + "color": "rgb(0, 0, 0)", "border": "rgb(224, 224, 224)", }) diff --git a/tests/rustdoc-gui/mobile.goml b/tests/rustdoc-gui/mobile.goml index 3e444cbd6dc..8c8516ebff8 100644 --- a/tests/rustdoc-gui/mobile.goml +++ b/tests/rustdoc-gui/mobile.goml @@ -12,7 +12,7 @@ assert-css: (".main-heading", { "flex-direction": "column" }) -assert-property: (".mobile-topbar h2", {"offsetHeight": 36}) +assert-property: (".mobile-topbar h2", {"offsetHeight": 33}) // Note: We can't use assert-text here because the 'Since' is set by CSS and // is therefore not part of the DOM. diff --git a/tests/rustdoc-gui/notable-trait.goml b/tests/rustdoc-gui/notable-trait.goml index b4fa7d0dbf0..20728915199 100644 --- a/tests/rustdoc-gui/notable-trait.goml +++ b/tests/rustdoc-gui/notable-trait.goml @@ -6,13 +6,13 @@ size: (1100, 600) // Checking they have the same y position. compare-elements-position: ( "//*[@id='method.create_an_iterator_from_read']//a[text()='NotableStructWithLongName']", - "//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits']", + "//*[@id='method.create_an_iterator_from_read']//*[@class='tooltip']", ("y"), ) // Checking they don't have the same x position. compare-elements-position-false: ( "//*[@id='method.create_an_iterator_from_read']//a[text()='NotableStructWithLongName']", - "//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits']", + "//*[@id='method.create_an_iterator_from_read']//*[@class='tooltip']", ("x"), ) // The `i` should be *after* the type. @@ -21,33 +21,33 @@ assert-position: ( {"x": 677}, ) assert-position: ( - "//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits']", + "//*[@id='method.create_an_iterator_from_read']//*[@class='tooltip']", {"x": 955}, ) // The tooltip should be below the `i` // Also, clicking the tooltip should bring its text into the DOM -assert-count: ("//*[@class='notable popover']", 0) -click: "//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits']" -assert-count: ("//*[@class='notable popover']", 1) +assert-count: ("//*[@class='tooltip popover']", 0) +click: "//*[@id='method.create_an_iterator_from_read']//*[@class='tooltip']" +assert-count: ("//*[@class='tooltip popover']", 1) compare-elements-position-near: ( - "//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits']", - "//*[@class='notable popover']", + "//*[@id='method.create_an_iterator_from_read']//*[@class='tooltip']", + "//*[@class='tooltip popover']", {"y": 30} ) compare-elements-position-false: ( - "//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits']", - "//*[@class='notable popover']", + "//*[@id='method.create_an_iterator_from_read']//*[@class='tooltip']", + "//*[@class='tooltip popover']", ("x") ) -click: "//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits']" +click: "//*[@id='method.create_an_iterator_from_read']//*[@class='tooltip']" move-cursor-to: "//h1" -assert-count: ("//*[@class='notable popover']", 0) +assert-count: ("//*[@class='tooltip popover']", 0) // Now only the `i` should be on the next line. size: (1055, 600) compare-elements-position-false: ( "//*[@id='method.create_an_iterator_from_read']//a[text()='NotableStructWithLongName']", - "//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits']", + "//*[@id='method.create_an_iterator_from_read']//*[@class='tooltip']", ("y", "x"), ) @@ -56,13 +56,13 @@ size: (980, 600) // Checking they have the same y position. compare-elements-position: ( "//*[@id='method.create_an_iterator_from_read']//a[text()='NotableStructWithLongName']", - "//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits']", + "//*[@id='method.create_an_iterator_from_read']//*[@class='tooltip']", ("y"), ) // Checking they don't have the same x position. compare-elements-position-false: ( "//*[@id='method.create_an_iterator_from_read']//a[text()='NotableStructWithLongName']", - "//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits']", + "//*[@id='method.create_an_iterator_from_read']//*[@class='tooltip']", ("x"), ) // The `i` should be *after* the type. @@ -71,7 +71,7 @@ assert-position: ( {"x": 245}, ) assert-position: ( - "//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits']", + "//*[@id='method.create_an_iterator_from_read']//*[@class='tooltip']", {"x": 523}, ) @@ -80,13 +80,13 @@ size: (650, 600) // Checking they have the same y position. compare-elements-position: ( "//*[@id='method.create_an_iterator_from_read']//a[text()='NotableStructWithLongName']", - "//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits']", + "//*[@id='method.create_an_iterator_from_read']//*[@class='tooltip']", ("y"), ) // Checking they don't have the same x position. compare-elements-position-false: ( "//*[@id='method.create_an_iterator_from_read']//a[text()='NotableStructWithLongName']", - "//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits']", + "//*[@id='method.create_an_iterator_from_read']//*[@class='tooltip']", ("x"), ) // The `i` should be *after* the type. @@ -95,29 +95,29 @@ assert-position: ( {"x": 15}, ) assert-position: ( - "//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits']", + "//*[@id='method.create_an_iterator_from_read']//*[@class='tooltip']", {"x": 293}, ) // The tooltip should STILL be below `i` -click: "//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits']" -assert-count: ("//*[@class='notable popover']", 1) +click: "//*[@id='method.create_an_iterator_from_read']//*[@class='tooltip']" +assert-count: ("//*[@class='tooltip popover']", 1) compare-elements-position-near: ( - "//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits']", - "//*[@class='notable popover']", + "//*[@id='method.create_an_iterator_from_read']//*[@class='tooltip']", + "//*[@class='tooltip popover']", {"y": 30} ) compare-elements-position-false: ( - "//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits']", - "//*[@class='notable popover']", + "//*[@id='method.create_an_iterator_from_read']//*[@class='tooltip']", + "//*[@class='tooltip popover']", ("x") ) assert-position: ( - "//*[@class='notable popover']", + "//*[@class='tooltip popover']", {"x": 0} ) -click: "//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits']" +click: "//*[@id='method.create_an_iterator_from_read']//*[@class='tooltip']" move-cursor-to: "//h1" -assert-count: ("//*[@class='notable popover']", 0) +assert-count: ("//*[@class='tooltip popover']", 0) // Now check the colors. define-function: ( @@ -133,26 +133,26 @@ define-function: ( // We reload the page so the local storage settings are being used. reload: - move-cursor-to: "//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits']" - assert-count: (".notable.popover", 1) + move-cursor-to: "//*[@id='method.create_an_iterator_from_read']//*[@class='tooltip']" + assert-count: (".tooltip.popover", 1) assert-css: ( - ".notable.popover h3", + ".tooltip.popover h3", {"color": |header_color|}, ALL, ) assert-css: ( - ".notable.popover pre", + ".tooltip.popover pre", {"color": |content_color|}, ALL, ) assert-css: ( - ".notable.popover pre a.struct", + ".tooltip.popover pre a.struct", {"color": |type_color|}, ALL, ) assert-css: ( - ".notable.popover pre a.trait", + ".tooltip.popover pre a.trait", {"color": |trait_color|}, ALL, ) @@ -195,24 +195,24 @@ call-function: ( reload: // Check that pressing escape works -click: "//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits']" -move-cursor-to: "//*[@class='notable popover']" -assert-count: ("//*[@class='notable popover']", 1) +click: "//*[@id='method.create_an_iterator_from_read']//*[@class='tooltip']" +move-cursor-to: "//*[@class='tooltip popover']" +assert-count: ("//*[@class='tooltip popover']", 1) press-key: "Escape" -assert-count: ("//*[@class='notable popover']", 0) -assert: "#method\.create_an_iterator_from_read .notable-traits:focus" +assert-count: ("//*[@class='tooltip popover']", 0) +assert: "#method\.create_an_iterator_from_read .tooltip:focus" // Check that clicking outside works. -click: "//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits']" -assert-count: ("//*[@class='notable popover']", 1) +click: "//*[@id='method.create_an_iterator_from_read']//*[@class='tooltip']" +assert-count: ("//*[@class='tooltip popover']", 1) click: ".search-input" -assert-count: ("//*[@class='notable popover']", 0) -assert-false: "#method\.create_an_iterator_from_read .notable-traits:focus" +assert-count: ("//*[@class='tooltip popover']", 0) +assert-false: "#method\.create_an_iterator_from_read .tooltip:focus" // Check that pressing tab over and over works. -click: "//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits']" -move-cursor-to: "//*[@class='notable popover']" -assert-count: ("//*[@class='notable popover']", 1) +click: "//*[@id='method.create_an_iterator_from_read']//*[@class='tooltip']" +move-cursor-to: "//*[@class='tooltip popover']" +assert-count: ("//*[@class='tooltip popover']", 1) press-key: "Tab" press-key: "Tab" press-key: "Tab" @@ -220,8 +220,8 @@ press-key: "Tab" press-key: "Tab" press-key: "Tab" press-key: "Tab" -assert-count: ("//*[@class='notable popover']", 0) -assert: "#method\.create_an_iterator_from_read .notable-traits:focus" +assert-count: ("//*[@class='tooltip popover']", 0) +assert: "#method\.create_an_iterator_from_read .tooltip:focus" // Now we check that the focus isn't given back to the wrong item when opening // another popover. @@ -231,8 +231,8 @@ click: "#method\.create_an_iterator_from_read .fn" assert-window-property-false: {"scrollY": |scroll|} // Store the new position. store-window-property: (scroll, "scrollY") -click: "//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits']" -wait-for: "//*[@class='notable popover']" +click: "//*[@id='method.create_an_iterator_from_read']//*[@class='tooltip']" +wait-for: "//*[@class='tooltip popover']" click: "#settings-menu a" click: ".search-input" // We ensure we didn't come back to the previous focused item. @@ -245,8 +245,8 @@ click: "#method\.create_an_iterator_from_read .fn" assert-window-property-false: {"scrollY": |scroll|} // Store the new position. store-window-property: (scroll, "scrollY") -click: "//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits']" -wait-for: "//*[@class='notable popover']" +click: "//*[@id='method.create_an_iterator_from_read']//*[@class='tooltip']" +wait-for: "//*[@class='tooltip popover']" click: "#settings-menu a" press-key: "Escape" // We ensure we didn't come back to the previous focused item. @@ -254,23 +254,23 @@ assert-window-property-false: {"scrollY": |scroll|} // Opening the mobile sidebar should close the popover. size: (650, 600) -click: "//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits']" -assert-count: ("//*[@class='notable popover']", 1) +click: "//*[@id='method.create_an_iterator_from_read']//*[@class='tooltip']" +assert-count: ("//*[@class='tooltip popover']", 1) click: ".sidebar-menu-toggle" assert: "//*[@class='sidebar shown']" -assert-count: ("//*[@class='notable popover']", 0) -assert-false: "#method\.create_an_iterator_from_read .notable-traits:focus" -// Clicking a notable popover should close the sidebar. -click: "//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits']" -assert-count: ("//*[@class='notable popover']", 1) +assert-count: ("//*[@class='tooltip popover']", 0) +assert-false: "#method\.create_an_iterator_from_read .tooltip:focus" +// Clicking a notable trait tooltip popover should close the sidebar. +click: "//*[@id='method.create_an_iterator_from_read']//*[@class='tooltip']" +assert-count: ("//*[@class='tooltip popover']", 1) assert-false: "//*[@class='sidebar shown']" // Also check the focus handling for the help button. size: (1100, 600) reload: -assert-count: ("//*[@class='notable popover']", 0) -click: "//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits']" -assert-count: ("//*[@class='notable popover']", 1) +assert-count: ("//*[@class='tooltip popover']", 0) +click: "//*[@id='method.create_an_iterator_from_read']//*[@class='tooltip']" +assert-count: ("//*[@class='tooltip popover']", 1) click: "#help-button a" -assert-count: ("//*[@class='notable popover']", 0) -assert-false: "#method\.create_an_iterator_from_read .notable-traits:focus" +assert-count: ("//*[@class='tooltip popover']", 0) +assert-false: "#method\.create_an_iterator_from_read .tooltip:focus" diff --git a/tests/rustdoc-gui/scrape-examples-layout.goml b/tests/rustdoc-gui/scrape-examples-layout.goml index 95102528ec1..dad727c7757 100644 --- a/tests/rustdoc-gui/scrape-examples-layout.goml +++ b/tests/rustdoc-gui/scrape-examples-layout.goml @@ -40,10 +40,10 @@ assert-property: ( store-value: (offset_y, 4) // First with desktop -assert-position: (".scraped-example .code-wrapper", {"y": 255}) -assert-position: (".scraped-example .code-wrapper .prev", {"y": 255 + |offset_y|}) +assert-position: (".scraped-example .code-wrapper", {"y": 253}) +assert-position: (".scraped-example .code-wrapper .prev", {"y": 253 + |offset_y|}) // Then with mobile size: (600, 600) -assert-position: (".scraped-example .code-wrapper", {"y": 314}) -assert-position: (".scraped-example .code-wrapper .prev", {"y": 314 + |offset_y|}) +assert-position: (".scraped-example .code-wrapper", {"y": 308}) +assert-position: (".scraped-example .code-wrapper .prev", {"y": 308 + |offset_y|}) diff --git a/tests/rustdoc-gui/search-result-display.goml b/tests/rustdoc-gui/search-result-display.goml index 43e608228d8..20a88c36edb 100644 --- a/tests/rustdoc-gui/search-result-display.goml +++ b/tests/rustdoc-gui/search-result-display.goml @@ -22,7 +22,7 @@ size: (900, 900) // First we check the current width, height and position. assert-css: ("#crate-search", {"width": "223px"}) -assert-css: (".search-results-title", {"height": "44px", "width": "640px"}) +assert-css: (".search-results-title", {"height": "50px", "width": "640px"}) assert-css: ("#search", {"width": "640px"}) // Then we update the text of one of the `<option>`. @@ -33,7 +33,7 @@ text: ( // Then we compare again to confirm the height didn't change. assert-css: ("#crate-search", {"width": "527px"}) -assert-css: (".search-results-title", {"height": "44px", "width": "640px"}) +assert-css: (".search-results-title", {"height": "50px", "width": "640px"}) // And we check that the `<select>` isn't bigger than its container (".search-results-title"). assert-css: ("#search", {"width": "640px"}) diff --git a/tests/rustdoc-gui/sidebar-mobile-scroll.goml b/tests/rustdoc-gui/sidebar-mobile-scroll.goml index 2449269b192..4442b263e9a 100644 --- a/tests/rustdoc-gui/sidebar-mobile-scroll.goml +++ b/tests/rustdoc-gui/sidebar-mobile-scroll.goml @@ -6,7 +6,7 @@ assert-css: (".sidebar", {"display": "block", "left": "-1000px"}) // Scroll down. scroll-to: "//h2[@id='blanket-implementations']" -assert-window-property: {"pageYOffset": "627"} +assert-window-property: {"pageYOffset": "622"} // Open the sidebar menu. click: ".sidebar-menu-toggle" @@ -21,11 +21,11 @@ assert-window-property: {"pageYOffset": "0"} // Close the sidebar menu. Make sure the scroll position gets restored. click: ".sidebar-menu-toggle" wait-for-css: (".sidebar", {"left": "-1000px"}) -assert-window-property: {"pageYOffset": "627"} +assert-window-property: {"pageYOffset": "622"} // Now test that scrollability returns when the browser window is just resized. click: ".sidebar-menu-toggle" wait-for-css: (".sidebar", {"left": "0px"}) assert-window-property: {"pageYOffset": "0"} size: (900, 600) -assert-window-property: {"pageYOffset": "627"} +assert-window-property: {"pageYOffset": "622"} diff --git a/tests/rustdoc-gui/sidebar-mobile.goml b/tests/rustdoc-gui/sidebar-mobile.goml index d5f4b619629..cc6267c3dc9 100644 --- a/tests/rustdoc-gui/sidebar-mobile.goml +++ b/tests/rustdoc-gui/sidebar-mobile.goml @@ -45,7 +45,7 @@ assert-property: (".mobile-topbar", {"clientHeight": "45"}) // so the target is not obscured by the topbar. click: ".sidebar-menu-toggle" click: ".sidebar-elems section .block li > a" -assert-position: ("#method\.must_use", {"y": 45}) +assert-position: ("#method\.must_use", {"y": 46}) // Check that the bottom-most item on the sidebar menu can be scrolled fully into view. click: ".sidebar-menu-toggle" diff --git a/tests/rustdoc-ui/intra-doc/errors.rs b/tests/rustdoc-ui/intra-doc/errors.rs index b29f7c29b5d..95dd2b98e03 100644 --- a/tests/rustdoc-ui/intra-doc/errors.rs +++ b/tests/rustdoc-ui/intra-doc/errors.rs @@ -103,3 +103,19 @@ pub trait T { macro_rules! m { () => {}; } + +///[`TestEnum::Variant1::field_name`] +//~^ ERROR unresolved link +//~| NOTE variant `Variant1` has no such field +pub enum TestEnum { + Variant1 {}, + Variant2 { field_name: u64 }, +} + +///[`TestEnumNoFields::Variant1::field_name`] +//~^ ERROR unresolved link +//~| NOTE `Variant1` is a variant, not a module or type, and cannot have associated items +pub enum TestEnumNoFields { + Variant1 (), + Variant2 {}, +} diff --git a/tests/rustdoc-ui/intra-doc/errors.stderr b/tests/rustdoc-ui/intra-doc/errors.stderr index 9a1896fb0cd..1b2416d7da7 100644 --- a/tests/rustdoc-ui/intra-doc/errors.stderr +++ b/tests/rustdoc-ui/intra-doc/errors.stderr @@ -142,6 +142,18 @@ error: unresolved link to `T::h` LL | /// [T::h!] | ^^^^^ the trait `T` has no macro named `h` +error: unresolved link to `TestEnum::Variant1::field_name` + --> $DIR/errors.rs:107:6 + | +LL | ///[`TestEnum::Variant1::field_name`] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ variant `Variant1` has no such field + +error: unresolved link to `TestEnumNoFields::Variant1::field_name` + --> $DIR/errors.rs:115:6 + | +LL | ///[`TestEnumNoFields::Variant1::field_name`] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `Variant1` is a variant, not a module or type, and cannot have associated items + error: unresolved link to `m` --> $DIR/errors.rs:98:6 | @@ -153,5 +165,5 @@ help: to link to the macro, add an exclamation mark LL | /// [m!()] | + -error: aborting due to 20 previous errors +error: aborting due to 22 previous errors diff --git a/tests/rustdoc-ui/z-help.stdout b/tests/rustdoc-ui/z-help.stdout index 6c1684201a2..96329f31723 100644 --- a/tests/rustdoc-ui/z-help.stdout +++ b/tests/rustdoc-ui/z-help.stdout @@ -176,6 +176,7 @@ -Z symbol-mangling-version=val -- which mangling version to use for symbol names ('legacy' (default) or 'v0') -Z teach=val -- show extended diagnostic help (default: no) -Z temps-dir=val -- the directory the intermediate files are written to + -Z terminal-urls=val -- use the OSC 8 hyperlink terminal specification to print hyperlinks in the compiler output -Z thinlto=val -- enable ThinLTO when possible -Z thir-unsafeck=val -- use the THIR unsafety checker (default: no) -Z threads=val -- use a thread pool with N threads diff --git a/tests/rustdoc/codeblock-title.rs b/tests/rustdoc/codeblock-title.rs index b9b0b0d1abf..761afb8bd08 100644 --- a/tests/rustdoc/codeblock-title.rs +++ b/tests/rustdoc/codeblock-title.rs @@ -3,7 +3,7 @@ // @has foo/fn.bar.html '//*[@class="example-wrap compile_fail"]/*[@class="tooltip"]' "ⓘ" // @has foo/fn.bar.html '//*[@class="example-wrap ignore"]/*[@class="tooltip"]' "ⓘ" // @has foo/fn.bar.html '//*[@class="example-wrap should_panic"]/*[@class="tooltip"]' "ⓘ" -// @has foo/fn.bar.html '//*[@data-edition="2018"]' "ⓘ" +// @has foo/fn.bar.html '//*[@title="This example runs with edition 2018"]' "ⓘ" /// foo /// diff --git a/tests/rustdoc/description.rs b/tests/rustdoc/description.rs index 05ec4282208..43cd59ebd09 100644 --- a/tests/rustdoc/description.rs +++ b/tests/rustdoc/description.rs @@ -22,3 +22,9 @@ pub mod foo_mod { // 'Only paragraph.' /// Only paragraph. pub fn foo_fn() {} + +// @has 'foo/fn.bar_fn.html' '//meta[@name="description"]/@content' \ +// 'Description with intra-doc link to foo_fn and [nonexistent_item] and foo_fn.' +#[allow(rustdoc::broken_intra_doc_links)] +/// Description with intra-doc link to [foo_fn] and [nonexistent_item] and [foo_fn](self::foo_fn). +pub fn bar_fn() {} diff --git a/tests/rustdoc/doc-notable_trait.rs b/tests/rustdoc/doc-notable_trait.rs index 279faf55401..d8941769fa6 100644 --- a/tests/rustdoc/doc-notable_trait.rs +++ b/tests/rustdoc/doc-notable_trait.rs @@ -9,7 +9,7 @@ impl<T: SomeTrait> SomeTrait for Wrapper<T> {} #[doc(notable_trait)] pub trait SomeTrait { // @has doc_notable_trait/trait.SomeTrait.html - // @has - '//a[@class="notable-traits"]/@data-ty' 'Wrapper<Self>' + // @has - '//a[@class="tooltip"]/@data-notable-ty' 'Wrapper<Self>' // @snapshot wrap-me - '//script[@id="notable-traits-data"]' fn wrap_me(self) -> Wrapper<Self> where Self: Sized { Wrapper { @@ -23,7 +23,7 @@ impl SomeTrait for SomeStruct {} impl SomeStruct { // @has doc_notable_trait/struct.SomeStruct.html - // @has - '//a[@class="notable-traits"]/@data-ty' 'SomeStruct' + // @has - '//a[@class="tooltip"]/@data-notable-ty' 'SomeStruct' // @snapshot some-struct-new - '//script[@id="notable-traits-data"]' pub fn new() -> SomeStruct { SomeStruct @@ -31,7 +31,7 @@ impl SomeStruct { } // @has doc_notable_trait/fn.bare_fn.html -// @has - '//a[@class="notable-traits"]/@data-ty' 'SomeStruct' +// @has - '//a[@class="tooltip"]/@data-notable-ty' 'SomeStruct' // @snapshot bare-fn - '//script[@id="notable-traits-data"]' pub fn bare_fn() -> SomeStruct { SomeStruct diff --git a/tests/rustdoc/markdown-summaries.rs b/tests/rustdoc/markdown-summaries.rs deleted file mode 100644 index 31e7072b5ce..00000000000 --- a/tests/rustdoc/markdown-summaries.rs +++ /dev/null @@ -1,27 +0,0 @@ -#![crate_type = "lib"] -#![crate_name = "summaries"] - -//! This *summary* has a [link] and `code`. -//! -//! This is the second paragraph. -//! -//! [link]: https://example.com - -// @hasraw search-index.js 'This <em>summary</em> has a link and <code>code</code>.' -// @!hasraw - 'second paragraph' - -/// This `code` will be rendered in a code tag. -/// -/// This text should not be rendered. -pub struct Sidebar; - -// @hasraw search-index.js 'This <code>code</code> will be rendered in a code tag.' -// @hasraw summaries/sidebar-items.js 'This `code` will be rendered in a code tag.' -// @!hasraw - 'text should not be rendered' - -/// ```text -/// this block should not be rendered -/// ``` -pub struct Sidebar2; - -// @!hasraw summaries/sidebar-items.js 'block should not be rendered' diff --git a/tests/rustdoc/reexport-macro.rs b/tests/rustdoc/reexport-macro.rs new file mode 100644 index 00000000000..c4dec703aed --- /dev/null +++ b/tests/rustdoc/reexport-macro.rs @@ -0,0 +1,23 @@ +// Ensure that macros are correctly reexported and that they get both the comment from the +// `pub use` and from the macro. + +#![crate_name = "foo"] + +// @has 'foo/macro.foo.html' +// @!has - '//*[@class="toggle top-doc"]/*[@class="docblock"]' 'x y' +// @has - '//*[@class="toggle top-doc"]/*[@class="docblock"]' 'y' +#[macro_use] +mod my_module { + /// y + #[macro_export] + macro_rules! foo { + () => (); + } +} + +// @has 'foo/another_mod/macro.bar.html' +// @has - '//*[@class="toggle top-doc"]/*[@class="docblock"]' 'x y' +pub mod another_mod { + /// x + pub use crate::foo as bar; +} diff --git a/tests/rustdoc/spotlight-from-dependency.rs b/tests/rustdoc/spotlight-from-dependency.rs index 090ad187d9c..426759c7bf8 100644 --- a/tests/rustdoc/spotlight-from-dependency.rs +++ b/tests/rustdoc/spotlight-from-dependency.rs @@ -3,7 +3,7 @@ use std::iter::Iterator; // @has foo/struct.Odd.html -// @has - '//*[@id="method.new"]//a[@class="notable-traits"]/@data-ty' 'Odd' +// @has - '//*[@id="method.new"]//a[@class="tooltip"]/@data-notable-ty' 'Odd' // @snapshot odd - '//script[@id="notable-traits-data"]' pub struct Odd { current: usize, diff --git a/tests/ui/const-generics/wrong-normalization.rs b/tests/ui/const-generics/wrong-normalization.rs new file mode 100644 index 00000000000..f1ce317b3f7 --- /dev/null +++ b/tests/ui/const-generics/wrong-normalization.rs @@ -0,0 +1,19 @@ +// This test ensures that if implementation on projections is supported, +// it doesn't end in very weird cycle error. + +#![crate_type = "lib"] + +pub trait Identity { + type Identity: ?Sized; +} + +impl<T: ?Sized> Identity for T { + type Identity = Self; +} + +pub struct I8<const F: i8>; + +impl <I8<{i8::MIN}> as Identity>::Identity { +//~^ ERROR no nominal type found for inherent implementation + pub fn foo(&self) {} +} diff --git a/tests/ui/const-generics/wrong-normalization.stderr b/tests/ui/const-generics/wrong-normalization.stderr new file mode 100644 index 00000000000..fb806bdb1e7 --- /dev/null +++ b/tests/ui/const-generics/wrong-normalization.stderr @@ -0,0 +1,11 @@ +error[E0118]: no nominal type found for inherent implementation + --> $DIR/wrong-normalization.rs:16:6 + | +LL | impl <I8<{i8::MIN}> as Identity>::Identity { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl requires a nominal type + | + = note: either implement a trait on it or create a newtype to wrap it instead + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0118`. diff --git a/tests/ui/diagnostic-flags/terminal_urls.rs b/tests/ui/diagnostic-flags/terminal_urls.rs new file mode 100644 index 00000000000..1f04e2aade1 --- /dev/null +++ b/tests/ui/diagnostic-flags/terminal_urls.rs @@ -0,0 +1,4 @@ +// compile-flags: -Zterminal-urls=yes +fn main() { + let () = 4; //~ ERROR +} diff --git a/tests/ui/diagnostic-flags/terminal_urls.stderr b/tests/ui/diagnostic-flags/terminal_urls.stderr new file mode 100644 index 00000000000..7f7e69c5d5d --- /dev/null +++ b/tests/ui/diagnostic-flags/terminal_urls.stderr @@ -0,0 +1,11 @@ +error[]8;;https://doc.rust-lang.org/error_codes/E0308.htmlE0308]8;;]: mismatched types + --> $DIR/terminal_urls.rs:3:9 + | +LL | let () = 4; + | ^^ - this expression has type `{integer}` + | | + | expected integer, found `()` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/hygiene/panic-location.run.stderr b/tests/ui/hygiene/panic-location.run.stderr index 0b23b1cc2f4..1c6a7b02f8e 100644 --- a/tests/ui/hygiene/panic-location.run.stderr +++ b/tests/ui/hygiene/panic-location.run.stderr @@ -1,2 +1,2 @@ -thread 'main' panicked at 'capacity overflow', library/alloc/src/raw_vec.rs:518:5 +thread 'main' panicked at 'capacity overflow', library/alloc/src/raw_vec.rs:525:5 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace diff --git a/tests/ui/impl-trait/nested-return-type2.rs b/tests/ui/impl-trait/nested-return-type2.rs index cc1f1f4ec44..fe883ce6fc8 100644 --- a/tests/ui/impl-trait/nested-return-type2.rs +++ b/tests/ui/impl-trait/nested-return-type2.rs @@ -1,4 +1,7 @@ // check-pass +// compile-flags: -Zvalidate-mir + +// Using -Zvalidate-mir as a regression test for #107346. trait Duh {} diff --git a/tests/ui/impl-trait/nested-return-type2.stderr b/tests/ui/impl-trait/nested-return-type2.stderr index 3aed05ca132..09ad3bd05c1 100644 --- a/tests/ui/impl-trait/nested-return-type2.stderr +++ b/tests/ui/impl-trait/nested-return-type2.stderr @@ -1,5 +1,5 @@ warning: opaque type `impl Trait<Assoc = impl Send>` does not satisfy its associated type bounds - --> $DIR/nested-return-type2.rs:25:24 + --> $DIR/nested-return-type2.rs:28:24 | LL | type Assoc: Duh; | --- this associated type bound is unsatisfied for `impl Send` diff --git a/tests/ui/native-library-link-flags/mix-bundle-and-whole-archive-link-attr.rs b/tests/ui/native-library-link-flags/mix-bundle-and-whole-archive-link-attr.rs index 066048795c8..0ccd441cc64 100644 --- a/tests/ui/native-library-link-flags/mix-bundle-and-whole-archive-link-attr.rs +++ b/tests/ui/native-library-link-flags/mix-bundle-and-whole-archive-link-attr.rs @@ -1,8 +1,11 @@ -// compile-flags: -Zunstable-options --crate-type rlib +// gate-test-packed_bundled_libs + +// ignore-wasm32-bare +// compile-flags: --crate-type rlib +// error-pattern: link modifiers combination `+bundle,+whole-archive` is unstable when generating rlibs // build-fail -// error-pattern: the linking modifiers `+bundle` and `+whole-archive` are not compatible with each other when generating rlibs -#[link(name = "mylib", kind = "static", modifiers = "+bundle,+whole-archive")] -extern "C" { } +#[link(name = "rust_test_helpers", kind = "static", modifiers = "+bundle,+whole-archive")] +extern "C" {} -fn main() { } +fn main() {} diff --git a/tests/ui/native-library-link-flags/mix-bundle-and-whole-archive-link-attr.stderr b/tests/ui/native-library-link-flags/mix-bundle-and-whole-archive-link-attr.stderr index 246efb8d627..8a9fed740b0 100644 --- a/tests/ui/native-library-link-flags/mix-bundle-and-whole-archive-link-attr.stderr +++ b/tests/ui/native-library-link-flags/mix-bundle-and-whole-archive-link-attr.stderr @@ -1,6 +1,4 @@ -error: the linking modifiers `+bundle` and `+whole-archive` are not compatible with each other when generating rlibs +error: link modifiers combination `+bundle,+whole-archive` is unstable when generating rlibs -error: could not find native static library `mylib`, perhaps an -L flag is missing? - -error: aborting due to 2 previous errors +error: aborting due to previous error diff --git a/tests/ui/native-library-link-flags/mix-bundle-and-whole-archive.rs b/tests/ui/native-library-link-flags/mix-bundle-and-whole-archive.rs index 1d0768d99cf..18d4b52a34c 100644 --- a/tests/ui/native-library-link-flags/mix-bundle-and-whole-archive.rs +++ b/tests/ui/native-library-link-flags/mix-bundle-and-whole-archive.rs @@ -1,7 +1,8 @@ -// Mixing +bundle and +whole-archive is not allowed +// gate-test-packed_bundled_libs -// compile-flags: -l static:+bundle,+whole-archive=mylib -Zunstable-options --crate-type rlib +// ignore-wasm32-bare +// compile-flags: -l static:+bundle,+whole-archive=rust_test_helpers --crate-type rlib +// error-pattern: link modifiers combination `+bundle,+whole-archive` is unstable when generating rlibs // build-fail -// error-pattern: the linking modifiers `+bundle` and `+whole-archive` are not compatible with each other when generating rlibs -fn main() { } +fn main() {} diff --git a/tests/ui/native-library-link-flags/mix-bundle-and-whole-archive.stderr b/tests/ui/native-library-link-flags/mix-bundle-and-whole-archive.stderr index 246efb8d627..8a9fed740b0 100644 --- a/tests/ui/native-library-link-flags/mix-bundle-and-whole-archive.stderr +++ b/tests/ui/native-library-link-flags/mix-bundle-and-whole-archive.stderr @@ -1,6 +1,4 @@ -error: the linking modifiers `+bundle` and `+whole-archive` are not compatible with each other when generating rlibs +error: link modifiers combination `+bundle,+whole-archive` is unstable when generating rlibs -error: could not find native static library `mylib`, perhaps an -L flag is missing? - -error: aborting due to 2 previous errors +error: aborting due to previous error diff --git a/tests/ui/regions/regions-mock-codegen.rs b/tests/ui/regions/regions-mock-codegen.rs index 9d0ca76e409..d5c93f81fd8 100644 --- a/tests/ui/regions/regions-mock-codegen.rs +++ b/tests/ui/regions/regions-mock-codegen.rs @@ -22,15 +22,15 @@ struct Ccx { x: isize, } -fn allocate(_bcx: &arena) -> &Bcx<'_> { +fn allocate(_bcx: &arena) -> &mut Bcx<'_> { unsafe { let layout = Layout::new::<Bcx>(); let ptr = Global.allocate(layout).unwrap_or_else(|_| handle_alloc_error(layout)); - &*(ptr.as_ptr() as *const _) + &mut *ptr.as_ptr().cast() } } -fn h<'a>(bcx: &'a Bcx<'a>) -> &'a Bcx<'a> { +fn h<'a>(bcx: &'a Bcx<'a>) -> &'a mut Bcx<'a> { return allocate(bcx.fcx.arena); } @@ -38,7 +38,7 @@ fn g(fcx: &Fcx) { let bcx = Bcx { fcx }; let bcx2 = h(&bcx); unsafe { - Global.deallocate(NonNull::new_unchecked(bcx2 as *const _ as *mut _), Layout::new::<Bcx>()); + Global.deallocate(NonNull::new_unchecked(bcx2 as *mut _ as *mut _), Layout::new::<Bcx>()); } } diff --git a/tests/ui/simd/intrinsic/generic-cast-pass.rs b/tests/ui/simd/intrinsic/generic-cast-pass.rs index 15f232e2c0f..89436c83e25 100644 --- a/tests/ui/simd/intrinsic/generic-cast-pass.rs +++ b/tests/ui/simd/intrinsic/generic-cast-pass.rs @@ -1,121 +1,59 @@ // run-pass -#![allow(unused_must_use)] // ignore-emscripten FIXME(#45351) hits an LLVM assert -#![feature(repr_simd, platform_intrinsics, concat_idents, test)] -#![allow(non_camel_case_types)] - -extern crate test; - -#[repr(simd)] -#[derive(PartialEq, Debug)] -struct i32x4(i32, i32, i32, i32); -#[repr(simd)] -#[derive(PartialEq, Debug)] -struct i8x4(i8, i8, i8, i8); - -#[repr(simd)] -#[derive(PartialEq, Debug)] -struct u32x4(u32, u32, u32, u32); -#[repr(simd)] -#[derive(PartialEq, Debug)] -struct u8x4(u8, u8, u8, u8); - -#[repr(simd)] -#[derive(PartialEq, Debug)] -struct f32x4(f32, f32, f32, f32); - -#[repr(simd)] -#[derive(PartialEq, Debug)] -struct f64x4(f64, f64, f64, f64); - +#![feature(repr_simd, platform_intrinsics)] extern "platform-intrinsic" { fn simd_cast<T, U>(x: T) -> U; } -const A: i32 = -1234567; -const B: i32 = 12345678; -const C: i32 = -123456789; -const D: i32 = 1234567890; +use std::cmp::{max, min}; -trait Foo { - fn is_float() -> bool { false } - fn in_range(x: i32) -> bool; -} -impl Foo for i32 { - fn in_range(_: i32) -> bool { true } -} -impl Foo for i8 { - fn in_range(x: i32) -> bool { -128 <= x && x < 128 } -} -impl Foo for u32 { - fn in_range(x: i32) -> bool { 0 <= x } -} -impl Foo for u8 { - fn in_range(x: i32) -> bool { 0 <= x && x < 128 } -} -impl Foo for f32 { - fn is_float() -> bool { true } - fn in_range(_: i32) -> bool { true } -} -impl Foo for f64 { - fn is_float() -> bool { true } - fn in_range(_: i32) -> bool { true } -} +#[derive(Copy, Clone)] +#[repr(simd)] +struct V<T>([T; 2]); fn main() { - macro_rules! test { - ($from: ident, $to: ident) => {{ - // force the casts to actually happen, or else LLVM/rustc - // may fold them and get slightly different results. - let (a, b, c, d) = test::black_box((A as $from, B as $from, C as $from, D as $from)); - // the SIMD vectors are all FOOx4, so we can concat_idents - // so we don't have to pass in the extra args to the macro - let mut from = simd_cast(concat_idents!($from, x4)(a, b, c, d)); - let mut to = concat_idents!($to, x4)(a as $to, - b as $to, - c as $to, - d as $to); - // assist type inference, it needs to know what `from` is - // for the `if` statements. - to == from; + unsafe { + let u = V::<u32>([i16::MIN as u32, i16::MAX as u32]); + let i: V<i16> = simd_cast(u); + assert_eq!(i.0[0], u.0[0] as i16); + assert_eq!(i.0[1], u.0[1] as i16); + } - // there are platform differences for some out of range - // casts, so we just normalize such things: it's OK for - // "invalid" calculations to result in nonsense answers. - // (e.g., negative float to unsigned integer goes through a - // library routine on the default i686 platforms, and the - // implementation of that routine differs on e.g., Linux - // vs. macOS, resulting in different answers.) - if $from::is_float() { - if !$to::in_range(A) { from.0 = 0 as $to; to.0 = 0 as $to; } - if !$to::in_range(B) { from.1 = 0 as $to; to.1 = 0 as $to; } - if !$to::in_range(C) { from.2 = 0 as $to; to.2 = 0 as $to; } - if !$to::in_range(D) { from.3 = 0 as $to; to.3 = 0 as $to; } - } + unsafe { + let f = V::<f32>([i16::MIN as f32, i16::MAX as f32]); + let i: V<i16> = simd_cast(f); + assert_eq!(i.0[0], f.0[0] as i16); + assert_eq!(i.0[1], f.0[1] as i16); + } - assert!(to == from, - "{} -> {} ({:?} != {:?})", stringify!($from), stringify!($to), - from, to); - }} + unsafe { + let f = V::<f32>([u8::MIN as f32, u8::MAX as f32]); + let u: V<u8> = simd_cast(f); + assert_eq!(u.0[0], f.0[0] as u8); + assert_eq!(u.0[1], f.0[1] as u8); } - macro_rules! tests { - (: $($to: ident),*) => { () }; - // repeating the list twice is easier than writing a cartesian - // product macro - ($from: ident $(, $from_: ident)*: $($to: ident),*) => { - fn $from() { unsafe { $( test!($from, $to); )* } } - tests!($($from_),*: $($to),*) - }; - ($($types: ident),*) => {{ - tests!($($types),* : $($types),*); - $($types();)* - }} + + unsafe { + // We would like to do isize::MIN..=isize::MAX, but those values are not representable in + // an f64, so we clamp to the range of an i32 to prevent running into UB. + let f = V::<f64>([ + max(isize::MIN, i32::MIN as isize) as f64, + min(isize::MAX, i32::MAX as isize) as f64, + ]); + let i: V<isize> = simd_cast(f); + assert_eq!(i.0[0], f.0[0] as isize); + assert_eq!(i.0[1], f.0[1] as isize); } - // test various combinations, including truncation, - // signed/unsigned extension, and floating point casts. - tests!(i32, i8, u32, u8, f32); - tests!(i32, u32, f32, f64) + unsafe { + let f = V::<f64>([ + max(usize::MIN, u32::MIN as usize) as f64, + min(usize::MAX, u32::MAX as usize) as f64, + ]); + let u: V<usize> = simd_cast(f); + assert_eq!(u.0[0], f.0[0] as usize); + assert_eq!(u.0[1], f.0[1] as usize); + } } diff --git a/tests/ui/simd/intrinsic/generic-gather-pass.rs b/tests/ui/simd/intrinsic/generic-gather-pass.rs index 805caebe5b1..7d4b3dbd7b4 100644 --- a/tests/ui/simd/intrinsic/generic-gather-pass.rs +++ b/tests/ui/simd/intrinsic/generic-gather-pass.rs @@ -24,9 +24,9 @@ fn main() { // reading from *const unsafe { - let pointer = &x[0] as *const f32; + let pointer = x.as_ptr(); let pointers = x4( - pointer.offset(0) as *const f32, + pointer.offset(0), pointer.offset(2), pointer.offset(4), pointer.offset(6) @@ -39,9 +39,9 @@ fn main() { // reading from *mut unsafe { - let pointer = &mut x[0] as *mut f32; + let pointer = x.as_mut_ptr(); let pointers = x4( - pointer.offset(0) as *mut f32, + pointer.offset(0), pointer.offset(2), pointer.offset(4), pointer.offset(6) @@ -54,9 +54,9 @@ fn main() { // writing to *mut unsafe { - let pointer = &mut x[0] as *mut f32; + let pointer = x.as_mut_ptr(); let pointers = x4( - pointer.offset(0) as *mut f32, + pointer.offset(0), pointer.offset(2), pointer.offset(4), pointer.offset(6) @@ -85,9 +85,9 @@ fn main() { // reading from *const unsafe { - let pointer = &y[0] as *const *const f32; + let pointer = y.as_ptr(); let pointers = x4( - pointer.offset(0) as *const *const f32, + pointer.offset(0), pointer.offset(2), pointer.offset(4), pointer.offset(6) @@ -100,9 +100,9 @@ fn main() { // reading from *mut unsafe { - let pointer = &mut y[0] as *mut *const f32; + let pointer = y.as_mut_ptr(); let pointers = x4( - pointer.offset(0) as *mut *const f32, + pointer.offset(0), pointer.offset(2), pointer.offset(4), pointer.offset(6) @@ -115,9 +115,9 @@ fn main() { // writing to *mut unsafe { - let pointer = &mut y[0] as *mut *const f32; + let pointer = y.as_mut_ptr(); let pointers = x4( - pointer.offset(0) as *mut *const f32, + pointer.offset(0), pointer.offset(2), pointer.offset(4), pointer.offset(6) diff --git a/tests/ui/simd/issue-89193.rs b/tests/ui/simd/issue-89193.rs index 79c4e6a312c..cd24d6675b2 100644 --- a/tests/ui/simd/issue-89193.rs +++ b/tests/ui/simd/issue-89193.rs @@ -17,13 +17,14 @@ extern "platform-intrinsic" { fn main() { let x: [usize; 4] = [10, 11, 12, 13]; let default = x4(0_usize, 1, 2, 3); - let mask = x4(1_i32, 1, 1, 1); + let all_set = u8::MAX as i8; // aka -1 + let mask = x4(all_set, all_set, all_set, all_set); let expected = x4(10_usize, 11, 12, 13); unsafe { - let pointer = &x[0] as *const usize; + let pointer = x.as_ptr(); let pointers = x4( - pointer.offset(0) as *const usize, + pointer.offset(0), pointer.offset(1), pointer.offset(2), pointer.offset(3) @@ -38,9 +39,9 @@ fn main() { let expected = x4(10_isize, 11, 12, 13); unsafe { - let pointer = &x[0] as *const isize; + let pointer = x.as_ptr(); let pointers = x4( - pointer.offset(0) as *const isize, + pointer.offset(0), pointer.offset(1), pointer.offset(2), pointer.offset(3) diff --git a/tests/ui/suggestions/issue-104961.fixed b/tests/ui/suggestions/issue-104961.fixed new file mode 100644 index 00000000000..520d638b174 --- /dev/null +++ b/tests/ui/suggestions/issue-104961.fixed @@ -0,0 +1,16 @@ +// run-rustfix + +fn foo(x: &str) -> bool { + x.starts_with(&("hi".to_string() + " you")) + //~^ ERROR expected a `FnMut<(char,)>` closure, found `String` +} + +fn foo2(x: &str) -> bool { + x.starts_with(&"hi".to_string()) + //~^ ERROR expected a `FnMut<(char,)>` closure, found `String` +} + +fn main() { + foo("hi you"); + foo2("hi"); +} diff --git a/tests/ui/suggestions/issue-104961.rs b/tests/ui/suggestions/issue-104961.rs new file mode 100644 index 00000000000..aeb787abb6f --- /dev/null +++ b/tests/ui/suggestions/issue-104961.rs @@ -0,0 +1,16 @@ +// run-rustfix + +fn foo(x: &str) -> bool { + x.starts_with("hi".to_string() + " you") + //~^ ERROR expected a `FnMut<(char,)>` closure, found `String` +} + +fn foo2(x: &str) -> bool { + x.starts_with("hi".to_string()) + //~^ ERROR expected a `FnMut<(char,)>` closure, found `String` +} + +fn main() { + foo("hi you"); + foo2("hi"); +} diff --git a/tests/ui/suggestions/issue-104961.stderr b/tests/ui/suggestions/issue-104961.stderr new file mode 100644 index 00000000000..8cec6a3f827 --- /dev/null +++ b/tests/ui/suggestions/issue-104961.stderr @@ -0,0 +1,37 @@ +error[E0277]: expected a `FnMut<(char,)>` closure, found `String` + --> $DIR/issue-104961.rs:4:19 + | +LL | x.starts_with("hi".to_string() + " you") + | ----------- ^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Pattern<'_>` is not implemented for `String` + | | + | required by a bound introduced by this call + | + = note: the trait bound `String: Pattern<'_>` is not satisfied + = note: required for `String` to implement `Pattern<'_>` +note: required by a bound in `core::str::<impl str>::starts_with` + --> $SRC_DIR/core/src/str/mod.rs:LL:COL +help: consider borrowing here + | +LL | x.starts_with(&("hi".to_string() + " you")) + | ++ + + +error[E0277]: expected a `FnMut<(char,)>` closure, found `String` + --> $DIR/issue-104961.rs:9:19 + | +LL | x.starts_with("hi".to_string()) + | ----------- ^^^^^^^^^^^^^^^^ the trait `Pattern<'_>` is not implemented for `String` + | | + | required by a bound introduced by this call + | + = note: the trait bound `String: Pattern<'_>` is not satisfied + = note: required for `String` to implement `Pattern<'_>` +note: required by a bound in `core::str::<impl str>::starts_with` + --> $SRC_DIR/core/src/str/mod.rs:LL:COL +help: consider borrowing here + | +LL | x.starts_with(&"hi".to_string()) + | + + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/suggestions/suggest-call-on-pat-mismatch.rs b/tests/ui/suggestions/suggest-call-on-pat-mismatch.rs new file mode 100644 index 00000000000..657dd9c22c2 --- /dev/null +++ b/tests/ui/suggestions/suggest-call-on-pat-mismatch.rs @@ -0,0 +1,16 @@ +enum E { + One(i32, i32), +} + +fn main() { + let var = E::One; + if let E::One(var1, var2) = var { + //~^ ERROR mismatched types + //~| HELP use parentheses to construct this tuple variant + println!("{var1} {var2}"); + } + + let Some(x) = Some; + //~^ ERROR mismatched types + //~| HELP use parentheses to construct this tuple variant +} diff --git a/tests/ui/suggestions/suggest-call-on-pat-mismatch.stderr b/tests/ui/suggestions/suggest-call-on-pat-mismatch.stderr new file mode 100644 index 00000000000..7338312bab6 --- /dev/null +++ b/tests/ui/suggestions/suggest-call-on-pat-mismatch.stderr @@ -0,0 +1,33 @@ +error[E0308]: mismatched types + --> $DIR/suggest-call-on-pat-mismatch.rs:7:12 + | +LL | if let E::One(var1, var2) = var { + | ^^^^^^^^^^^^^^^^^^ --- this expression has type `fn(i32, i32) -> E {E::One}` + | | + | expected enum constructor, found `E` + | + = note: expected enum constructor `fn(i32, i32) -> E {E::One}` + found enum `E` +help: use parentheses to construct this tuple variant + | +LL | if let E::One(var1, var2) = var(/* i32 */, /* i32 */) { + | ++++++++++++++++++++++ + +error[E0308]: mismatched types + --> $DIR/suggest-call-on-pat-mismatch.rs:13:9 + | +LL | let Some(x) = Some; + | ^^^^^^^ ---- this expression has type `fn(_) -> Option<_> {Option::<_>::Some}` + | | + | expected enum constructor, found `Option<_>` + | + = note: expected enum constructor `fn(_) -> Option<_> {Option::<_>::Some}` + found enum `Option<_>` +help: use parentheses to construct this tuple variant + | +LL | let Some(x) = Some(/* value */); + | +++++++++++++ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/traits/new-solver/alias_eq_cant_be_furthur_normalized.rs b/tests/ui/traits/new-solver/alias_eq_cant_be_furthur_normalized.rs new file mode 100644 index 00000000000..dc726ba51f9 --- /dev/null +++ b/tests/ui/traits/new-solver/alias_eq_cant_be_furthur_normalized.rs @@ -0,0 +1,29 @@ +// check-pass +// compile-flags: -Ztrait-solver=next + +// check that a goal such as `alias-eq(<T as TraitB>::Assoc<bool>, <T as TraitB>::Assoc<?0>)` +// succeeds with a constraint that `?0 = bool` + +// FIXME(deferred_projection_equality): add a test that this is true during coherence + +trait TraitA {} + +trait TraitB { + type Assoc<T: ?Sized>; +} + +impl<T: TraitB> TraitA for (T, T::Assoc<bool>) {} + +impl TraitB for i32 { + type Assoc<T: ?Sized> = u32; +} + +fn needs_a<T: TraitA>() {} + +fn bar<T: TraitB>() { + needs_a::<(T, <T as TraitB>::Assoc<_>)>(); +} + +fn main() { + bar::<i32>(); +} diff --git a/tests/ui/traits/new-solver/alias_eq_dont_use_normalizes_to_if_substs_eq.rs b/tests/ui/traits/new-solver/alias_eq_dont_use_normalizes_to_if_substs_eq.rs new file mode 100644 index 00000000000..fd5d0e3b194 --- /dev/null +++ b/tests/ui/traits/new-solver/alias_eq_dont_use_normalizes_to_if_substs_eq.rs @@ -0,0 +1,45 @@ +// compile-flags: -Ztrait-solver=next + +// check that when computing `alias-eq(<() as Foo<u16, T>>::Assoc, <() as Foo<?0, T>>::Assoc)` +// we do not infer `?0 = u8` via the `for<STOP> (): Foo<u8, STOP>` impl or `?0 = u16` by +// relating substs as either could be a valid solution. + +trait Foo<T, STOP> { + type Assoc; +} + +impl<STOP> Foo<u8, STOP> for () +where + (): Foo<u16, STOP>, +{ + type Assoc = <() as Foo<u16, STOP>>::Assoc; +} + +impl Foo<u16, i8> for () { + type Assoc = u8; +} + +impl Foo<u16, i16> for () { + type Assoc = u16; +} + +fn output<T, U>() -> <() as Foo<T, U>>::Assoc +where + (): Foo<T, U>, +{ + todo!() +} + +fn incomplete<T>() +where + (): Foo<u16, T>, +{ + // `<() as Foo<u16, STOP>>::Assoc == <() as Foo<_, STOP>>::Assoc` + let _: <() as Foo<u16, T>>::Assoc = output::<_, T>(); + //~^ error: type annotations needed + + // let _: <() as Foo<u16, T>>::Assoc = output::<u8, T>(); // OK + // let _: <() as Foo<u16, T>>::Assoc = output::<u16, T>(); // OK +} + +fn main() {} diff --git a/tests/ui/traits/new-solver/alias_eq_dont_use_normalizes_to_if_substs_eq.stderr b/tests/ui/traits/new-solver/alias_eq_dont_use_normalizes_to_if_substs_eq.stderr new file mode 100644 index 00000000000..a6712332c37 --- /dev/null +++ b/tests/ui/traits/new-solver/alias_eq_dont_use_normalizes_to_if_substs_eq.stderr @@ -0,0 +1,9 @@ +error[E0282]: type annotations needed + --> $DIR/alias_eq_dont_use_normalizes_to_if_substs_eq.rs:38:41 + | +LL | let _: <() as Foo<u16, T>>::Assoc = output::<_, T>(); + | ^^^^^^^^^^^^^^ cannot infer type of the type parameter `T` declared on the function `output` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0282`. diff --git a/tests/ui/traits/new-solver/alias_eq_simple.rs b/tests/ui/traits/new-solver/alias_eq_simple.rs new file mode 100644 index 00000000000..6792cf3ce35 --- /dev/null +++ b/tests/ui/traits/new-solver/alias_eq_simple.rs @@ -0,0 +1,22 @@ +// check-pass +// compile-flags: -Ztrait-solver=next + +// test that the new solver can handle `alias-eq(<i32 as TraitB>::Assoc, u32)` + +trait TraitA {} + +trait TraitB { + type Assoc; +} + +impl<T: TraitB> TraitA for (T, T::Assoc) {} + +impl TraitB for i32 { + type Assoc = u32; +} + +fn needs_a<T: TraitA>() {} + +fn main() { + needs_a::<(i32, u32)>(); +} diff --git a/tests/ui/traits/new-solver/alias_eq_substs_eq_not_intercrate.rs b/tests/ui/traits/new-solver/alias_eq_substs_eq_not_intercrate.rs new file mode 100644 index 00000000000..d4cc380fa21 --- /dev/null +++ b/tests/ui/traits/new-solver/alias_eq_substs_eq_not_intercrate.rs @@ -0,0 +1,20 @@ +// compile-flags: -Ztrait-solver=next + +// check that a `alias-eq(<?0 as TraitB>::Assoc, <T as TraitB>::Assoc)` goal fails. + +// FIXME(deferred_projection_equality): add a test that this is true during coherence + +trait TraitB { + type Assoc; +} + +fn needs_a<T: TraitB>() -> T::Assoc { + unimplemented!() +} + +fn bar<T: TraitB>() { + let _: <_ as TraitB>::Assoc = needs_a::<T>(); + //~^ error: type annotations needed +} + +fn main() {} diff --git a/tests/ui/traits/new-solver/alias_eq_substs_eq_not_intercrate.stderr b/tests/ui/traits/new-solver/alias_eq_substs_eq_not_intercrate.stderr new file mode 100644 index 00000000000..d063d8fce11 --- /dev/null +++ b/tests/ui/traits/new-solver/alias_eq_substs_eq_not_intercrate.stderr @@ -0,0 +1,9 @@ +error[E0282]: type annotations needed + --> $DIR/alias_eq_substs_eq_not_intercrate.rs:16:12 + | +LL | let _: <_ as TraitB>::Assoc = needs_a::<T>(); + | ^^^^^^^^^^^^^^^^^^^^ cannot infer type for associated type `<_ as TraitB>::Assoc` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0282`. diff --git a/tests/ui/traits/new-solver/normalizes_to_ignores_unnormalizable_candidate.rs b/tests/ui/traits/new-solver/normalizes_to_ignores_unnormalizable_candidate.rs new file mode 100644 index 00000000000..46343241b45 --- /dev/null +++ b/tests/ui/traits/new-solver/normalizes_to_ignores_unnormalizable_candidate.rs @@ -0,0 +1,40 @@ +// [no_self_infer] check-pass +// compile-flags: -Ztrait-solver=next +// revisions: self_infer no_self_infer + +// checks that the new solver is smart enough to infer `?0 = U` when solving: +// `normalizes-to(<Vec<?0> as Trait>::Assoc, u8)` +// with `normalizes-to(<Vec<U> as Trait>::Assoc, u8)` in the paramenv even when +// there is a separate `Vec<T>: Trait` bound in the paramenv. +// +// FIXME(-Ztrait-solver=next) +// This could also compile for `normalizes-to(<?0 as Trait>::Assoc, u8)` but +// we currently immediately consider a goal ambiguous if the self type is an +// inference variable. + +trait Trait { + type Assoc; +} + +fn foo<T: Trait<Assoc = u8>>(x: T) {} + +#[cfg(self_infer)] +fn unconstrained<T>() -> T { + todo!() +} + +#[cfg(no_self_infer)] +fn unconstrained<T>() -> Vec<T> { + todo!() +} + +fn bar<T, U>() +where + Vec<T>: Trait, + Vec<U>: Trait<Assoc = u8>, +{ + foo(unconstrained()) + //[self_infer]~^ ERROR type annotations needed +} + +fn main() {} diff --git a/tests/ui/traits/new-solver/normalizes_to_ignores_unnormalizable_candidate.self_infer.stderr b/tests/ui/traits/new-solver/normalizes_to_ignores_unnormalizable_candidate.self_infer.stderr new file mode 100644 index 00000000000..06283201261 --- /dev/null +++ b/tests/ui/traits/new-solver/normalizes_to_ignores_unnormalizable_candidate.self_infer.stderr @@ -0,0 +1,14 @@ +error[E0282]: type annotations needed + --> $DIR/normalizes_to_ignores_unnormalizable_candidate.rs:36:5 + | +LL | foo(unconstrained()) + | ^^^ cannot infer type of the type parameter `T` declared on the function `foo` + | +help: consider specifying the generic argument + | +LL | foo::<T>(unconstrained()) + | +++++ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0282`. diff --git a/tests/ui/traits/new-solver/param-candidate-doesnt-shadow-project.rs b/tests/ui/traits/new-solver/param-candidate-doesnt-shadow-project.rs new file mode 100644 index 00000000000..bdf999ec5dd --- /dev/null +++ b/tests/ui/traits/new-solver/param-candidate-doesnt-shadow-project.rs @@ -0,0 +1,25 @@ +// compile-flags: -Ztrait-solver=next +// check-pass + +trait Foo { + type Assoc; +} + +trait Bar {} + +impl<T> Foo for T { + type Assoc = i32; +} + +impl<T> Bar for T where T: Foo<Assoc = i32> {} + +fn require_bar<T: Bar>() {} + +fn foo<T: Foo>() { + // Unlike the classic solver, `<T as Foo>::Assoc = _` will still project + // down to `i32` even though there's a param-env candidate here, since we + // don't assemble any param-env projection candidates for `T: Foo` alone. + require_bar::<T>(); +} + +fn main() {} diff --git a/tests/ui/traits/new-solver/two-projection-param-candidates-are-ambiguous.rs b/tests/ui/traits/new-solver/two-projection-param-candidates-are-ambiguous.rs new file mode 100644 index 00000000000..cde2059ca9b --- /dev/null +++ b/tests/ui/traits/new-solver/two-projection-param-candidates-are-ambiguous.rs @@ -0,0 +1,30 @@ +// compile-flags: -Ztrait-solver=next + +// When we're solving `<T as Foo>::Assoc = i32`, we actually first solve +// `<T as Foo>::Assoc = _#1t`, then unify `_#1t` with `i32`. That goal +// with the inference variable is ambiguous when there are >1 param-env +// candidates. + +// We don't unify the RHS of a projection goal eagerly when solving, both +// for caching reasons and partly to make sure that we don't make the new +// trait solver smarter than it should be. + +// This is (as far as I can tell) a forwards-compatible decision, but if you +// make this test go from fail to pass, be sure you understand the implications! + +trait Foo { + type Assoc; +} + +trait Bar {} + +impl<T> Bar for T where T: Foo<Assoc = i32> {} + +fn needs_bar<T: Bar>() {} + +fn foo<T: Foo<Assoc = i32> + Foo<Assoc = u32>>() { + needs_bar::<T>(); + //~^ ERROR type annotations needed: cannot satisfy `T: Bar` +} + +fn main() {} diff --git a/tests/ui/traits/new-solver/two-projection-param-candidates-are-ambiguous.stderr b/tests/ui/traits/new-solver/two-projection-param-candidates-are-ambiguous.stderr new file mode 100644 index 00000000000..fa5e780ee5e --- /dev/null +++ b/tests/ui/traits/new-solver/two-projection-param-candidates-are-ambiguous.stderr @@ -0,0 +1,16 @@ +error[E0283]: type annotations needed: cannot satisfy `T: Bar` + --> $DIR/two-projection-param-candidates-are-ambiguous.rs:26:5 + | +LL | needs_bar::<T>(); + | ^^^^^^^^^^^^^^ + | + = note: cannot satisfy `T: Bar` +note: required by a bound in `needs_bar` + --> $DIR/two-projection-param-candidates-are-ambiguous.rs:23:17 + | +LL | fn needs_bar<T: Bar>() {} + | ^^^ required by this bound in `needs_bar` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0283`. |
