diff --git a/compiler/rustc_hir_typeck/src/intrinsicck.rs b/compiler/rustc_hir_typeck/src/intrinsicck.rs index 3c5eafd948488..362c07431e0a2 100644 --- a/compiler/rustc_hir_typeck/src/intrinsicck.rs +++ b/compiler/rustc_hir_typeck/src/intrinsicck.rs @@ -82,8 +82,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Try to display a sensible error with as much information as possible. let skeleton_string = |ty: Ty<'tcx>, sk| match sk { - Ok(SizeSkeleton::Known(size)) => format!("{} bits", size.bits()), Ok(SizeSkeleton::Pointer { tail, .. }) => format!("pointer to `{tail}`"), + Ok(SizeSkeleton::Known(size)) => { + if let Some(v) = u128::from(size.bytes()).checked_mul(8) { + format!("{} bits", v) + } else { + // `u128` should definitely be able to hold the size of different architectures + // larger sizes should be reported as error `are too big for the current architecture` + // otherwise we have a bug somewhere + bug!("{:?} overflow for u128", size) + } + } Ok(SizeSkeleton::Generic(size)) => { if let Some(size) = size.try_eval_target_usize(tcx, self.param_env) { format!("{size} bytes") diff --git a/compiler/rustc_hir_typeck/src/writeback.rs b/compiler/rustc_hir_typeck/src/writeback.rs index a395858262f04..29abe921bbdcd 100644 --- a/compiler/rustc_hir_typeck/src/writeback.rs +++ b/compiler/rustc_hir_typeck/src/writeback.rs @@ -136,7 +136,10 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { fn write_ty_to_typeck_results(&mut self, hir_id: hir::HirId, ty: Ty<'tcx>) { debug!("write_ty_to_typeck_results({:?}, {:?})", hir_id, ty); - assert!(!ty.has_infer() && !ty.has_placeholders() && !ty.has_free_regions()); + assert!( + !ty.has_infer() && !ty.has_placeholders() && !ty.has_free_regions(), + "{ty} can't be put into typeck results" + ); self.typeck_results.node_types_mut().insert(hir_id, ty); } @@ -803,7 +806,11 @@ impl<'cx, 'tcx> TypeFolder> for Resolver<'cx, 'tcx> { // We must normalize erasing regions here, since later lints // expect that types that show up in the typeck are fully // normalized. - self.fcx.tcx.try_normalize_erasing_regions(self.fcx.param_env, t).unwrap_or(t) + if let Ok(t) = self.fcx.tcx.try_normalize_erasing_regions(self.fcx.param_env, t) { + t + } else { + EraseEarlyRegions { tcx: self.fcx.tcx }.fold_ty(t) + } } Ok(t) => { // Do not anonymize late-bound regions diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs index 7f944fb574596..47d8e5993fd82 100644 --- a/compiler/rustc_resolve/src/imports.rs +++ b/compiler/rustc_resolve/src/imports.rs @@ -338,7 +338,21 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { } else { resolution.binding = Some(nonglob_binding); } - resolution.shadowed_glob = Some(glob_binding); + + if let Some(old_binding) = resolution.shadowed_glob { + assert!(old_binding.is_glob_import()); + if glob_binding.res() != old_binding.res() { + resolution.shadowed_glob = Some(this.ambiguity( + AmbiguityKind::GlobVsGlob, + old_binding, + glob_binding, + )); + } else if !old_binding.vis.is_at_least(binding.vis, this.tcx) { + resolution.shadowed_glob = Some(glob_binding); + } + } else { + resolution.shadowed_glob = Some(glob_binding); + } } (false, false) => { return Err(old_binding); diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index f205ff15ec3d0..5bd9389a400af 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -1940,8 +1940,6 @@ pub(crate) fn small_url_encode(s: String) -> String { // While the same is not true for hashes, rustdoc only needs to be // consistent with itself when encoding them. st += "+"; - } else if b == b'%' { - st += "%%"; } else { write!(st, "%{:02X}", b).unwrap(); } diff --git a/src/librustdoc/html/static/js/search.js b/src/librustdoc/html/static/js/search.js index 984358396ab2a..1ccfca8d0d5ff 100644 --- a/src/librustdoc/html/static/js/search.js +++ b/src/librustdoc/html/static/js/search.js @@ -386,6 +386,35 @@ function initSearch(rawSearchIndex) { if (query.literalSearch && parserState.totalElems - parserState.genericsElems > 0) { throw ["You cannot have more than one element if you use quotes"]; } + const typeFilter = parserState.typeFilter; + parserState.typeFilter = null; + if (name === "!") { + if (typeFilter !== null && typeFilter !== "primitive") { + throw [ + "Invalid search type: primitive never type ", + "!", + " and ", + typeFilter, + " both specified", + ]; + } + if (generics.length !== 0) { + throw [ + "Never type ", + "!", + " does not accept generic parameters", + ]; + } + return { + name: "never", + id: -1, + fullPath: ["never"], + pathWithoutLast: [], + pathLast: "never", + generics: [], + typeFilter: "primitive", + }; + } const pathSegments = name.split("::"); if (pathSegments.length > 1) { for (let i = 0, len = pathSegments.length; i < len; ++i) { @@ -399,6 +428,13 @@ function initSearch(rawSearchIndex) { } throw ["Unexpected ", "::::"]; } + + if (pathSegment === "!") { + pathSegments[i] = "never"; + if (i !== 0) { + throw ["Never type ", "!", " is not associated item"]; + } + } } } // In case we only have something like `

`, there is no name. @@ -409,8 +445,6 @@ function initSearch(rawSearchIndex) { if (isInGenerics) { parserState.genericsElems += 1; } - const typeFilter = parserState.typeFilter; - parserState.typeFilter = null; return { name: name, id: -1, @@ -459,10 +493,11 @@ function initSearch(rawSearchIndex) { break; } if (foundExclamation !== -1) { - if (start <= (end - 2)) { + if (foundExclamation !== start && + isIdentCharacter(parserState.userQuery[foundExclamation - 1]) + ) { throw ["Cannot have associated items in macros"]; } else { - // if start == end - 1, we got the never type // while the never type has no associated macros, we still // can parse a path like that foundExclamation = -1; @@ -478,7 +513,10 @@ function initSearch(rawSearchIndex) { end = parserState.pos; } // if start == end - 1, we got the never type - if (foundExclamation !== -1 && start <= (end - 2)) { + if (foundExclamation !== -1 && + foundExclamation !== start && + isIdentCharacter(parserState.userQuery[foundExclamation - 1]) + ) { if (parserState.typeFilter === null) { parserState.typeFilter = "macro"; } else if (parserState.typeFilter !== "macro") { diff --git a/src/tools/tidy/src/ui_tests.rs b/src/tools/tidy/src/ui_tests.rs index 5c6a94877884d..55bf38110a6d5 100644 --- a/src/tools/tidy/src/ui_tests.rs +++ b/src/tools/tidy/src/ui_tests.rs @@ -10,7 +10,7 @@ use std::path::{Path, PathBuf}; const ENTRY_LIMIT: usize = 900; // FIXME: The following limits should be reduced eventually. -const ISSUES_ENTRY_LIMIT: usize = 1898; +const ISSUES_ENTRY_LIMIT: usize = 1896; const ROOT_ENTRY_LIMIT: usize = 870; const EXPECTED_TEST_FILE_EXTENSIONS: &[&str] = &[ diff --git a/tests/rustdoc-js-std/never.js b/tests/rustdoc-js-std/never.js index ed3776b3c2ae0..27d415b5e486d 100644 --- a/tests/rustdoc-js-std/never.js +++ b/tests/rustdoc-js-std/never.js @@ -1,6 +1,14 @@ -const EXPECTED = { - 'query': '!', - 'others': [ - { 'path': 'std', 'name': 'never' }, - ], -}; +const EXPECTED = [ + { + 'query': '!', + 'others': [ + { 'path': 'std', 'name': 'never' }, + ], + }, + { + 'query': '!::clone', + 'others': [ + { 'path': 'std::never', 'name': 'clone' }, + ], + }, +]; diff --git a/tests/rustdoc-js-std/parser-errors.js b/tests/rustdoc-js-std/parser-errors.js index aa8ee86d67247..af7f63f99cbdf 100644 --- a/tests/rustdoc-js-std/parser-errors.js +++ b/tests/rustdoc-js-std/parser-errors.js @@ -359,6 +359,15 @@ const PARSED = [ userQuery: "mod:a!", error: 'Invalid search type: macro `!` and `mod` both specified', }, + { + query: "mod:!", + elems: [], + foundElems: 0, + original: "mod:!", + returned: [], + userQuery: "mod:!", + error: 'Invalid search type: primitive never type `!` and `mod` both specified', + }, { query: "a!::a", elems: [], diff --git a/tests/rustdoc-js-std/parser-ident.js b/tests/rustdoc-js-std/parser-ident.js index d9ee5fb564b68..f65a7ce6692b0 100644 --- a/tests/rustdoc-js-std/parser-ident.js +++ b/tests/rustdoc-js-std/parser-ident.js @@ -8,11 +8,12 @@ const PARSED = [ pathLast: "r", generics: [ { - name: "!", - fullPath: ["!"], + name: "never", + fullPath: ["never"], pathWithoutLast: [], - pathLast: "!", + pathLast: "never", generics: [], + typeFilter: 15, }, ], typeFilter: -1, @@ -26,12 +27,12 @@ const PARSED = [ { query: "!", elems: [{ - name: "!", - fullPath: ["!"], + name: "never", + fullPath: ["never"], pathWithoutLast: [], - pathLast: "!", + pathLast: "never", generics: [], - typeFilter: -1, + typeFilter: 15, }], foundElems: 1, original: "!", @@ -64,12 +65,21 @@ const PARSED = [ userQuery: "a!::b", error: "Cannot have associated items in macros", }, + { + query: "!", + elems: [], + foundElems: 0, + original: "!", + returned: [], + userQuery: "!", + error: "Never type `!` does not accept generic parameters", + }, { query: "!::b", elems: [{ name: "!::b", - fullPath: ["!", "b"], - pathWithoutLast: ["!"], + fullPath: ["never", "b"], + pathWithoutLast: ["never"], pathLast: "b", generics: [], typeFilter: -1, @@ -80,6 +90,58 @@ const PARSED = [ userQuery: "!::b", error: null, }, + { + query: "b::!", + elems: [], + foundElems: 0, + original: "b::!", + returned: [], + userQuery: "b::!", + error: "Never type `!` is not associated item", + }, + { + query: "!::!", + elems: [], + foundElems: 0, + original: "!::!", + returned: [], + userQuery: "!::!", + error: "Never type `!` is not associated item", + }, + { + query: "b::!::c", + elems: [], + foundElems: 0, + original: "b::!::c", + returned: [], + userQuery: "b::!::c", + error: "Never type `!` is not associated item", + }, + { + query: "!::b", + elems: [{ + name: "!::b", + fullPath: ["never", "b"], + pathWithoutLast: ["never"], + pathLast: "b", + generics: [ + { + name: "t", + fullPath: ["t"], + pathWithoutLast: [], + pathLast: "t", + generics: [], + typeFilter: -1, + } + ], + typeFilter: -1, + }], + foundElems: 1, + original: "!::b", + returned: [], + userQuery: "!::b", + error: null, + }, { query: "a!::b!", elems: [], diff --git a/tests/rustdoc-js-std/parser-returned.js b/tests/rustdoc-js-std/parser-returned.js index 665e2a9b2e3d7..6ea86609115bf 100644 --- a/tests/rustdoc-js-std/parser-returned.js +++ b/tests/rustdoc-js-std/parser-returned.js @@ -84,12 +84,12 @@ const PARSED = [ foundElems: 1, original: "-> !", returned: [{ - name: "!", - fullPath: ["!"], + name: "never", + fullPath: ["never"], pathWithoutLast: [], - pathLast: "!", + pathLast: "never", generics: [], - typeFilter: -1, + typeFilter: 15, }], userQuery: "-> !", error: null, diff --git a/tests/rustdoc-js/never-search.js b/tests/rustdoc-js/never-search.js new file mode 100644 index 0000000000000..ed24d693133ba --- /dev/null +++ b/tests/rustdoc-js/never-search.js @@ -0,0 +1,46 @@ +// exact-check + +const EXPECTED = [ + { + 'query': '-> !', + 'others': [ + { 'path': 'never_search', 'name': 'loops' }, + ], + }, + { + 'query': '-> never', + 'others': [ + { 'path': 'never_search', 'name': 'loops' }, + { 'path': 'never_search', 'name': 'returns' }, + ], + }, + { + 'query': '!', + 'in_args': [ + { 'path': 'never_search', 'name': 'impossible' }, + { 'path': 'never_search', 'name': 'box_impossible' }, + ], + }, + { + 'query': 'never', + 'in_args': [ + { 'path': 'never_search', 'name': 'impossible' }, + { 'path': 'never_search', 'name': 'uninteresting' }, + { 'path': 'never_search', 'name': 'box_impossible' }, + { 'path': 'never_search', 'name': 'box_uninteresting' }, + ], + }, + { + 'query': 'box', + 'in_args': [ + { 'path': 'never_search', 'name': 'box_impossible' }, + ], + }, + { + 'query': 'box', + 'in_args': [ + { 'path': 'never_search', 'name': 'box_impossible' }, + { 'path': 'never_search', 'name': 'box_uninteresting' }, + ], + }, +]; diff --git a/tests/rustdoc-js/never-search.rs b/tests/rustdoc-js/never-search.rs new file mode 100644 index 0000000000000..299b4660dae9e --- /dev/null +++ b/tests/rustdoc-js/never-search.rs @@ -0,0 +1,13 @@ +#![feature(never_type)] + +#[allow(nonstandard_style)] +pub struct never; + +pub fn loops() -> ! { loop {} } +pub fn returns() -> never { never } + +pub fn impossible(x: !) { match x {} } +pub fn uninteresting(x: never) { match x { never => {} } } + +pub fn box_impossible(x: Box) { match *x {} } +pub fn box_uninteresting(x: Box) { match *x { never => {} } } diff --git a/tests/ui/const-generics/issue-112505-overflow.rs b/tests/ui/const-generics/issue-112505-overflow.rs new file mode 100644 index 0000000000000..0dd7776d59544 --- /dev/null +++ b/tests/ui/const-generics/issue-112505-overflow.rs @@ -0,0 +1,7 @@ +#![feature(transmute_generic_consts)] + +fn overflow(v: [[[u32; 8888888]; 9999999]; 777777777]) -> [[[u32; 9999999]; 777777777]; 239] { + unsafe { std::mem::transmute(v) } //~ ERROR cannot transmute between types of different sizes +} + +fn main() { } diff --git a/tests/ui/const-generics/issue-112505-overflow.stderr b/tests/ui/const-generics/issue-112505-overflow.stderr new file mode 100644 index 0000000000000..0432f2fa8be5d --- /dev/null +++ b/tests/ui/const-generics/issue-112505-overflow.stderr @@ -0,0 +1,12 @@ +error[E0512]: cannot transmute between types of different sizes, or dependently-sized types + --> $DIR/issue-112505-overflow.rs:4:14 + | +LL | unsafe { std::mem::transmute(v) } + | ^^^^^^^^^^^^^^^^^^^ + | + = note: source type: `[[[u32; 8888888]; 9999999]; 777777777]` (values of the type `[[[u32; 8888888]; 9999999]; 777777777]` are too big for the current architecture) + = note: target type: `[[[u32; 9999999]; 777777777]; 239]` (59484438436515561504 bits) + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0512`. diff --git a/tests/ui/issues/issue-20605.stderr b/tests/ui/for/issue-20605.current.stderr similarity index 95% rename from tests/ui/issues/issue-20605.stderr rename to tests/ui/for/issue-20605.current.stderr index e1858b6398932..b9a53cbd4fcb2 100644 --- a/tests/ui/issues/issue-20605.stderr +++ b/tests/ui/for/issue-20605.current.stderr @@ -1,5 +1,5 @@ error[E0277]: the size for values of type `dyn Iterator` cannot be known at compilation time - --> $DIR/issue-20605.rs:2:17 + --> $DIR/issue-20605.rs:5:17 | LL | for item in *things { *item = 0 } | ^^^^^^^ the trait `IntoIterator` is not implemented for `dyn Iterator` diff --git a/tests/ui/for/issue-20605.next.stderr b/tests/ui/for/issue-20605.next.stderr new file mode 100644 index 0000000000000..5362a68c834a3 --- /dev/null +++ b/tests/ui/for/issue-20605.next.stderr @@ -0,0 +1,25 @@ +error[E0277]: the trait bound `dyn Iterator: IntoIterator` is not satisfied + --> $DIR/issue-20605.rs:5:17 + | +LL | for item in *things { *item = 0 } + | ^^^^^^^ the trait `IntoIterator` is not implemented for `dyn Iterator` + +error[E0277]: the size for values of type ` as IntoIterator>::IntoIter` cannot be known at compilation time + --> $DIR/issue-20605.rs:5:17 + | +LL | for item in *things { *item = 0 } + | ^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for ` as IntoIterator>::IntoIter` + = note: all local variables must have a statically known size + = help: unsized locals are gated as an unstable feature + +error: the type `<_ as IntoIterator>::IntoIter` is not well-formed + --> $DIR/issue-20605.rs:5:17 + | +LL | for item in *things { *item = 0 } + | ^^^^^^^ + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/for/issue-20605.rs b/tests/ui/for/issue-20605.rs new file mode 100644 index 0000000000000..499271fa92fa9 --- /dev/null +++ b/tests/ui/for/issue-20605.rs @@ -0,0 +1,11 @@ +// revisions: current next +//[next] compile-flags: -Ztrait-solver=next + +fn changer<'a>(mut things: Box>) { + for item in *things { *item = 0 } + //~^ ERROR the size for values of type + //[next]~^^ ERROR the type `<_ as IntoIterator>::IntoIter` is not well-formed + //[next]~| ERROR the trait bound `dyn Iterator: IntoIterator` is not satisfied +} + +fn main() {} diff --git a/tests/ui/issues/issue-20605.rs b/tests/ui/issues/issue-20605.rs deleted file mode 100644 index 17b7d32ebf59b..0000000000000 --- a/tests/ui/issues/issue-20605.rs +++ /dev/null @@ -1,6 +0,0 @@ -fn changer<'a>(mut things: Box>) { - for item in *things { *item = 0 } -//~^ ERROR the size for values of type -} - -fn main() {} diff --git a/tests/ui/resolve/issue-105069.stderr b/tests/ui/resolve/issue-105069.stderr index 1e6c9c6e2dc34..a049cac830ab4 100644 --- a/tests/ui/resolve/issue-105069.stderr +++ b/tests/ui/resolve/issue-105069.stderr @@ -4,17 +4,19 @@ error[E0659]: `V` is ambiguous LL | use V; | ^ ambiguous name | - = note: ambiguous because of multiple potential import sources + = note: ambiguous because of multiple glob imports of a name in the same module note: `V` could refer to the variant imported here --> $DIR/issue-105069.rs:1:5 | LL | use self::A::*; | ^^^^^^^^^^ + = help: consider adding an explicit import of `V` to disambiguate note: `V` could also refer to the variant imported here --> $DIR/issue-105069.rs:3:5 | LL | use self::B::*; | ^^^^^^^^^^ + = help: consider adding an explicit import of `V` to disambiguate error: aborting due to previous error diff --git a/tests/ui/resolve/issue-109153.rs b/tests/ui/resolve/issue-109153.rs new file mode 100644 index 0000000000000..bff6c911236e6 --- /dev/null +++ b/tests/ui/resolve/issue-109153.rs @@ -0,0 +1,14 @@ +use foo::*; + +mod foo { + pub mod bar { + pub mod bar { + pub mod bar {} + } + } +} + +use bar::bar; //~ ERROR `bar` is ambiguous +use bar::*; + +fn main() { } diff --git a/tests/ui/resolve/issue-109153.stderr b/tests/ui/resolve/issue-109153.stderr new file mode 100644 index 0000000000000..1a345d2a3e3a7 --- /dev/null +++ b/tests/ui/resolve/issue-109153.stderr @@ -0,0 +1,23 @@ +error[E0659]: `bar` is ambiguous + --> $DIR/issue-109153.rs:11:5 + | +LL | use bar::bar; + | ^^^ ambiguous name + | + = note: ambiguous because of multiple glob imports of a name in the same module +note: `bar` could refer to the module imported here + --> $DIR/issue-109153.rs:1:5 + | +LL | use foo::*; + | ^^^^^^ + = help: consider adding an explicit import of `bar` to disambiguate +note: `bar` could also refer to the module imported here + --> $DIR/issue-109153.rs:12:5 + | +LL | use bar::*; + | ^^^^^^ + = help: consider adding an explicit import of `bar` to disambiguate + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0659`.