From 3e08354fb0dc7a5f7733da9b308d483b9c1d2514 Mon Sep 17 00:00:00 2001 From: Lzu Tao Date: Sun, 20 Sep 2020 12:46:06 +0000 Subject: [PATCH 01/17] Correct file path after some restructures in compiler --- compiler/rustc_codegen_ssa/src/traits/intrinsic.rs | 6 +++--- compiler/rustc_error_codes/src/error_codes/E0092.md | 4 ++-- compiler/rustc_error_codes/src/error_codes/E0093.md | 4 ++-- compiler/rustc_mir/src/interpret/terminator.rs | 4 ++-- compiler/rustc_typeck/src/check/intrinsic.rs | 4 ++-- library/core/src/intrinsics.rs | 6 +++--- library/panic_unwind/src/seh.rs | 2 +- 7 files changed, 15 insertions(+), 15 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/traits/intrinsic.rs b/compiler/rustc_codegen_ssa/src/traits/intrinsic.rs index 9d48e233de655..ccd294d92b2f4 100644 --- a/compiler/rustc_codegen_ssa/src/traits/intrinsic.rs +++ b/compiler/rustc_codegen_ssa/src/traits/intrinsic.rs @@ -5,9 +5,9 @@ use rustc_span::Span; use rustc_target::abi::call::FnAbi; pub trait IntrinsicCallMethods<'tcx>: BackendTypes { - /// Remember to add all intrinsics here, in librustc_typeck/check/mod.rs, - /// and in libcore/intrinsics.rs; if you need access to any llvm intrinsics, - /// add them to librustc_codegen_llvm/context.rs + /// Remember to add all intrinsics here, in `compiler/rustc_typeck/src/check/mod.rs`, + /// and in `library/core/src/intrinsics.rs`; if you need access to any LLVM intrinsics, + /// add them to `compiler/rustc_codegen_llvm/src/context.rs`. fn codegen_intrinsic_call( &mut self, instance: ty::Instance<'tcx>, diff --git a/compiler/rustc_error_codes/src/error_codes/E0092.md b/compiler/rustc_error_codes/src/error_codes/E0092.md index e289534bf7abd..496174b28efac 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0092.md +++ b/compiler/rustc_error_codes/src/error_codes/E0092.md @@ -12,8 +12,8 @@ extern "rust-intrinsic" { ``` Please check you didn't make a mistake in the function's name. All intrinsic -functions are defined in `librustc_codegen_llvm/intrinsic.rs` and in -`libcore/intrinsics.rs` in the Rust source code. Example: +functions are defined in `compiler/rustc_codegen_llvm/src/intrinsic.rs` and in +`library/core/src/intrinsics.rs` in the Rust source code. Example: ``` #![feature(intrinsics)] diff --git a/compiler/rustc_error_codes/src/error_codes/E0093.md b/compiler/rustc_error_codes/src/error_codes/E0093.md index 8e7de1a9d37b3..6d58e50ec8813 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0093.md +++ b/compiler/rustc_error_codes/src/error_codes/E0093.md @@ -17,8 +17,8 @@ fn main() { ``` Please check you didn't make a mistake in the function's name. All intrinsic -functions are defined in `librustc_codegen_llvm/intrinsic.rs` and in -`libcore/intrinsics.rs` in the Rust source code. Example: +functions are defined in `compiler/rustc_codegen_llvm/src/intrinsic.rs` and in +`library/core/src/intrinsics.rs` in the Rust source code. Example: ``` #![feature(intrinsics)] diff --git a/compiler/rustc_mir/src/interpret/terminator.rs b/compiler/rustc_mir/src/interpret/terminator.rs index d3c0b497a1675..00271f227d871 100644 --- a/compiler/rustc_mir/src/interpret/terminator.rs +++ b/compiler/rustc_mir/src/interpret/terminator.rs @@ -385,9 +385,9 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { ty::InstanceDef::Virtual(_, idx) => { let mut args = args.to_vec(); // We have to implement all "object safe receivers". Currently we - // support built-in pointers (&, &mut, Box) as well as unsized-self. We do + // support built-in pointers `(&, &mut, Box)` as well as unsized-self. We do // not yet support custom self types. - // Also see librustc_codegen_llvm/abi.rs and librustc_codegen_llvm/mir/block.rs. + // Also see `compiler/rustc_codegen_llvm/src/abi.rs` and `compiler/rustc_codegen_ssa/src/mir/block.rs`. let receiver_place = match args[0].layout.ty.builtin_deref(true) { Some(_) => { // Built-in pointer. diff --git a/compiler/rustc_typeck/src/check/intrinsic.rs b/compiler/rustc_typeck/src/check/intrinsic.rs index b8230f524446a..2ee867c2dd648 100644 --- a/compiler/rustc_typeck/src/check/intrinsic.rs +++ b/compiler/rustc_typeck/src/check/intrinsic.rs @@ -106,8 +106,8 @@ pub fn intrinsic_operation_unsafety(intrinsic: Symbol) -> hir::Unsafety { } } -/// Remember to add all intrinsics here, in librustc_codegen_llvm/intrinsic.rs, -/// and in libcore/intrinsics.rs +/// Remember to add all intrinsics here, in `compiler/rustc_codegen_llvm/src/intrinsic.rs`, +/// and in `library/core/src/intrinsics.rs`. pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) { let param = |n| tcx.mk_ty_param(n, Symbol::intern(&format!("P{}", n))); let def_id = tcx.hir().local_def_id(it.hir_id).to_def_id(); diff --git a/library/core/src/intrinsics.rs b/library/core/src/intrinsics.rs index dd9af2d07e770..de4d2efe29461 100644 --- a/library/core/src/intrinsics.rs +++ b/library/core/src/intrinsics.rs @@ -1,7 +1,7 @@ //! Compiler intrinsics. //! -//! The corresponding definitions are in `librustc_codegen_llvm/intrinsic.rs`. -//! The corresponding const implementations are in `librustc_mir/interpret/intrinsics.rs` +//! The corresponding definitions are in `compiler/rustc_codegen_llvm/src/intrinsic.rs`. +//! The corresponding const implementations are in `compiler/rustc_mir/src/interpret/intrinsics.rs` //! //! # Const intrinsics //! @@ -10,7 +10,7 @@ //! //! In order to make an intrinsic usable at compile-time, one needs to copy the implementation //! from https://github.com/rust-lang/miri/blob/master/src/shims/intrinsics.rs to -//! `librustc_mir/interpret/intrinsics.rs` and add a +//! `compiler/rustc_mir/src/interpret/intrinsics.rs` and add a //! `#[rustc_const_unstable(feature = "foo", issue = "01234")]` to the intrinsic. //! //! If an intrinsic is supposed to be used from a `const fn` with a `rustc_const_stable` attribute, diff --git a/library/panic_unwind/src/seh.rs b/library/panic_unwind/src/seh.rs index eca169373f39f..5597bbb93d236 100644 --- a/library/panic_unwind/src/seh.rs +++ b/library/panic_unwind/src/seh.rs @@ -175,7 +175,7 @@ pub struct _TypeDescriptor { // to be able to catch Rust panics by simply declaring a `struct rust_panic`. // // When modifying, make sure that the type name string exactly matches -// the one used in src/librustc_codegen_llvm/intrinsic.rs. +// the one used in `compiler/rustc_codegen_llvm/src/intrinsic.rs`. const TYPE_NAME: [u8; 11] = *b"rust_panic\0"; static mut THROW_INFO: _ThrowInfo = _ThrowInfo { From 4387480dea6e2611483d431857f0f85b65e3c00c Mon Sep 17 00:00:00 2001 From: Lzu Tao Date: Sun, 20 Sep 2020 13:30:32 +0000 Subject: [PATCH 02/17] Add unstably const support for assume intrinsic --- compiler/rustc_mir/src/interpret/intrinsics.rs | 6 ++++++ library/core/src/intrinsics.rs | 1 + src/test/ui/consts/const-eval/const_assume.rs | 17 +++++++++++++++++ 3 files changed, 24 insertions(+) create mode 100644 src/test/ui/consts/const-eval/const_assume.rs diff --git a/compiler/rustc_mir/src/interpret/intrinsics.rs b/compiler/rustc_mir/src/interpret/intrinsics.rs index 0664f25e409dc..d3b6d706337ed 100644 --- a/compiler/rustc_mir/src/interpret/intrinsics.rs +++ b/compiler/rustc_mir/src/interpret/intrinsics.rs @@ -435,6 +435,12 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { // These just return their argument self.copy_op(args[0], dest)?; } + sym::assume => { + let cond = self.read_scalar(args[0])?.check_init()?.to_bool()?; + if !cond { + throw_ub_format!("`assume` intrinsic called with `false`"); + } + } _ => return Ok(false), } diff --git a/library/core/src/intrinsics.rs b/library/core/src/intrinsics.rs index de4d2efe29461..c68200c90d8d0 100644 --- a/library/core/src/intrinsics.rs +++ b/library/core/src/intrinsics.rs @@ -733,6 +733,7 @@ extern "rust-intrinsic" { /// own, or if it does not enable any significant optimizations. /// /// This intrinsic does not have a stable counterpart. + #[rustc_const_unstable(feature = "const_assume", issue = "76972")] pub fn assume(b: bool); /// Hints to the compiler that branch condition is likely to be true. diff --git a/src/test/ui/consts/const-eval/const_assume.rs b/src/test/ui/consts/const-eval/const_assume.rs new file mode 100644 index 0000000000000..f72f151824bed --- /dev/null +++ b/src/test/ui/consts/const-eval/const_assume.rs @@ -0,0 +1,17 @@ +// check-pass + +// Check that `const_assume` feature allow `assume` intrinsic +// to be used in const contexts. + +#![feature(core_intrinsics, const_assume)] + +extern crate core; + +use core::intrinsics::assume; + +pub const unsafe fn foo(x: usize, y: usize) -> usize { + assume(y != 0); + x / y +} + +fn main() {} From 9f27f3796d3487411ab035803a0757d69040649c Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Tue, 22 Sep 2020 17:20:15 -0700 Subject: [PATCH 03/17] Include libunwind in the rust-src component. --- src/bootstrap/dist.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index cf73e570fa56f..55ca25ffe060a 100644 --- a/src/bootstrap/dist.rs +++ b/src/bootstrap/dist.rs @@ -1022,7 +1022,7 @@ impl Step for Src { copy_src_dirs( builder, &builder.src, - &["library"], + &["library", "src/llvm-project/libunwind"], &[ // not needed and contains symlinks which rustup currently // chokes on when unpacking. From 631c6883502144fdb8ac754c9ef1f74111fd3222 Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Wed, 23 Sep 2020 11:09:10 +0200 Subject: [PATCH 04/17] Make [].as_[mut_]ptr_range() (unstably) const. --- library/core/src/slice/mod.rs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs index ff926c517bc7c..12dcd6c6ba8d0 100644 --- a/library/core/src/slice/mod.rs +++ b/library/core/src/slice/mod.rs @@ -433,8 +433,9 @@ impl [T] { /// assert_eq!(x, &[3, 4, 6]); /// ``` #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_const_unstable(feature = "const_ptr_offset", issue = "71499")] #[inline] - pub fn as_mut_ptr(&mut self) -> *mut T { + pub const fn as_mut_ptr(&mut self) -> *mut T { self as *mut [T] as *mut T } @@ -469,8 +470,9 @@ impl [T] { /// /// [`as_ptr`]: #method.as_ptr #[unstable(feature = "slice_ptr_range", issue = "65807")] + #[rustc_const_unstable(feature = "const_ptr_offset", issue = "71499")] #[inline] - pub fn as_ptr_range(&self) -> Range<*const T> { + pub const fn as_ptr_range(&self) -> Range<*const T> { let start = self.as_ptr(); // SAFETY: The `add` here is safe, because: // @@ -510,8 +512,9 @@ impl [T] { /// /// [`as_mut_ptr`]: #method.as_mut_ptr #[unstable(feature = "slice_ptr_range", issue = "65807")] + #[rustc_const_unstable(feature = "const_ptr_offset", issue = "71499")] #[inline] - pub fn as_mut_ptr_range(&mut self) -> Range<*mut T> { + pub const fn as_mut_ptr_range(&mut self) -> Range<*mut T> { let start = self.as_mut_ptr(); // SAFETY: See as_ptr_range() above for why `add` here is safe. let end = unsafe { start.add(self.len()) }; From b5d47bfa3aafb8fcb8c60d93fea45207c7ea5c7b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Kr=C3=BCger?= Date: Wed, 23 Sep 2020 15:45:35 +0200 Subject: [PATCH 05/17] clarify that `changelog-seen = 1` goes to the beginning of config.toml Fixes #77105 --- src/bootstrap/bin/main.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bootstrap/bin/main.rs b/src/bootstrap/bin/main.rs index f7512aa9fcebd..6af13fc83d0ef 100644 --- a/src/bootstrap/bin/main.rs +++ b/src/bootstrap/bin/main.rs @@ -40,7 +40,7 @@ fn check_version(config: &Config) -> Option { } } else { msg.push_str("warning: x.py has made several changes recently you may want to look at\n"); - format!("add `changelog-seen = {}` to `config.toml`", VERSION) + format!("add `changelog-seen = {}` at the top of `config.toml`", VERSION) }; msg.push_str("help: consider looking at the changes in `src/bootstrap/CHANGELOG.md`\n"); From bcbd2ccc8d4591705fd5b63a5d5f5fc320cd89be Mon Sep 17 00:00:00 2001 From: Dylan MacKenzie Date: Wed, 23 Sep 2020 14:25:23 -0700 Subject: [PATCH 06/17] Add `keep-stage-std` to `x.py` This keeps only the `std` artifacts compiled by the given stage, not the compiler. This is useful when working on the latter stages of the compiler in tandem with the standard library, since you don't have to rebuild the *entire* compiler when the standard library changes. --- src/bootstrap/compile.rs | 9 ++++++++- src/bootstrap/config.rs | 2 ++ src/bootstrap/flags.rs | 17 ++++++++++++++++- 3 files changed, 26 insertions(+), 2 deletions(-) diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs index 08907edef1d1e..02095c27335e4 100644 --- a/src/bootstrap/compile.rs +++ b/src/bootstrap/compile.rs @@ -59,7 +59,9 @@ impl Step for Std { let target = self.target; let compiler = self.compiler; - if builder.config.keep_stage.contains(&compiler.stage) { + if builder.config.keep_stage.contains(&compiler.stage) + || builder.config.keep_stage_std.contains(&compiler.stage) + { builder.info("Warning: Using a potentially old libstd. This may not behave well."); builder.ensure(StdLink { compiler, target_compiler: compiler, target }); return; @@ -472,6 +474,11 @@ impl Step for Rustc { if builder.config.keep_stage.contains(&compiler.stage) { builder.info("Warning: Using a potentially old librustc. This may not behave well."); + builder.info("Warning: Use `--keep-stage-std` if you want to rebuild the compiler when it changes"); + builder.info( + "Warning: Please file a GitHub issue if `--keep-stage-std` doesn't work for you.", + ); + builder.info("Warning: It may replace `--keep-stage` in the future"); builder.ensure(RustcLink { compiler, target_compiler: compiler, target }); return; } diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs index c74501979f0ec..53fef7a838df6 100644 --- a/src/bootstrap/config.rs +++ b/src/bootstrap/config.rs @@ -71,6 +71,7 @@ pub struct Config { pub on_fail: Option, pub stage: u32, pub keep_stage: Vec, + pub keep_stage_std: Vec, pub src: PathBuf, pub jobs: Option, pub cmd: Subcommand, @@ -539,6 +540,7 @@ impl Config { config.incremental = flags.incremental; config.dry_run = flags.dry_run; config.keep_stage = flags.keep_stage; + config.keep_stage_std = flags.keep_stage_std; config.bindir = "bin".into(); // default if let Some(value) = flags.deny_warnings { config.deny_warnings = value; diff --git a/src/bootstrap/flags.rs b/src/bootstrap/flags.rs index 842c84a3e5cd6..dad31fc77be17 100644 --- a/src/bootstrap/flags.rs +++ b/src/bootstrap/flags.rs @@ -19,6 +19,7 @@ pub struct Flags { pub on_fail: Option, pub stage: Option, pub keep_stage: Vec, + pub keep_stage_std: Vec, pub host: Option>, pub target: Option>, @@ -144,6 +145,13 @@ To learn more about a subcommand, run `./x.py -h`", (pass multiple times to keep e.g., both stages 0 and 1)", "N", ); + opts.optmulti( + "", + "keep-stage-std", + "stage(s) of the standard library to keep without recompiling \ + (pass multiple times to keep e.g., both stages 0 and 1)", + "N", + ); opts.optopt("", "src", "path to the root of the rust checkout", "DIR"); let j_msg = format!( "number of jobs to run in parallel; \ @@ -510,7 +518,9 @@ Arguments: println!("--stage not supported for x.py check, always treated as stage 0"); process::exit(1); } - if matches.opt_str("keep-stage").is_some() { + if matches.opt_str("keep-stage").is_some() + || matches.opt_str("keep-stage-std").is_some() + { println!("--keep-stage not supported for x.py check, only one stage available"); process::exit(1); } @@ -528,6 +538,11 @@ Arguments: .into_iter() .map(|j| j.parse().expect("`keep-stage` should be a number")) .collect(), + keep_stage_std: matches + .opt_strs("keep-stage-std") + .into_iter() + .map(|j| j.parse().expect("`keep-stage-std` should be a number")) + .collect(), host: if matches.opt_present("host") { Some( split(&matches.opt_strs("host")) From c0ddaed2bfa95d488db7576055ee7472968babfd Mon Sep 17 00:00:00 2001 From: Dylan MacKenzie Date: Wed, 23 Sep 2020 16:17:11 -0700 Subject: [PATCH 07/17] Remove warning about possible future deprecation --- src/bootstrap/compile.rs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs index 02095c27335e4..40bf6c48296b2 100644 --- a/src/bootstrap/compile.rs +++ b/src/bootstrap/compile.rs @@ -475,10 +475,6 @@ impl Step for Rustc { if builder.config.keep_stage.contains(&compiler.stage) { builder.info("Warning: Using a potentially old librustc. This may not behave well."); builder.info("Warning: Use `--keep-stage-std` if you want to rebuild the compiler when it changes"); - builder.info( - "Warning: Please file a GitHub issue if `--keep-stage-std` doesn't work for you.", - ); - builder.info("Warning: It may replace `--keep-stage` in the future"); builder.ensure(RustcLink { compiler, target_compiler: compiler, target }); return; } From 945a732dd6c3928e0219a862066c92bde45d26bf Mon Sep 17 00:00:00 2001 From: Camelid Date: Wed, 23 Sep 2020 16:18:59 -0700 Subject: [PATCH 08/17] Update mdBook 0.4.2 -> 0.4.3 --- Cargo.lock | 4 ++-- src/tools/rustbook/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 68288916e6d12..3727e3d20f86b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1848,9 +1848,9 @@ dependencies = [ [[package]] name = "mdbook" -version = "0.4.2" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b75e31ae4eaa0e45e17ee2b6b9e3ed969c3c6ff12bb4c2e352c42493f4ebb706" +checksum = "29be448fcafb00c5a8966c4020c2a5ffbbc333e5b96d0bb5ef54b5bd0524d9ff" dependencies = [ "ammonia", "anyhow", diff --git a/src/tools/rustbook/Cargo.toml b/src/tools/rustbook/Cargo.toml index f0a6ce2fa06c2..f5e5c0867b48a 100644 --- a/src/tools/rustbook/Cargo.toml +++ b/src/tools/rustbook/Cargo.toml @@ -9,6 +9,6 @@ edition = "2018" clap = "2.25.0" [dependencies.mdbook] -version = "0.4.0" +version = "0.4.3" default-features = false features = ["search"] From 16769eb19e8051a32a93c1b3fd7847aff5c9eded Mon Sep 17 00:00:00 2001 From: Dylan MacKenzie Date: Wed, 23 Sep 2020 16:22:53 -0700 Subject: [PATCH 09/17] Add entry to CHANGELOG for `--keep-stage-std` --- src/bootstrap/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/bootstrap/CHANGELOG.md b/src/bootstrap/CHANGELOG.md index 5fcaafab959e9..1510f4d59fa34 100644 --- a/src/bootstrap/CHANGELOG.md +++ b/src/bootstrap/CHANGELOG.md @@ -15,6 +15,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - Make the default stage for x.py configurable [#76625](https://github.com/rust-lang/rust/pull/76625) - Add a dedicated debug-logging option [#76588](https://github.com/rust-lang/rust/pull/76588) - Add sample defaults for x.py [#76628](https://github.com/rust-lang/rust/pull/76628) +- Add `--keep-stage-std`, which behaves like `keep-stage` but allows the stage + 0 compiler artifacts (i.e., stage1/bin/rustc) to be rebuilt if changed + [#77120](https://github.com/rust-lang/rust/pull/77120). + ## [Version 0] - 2020-09-11 From 50d96635872b0625da84b7f2e2556b1804cc9de7 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Wed, 23 Sep 2020 17:06:56 -0700 Subject: [PATCH 10/17] Update cargo --- src/tools/cargo | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/cargo b/src/tools/cargo index 8777a6b1e8834..05c611ae3c425 160000 --- a/src/tools/cargo +++ b/src/tools/cargo @@ -1 +1 @@ -Subproject commit 8777a6b1e8834899f51b7e09cc9b8d85b2417110 +Subproject commit 05c611ae3c4255b7a2bcf4fcfa65b20286a07839 From dd7b8c85a6a2bffb2cce1c40ba72680a1d7be93b Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Sun, 20 Sep 2020 00:32:00 -0400 Subject: [PATCH 11/17] Perform most diagnostic lookups in `resolution_failure` Previously, these were spread throughout the codebase. This had two drawbacks: 1. It caused the fast path to be slower: even if a link resolved, rustdoc would still perform various lookups for the error diagnostic. 2. It was inconsistent and didn't always give all diagnostics (https://github.com/rust-lang/rust/issues/76925) Now, diagnostics only perform expensive lookups in the error case. Additionally, the error handling is much more consistent, both in wording and behavior. - Remove `CannotHaveAssociatedItems`, `NotInScope`, `NoAssocItem`, and `NotAVariant` in favor of the more general `NotResolved` `resolution_failure` will now look up which of the four above categories is relevant, instead of requiring the rest of the code to be consistent and accurate in which it picked. - Remove unnecessary lookups throughout the intra-doc link pass. These are now done by `resolution_failure`. + Remove unnecessary `extra_fragment` argument to `variant_field()`; it was only used to do lookups on failure. + Remove various lookups related to associated items + Remove distinction between 'not in scope' and 'no associated item' - Don't perform unnecessary copies - Remove unused variables and code - Update tests - Note why looking at other namespaces is still necessary - 'has no inner item' -> 'contains no item' bless tests --- .../passes/collect_intra_doc_links.rs | 397 +++++++++--------- .../deny-intra-link-resolution-failure.stderr | 2 +- src/test/rustdoc-ui/intra-link-errors.rs | 16 +- src/test/rustdoc-ui/intra-link-errors.stderr | 51 ++- .../intra-link-span-ice-55723.stderr | 2 +- .../intra-links-warning-crlf.stderr | 8 +- .../rustdoc-ui/intra-links-warning.stderr | 36 +- src/test/rustdoc-ui/lint-group.stderr | 2 +- .../rustdoc/intra-link-associated-items.rs | 2 + 9 files changed, 263 insertions(+), 253 deletions(-) diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index 5a9eeec4dfec3..71fd5deca54b7 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -60,14 +60,6 @@ impl<'a> From> for ErrorKind<'a> { #[derive(Debug)] enum ResolutionFailure<'a> { - /// This resolved, but with the wrong namespace. - /// `Namespace` is the expected namespace (as opposed to the actual). - WrongNamespace(Res, Namespace), - /// This has a partial resolution, but is not in the TypeNS and so cannot - /// have associated items or fields. - CannotHaveAssociatedItems(Res, Namespace), - /// `name` is the base name of the path (not necessarily the whole link) - NotInScope { module_id: DefId, name: Cow<'a, str> }, /// this is a primitive type without an impls (no associated methods) /// when will this actually happen? /// the `Res` is the primitive it resolved to @@ -75,33 +67,19 @@ enum ResolutionFailure<'a> { /// `[u8::not_found]` /// the `Res` is the primitive it resolved to NoPrimitiveAssocItem { res: Res, prim_name: &'a str, assoc_item: Symbol }, - /// `[S::not_found]` - /// the `String` is the associated item that wasn't found - NoAssocItem(Res, Symbol), + /// This resolved, but with the wrong namespace. + /// `Namespace` is the expected namespace (as opposed to the actual). + WrongNamespace(Res, Namespace), + /// The link failed to resolve. `resolution_failure` should look to see if there's + /// a more helpful error that can be given. + NotResolved { module_id: DefId, partial_res: Option, unresolved: Cow<'a, str> }, /// should not ever happen NoParentItem, - /// this could be an enum variant, but the last path fragment wasn't resolved. - /// the `String` is the variant that didn't exist - NotAVariant(Res, Symbol), /// used to communicate that this should be ignored, but shouldn't be reported to the user Dummy, } impl ResolutionFailure<'a> { - // A partial or full resolution - fn res(&self) -> Option { - use ResolutionFailure::*; - match self { - NoPrimitiveAssocItem { res, .. } - | NoAssocItem(res, _) - | NoPrimitiveImpl(res, _) - | NotAVariant(res, _) - | WrongNamespace(res, _) - | CannotHaveAssociatedItems(res, _) => Some(*res), - NotInScope { .. } | NoParentItem | Dummy => None, - } - } - // This resolved fully (not just partially) but is erroneous for some other reason fn full_res(&self) -> Option { match self { @@ -136,22 +114,25 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> { path_str: &'path str, current_item: &Option, module_id: DefId, - extra_fragment: &Option, ) -> Result<(Res, Option), ErrorKind<'path>> { let cx = self.cx; + let no_res = || ResolutionFailure::NotResolved { + module_id, + partial_res: None, + unresolved: path_str.into(), + }; debug!("looking for enum variant {}", path_str); let mut split = path_str.rsplitn(3, "::"); - let variant_field_name = split + let (variant_field_str, variant_field_name) = split .next() - .map(|f| Symbol::intern(f)) + .map(|f| (f, Symbol::intern(f))) .expect("fold_item should ensure link is non-empty"); - let variant_name = + let (variant_str, variant_name) = // we're not sure this is a variant at all, so use the full string - split.next().map(|f| Symbol::intern(f)).ok_or_else(|| ResolutionFailure::NotInScope { - module_id, - name: path_str.into(), - })?; + // If there's no second component, the link looks like `[path]`. + // So there's no partial res and we should say the whole link failed to resolve. + split.next().map(|f| (f, Symbol::intern(f))).ok_or_else(no_res)?; let path = split .next() .map(|f| { @@ -162,10 +143,9 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> { } f.to_owned() }) - .ok_or_else(|| ResolutionFailure::NotInScope { - module_id, - name: variant_name.to_string().into(), - })?; + // If there's no third component, we saw `[a::b]` before and it failed to resolve. + // So there's no partial res. + .ok_or_else(no_res)?; let ty_res = cx .enter_resolver(|resolver| { resolver.resolve_str_path_error(DUMMY_SP, &path, TypeNS, module_id) @@ -173,7 +153,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> { .map(|(_, res)| res) .unwrap_or(Res::Err); if let Res::Err = ty_res { - return Err(ResolutionFailure::NotInScope { module_id, name: path.into() }.into()); + return Err(no_res().into()); } let ty_res = ty_res.map_id(|_| panic!("unexpected node_id")); match ty_res { @@ -196,38 +176,27 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> { ty_res, Some(format!( "variant.{}.field.{}", - variant_name, variant_field_name + variant_str, variant_field_name )), )) } else { - Err(ResolutionFailure::NotAVariant(ty_res, variant_field_name).into()) + Err(ResolutionFailure::NotResolved { + module_id, + partial_res: Some(Res::Def(DefKind::Enum, def.did)), + unresolved: variant_field_str.into(), + } + .into()) } } _ => unreachable!(), } } - // `variant_field` looks at 3 different path segments in a row. - // But `NoAssocItem` assumes there are only 2. Check to see if there's - // an intermediate segment that resolves. - _ => { - let intermediate_path = format!("{}::{}", path, variant_name); - // NOTE: we have to be careful here, because we're already in `resolve`. - // We know this doesn't recurse forever because we use a shorter path each time. - // NOTE: this uses `TypeNS` because nothing else has a valid path segment after - let kind = if let Some(intermediate) = self.check_full_res( - TypeNS, - &intermediate_path, - module_id, - current_item, - extra_fragment, - ) { - ResolutionFailure::NoAssocItem(intermediate, variant_field_name) - } else { - // Even with the shorter path, it didn't resolve, so say that. - ResolutionFailure::NoAssocItem(ty_res, variant_name) - }; - Err(kind.into()) + _ => Err(ResolutionFailure::NotResolved { + module_id, + partial_res: Some(ty_res), + unresolved: variant_str.into(), } + .into()), } } @@ -248,11 +217,11 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> { false, ) { if let SyntaxExtensionKind::LegacyBang { .. } = ext.kind { - return Some(Ok(res.map_id(|_| panic!("unexpected id")))); + return Ok(res.map_id(|_| panic!("unexpected id"))); } } if let Some(res) = resolver.all_macros().get(&Symbol::intern(path_str)) { - return Some(Ok(res.map_id(|_| panic!("unexpected id")))); + return Ok(res.map_id(|_| panic!("unexpected id"))); } debug!("resolving {} as a macro in the module {:?}", path_str, module_id); if let Ok((_, res)) = @@ -261,28 +230,14 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> { // don't resolve builtins like `#[derive]` if let Res::Def(..) = res { let res = res.map_id(|_| panic!("unexpected node_id")); - return Some(Ok(res)); - } - } - None - }) - // This weird control flow is so we don't borrow the resolver more than once at a time - .unwrap_or_else(|| { - let mut split = path_str.rsplitn(2, "::"); - if let Some((parent, base)) = split.next().and_then(|x| Some((split.next()?, x))) { - if let Some(res) = self.check_full_res(TypeNS, parent, module_id, &None, &None) { - return Err(if matches!(res, Res::PrimTy(_)) { - ResolutionFailure::NoPrimitiveAssocItem { - res, - prim_name: parent, - assoc_item: Symbol::intern(base), - } - } else { - ResolutionFailure::NoAssocItem(res, Symbol::intern(base)) - }); + return Ok(res); } } - Err(ResolutionFailure::NotInScope { module_id, name: path_str.into() }) + Err(ResolutionFailure::NotResolved { + module_id, + partial_res: None, + unresolved: path_str.into(), + }) }) } @@ -347,7 +302,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> { // Try looking for methods and associated items. let mut split = path_str.rsplitn(2, "::"); // this can be an `unwrap()` because we ensure the link is never empty - let item_name = Symbol::intern(split.next().unwrap()); + let (item_str, item_name) = split.next().map(|i| (i, Symbol::intern(i))).unwrap(); let path_root = split .next() .map(|f| { @@ -362,7 +317,11 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> { // So we can be sure that `rustc_resolve` was accurate when it said it wasn't resolved. .ok_or_else(|| { debug!("found no `::`, assumming {} was correctly not in scope", item_name); - ResolutionFailure::NotInScope { module_id, name: item_name.to_string().into() } + ResolutionFailure::NotResolved { + module_id, + partial_res: None, + unresolved: item_str.into(), + } })?; if let Some((path, prim)) = is_primitive(&path_root, TypeNS) { @@ -383,7 +342,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> { ty::AssocKind::Const => "associatedconstant", ty::AssocKind::Type => "associatedtype", }) - .map(|out| (prim, Some(format!("{}#{}.{}", path, out, item_name)))); + .map(|out| (prim, Some(format!("{}#{}.{}", path, out, item_str)))); if let Some(link) = link { return Ok(link); } @@ -411,25 +370,14 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> { let ty_res = match ty_res { Err(()) | Ok(Res::Err) => { return if ns == Namespace::ValueNS { - self.variant_field(path_str, current_item, module_id, extra_fragment) + self.variant_field(path_str, current_item, module_id) } else { - // See if it only broke because of the namespace. - let kind = cx.enter_resolver(|resolver| { - // NOTE: this doesn't use `check_full_res` because we explicitly want to ignore `TypeNS` (we already checked it) - for &ns in &[MacroNS, ValueNS] { - match resolver - .resolve_str_path_error(DUMMY_SP, &path_root, ns, module_id) - { - Ok((_, Res::Err)) | Err(()) => {} - Ok((_, res)) => { - let res = res.map_id(|_| panic!("unexpected node_id")); - return ResolutionFailure::CannotHaveAssociatedItems(res, ns); - } - } - } - ResolutionFailure::NotInScope { module_id, name: path_root.into() } - }); - Err(kind.into()) + Err(ResolutionFailure::NotResolved { + module_id, + partial_res: None, + unresolved: path_root.into(), + } + .into()) }; } Ok(res) => res, @@ -479,7 +427,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> { // but the disambiguator logic expects the associated item. // Store the kind in a side channel so that only the disambiguator logic looks at it. self.kind_side_channel.set(Some((kind.as_def_kind(), id))); - Ok((ty_res, Some(format!("{}.{}", out, item_name)))) + Ok((ty_res, Some(format!("{}.{}", out, item_str)))) }) } else if ns == Namespace::ValueNS { debug!("looking for variants or fields named {} for {:?}", item_name, did); @@ -522,7 +470,12 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> { } } else { // We already know this isn't in ValueNS, so no need to check variant_field - return Err(ResolutionFailure::NoAssocItem(ty_res, item_name).into()); + return Err(ResolutionFailure::NotResolved { + module_id, + partial_res: Some(ty_res), + unresolved: item_str.into(), + } + .into()); } } Res::Def(DefKind::Trait, did) => cx @@ -546,16 +499,21 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> { Err(ErrorKind::AnchorFailure(AnchorFailure::RustdocAnchorConflict(ty_res))) } else { let res = Res::Def(item.kind.as_def_kind(), item.def_id); - Ok((res, Some(format!("{}.{}", kind, item_name)))) + Ok((res, Some(format!("{}.{}", kind, item_str)))) } }), _ => None, }; res.unwrap_or_else(|| { if ns == Namespace::ValueNS { - self.variant_field(path_str, current_item, module_id, extra_fragment) + self.variant_field(path_str, current_item, module_id) } else { - Err(ResolutionFailure::NoAssocItem(ty_res, item_name).into()) + Err(ResolutionFailure::NotResolved { + module_id, + partial_res: Some(ty_res), + unresolved: item_str.into(), + } + .into()) } }) } @@ -1133,6 +1091,8 @@ impl LinkCollector<'_, '_> { // We only looked in one namespace. Try to give a better error if possible. if kind.full_res().is_none() { let other_ns = if ns == ValueNS { TypeNS } else { ValueNS }; + // FIXME: really it should be `resolution_failure` that does this, not `resolve_with_disambiguator` + // See https://github.com/rust-lang/rust/pull/76955#discussion_r493953382 for a good approach for &new_ns in &[other_ns, MacroNS] { if let Some(res) = self.check_full_res( new_ns, @@ -1535,7 +1495,6 @@ fn resolution_failure( dox, &link_range, |diag, sp| { - let in_scope = kinds.iter().any(|kind| kind.res().is_some()); let item = |res: Res| { format!( "the {} `{}`", @@ -1556,53 +1515,142 @@ fn resolution_failure( // ignore duplicates let mut variants_seen = SmallVec::<[_; 3]>::new(); for mut failure in kinds { - // Check if _any_ parent of the path gets resolved. - // If so, report it and say the first which failed; if not, say the first path segment didn't resolve. - if let ResolutionFailure::NotInScope { module_id, name } = &mut failure { - let mut current = name.as_ref(); - loop { - current = match current.rsplitn(2, "::").nth(1) { - Some(p) => p, - None => { - *name = current.to_owned().into(); - break; - } - }; - if let Some(res) = - collector.check_full_res(TypeNS, ¤t, *module_id, &None, &None) - { - failure = ResolutionFailure::NoAssocItem(res, Symbol::intern(current)); - break; - } - } - } let variant = std::mem::discriminant(&failure); if variants_seen.contains(&variant) { continue; } variants_seen.push(variant); - let note = match failure { - ResolutionFailure::NotInScope { module_id, name, .. } => { - if in_scope { - continue; + + if let ResolutionFailure::NotResolved { module_id, partial_res, unresolved } = + &mut failure + { + use DefKind::*; + + let module_id = *module_id; + // FIXME(jynelson): this might conflict with my `Self` fix in #76467 + fn split(path: &str) -> Option<(&str, &str)> { + let mut splitter = path.rsplitn(2, "::"); + splitter.next().and_then(|right| splitter.next().map(|left| (left, right))) + } + + // Check if _any_ parent of the path gets resolved. + // If so, report it and say the first which failed; if not, say the first path segment didn't resolve. + let mut name = path_str; + 'outer: loop { + let (start, end) = if let Some(x) = split(name) { + x + } else { + // avoid bug that marked [Quux::Z] as missing Z, not Quux + if partial_res.is_none() { + *unresolved = name.into(); + } + break; + }; + name = start; + for &ns in &[TypeNS, ValueNS, MacroNS] { + if let Some(res) = + collector.check_full_res(ns, &start, module_id, &None, &None) + { + debug!("found partial_res={:?}", res); + *partial_res = Some(res); + *unresolved = end.into(); + break 'outer; + } } + *unresolved = end.into(); + } + + let last_found_module = match *partial_res { + Some(Res::Def(DefKind::Mod, id)) => Some(id), + None => Some(module_id), + _ => None, + }; + // See if this was a module: `[path]` or `[std::io::nope]` + if let Some(module) = last_found_module { // NOTE: uses an explicit `continue` so the `note:` will come before the `help:` - let module_name = collector.cx.tcx.item_name(module_id); - let note = format!("no item named `{}` in `{}`", name, module_name); + let module_name = collector.cx.tcx.item_name(module); + let note = format!( + "the module `{}` contains no item named `{}`", + module_name, unresolved + ); if let Some(span) = sp { diag.span_label(span, ¬e); } else { diag.note(¬e); } - // If the link has `::` in the path, assume it's meant to be an intra-doc link + // If the link has `::` in it, assume it was meant to be an intra-doc link. + // Otherwise, the `[]` might be unrelated. + // FIXME: don't show this for autolinks (`<>`), `()` style links, or reference links if !path_str.contains("::") { - // Otherwise, the `[]` might be unrelated. - // FIXME(https://github.com/raphlinus/pulldown-cmark/issues/373): - // don't show this for autolinks (`<>`), `()` style links, or reference links diag.help(r#"to escape `[` and `]` characters, add '\' before them like `\[` or `\]`"#); } continue; } + + // Otherwise, it must be an associated item or variant + let res = partial_res.expect("None case was handled by `last_found_module`"); + let diagnostic_name; + let (kind, name) = match res { + Res::Def(kind, def_id) => { + diagnostic_name = collector.cx.tcx.item_name(def_id).as_str(); + (Some(kind), &*diagnostic_name) + } + Res::PrimTy(_) => (None, name), + _ => unreachable!("only ADTs and primitives are in scope at module level"), + }; + let path_description = if let Some(kind) = kind { + match kind { + Mod | ForeignMod => "inner item", + Struct => "field or associated item", + Enum | Union => "variant or associated item", + Variant + | Field + | Closure + | Generator + | AssocTy + | AssocConst + | AssocFn + | Fn + | Macro(_) + | Const + | ConstParam + | ExternCrate + | Use + | LifetimeParam + | Ctor(_, _) + | AnonConst => { + let note = assoc_item_not_allowed(res); + if let Some(span) = sp { + diag.span_label(span, ¬e); + } else { + diag.note(¬e); + } + return; + } + Trait | TyAlias | ForeignTy | OpaqueTy | TraitAlias | TyParam + | Static => "associated item", + Impl | GlobalAsm => unreachable!("not a path"), + } + } else { + res.descr() + }; + let note = format!( + "the {} `{}` has no {} named `{}`", + res.descr(), + name, + disambiguator.map_or(path_description, |d| d.descr()), + unresolved, + ); + if let Some(span) = sp { + diag.span_label(span, ¬e); + } else { + diag.note(¬e); + } + + continue; + } + let note = match failure { + ResolutionFailure::NotResolved { .. } => unreachable!("handled above"), ResolutionFailure::Dummy => continue, ResolutionFailure::WrongNamespace(res, expected_ns) => { if let Res::Def(kind, _) = res { @@ -1637,69 +1685,6 @@ fn resolution_failure( prim_name, assoc_item ) } - ResolutionFailure::NoAssocItem(res, assoc_item) => { - use DefKind::*; - - let (kind, def_id) = match res { - Res::Def(kind, def_id) => (kind, def_id), - x => unreachable!( - "primitives are covered above and other `Res` variants aren't possible at module scope: {:?}", - x, - ), - }; - let name = collector.cx.tcx.item_name(def_id); - let path_description = if let Some(disambiguator) = disambiguator { - disambiguator.descr() - } else { - match kind { - Mod | ForeignMod => "inner item", - Struct => "field or associated item", - Enum | Union => "variant or associated item", - Variant - | Field - | Closure - | Generator - | AssocTy - | AssocConst - | AssocFn - | Fn - | Macro(_) - | Const - | ConstParam - | ExternCrate - | Use - | LifetimeParam - | Ctor(_, _) - | AnonConst => { - let note = assoc_item_not_allowed(res); - if let Some(span) = sp { - diag.span_label(span, ¬e); - } else { - diag.note(¬e); - } - return; - } - Trait | TyAlias | ForeignTy | OpaqueTy | TraitAlias | TyParam - | Static => "associated item", - Impl | GlobalAsm => unreachable!("not a path"), - } - }; - format!( - "the {} `{}` has no {} named `{}`", - res.descr(), - name, - path_description, - assoc_item - ) - } - ResolutionFailure::CannotHaveAssociatedItems(res, _) => { - assoc_item_not_allowed(res) - } - ResolutionFailure::NotAVariant(res, variant) => format!( - "this link partially resolves to {}, but there is no variant named {}", - item(res), - variant - ), }; if let Some(span) = sp { diag.span_label(span, ¬e); diff --git a/src/test/rustdoc-ui/deny-intra-link-resolution-failure.stderr b/src/test/rustdoc-ui/deny-intra-link-resolution-failure.stderr index 5020b97b2f201..33260fa0e1e66 100644 --- a/src/test/rustdoc-ui/deny-intra-link-resolution-failure.stderr +++ b/src/test/rustdoc-ui/deny-intra-link-resolution-failure.stderr @@ -2,7 +2,7 @@ error: unresolved link to `v2` --> $DIR/deny-intra-link-resolution-failure.rs:3:6 | LL | /// [v2] - | ^^ no item named `v2` in `deny_intra_link_resolution_failure` + | ^^ the module `deny_intra_link_resolution_failure` contains no item named `v2` | note: the lint level is defined here --> $DIR/deny-intra-link-resolution-failure.rs:1:9 diff --git a/src/test/rustdoc-ui/intra-link-errors.rs b/src/test/rustdoc-ui/intra-link-errors.rs index 26b629b1313da..8c250fbc58b27 100644 --- a/src/test/rustdoc-ui/intra-link-errors.rs +++ b/src/test/rustdoc-ui/intra-link-errors.rs @@ -6,19 +6,23 @@ /// [path::to::nonexistent::module] //~^ ERROR unresolved link -//~| NOTE no item named `path` in `intra_link_errors` +//~| NOTE `intra_link_errors` contains no item named `path` /// [path::to::nonexistent::macro!] //~^ ERROR unresolved link -//~| NOTE no item named `path` in `intra_link_errors` +//~| NOTE `intra_link_errors` contains no item named `path` /// [type@path::to::nonexistent::type] //~^ ERROR unresolved link -//~| NOTE no item named `path` in `intra_link_errors` +//~| NOTE `intra_link_errors` contains no item named `path` /// [std::io::not::here] //~^ ERROR unresolved link -//~| NOTE the module `io` has no inner item +//~| NOTE `io` contains no item named `not` + +/// [type@std::io::not::here] +//~^ ERROR unresolved link +//~| NOTE `io` contains no item named `not` /// [std::io::Error::x] //~^ ERROR unresolved link @@ -32,6 +36,10 @@ //~^ ERROR unresolved link //~| NOTE `f` is a function, not a module +/// [f::A!] +//~^ ERROR unresolved link +//~| NOTE `f` is a function, not a module + /// [S::A] //~^ ERROR unresolved link //~| NOTE struct `S` has no field or associated item diff --git a/src/test/rustdoc-ui/intra-link-errors.stderr b/src/test/rustdoc-ui/intra-link-errors.stderr index fbf3dcbbec29a..cd06ee6f798dc 100644 --- a/src/test/rustdoc-ui/intra-link-errors.stderr +++ b/src/test/rustdoc-ui/intra-link-errors.stderr @@ -2,7 +2,7 @@ error: unresolved link to `path::to::nonexistent::module` --> $DIR/intra-link-errors.rs:7:6 | LL | /// [path::to::nonexistent::module] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no item named `path` in `intra_link_errors` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the module `intra_link_errors` contains no item named `path` | note: the lint level is defined here --> $DIR/intra-link-errors.rs:1:9 @@ -14,64 +14,79 @@ error: unresolved link to `path::to::nonexistent::macro` --> $DIR/intra-link-errors.rs:11:6 | LL | /// [path::to::nonexistent::macro!] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no item named `path` in `intra_link_errors` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the module `intra_link_errors` contains no item named `path` error: unresolved link to `path::to::nonexistent::type` --> $DIR/intra-link-errors.rs:15:6 | LL | /// [type@path::to::nonexistent::type] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no item named `path` in `intra_link_errors` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the module `intra_link_errors` contains no item named `path` error: unresolved link to `std::io::not::here` --> $DIR/intra-link-errors.rs:19:6 | LL | /// [std::io::not::here] - | ^^^^^^^^^^^^^^^^^^ the module `io` has no inner item named `not` + | ^^^^^^^^^^^^^^^^^^ the module `io` contains no item named `not` -error: unresolved link to `std::io::Error::x` +error: unresolved link to `std::io::not::here` --> $DIR/intra-link-errors.rs:23:6 | +LL | /// [type@std::io::not::here] + | ^^^^^^^^^^^^^^^^^^^^^^^ the module `io` contains no item named `not` + +error: unresolved link to `std::io::Error::x` + --> $DIR/intra-link-errors.rs:27:6 + | LL | /// [std::io::Error::x] | ^^^^^^^^^^^^^^^^^ the struct `Error` has no field or associated item named `x` error: unresolved link to `std::io::ErrorKind::x` - --> $DIR/intra-link-errors.rs:27:6 + --> $DIR/intra-link-errors.rs:31:6 | LL | /// [std::io::ErrorKind::x] | ^^^^^^^^^^^^^^^^^^^^^ the enum `ErrorKind` has no variant or associated item named `x` error: unresolved link to `f::A` - --> $DIR/intra-link-errors.rs:31:6 + --> $DIR/intra-link-errors.rs:35:6 | LL | /// [f::A] | ^^^^ `f` is a function, not a module or type, and cannot have associated items +error: unresolved link to `f::A` + --> $DIR/intra-link-errors.rs:39:6 + | +LL | /// [f::A!] + | ^^^^^ `f` is a function, not a module or type, and cannot have associated items + error: unresolved link to `S::A` - --> $DIR/intra-link-errors.rs:35:6 + --> $DIR/intra-link-errors.rs:43:6 | LL | /// [S::A] | ^^^^ the struct `S` has no field or associated item named `A` error: unresolved link to `S::fmt` - --> $DIR/intra-link-errors.rs:39:6 + --> $DIR/intra-link-errors.rs:47:6 | LL | /// [S::fmt] | ^^^^^^ the struct `S` has no field or associated item named `fmt` error: unresolved link to `E::D` - --> $DIR/intra-link-errors.rs:43:6 + --> $DIR/intra-link-errors.rs:51:6 | LL | /// [E::D] | ^^^^ the enum `E` has no variant or associated item named `D` error: unresolved link to `u8::not_found` - --> $DIR/intra-link-errors.rs:47:6 + --> $DIR/intra-link-errors.rs:55:6 | LL | /// [u8::not_found] - | ^^^^^^^^^^^^^ the builtin type `u8` does not have an associated item named `not_found` + | ^^^^^^^^^^^^^ + | | + | the builtin type `u8` does not have an associated item named `not_found` + | the builtin type `u8` has no builtin type named `not_found` error: unresolved link to `S` - --> $DIR/intra-link-errors.rs:51:6 + --> $DIR/intra-link-errors.rs:59:6 | LL | /// [S!] | ^^ @@ -80,7 +95,7 @@ LL | /// [S!] | help: to link to the struct, prefix with `struct@`: `struct@S` error: unresolved link to `T::g` - --> $DIR/intra-link-errors.rs:69:6 + --> $DIR/intra-link-errors.rs:77:6 | LL | /// [type@T::g] | ^^^^^^^^^ @@ -89,13 +104,13 @@ LL | /// [type@T::g] | help: to link to the associated function, add parentheses: `T::g()` error: unresolved link to `T::h` - --> $DIR/intra-link-errors.rs:74:6 + --> $DIR/intra-link-errors.rs:82:6 | LL | /// [T::h!] | ^^^^^ the trait `T` has no macro named `h` error: unresolved link to `S::h` - --> $DIR/intra-link-errors.rs:61:6 + --> $DIR/intra-link-errors.rs:69:6 | LL | /// [type@S::h] | ^^^^^^^^^ @@ -104,7 +119,7 @@ LL | /// [type@S::h] | help: to link to the associated function, add parentheses: `S::h()` error: unresolved link to `m` - --> $DIR/intra-link-errors.rs:81:6 + --> $DIR/intra-link-errors.rs:89:6 | LL | /// [m()] | ^^^ @@ -112,5 +127,5 @@ LL | /// [m()] | this link resolves to the macro `m`, which is not in the value namespace | help: to link to the macro, add an exclamation mark: `m!` -error: aborting due to 16 previous errors +error: aborting due to 18 previous errors diff --git a/src/test/rustdoc-ui/intra-link-span-ice-55723.stderr b/src/test/rustdoc-ui/intra-link-span-ice-55723.stderr index 3c13df20588d8..d946aa939800c 100644 --- a/src/test/rustdoc-ui/intra-link-span-ice-55723.stderr +++ b/src/test/rustdoc-ui/intra-link-span-ice-55723.stderr @@ -2,7 +2,7 @@ error: unresolved link to `i` --> $DIR/intra-link-span-ice-55723.rs:9:10 | LL | /// (arr[i]) - | ^ no item named `i` in `intra_link_span_ice_55723` + | ^ the module `intra_link_span_ice_55723` contains no item named `i` | note: the lint level is defined here --> $DIR/intra-link-span-ice-55723.rs:1:9 diff --git a/src/test/rustdoc-ui/intra-links-warning-crlf.stderr b/src/test/rustdoc-ui/intra-links-warning-crlf.stderr index 351f8fafa64d8..76a2ac0c8cf02 100644 --- a/src/test/rustdoc-ui/intra-links-warning-crlf.stderr +++ b/src/test/rustdoc-ui/intra-links-warning-crlf.stderr @@ -2,7 +2,7 @@ warning: unresolved link to `error` --> $DIR/intra-links-warning-crlf.rs:7:6 | LL | /// [error] - | ^^^^^ no item named `error` in `intra_links_warning_crlf` + | ^^^^^ the module `intra_links_warning_crlf` contains no item named `error` | = note: `#[warn(broken_intra_doc_links)]` on by default = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` @@ -11,7 +11,7 @@ warning: unresolved link to `error1` --> $DIR/intra-links-warning-crlf.rs:12:11 | LL | /// docs [error1] - | ^^^^^^ no item named `error1` in `intra_links_warning_crlf` + | ^^^^^^ the module `intra_links_warning_crlf` contains no item named `error1` | = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` @@ -19,7 +19,7 @@ warning: unresolved link to `error2` --> $DIR/intra-links-warning-crlf.rs:15:11 | LL | /// docs [error2] - | ^^^^^^ no item named `error2` in `intra_links_warning_crlf` + | ^^^^^^ the module `intra_links_warning_crlf` contains no item named `error2` | = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` @@ -27,7 +27,7 @@ warning: unresolved link to `error` --> $DIR/intra-links-warning-crlf.rs:23:20 | LL | * It also has an [error]. - | ^^^^^ no item named `error` in `intra_links_warning_crlf` + | ^^^^^ the module `intra_links_warning_crlf` contains no item named `error` | = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` diff --git a/src/test/rustdoc-ui/intra-links-warning.stderr b/src/test/rustdoc-ui/intra-links-warning.stderr index 0832e00d35a00..09db465df59fb 100644 --- a/src/test/rustdoc-ui/intra-links-warning.stderr +++ b/src/test/rustdoc-ui/intra-links-warning.stderr @@ -10,37 +10,37 @@ warning: unresolved link to `Bar::foo` --> $DIR/intra-links-warning.rs:3:35 | LL | //! Test with [Foo::baz], [Bar::foo], ... - | ^^^^^^^^ no item named `Bar` in `intra_links_warning` + | ^^^^^^^^ the module `intra_links_warning` contains no item named `Bar` warning: unresolved link to `Uniooon::X` --> $DIR/intra-links-warning.rs:6:13 | LL | //! , [Uniooon::X] and [Qux::Z]. - | ^^^^^^^^^^ no item named `Uniooon` in `intra_links_warning` + | ^^^^^^^^^^ the module `intra_links_warning` contains no item named `Uniooon` warning: unresolved link to `Qux::Z` --> $DIR/intra-links-warning.rs:6:30 | LL | //! , [Uniooon::X] and [Qux::Z]. - | ^^^^^^ no item named `Qux` in `intra_links_warning` + | ^^^^^^ the module `intra_links_warning` contains no item named `Qux` warning: unresolved link to `Uniooon::X` --> $DIR/intra-links-warning.rs:10:14 | LL | //! , [Uniooon::X] and [Qux::Z]. - | ^^^^^^^^^^ no item named `Uniooon` in `intra_links_warning` + | ^^^^^^^^^^ the module `intra_links_warning` contains no item named `Uniooon` warning: unresolved link to `Qux::Z` --> $DIR/intra-links-warning.rs:10:31 | LL | //! , [Uniooon::X] and [Qux::Z]. - | ^^^^^^ no item named `Qux` in `intra_links_warning` + | ^^^^^^ the module `intra_links_warning` contains no item named `Qux` warning: unresolved link to `Qux:Y` --> $DIR/intra-links-warning.rs:14:13 | LL | /// [Qux:Y] - | ^^^^^ no item named `Qux:Y` in `intra_links_warning` + | ^^^^^ the module `intra_links_warning` contains no item named `Qux:Y` | = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` @@ -48,7 +48,7 @@ warning: unresolved link to `error` --> $DIR/intra-links-warning.rs:58:30 | LL | * time to introduce a link [error]*/ - | ^^^^^ no item named `error` in `intra_links_warning` + | ^^^^^ the module `intra_links_warning` contains no item named `error` | = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` @@ -56,7 +56,7 @@ warning: unresolved link to `error` --> $DIR/intra-links-warning.rs:64:30 | LL | * time to introduce a link [error] - | ^^^^^ no item named `error` in `intra_links_warning` + | ^^^^^ the module `intra_links_warning` contains no item named `error` | = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` @@ -70,7 +70,7 @@ LL | #[doc = "single line [error]"] single line [error] ^^^^^ - = note: no item named `error` in `intra_links_warning` + = note: the module `intra_links_warning` contains no item named `error` = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` warning: unresolved link to `error` @@ -83,7 +83,7 @@ LL | #[doc = "single line with \"escaping\" [error]"] single line with "escaping" [error] ^^^^^ - = note: no item named `error` in `intra_links_warning` + = note: the module `intra_links_warning` contains no item named `error` = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` warning: unresolved link to `error` @@ -98,14 +98,14 @@ LL | | /// [error] [error] ^^^^^ - = note: no item named `error` in `intra_links_warning` + = note: the module `intra_links_warning` contains no item named `error` = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` warning: unresolved link to `error1` --> $DIR/intra-links-warning.rs:80:11 | LL | /// docs [error1] - | ^^^^^^ no item named `error1` in `intra_links_warning` + | ^^^^^^ the module `intra_links_warning` contains no item named `error1` | = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` @@ -113,7 +113,7 @@ warning: unresolved link to `error2` --> $DIR/intra-links-warning.rs:82:11 | LL | /// docs [error2] - | ^^^^^^ no item named `error2` in `intra_links_warning` + | ^^^^^^ the module `intra_links_warning` contains no item named `error2` | = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` @@ -121,7 +121,7 @@ warning: unresolved link to `BarA` --> $DIR/intra-links-warning.rs:21:10 | LL | /// bar [BarA] bar - | ^^^^ no item named `BarA` in `intra_links_warning` + | ^^^^ the module `intra_links_warning` contains no item named `BarA` | = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` @@ -129,7 +129,7 @@ warning: unresolved link to `BarB` --> $DIR/intra-links-warning.rs:27:9 | LL | * bar [BarB] bar - | ^^^^ no item named `BarB` in `intra_links_warning` + | ^^^^ the module `intra_links_warning` contains no item named `BarB` | = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` @@ -137,7 +137,7 @@ warning: unresolved link to `BarC` --> $DIR/intra-links-warning.rs:34:6 | LL | bar [BarC] bar - | ^^^^ no item named `BarC` in `intra_links_warning` + | ^^^^ the module `intra_links_warning` contains no item named `BarC` | = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` @@ -151,7 +151,7 @@ LL | #[doc = "Foo\nbar [BarD] bar\nbaz"] bar [BarD] bar ^^^^ - = note: no item named `BarD` in `intra_links_warning` + = note: the module `intra_links_warning` contains no item named `BarD` = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` warning: unresolved link to `BarF` @@ -167,7 +167,7 @@ LL | f!("Foo\nbar [BarF] bar\nbaz"); bar [BarF] bar ^^^^ - = note: no item named `BarF` in `intra_links_warning` + = note: the module `intra_links_warning` contains no item named `BarF` = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` = note: this warning originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/src/test/rustdoc-ui/lint-group.stderr b/src/test/rustdoc-ui/lint-group.stderr index 550b79f6e8928..4e9134ea469bd 100644 --- a/src/test/rustdoc-ui/lint-group.stderr +++ b/src/test/rustdoc-ui/lint-group.stderr @@ -32,7 +32,7 @@ error: unresolved link to `error` --> $DIR/lint-group.rs:9:29 | LL | /// what up, let's make an [error] - | ^^^^^ no item named `error` in `lint_group` + | ^^^^^ the module `lint_group` contains no item named `error` | note: the lint level is defined here --> $DIR/lint-group.rs:7:9 diff --git a/src/test/rustdoc/intra-link-associated-items.rs b/src/test/rustdoc/intra-link-associated-items.rs index 16a21e33748fa..dec0deae5df7c 100644 --- a/src/test/rustdoc/intra-link-associated-items.rs +++ b/src/test/rustdoc/intra-link-associated-items.rs @@ -3,8 +3,10 @@ /// [`std::collections::BTreeMap::into_iter`] /// [`String::from`] is ambiguous as to which `From` impl +/// [type@Vec::into_iter] uses a disambiguator // @has 'intra_link_associated_items/fn.foo.html' '//a[@href="https://doc.rust-lang.org/nightly/alloc/collections/btree/map/struct.BTreeMap.html#method.into_iter"]' 'std::collections::BTreeMap::into_iter' // @has 'intra_link_associated_items/fn.foo.html' '//a[@href="https://doc.rust-lang.org/nightly/alloc/string/struct.String.html#method.from"]' 'String::from' +// @has 'intra_link_associated_items/fn.foo.html' '//a[@href="https://doc.rust-lang.org/nightly/alloc/vec/struct.Vec.html#method.into_iter"]' 'Vec::into_iter' pub fn foo() {} /// Link to [MyStruct], [link from struct][MyStruct::method], [MyStruct::clone], [MyStruct::Input] From 472e52e5a03790becdbe21be1002a90dd2d7d3d4 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Sun, 20 Sep 2020 02:18:09 -0400 Subject: [PATCH 12/17] Fix intra-doc links for primitives - Add `PrimTy::name` and `PrimTy::name_str` - Use those new functions to distinguish between the name in scope and the canonical name - Fix diagnostics for primitive types - Add tests for primitives --- compiler/rustc_hir/src/hir.rs | 24 +++++++++++++++++++ .../passes/collect_intra_doc_links.rs | 20 +++++++++++----- src/test/rustdoc-ui/intra-link-errors.stderr | 5 +--- src/test/rustdoc/primitive-link.rs | 7 ++++++ 4 files changed, 46 insertions(+), 10 deletions(-) diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index cd4185226dce5..636f67a77c890 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -2004,6 +2004,30 @@ pub enum PrimTy { Char, } +impl PrimTy { + pub fn name_str(self) -> &'static str { + match self { + PrimTy::Int(i) => i.name_str(), + PrimTy::Uint(u) => u.name_str(), + PrimTy::Float(f) => f.name_str(), + PrimTy::Str => "str", + PrimTy::Bool => "bool", + PrimTy::Char => "char", + } + } + + pub fn name(self) -> Symbol { + match self { + PrimTy::Int(i) => i.name(), + PrimTy::Uint(u) => u.name(), + PrimTy::Float(f) => f.name(), + PrimTy::Str => sym::str, + PrimTy::Bool => sym::bool, + PrimTy::Char => sym::char, + } + } +} + #[derive(Debug, HashStable_Generic)] pub struct BareFnTy<'hir> { pub unsafety: Unsafety, diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index 71fd5deca54b7..af077e0f5eb6b 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -273,13 +273,13 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> { return handle_variant(cx, res, extra_fragment); } // Not a trait item; just return what we found. - Res::PrimTy(..) => { + Res::PrimTy(ty) => { if extra_fragment.is_some() { return Err(ErrorKind::AnchorFailure( AnchorFailure::RustdocAnchorConflict(res), )); } - return Ok((res, Some(path_str.to_owned()))); + return Ok((res, Some(ty.name_str().to_owned()))); } Res::Def(DefKind::Mod, _) => { return Ok((res, extra_fragment.clone())); @@ -292,6 +292,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> { if value != (ns == ValueNS) { return Err(ResolutionFailure::WrongNamespace(res, ns).into()); } + // FIXME: why is this necessary? } else if let Some((path, prim)) = is_primitive(path_str, ns) { if extra_fragment.is_some() { return Err(ErrorKind::AnchorFailure(AnchorFailure::RustdocAnchorConflict(prim))); @@ -1008,12 +1009,12 @@ impl LinkCollector<'_, '_> { suggest_disambiguator(resolved, diag, path_str, dox, sp, &link_range); }); }; - if let Res::PrimTy(_) = res { + if let Res::PrimTy(ty) = res { match disambiguator { Some(Disambiguator::Primitive | Disambiguator::Namespace(_)) | None => { item.attrs.links.push(ItemLink { link: ori_link, - link_text: path_str.to_owned(), + link_text, did: None, fragment, }); @@ -1488,6 +1489,10 @@ fn resolution_failure( link_range: Option>, kinds: SmallVec<[ResolutionFailure<'_>; 3]>, ) { + let has_primitive = kinds.iter().any(|err| + matches!(err, ResolutionFailure::NoPrimitiveAssocItem{..} | ResolutionFailure::NoPrimitiveImpl(_, _)) + ); + report_diagnostic( collector.cx, &format!("unresolved link to `{}`", path_str), @@ -1528,6 +1533,7 @@ fn resolution_failure( let module_id = *module_id; // FIXME(jynelson): this might conflict with my `Self` fix in #76467 + // FIXME: use itertools `collect_tuple` instead fn split(path: &str) -> Option<(&str, &str)> { let mut splitter = path.rsplitn(2, "::"); splitter.next().and_then(|right| splitter.next().map(|left| (left, right))) @@ -1567,7 +1573,6 @@ fn resolution_failure( }; // See if this was a module: `[path]` or `[std::io::nope]` if let Some(module) = last_found_module { - // NOTE: uses an explicit `continue` so the `note:` will come before the `help:` let module_name = collector.cx.tcx.item_name(module); let note = format!( "the module `{}` contains no item named `{}`", @@ -1595,7 +1600,10 @@ fn resolution_failure( diagnostic_name = collector.cx.tcx.item_name(def_id).as_str(); (Some(kind), &*diagnostic_name) } - Res::PrimTy(_) => (None, name), + Res::PrimTy(_) => { + assert!(has_primitive); + continue; + } _ => unreachable!("only ADTs and primitives are in scope at module level"), }; let path_description = if let Some(kind) = kind { diff --git a/src/test/rustdoc-ui/intra-link-errors.stderr b/src/test/rustdoc-ui/intra-link-errors.stderr index cd06ee6f798dc..fab8c105a4953 100644 --- a/src/test/rustdoc-ui/intra-link-errors.stderr +++ b/src/test/rustdoc-ui/intra-link-errors.stderr @@ -80,10 +80,7 @@ error: unresolved link to `u8::not_found` --> $DIR/intra-link-errors.rs:55:6 | LL | /// [u8::not_found] - | ^^^^^^^^^^^^^ - | | - | the builtin type `u8` does not have an associated item named `not_found` - | the builtin type `u8` has no builtin type named `not_found` + | ^^^^^^^^^^^^^ the builtin type `u8` does not have an associated item named `not_found` error: unresolved link to `S` --> $DIR/intra-link-errors.rs:59:6 diff --git a/src/test/rustdoc/primitive-link.rs b/src/test/rustdoc/primitive-link.rs index 819ef05174a8a..8f69b894a223d 100644 --- a/src/test/rustdoc/primitive-link.rs +++ b/src/test/rustdoc/primitive-link.rs @@ -4,6 +4,13 @@ // @has foo/struct.Foo.html '//*[@class="docblock"]/p/a[@href="https://doc.rust-lang.org/nightly/std/primitive.u32.html"]' 'u32' // @has foo/struct.Foo.html '//*[@class="docblock"]/p/a[@href="https://doc.rust-lang.org/nightly/std/primitive.i64.html"]' 'i64' +// @has foo/struct.Foo.html '//*[@class="docblock"]/p/a[@href="https://doc.rust-lang.org/nightly/std/primitive.i32.html"]' 'std::primitive::i32' +// @has foo/struct.Foo.html '//*[@class="docblock"]/p/a[@href="https://doc.rust-lang.org/nightly/std/primitive.str.html"]' 'std::primitive::str' + +// FIXME: this doesn't resolve +// @ has foo/struct.Foo.html '//*[@class="docblock"]/p/a[@href="https://doc.rust-lang.org/nightly/std/primitive.i32.html#associatedconstant.MAX"]' 'std::primitive::i32::MAX' /// It contains [`u32`] and [i64]. +/// It also links to [std::primitive::i32], [std::primitive::str], +/// and [`std::primitive::i32::MAX`]. pub struct Foo; From 049d29bac580b958cdff6e898dad22de09a27958 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Sun, 20 Sep 2020 02:39:19 -0400 Subject: [PATCH 13/17] Unify primitive errors with other intra-link errors Now that `PrimTy::name()` exists, there's no need to carry around the name of the primitive that failed to resolve. This removes the variants special-casing primitives in favor of `NotResolved`. - Remove `NoPrimitiveImpl` and `NoPrimitiveAssocItem` - Remove hacky `has_primitive` check in `resolution_failure()` - Fixup a couple tests that I forgot to `--bless` before --- .../passes/collect_intra_doc_links.rs | 48 ++++++------------- src/test/rustdoc-ui/intra-link-errors.rs | 11 ++++- src/test/rustdoc-ui/intra-link-errors.stderr | 29 ++++++++--- .../rustdoc/intra-link-associated-items.rs | 2 +- 4 files changed, 47 insertions(+), 43 deletions(-) diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index af077e0f5eb6b..cb2de05598f4b 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -60,13 +60,6 @@ impl<'a> From> for ErrorKind<'a> { #[derive(Debug)] enum ResolutionFailure<'a> { - /// this is a primitive type without an impls (no associated methods) - /// when will this actually happen? - /// the `Res` is the primitive it resolved to - NoPrimitiveImpl(Res, String), - /// `[u8::not_found]` - /// the `Res` is the primitive it resolved to - NoPrimitiveAssocItem { res: Res, prim_name: &'a str, assoc_item: Symbol }, /// This resolved, but with the wrong namespace. /// `Namespace` is the expected namespace (as opposed to the actual). WrongNamespace(Res, Namespace), @@ -326,8 +319,12 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> { })?; if let Some((path, prim)) = is_primitive(&path_root, TypeNS) { - let impls = primitive_impl(cx, &path) - .ok_or_else(|| ResolutionFailure::NoPrimitiveImpl(prim, path_root.into()))?; + let impls = + primitive_impl(cx, &path).ok_or_else(|| ResolutionFailure::NotResolved { + module_id, + partial_res: Some(prim), + unresolved: item_str.into(), + })?; for &impl_ in impls { let link = cx .tcx @@ -354,10 +351,10 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> { item_name, ns.descr() ); - return Err(ResolutionFailure::NoPrimitiveAssocItem { - res: prim, - prim_name: path, - assoc_item: item_name, + return Err(ResolutionFailure::NotResolved { + module_id, + partial_res: Some(prim), + unresolved: item_str.into(), } .into()); } @@ -1009,7 +1006,7 @@ impl LinkCollector<'_, '_> { suggest_disambiguator(resolved, diag, path_str, dox, sp, &link_range); }); }; - if let Res::PrimTy(ty) = res { + if let Res::PrimTy(..) = res { match disambiguator { Some(Disambiguator::Primitive | Disambiguator::Namespace(_)) | None => { item.attrs.links.push(ItemLink { @@ -1489,10 +1486,6 @@ fn resolution_failure( link_range: Option>, kinds: SmallVec<[ResolutionFailure<'_>; 3]>, ) { - let has_primitive = kinds.iter().any(|err| - matches!(err, ResolutionFailure::NoPrimitiveAssocItem{..} | ResolutionFailure::NoPrimitiveImpl(_, _)) - ); - report_diagnostic( collector.cx, &format!("unresolved link to `{}`", path_str), @@ -1533,7 +1526,7 @@ fn resolution_failure( let module_id = *module_id; // FIXME(jynelson): this might conflict with my `Self` fix in #76467 - // FIXME: use itertools `collect_tuple` instead + // FIXME: maybe use itertools `collect_tuple` instead? fn split(path: &str) -> Option<(&str, &str)> { let mut splitter = path.rsplitn(2, "::"); splitter.next().and_then(|right| splitter.next().map(|left| (left, right))) @@ -1600,10 +1593,7 @@ fn resolution_failure( diagnostic_name = collector.cx.tcx.item_name(def_id).as_str(); (Some(kind), &*diagnostic_name) } - Res::PrimTy(_) => { - assert!(has_primitive); - continue; - } + Res::PrimTy(ty) => (None, ty.name_str()), _ => unreachable!("only ADTs and primitives are in scope at module level"), }; let path_description = if let Some(kind) = kind { @@ -1640,7 +1630,7 @@ fn resolution_failure( Impl | GlobalAsm => unreachable!("not a path"), } } else { - res.descr() + "associated item" }; let note = format!( "the {} `{}` has no {} named `{}`", @@ -1683,16 +1673,6 @@ fn resolution_failure( diag.level = rustc_errors::Level::Bug; "all intra doc links should have a parent item".to_owned() } - ResolutionFailure::NoPrimitiveImpl(res, _) => format!( - "this link partially resolves to {}, which does not have any associated items", - item(res), - ), - ResolutionFailure::NoPrimitiveAssocItem { prim_name, assoc_item, .. } => { - format!( - "the builtin type `{}` does not have an associated item named `{}`", - prim_name, assoc_item - ) - } }; if let Some(span) = sp { diag.span_label(span, ¬e); diff --git a/src/test/rustdoc-ui/intra-link-errors.rs b/src/test/rustdoc-ui/intra-link-errors.rs index 8c250fbc58b27..0278caf308776 100644 --- a/src/test/rustdoc-ui/intra-link-errors.rs +++ b/src/test/rustdoc-ui/intra-link-errors.rs @@ -54,7 +54,16 @@ /// [u8::not_found] //~^ ERROR unresolved link -//~| NOTE the builtin type `u8` does not have an associated item named `not_found` +//~| NOTE the builtin type `u8` has no associated item named `not_found` + +/// [std::primitive::u8::not_found] +//~^ ERROR unresolved link +//~| NOTE the builtin type `u8` has no associated item named `not_found` + +/// [type@Vec::into_iter] +//~^ ERROR unresolved link +//~| HELP to link to the associated function, add parentheses +//~| NOTE this link resolves to the associated function `into_iter` /// [S!] //~^ ERROR unresolved link diff --git a/src/test/rustdoc-ui/intra-link-errors.stderr b/src/test/rustdoc-ui/intra-link-errors.stderr index fab8c105a4953..b63f799535a1f 100644 --- a/src/test/rustdoc-ui/intra-link-errors.stderr +++ b/src/test/rustdoc-ui/intra-link-errors.stderr @@ -80,11 +80,26 @@ error: unresolved link to `u8::not_found` --> $DIR/intra-link-errors.rs:55:6 | LL | /// [u8::not_found] - | ^^^^^^^^^^^^^ the builtin type `u8` does not have an associated item named `not_found` + | ^^^^^^^^^^^^^ the builtin type `u8` has no associated item named `not_found` -error: unresolved link to `S` +error: unresolved link to `std::primitive::u8::not_found` --> $DIR/intra-link-errors.rs:59:6 | +LL | /// [std::primitive::u8::not_found] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the builtin type `u8` has no associated item named `not_found` + +error: unresolved link to `Vec::into_iter` + --> $DIR/intra-link-errors.rs:63:6 + | +LL | /// [type@Vec::into_iter] + | ^^^^^^^^^^^^^^^^^^^ + | | + | this link resolves to the associated function `into_iter`, which is not in the type namespace + | help: to link to the associated function, add parentheses: `Vec::into_iter()` + +error: unresolved link to `S` + --> $DIR/intra-link-errors.rs:68:6 + | LL | /// [S!] | ^^ | | @@ -92,7 +107,7 @@ LL | /// [S!] | help: to link to the struct, prefix with `struct@`: `struct@S` error: unresolved link to `T::g` - --> $DIR/intra-link-errors.rs:77:6 + --> $DIR/intra-link-errors.rs:86:6 | LL | /// [type@T::g] | ^^^^^^^^^ @@ -101,13 +116,13 @@ LL | /// [type@T::g] | help: to link to the associated function, add parentheses: `T::g()` error: unresolved link to `T::h` - --> $DIR/intra-link-errors.rs:82:6 + --> $DIR/intra-link-errors.rs:91:6 | LL | /// [T::h!] | ^^^^^ the trait `T` has no macro named `h` error: unresolved link to `S::h` - --> $DIR/intra-link-errors.rs:69:6 + --> $DIR/intra-link-errors.rs:78:6 | LL | /// [type@S::h] | ^^^^^^^^^ @@ -116,7 +131,7 @@ LL | /// [type@S::h] | help: to link to the associated function, add parentheses: `S::h()` error: unresolved link to `m` - --> $DIR/intra-link-errors.rs:89:6 + --> $DIR/intra-link-errors.rs:98:6 | LL | /// [m()] | ^^^ @@ -124,5 +139,5 @@ LL | /// [m()] | this link resolves to the macro `m`, which is not in the value namespace | help: to link to the macro, add an exclamation mark: `m!` -error: aborting due to 18 previous errors +error: aborting due to 20 previous errors diff --git a/src/test/rustdoc/intra-link-associated-items.rs b/src/test/rustdoc/intra-link-associated-items.rs index dec0deae5df7c..daf7075a91740 100644 --- a/src/test/rustdoc/intra-link-associated-items.rs +++ b/src/test/rustdoc/intra-link-associated-items.rs @@ -3,7 +3,7 @@ /// [`std::collections::BTreeMap::into_iter`] /// [`String::from`] is ambiguous as to which `From` impl -/// [type@Vec::into_iter] uses a disambiguator +/// [Vec::into_iter()] uses a disambiguator // @has 'intra_link_associated_items/fn.foo.html' '//a[@href="https://doc.rust-lang.org/nightly/alloc/collections/btree/map/struct.BTreeMap.html#method.into_iter"]' 'std::collections::BTreeMap::into_iter' // @has 'intra_link_associated_items/fn.foo.html' '//a[@href="https://doc.rust-lang.org/nightly/alloc/string/struct.String.html#method.from"]' 'String::from' // @has 'intra_link_associated_items/fn.foo.html' '//a[@href="https://doc.rust-lang.org/nightly/alloc/vec/struct.Vec.html#method.into_iter"]' 'Vec::into_iter' From 9baa601afd50f57655be9eb7e5e2892c2ea9f005 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Sat, 12 Sep 2020 02:32:43 -0400 Subject: [PATCH 14/17] Add `x.py setup` - Suggest `x.py setup` if config.toml doesn't exist yet (twice, once before and once after the build) - Prompt for a profile if not given on the command line - Print the configuration file that will be used - Print helpful starting commands after setup - Link to the dev-guide after finishing - Note that distro maintainers will see the changelog warning --- src/bootstrap/CHANGELOG.md | 1 + src/bootstrap/bin/main.rs | 19 ++++++-- src/bootstrap/builder.rs | 4 +- src/bootstrap/config.rs | 7 ++- src/bootstrap/flags.rs | 32 +++++++++++++- src/bootstrap/lib.rs | 7 ++- src/bootstrap/run.rs | 2 +- src/bootstrap/setup.rs | 88 ++++++++++++++++++++++++++++++++++++++ 8 files changed, 152 insertions(+), 8 deletions(-) create mode 100644 src/bootstrap/setup.rs diff --git a/src/bootstrap/CHANGELOG.md b/src/bootstrap/CHANGELOG.md index 5fcaafab959e9..aa398f25020f1 100644 --- a/src/bootstrap/CHANGELOG.md +++ b/src/bootstrap/CHANGELOG.md @@ -6,6 +6,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). ## [Non-breaking changes since the last major version] +- Add `x.py setup` [#76631](https://github.com/rust-lang/rust/pull/76631) - Add a changelog for x.py [#76626](https://github.com/rust-lang/rust/pull/76626) - Optionally, download LLVM from CI on Linux and NixOS + [#76439](https://github.com/rust-lang/rust/pull/76349) diff --git a/src/bootstrap/bin/main.rs b/src/bootstrap/bin/main.rs index f7512aa9fcebd..669dd7a33de18 100644 --- a/src/bootstrap/bin/main.rs +++ b/src/bootstrap/bin/main.rs @@ -7,21 +7,34 @@ use std::env; -use bootstrap::{Build, Config}; +use bootstrap::{Build, Config, Subcommand}; fn main() { let args = env::args().skip(1).collect::>(); let config = Config::parse(&args); let changelog_suggestion = check_version(&config); - if let Some(suggestion) = &changelog_suggestion { + + // NOTE: Since `./configure` generates a `config.toml`, distro maintainers will see the + // changelog warning, not the `x.py setup` message. + let suggest_setup = !config.config.exists() && !matches!(config.cmd, Subcommand::Setup { .. }); + if suggest_setup { + println!("warning: you have not made a `config.toml`"); + println!("help: consider running `x.py setup` or copying `config.toml.example`"); + } else if let Some(suggestion) = &changelog_suggestion { println!("{}", suggestion); } Build::new(config).build(); - if let Some(suggestion) = changelog_suggestion { + if suggest_setup { + println!("warning: you have not made a `config.toml`"); + println!("help: consider running `x.py setup` or copying `config.toml.example`"); + } else if let Some(suggestion) = &changelog_suggestion { println!("{}", suggestion); + } + + if suggest_setup || changelog_suggestion.is_some() { println!("note: this message was printed twice to make it more likely to be seen"); } } diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index d2537d65e67f5..4aaaeb8a93bda 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -549,7 +549,9 @@ impl<'a> Builder<'a> { Subcommand::Dist { ref paths } => (Kind::Dist, &paths[..]), Subcommand::Install { ref paths } => (Kind::Install, &paths[..]), Subcommand::Run { ref paths } => (Kind::Run, &paths[..]), - Subcommand::Format { .. } | Subcommand::Clean { .. } => panic!(), + Subcommand::Format { .. } | Subcommand::Clean { .. } | Subcommand::Setup { .. } => { + panic!() + } }; Self::new_internal(build, kind, paths.to_owned()) diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs index c74501979f0ec..46a9d989652e9 100644 --- a/src/bootstrap/config.rs +++ b/src/bootstrap/config.rs @@ -72,6 +72,8 @@ pub struct Config { pub stage: u32, pub keep_stage: Vec, pub src: PathBuf, + // defaults to `config.toml` + pub config: PathBuf, pub jobs: Option, pub cmd: Subcommand, pub incremental: bool, @@ -512,6 +514,7 @@ impl Config { config.rust_codegen_backends = vec![INTERNER.intern_str("llvm")]; config.deny_warnings = true; config.missing_tools = false; + config.config = PathBuf::from("config.toml"); // set by bootstrap.py config.build = TargetSelection::from_user(&env!("BUILD_TRIPLE")); @@ -556,7 +559,7 @@ impl Config { let get_toml = |file: PathBuf| { use std::process; - let contents = t!(fs::read_to_string(&file), "configuration file did not exist"); + let contents = t!(fs::read_to_string(&file), "`include` config not found"); match toml::from_str(&contents) { Ok(table) => table, Err(err) => { @@ -642,6 +645,7 @@ impl Config { | Subcommand::Clippy { .. } | Subcommand::Fix { .. } | Subcommand::Run { .. } + | Subcommand::Setup { .. } | Subcommand::Format { .. } => flags.stage.unwrap_or(0), }; @@ -666,6 +670,7 @@ impl Config { | Subcommand::Clippy { .. } | Subcommand::Fix { .. } | Subcommand::Run { .. } + | Subcommand::Setup { .. } | Subcommand::Format { .. } => {} } } diff --git a/src/bootstrap/flags.rs b/src/bootstrap/flags.rs index 842c84a3e5cd6..643edeb8321ba 100644 --- a/src/bootstrap/flags.rs +++ b/src/bootstrap/flags.rs @@ -7,6 +7,7 @@ use std::env; use std::path::PathBuf; use std::process; +use build_helper::t; use getopts::Options; use crate::builder::Builder; @@ -88,6 +89,9 @@ pub enum Subcommand { Run { paths: Vec, }, + Setup { + path: String, + }, } impl Default for Subcommand { @@ -191,6 +195,7 @@ To learn more about a subcommand, run `./x.py -h`", || (s == "install") || (s == "run") || (s == "r") + || (s == "setup") }); let subcommand = match subcommand { Some(s) => s, @@ -445,10 +450,21 @@ Arguments: At least a tool needs to be called.", ); } + "setup" => { + subcommand_help.push_str( + "\n +Arguments: + This subcommand accepts a 'profile' to use for builds. For example: + + ./x.py setup library + + The profile is optional and you will be prompted interactively if it is not given.", + ); + } _ => {} }; // Get any optional paths which occur after the subcommand - let paths = matches.free[1..].iter().map(|p| p.into()).collect::>(); + let mut paths = matches.free[1..].iter().map(|p| p.into()).collect::>(); let cfg_file = env::var_os("BOOTSTRAP_CONFIG").map(PathBuf::from); let verbose = matches.opt_present("verbose"); @@ -500,6 +516,20 @@ Arguments: } Subcommand::Run { paths } } + "setup" => { + let path = if paths.len() > 1 { + println!("\nat most one profile can be passed to setup\n"); + usage(1, &opts, verbose, &subcommand_help) + } else if let Some(path) = paths.pop() { + t!(path.into_os_string().into_string().map_err(|path| format!( + "{} is not a valid UTF8 string", + path.to_string_lossy() + ))) + } else { + t!(crate::setup::interactive_path()) + }; + Subcommand::Setup { path } + } _ => { usage(1, &opts, verbose, &subcommand_help); } diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs index 3f7aeae0ed495..4cc72f5f39c97 100644 --- a/src/bootstrap/lib.rs +++ b/src/bootstrap/lib.rs @@ -141,6 +141,7 @@ mod metadata; mod native; mod run; mod sanity; +mod setup; mod test; mod tool; mod toolstate; @@ -165,7 +166,7 @@ mod job { use crate::cache::{Interned, INTERNER}; pub use crate::config::Config; -use crate::flags::Subcommand; +pub use crate::flags::Subcommand; const LLVM_TOOLS: &[&str] = &[ "llvm-nm", // used to inspect binaries; it shows symbol names, their sizes and visibility @@ -470,6 +471,10 @@ impl Build { return clean::clean(self, all); } + if let Subcommand::Setup { path: include_name } = &self.config.cmd { + return setup::setup(&self.config.src, include_name); + } + { let builder = builder::Builder::new(&self); if let Some(path) = builder.paths.get(0) { diff --git a/src/bootstrap/run.rs b/src/bootstrap/run.rs index 900534714277c..ba593cadbad81 100644 --- a/src/bootstrap/run.rs +++ b/src/bootstrap/run.rs @@ -10,7 +10,7 @@ impl Step for ExpandYamlAnchors { /// Runs the `expand-yaml_anchors` tool. /// - /// This tool in `src/tools` read the CI configuration files written in YAML and expands the + /// This tool in `src/tools` reads the CI configuration files written in YAML and expands the /// anchors in them, since GitHub Actions doesn't support them. fn run(self, builder: &Builder<'_>) { builder.info("Expanding YAML anchors in the GitHub Actions configuration"); diff --git a/src/bootstrap/setup.rs b/src/bootstrap/setup.rs new file mode 100644 index 0000000000000..9d3a889aa008e --- /dev/null +++ b/src/bootstrap/setup.rs @@ -0,0 +1,88 @@ +use crate::t; +use std::path::{Path, PathBuf}; +use std::{ + env, fs, + io::{self, Write}, +}; + +pub fn setup(src_path: &Path, include_name: &str) { + let cfg_file = env::var_os("BOOTSTRAP_CONFIG").map(PathBuf::from); + + if cfg_file.as_ref().map_or(false, |f| f.exists()) { + let file = cfg_file.unwrap(); + println!( + "error: you asked `x.py` to setup a new config file, but one already exists at `{}`", + file.display() + ); + println!( + "help: try adding `profile = \"{}\"` at the top of {}", + include_name, + file.display() + ); + println!( + "note: this will use the configuration in {}/src/bootstrap/defaults/config.toml.{}", + src_path.display(), + include_name + ); + std::process::exit(1); + } + + let path = cfg_file.unwrap_or_else(|| src_path.join("config.toml")); + let settings = format!( + "# Includes one of the default files in src/bootstrap/defaults\n\ + profile = \"{}\"\n", + include_name + ); + t!(fs::write(path, settings)); + + let include_path = + format!("{}/src/bootstrap/defaults/config.toml.{}", src_path.display(), include_name); + println!("`x.py` will now use the configuration at {}", include_path); + + let suggestions = match include_name { + "codegen" | "compiler" => &["check", "build", "test"][..], + "library" => &["check", "build", "test library/std", "doc"], + "user" => &["dist", "build"], + _ => return, + }; + + println!("To get started, try one of the following commands:"); + for cmd in suggestions { + println!("- `x.py {}`", cmd); + } + + if include_name != "user" { + println!( + "For more suggestions, see https://rustc-dev-guide.rust-lang.org/building/suggested.html" + ); + } +} + +// Used to get the path for `Subcommand::Setup` +pub fn interactive_path() -> io::Result { + let mut input = String::new(); + println!( + "Welcome to the Rust project! What do you want to do with x.py? +a) Contribute to the standard library +b) Contribute to the compiler +c) Contribute to the compiler, and also modify LLVM or codegen +d) Install Rust from source" + ); + let template = loop { + print!("Please choose one (a/b/c/d): "); + io::stdout().flush()?; + io::stdin().read_line(&mut input)?; + break match input.trim().to_lowercase().as_str() { + "a" | "lib" | "library" => "library", + "b" | "compiler" => "compiler", + "c" | "llvm" => "llvm", + "d" | "user" | "maintainer" => "maintainer", + _ => { + println!("error: unrecognized option '{}'", input.trim()); + println!("note: press Ctrl+C to exit"); + continue; + } + }; + }; + Ok(template.to_owned()) +} From 382d7243a70f7b9fd9330334a12f76985067ef06 Mon Sep 17 00:00:00 2001 From: Lzu Tao Date: Thu, 24 Sep 2020 14:41:40 +0000 Subject: [PATCH 15/17] move test to intergrated test in library/core --- library/core/tests/intrinsics.rs | 15 +++++++++++++++ library/core/tests/lib.rs | 2 ++ src/test/ui/consts/const-eval/const_assume.rs | 17 ----------------- 3 files changed, 17 insertions(+), 17 deletions(-) delete mode 100644 src/test/ui/consts/const-eval/const_assume.rs diff --git a/library/core/tests/intrinsics.rs b/library/core/tests/intrinsics.rs index fed7c4a5bf399..de163a60c98f4 100644 --- a/library/core/tests/intrinsics.rs +++ b/library/core/tests/intrinsics.rs @@ -1,4 +1,5 @@ use core::any::TypeId; +use core::intrinsics::assume; #[test] fn test_typeid_sized_types() { @@ -20,3 +21,17 @@ fn test_typeid_unsized_types() { assert_eq!(TypeId::of::(), TypeId::of::()); assert!(TypeId::of::() != TypeId::of::()); } + +// Check that `const_assume` feature allow `assume` intrinsic +// to be used in const contexts. +#[test] +fn test_assume_can_be_in_const_contexts() { + const unsafe fn foo(x: usize, y: usize) -> usize { + // SAFETY: the entire function is not safe, + // but it is just an example not used elsewhere. + unsafe { assume(y != 0) }; + x / y + } + let rs = unsafe { foo(42, 97) }; + assert_eq!(rs, 0); +} diff --git a/library/core/tests/lib.rs b/library/core/tests/lib.rs index 4db391f3e567e..3a6caaa19fcd9 100644 --- a/library/core/tests/lib.rs +++ b/library/core/tests/lib.rs @@ -7,6 +7,8 @@ #![feature(bound_cloned)] #![feature(box_syntax)] #![feature(cell_update)] +#![feature(const_assume)] +#![feature(core_intrinsics)] #![feature(core_private_bignum)] #![feature(core_private_diy_float)] #![feature(debug_non_exhaustive)] diff --git a/src/test/ui/consts/const-eval/const_assume.rs b/src/test/ui/consts/const-eval/const_assume.rs deleted file mode 100644 index f72f151824bed..0000000000000 --- a/src/test/ui/consts/const-eval/const_assume.rs +++ /dev/null @@ -1,17 +0,0 @@ -// check-pass - -// Check that `const_assume` feature allow `assume` intrinsic -// to be used in const contexts. - -#![feature(core_intrinsics, const_assume)] - -extern crate core; - -use core::intrinsics::assume; - -pub const unsafe fn foo(x: usize, y: usize) -> usize { - assume(y != 0); - x / y -} - -fn main() {} From 1857184cd1b723a9478a0ed325b4a7f967693f71 Mon Sep 17 00:00:00 2001 From: Bastian Kauschke Date: Thu, 24 Sep 2020 19:22:36 +0200 Subject: [PATCH 16/17] remove enum name from ImplSource variants --- compiler/rustc_middle/src/traits/mod.rs | 89 +++++++++---------- .../src/traits/structural_impls.rs | 22 ++--- compiler/rustc_mir/src/monomorphize/mod.rs | 2 +- .../src/traits/auto_trait.rs | 7 +- .../src/traits/project.rs | 38 ++++---- .../src/traits/select/confirmation.rs | 32 +++---- compiler/rustc_ty/src/instance.rs | 22 ++--- .../rustc_typeck/src/check/method/probe.rs | 2 +- 8 files changed, 104 insertions(+), 110 deletions(-) diff --git a/compiler/rustc_middle/src/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs index a554c80cdaa1a..1dd6d590d908f 100644 --- a/compiler/rustc_middle/src/traits/mod.rs +++ b/compiler/rustc_middle/src/traits/mod.rs @@ -28,7 +28,6 @@ pub use self::select::{EvaluationCache, EvaluationResult, OverflowError, Selecti pub type CanonicalChalkEnvironmentAndGoal<'tcx> = Canonical<'tcx, ChalkEnvironmentAndGoal<'tcx>>; -pub use self::ImplSource::*; pub use self::ObligationCauseCode::*; pub use self::chalk::{ChalkEnvironmentAndGoal, RustInterner as ChalkRustInterner}; @@ -418,10 +417,10 @@ pub type SelectionResult<'tcx, T> = Result, SelectionError<'tcx>>; /// /// // Case B: ImplSource must be provided by caller. This applies when /// // type is a type parameter. -/// param.clone(); // ImplSourceParam +/// param.clone(); // ImplSource::Param /// /// // Case C: A mix of cases A and B. -/// mixed.clone(); // ImplSource(Impl_1, [ImplSourceParam]) +/// mixed.clone(); // ImplSource(Impl_1, [ImplSource::Param]) /// } /// ``` /// @@ -431,72 +430,72 @@ pub type SelectionResult<'tcx, T> = Result, SelectionError<'tcx>>; #[derive(Clone, PartialEq, Eq, TyEncodable, TyDecodable, HashStable, TypeFoldable, Lift)] pub enum ImplSource<'tcx, N> { /// ImplSource identifying a particular impl. - ImplSourceUserDefined(ImplSourceUserDefinedData<'tcx, N>), + UserDefined(ImplSourceUserDefinedData<'tcx, N>), /// ImplSource for auto trait implementations. /// This carries the information and nested obligations with regards /// to an auto implementation for a trait `Trait`. The nested obligations /// ensure the trait implementation holds for all the constituent types. - ImplSourceAutoImpl(ImplSourceAutoImplData), + AutoImpl(ImplSourceAutoImplData), /// Successful resolution to an obligation provided by the caller /// for some type parameter. The `Vec` represents the /// obligations incurred from normalizing the where-clause (if /// any). - ImplSourceParam(Vec), + Param(Vec), /// Virtual calls through an object. - ImplSourceObject(ImplSourceObjectData<'tcx, N>), + Object(ImplSourceObjectData<'tcx, N>), /// Successful resolution for a builtin trait. - ImplSourceBuiltin(ImplSourceBuiltinData), + Builtin(ImplSourceBuiltinData), /// ImplSource automatically generated for a closure. The `DefId` is the ID - /// of the closure expression. This is a `ImplSourceUserDefined` in spirit, but the + /// of the closure expression. This is a `ImplSource::UserDefined` in spirit, but the /// impl is generated by the compiler and does not appear in the source. - ImplSourceClosure(ImplSourceClosureData<'tcx, N>), + Closure(ImplSourceClosureData<'tcx, N>), /// Same as above, but for a function pointer type with the given signature. - ImplSourceFnPointer(ImplSourceFnPointerData<'tcx, N>), + FnPointer(ImplSourceFnPointerData<'tcx, N>), /// ImplSource for a builtin `DeterminantKind` trait implementation. - ImplSourceDiscriminantKind(ImplSourceDiscriminantKindData), + DiscriminantKind(ImplSourceDiscriminantKindData), /// ImplSource automatically generated for a generator. - ImplSourceGenerator(ImplSourceGeneratorData<'tcx, N>), + Generator(ImplSourceGeneratorData<'tcx, N>), /// ImplSource for a trait alias. - ImplSourceTraitAlias(ImplSourceTraitAliasData<'tcx, N>), + TraitAlias(ImplSourceTraitAliasData<'tcx, N>), } impl<'tcx, N> ImplSource<'tcx, N> { pub fn nested_obligations(self) -> Vec { match self { - ImplSourceUserDefined(i) => i.nested, - ImplSourceParam(n) => n, - ImplSourceBuiltin(i) => i.nested, - ImplSourceAutoImpl(d) => d.nested, - ImplSourceClosure(c) => c.nested, - ImplSourceGenerator(c) => c.nested, - ImplSourceObject(d) => d.nested, - ImplSourceFnPointer(d) => d.nested, - ImplSourceDiscriminantKind(ImplSourceDiscriminantKindData) => Vec::new(), - ImplSourceTraitAlias(d) => d.nested, + ImplSource::UserDefined(i) => i.nested, + ImplSource::Param(n) => n, + ImplSource::Builtin(i) => i.nested, + ImplSource::AutoImpl(d) => d.nested, + ImplSource::Closure(c) => c.nested, + ImplSource::Generator(c) => c.nested, + ImplSource::Object(d) => d.nested, + ImplSource::FnPointer(d) => d.nested, + ImplSource::DiscriminantKind(ImplSourceDiscriminantKindData) => Vec::new(), + ImplSource::TraitAlias(d) => d.nested, } } pub fn borrow_nested_obligations(&self) -> &[N] { match &self { - ImplSourceUserDefined(i) => &i.nested[..], - ImplSourceParam(n) => &n[..], - ImplSourceBuiltin(i) => &i.nested[..], - ImplSourceAutoImpl(d) => &d.nested[..], - ImplSourceClosure(c) => &c.nested[..], - ImplSourceGenerator(c) => &c.nested[..], - ImplSourceObject(d) => &d.nested[..], - ImplSourceFnPointer(d) => &d.nested[..], - ImplSourceDiscriminantKind(ImplSourceDiscriminantKindData) => &[], - ImplSourceTraitAlias(d) => &d.nested[..], + ImplSource::UserDefined(i) => &i.nested[..], + ImplSource::Param(n) => &n[..], + ImplSource::Builtin(i) => &i.nested[..], + ImplSource::AutoImpl(d) => &d.nested[..], + ImplSource::Closure(c) => &c.nested[..], + ImplSource::Generator(c) => &c.nested[..], + ImplSource::Object(d) => &d.nested[..], + ImplSource::FnPointer(d) => &d.nested[..], + ImplSource::DiscriminantKind(ImplSourceDiscriminantKindData) => &[], + ImplSource::TraitAlias(d) => &d.nested[..], } } @@ -505,42 +504,42 @@ impl<'tcx, N> ImplSource<'tcx, N> { F: FnMut(N) -> M, { match self { - ImplSourceUserDefined(i) => ImplSourceUserDefined(ImplSourceUserDefinedData { + ImplSource::UserDefined(i) => ImplSource::UserDefined(ImplSourceUserDefinedData { impl_def_id: i.impl_def_id, substs: i.substs, nested: i.nested.into_iter().map(f).collect(), }), - ImplSourceParam(n) => ImplSourceParam(n.into_iter().map(f).collect()), - ImplSourceBuiltin(i) => ImplSourceBuiltin(ImplSourceBuiltinData { + ImplSource::Param(n) => ImplSource::Param(n.into_iter().map(f).collect()), + ImplSource::Builtin(i) => ImplSource::Builtin(ImplSourceBuiltinData { nested: i.nested.into_iter().map(f).collect(), }), - ImplSourceObject(o) => ImplSourceObject(ImplSourceObjectData { + ImplSource::Object(o) => ImplSource::Object(ImplSourceObjectData { upcast_trait_ref: o.upcast_trait_ref, vtable_base: o.vtable_base, nested: o.nested.into_iter().map(f).collect(), }), - ImplSourceAutoImpl(d) => ImplSourceAutoImpl(ImplSourceAutoImplData { + ImplSource::AutoImpl(d) => ImplSource::AutoImpl(ImplSourceAutoImplData { trait_def_id: d.trait_def_id, nested: d.nested.into_iter().map(f).collect(), }), - ImplSourceClosure(c) => ImplSourceClosure(ImplSourceClosureData { + ImplSource::Closure(c) => ImplSource::Closure(ImplSourceClosureData { closure_def_id: c.closure_def_id, substs: c.substs, nested: c.nested.into_iter().map(f).collect(), }), - ImplSourceGenerator(c) => ImplSourceGenerator(ImplSourceGeneratorData { + ImplSource::Generator(c) => ImplSource::Generator(ImplSourceGeneratorData { generator_def_id: c.generator_def_id, substs: c.substs, nested: c.nested.into_iter().map(f).collect(), }), - ImplSourceFnPointer(p) => ImplSourceFnPointer(ImplSourceFnPointerData { + ImplSource::FnPointer(p) => ImplSource::FnPointer(ImplSourceFnPointerData { fn_ty: p.fn_ty, nested: p.nested.into_iter().map(f).collect(), }), - ImplSourceDiscriminantKind(ImplSourceDiscriminantKindData) => { - ImplSourceDiscriminantKind(ImplSourceDiscriminantKindData) + ImplSource::DiscriminantKind(ImplSourceDiscriminantKindData) => { + ImplSource::DiscriminantKind(ImplSourceDiscriminantKindData) } - ImplSourceTraitAlias(d) => ImplSourceTraitAlias(ImplSourceTraitAliasData { + ImplSource::TraitAlias(d) => ImplSource::TraitAlias(ImplSourceTraitAliasData { alias_def_id: d.alias_def_id, substs: d.substs, nested: d.nested.into_iter().map(f).collect(), diff --git a/compiler/rustc_middle/src/traits/structural_impls.rs b/compiler/rustc_middle/src/traits/structural_impls.rs index d73fc628ceb70..b8f6675b8e219 100644 --- a/compiler/rustc_middle/src/traits/structural_impls.rs +++ b/compiler/rustc_middle/src/traits/structural_impls.rs @@ -7,25 +7,25 @@ use std::fmt; impl<'tcx, N: fmt::Debug> fmt::Debug for traits::ImplSource<'tcx, N> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match *self { - super::ImplSourceUserDefined(ref v) => write!(f, "{:?}", v), + super::ImplSource::UserDefined(ref v) => write!(f, "{:?}", v), - super::ImplSourceAutoImpl(ref t) => write!(f, "{:?}", t), + super::ImplSource::AutoImpl(ref t) => write!(f, "{:?}", t), - super::ImplSourceClosure(ref d) => write!(f, "{:?}", d), + super::ImplSource::Closure(ref d) => write!(f, "{:?}", d), - super::ImplSourceGenerator(ref d) => write!(f, "{:?}", d), + super::ImplSource::Generator(ref d) => write!(f, "{:?}", d), - super::ImplSourceFnPointer(ref d) => write!(f, "ImplSourceFnPointer({:?})", d), + super::ImplSource::FnPointer(ref d) => write!(f, "({:?})", d), - super::ImplSourceDiscriminantKind(ref d) => write!(f, "{:?}", d), + super::ImplSource::DiscriminantKind(ref d) => write!(f, "{:?}", d), - super::ImplSourceObject(ref d) => write!(f, "{:?}", d), + super::ImplSource::Object(ref d) => write!(f, "{:?}", d), - super::ImplSourceParam(ref n) => write!(f, "ImplSourceParam({:?})", n), + super::ImplSource::Param(ref n) => write!(f, "ImplSourceParamData({:?})", n), - super::ImplSourceBuiltin(ref d) => write!(f, "{:?}", d), + super::ImplSource::Builtin(ref d) => write!(f, "{:?}", d), - super::ImplSourceTraitAlias(ref d) => write!(f, "{:?}", d), + super::ImplSource::TraitAlias(ref d) => write!(f, "{:?}", d), } } } @@ -96,7 +96,7 @@ impl<'tcx, N: fmt::Debug> fmt::Debug for traits::ImplSourceTraitAliasData<'tcx, fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!( f, - "ImplSourceTraitAlias(alias_def_id={:?}, substs={:?}, nested={:?})", + "ImplSourceTraitAliasData(alias_def_id={:?}, substs={:?}, nested={:?})", self.alias_def_id, self.substs, self.nested ) } diff --git a/compiler/rustc_mir/src/monomorphize/mod.rs b/compiler/rustc_mir/src/monomorphize/mod.rs index edafa00a03ad0..d2586f0f84dff 100644 --- a/compiler/rustc_mir/src/monomorphize/mod.rs +++ b/compiler/rustc_mir/src/monomorphize/mod.rs @@ -21,7 +21,7 @@ pub fn custom_coerce_unsize_info<'tcx>( }); match tcx.codegen_fulfill_obligation((ty::ParamEnv::reveal_all(), trait_ref)) { - Ok(traits::ImplSourceUserDefined(traits::ImplSourceUserDefinedData { + Ok(traits::ImplSource::UserDefined(traits::ImplSourceUserDefinedData { impl_def_id, .. })) => tcx.coerce_unsized_info(impl_def_id).custom_kind.unwrap(), diff --git a/compiler/rustc_trait_selection/src/traits/auto_trait.rs b/compiler/rustc_trait_selection/src/traits/auto_trait.rs index 6b87bc4f34ad4..35bfeff10b4aa 100644 --- a/compiler/rustc_trait_selection/src/traits/auto_trait.rs +++ b/compiler/rustc_trait_selection/src/traits/auto_trait.rs @@ -96,7 +96,7 @@ impl<'tcx> AutoTraitFinder<'tcx> { )); match result { - Ok(Some(ImplSource::ImplSourceUserDefined(_))) => { + Ok(Some(ImplSource::UserDefined(_))) => { debug!( "find_auto_trait_generics({:?}): \ manual impl found, bailing out", @@ -315,9 +315,8 @@ impl AutoTraitFinder<'tcx> { // If we see an explicit negative impl (e.g., `impl !Send for MyStruct`), // we immediately bail out, since it's impossible for us to continue. - if let ImplSource::ImplSourceUserDefined(ImplSourceUserDefinedData { - impl_def_id, - .. + if let ImplSource::UserDefined(ImplSourceUserDefinedData { + impl_def_id, .. }) = impl_source { // Blame 'tidy' for the weird bracket placement. diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index d37f819f376d3..ef8f7b69b5d60 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -1000,15 +1000,15 @@ fn assemble_candidates_from_impls<'cx, 'tcx>( }; let eligible = match &impl_source { - super::ImplSourceClosure(_) - | super::ImplSourceGenerator(_) - | super::ImplSourceFnPointer(_) - | super::ImplSourceObject(_) - | super::ImplSourceTraitAlias(_) => { + super::ImplSource::Closure(_) + | super::ImplSource::Generator(_) + | super::ImplSource::FnPointer(_) + | super::ImplSource::Object(_) + | super::ImplSource::TraitAlias(_) => { debug!("assemble_candidates_from_impls: impl_source={:?}", impl_source); true } - super::ImplSourceUserDefined(impl_data) => { + super::ImplSource::UserDefined(impl_data) => { // We have to be careful when projecting out of an // impl because of specialization. If we are not in // codegen (i.e., projection mode is not "any"), and the @@ -1060,7 +1060,7 @@ fn assemble_candidates_from_impls<'cx, 'tcx>( } } } - super::ImplSourceDiscriminantKind(..) => { + super::ImplSource::DiscriminantKind(..) => { // While `DiscriminantKind` is automatically implemented for every type, // the concrete discriminant may not be known yet. // @@ -1100,7 +1100,7 @@ fn assemble_candidates_from_impls<'cx, 'tcx>( | ty::Error(_) => false, } } - super::ImplSourceParam(..) => { + super::ImplSource::Param(..) => { // This case tell us nothing about the value of an // associated type. Consider: // @@ -1128,7 +1128,7 @@ fn assemble_candidates_from_impls<'cx, 'tcx>( // in `assemble_candidates_from_param_env`. false } - super::ImplSourceAutoImpl(..) | super::ImplSourceBuiltin(..) => { + super::ImplSource::AutoImpl(..) | super::ImplSource::Builtin(..) => { // These traits have no associated types. selcx.tcx().sess.delay_span_bug( obligation.cause.span, @@ -1186,20 +1186,20 @@ fn confirm_select_candidate<'cx, 'tcx>( impl_source: Selection<'tcx>, ) -> Progress<'tcx> { match impl_source { - super::ImplSourceUserDefined(data) => confirm_impl_candidate(selcx, obligation, data), - super::ImplSourceGenerator(data) => confirm_generator_candidate(selcx, obligation, data), - super::ImplSourceClosure(data) => confirm_closure_candidate(selcx, obligation, data), - super::ImplSourceFnPointer(data) => confirm_fn_pointer_candidate(selcx, obligation, data), - super::ImplSourceDiscriminantKind(data) => { + super::ImplSource::UserDefined(data) => confirm_impl_candidate(selcx, obligation, data), + super::ImplSource::Generator(data) => confirm_generator_candidate(selcx, obligation, data), + super::ImplSource::Closure(data) => confirm_closure_candidate(selcx, obligation, data), + super::ImplSource::FnPointer(data) => confirm_fn_pointer_candidate(selcx, obligation, data), + super::ImplSource::DiscriminantKind(data) => { confirm_discriminant_kind_candidate(selcx, obligation, data) } - super::ImplSourceObject(_) => { + super::ImplSource::Object(_) => { confirm_object_candidate(selcx, obligation, obligation_trait_ref) } - super::ImplSourceAutoImpl(..) - | super::ImplSourceParam(..) - | super::ImplSourceBuiltin(..) - | super::ImplSourceTraitAlias(..) => + super::ImplSource::AutoImpl(..) + | super::ImplSource::Param(..) + | super::ImplSource::Builtin(..) + | super::ImplSource::TraitAlias(..) => // we don't create Select candidates with this kind of resolution { span_bug!( diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index 9906c1f325f3d..88b656ce68082 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -19,16 +19,12 @@ use crate::traits::project::{self, normalize_with_depth}; use crate::traits::select::TraitObligationExt; use crate::traits::util; use crate::traits::util::{closure_trait_ref_and_return_type, predicate_for_trait_def}; +use crate::traits::ImplSource; use crate::traits::Normalized; use crate::traits::OutputTypeParameterMismatch; use crate::traits::Selection; use crate::traits::TraitNotObjectSafe; use crate::traits::{BuiltinDerivedObligation, ImplDerivedObligation}; -use crate::traits::{ - ImplSourceAutoImpl, ImplSourceBuiltin, ImplSourceClosure, ImplSourceDiscriminantKind, - ImplSourceFnPointer, ImplSourceGenerator, ImplSourceObject, ImplSourceParam, - ImplSourceTraitAlias, ImplSourceUserDefined, -}; use crate::traits::{ ImplSourceAutoImplData, ImplSourceBuiltinData, ImplSourceClosureData, ImplSourceDiscriminantKindData, ImplSourceFnPointerData, ImplSourceGeneratorData, @@ -55,67 +51,67 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { match candidate { BuiltinCandidate { has_nested } => { let data = self.confirm_builtin_candidate(obligation, has_nested); - Ok(ImplSourceBuiltin(data)) + Ok(ImplSource::Builtin(data)) } ParamCandidate(param) => { let obligations = self.confirm_param_candidate(obligation, param); - Ok(ImplSourceParam(obligations)) + Ok(ImplSource::Param(obligations)) } ImplCandidate(impl_def_id) => { - Ok(ImplSourceUserDefined(self.confirm_impl_candidate(obligation, impl_def_id))) + Ok(ImplSource::UserDefined(self.confirm_impl_candidate(obligation, impl_def_id))) } AutoImplCandidate(trait_def_id) => { let data = self.confirm_auto_impl_candidate(obligation, trait_def_id); - Ok(ImplSourceAutoImpl(data)) + Ok(ImplSource::AutoImpl(data)) } ProjectionCandidate => { self.confirm_projection_candidate(obligation); - Ok(ImplSourceParam(Vec::new())) + Ok(ImplSource::Param(Vec::new())) } ClosureCandidate => { let vtable_closure = self.confirm_closure_candidate(obligation)?; - Ok(ImplSourceClosure(vtable_closure)) + Ok(ImplSource::Closure(vtable_closure)) } GeneratorCandidate => { let vtable_generator = self.confirm_generator_candidate(obligation)?; - Ok(ImplSourceGenerator(vtable_generator)) + Ok(ImplSource::Generator(vtable_generator)) } FnPointerCandidate => { let data = self.confirm_fn_pointer_candidate(obligation)?; - Ok(ImplSourceFnPointer(data)) + Ok(ImplSource::FnPointer(data)) } DiscriminantKindCandidate => { - Ok(ImplSourceDiscriminantKind(ImplSourceDiscriminantKindData)) + Ok(ImplSource::DiscriminantKind(ImplSourceDiscriminantKindData)) } TraitAliasCandidate(alias_def_id) => { let data = self.confirm_trait_alias_candidate(obligation, alias_def_id); - Ok(ImplSourceTraitAlias(data)) + Ok(ImplSource::TraitAlias(data)) } ObjectCandidate => { let data = self.confirm_object_candidate(obligation); - Ok(ImplSourceObject(data)) + Ok(ImplSource::Object(data)) } BuiltinObjectCandidate => { // This indicates something like `Trait + Send: Send`. In this case, we know that // this holds because that's what the object type is telling us, and there's really // no additional obligations to prove and no types in particular to unify, etc. - Ok(ImplSourceParam(Vec::new())) + Ok(ImplSource::Param(Vec::new())) } BuiltinUnsizeCandidate => { let data = self.confirm_builtin_unsize_candidate(obligation)?; - Ok(ImplSourceBuiltin(data)) + Ok(ImplSource::Builtin(data)) } } } diff --git a/compiler/rustc_ty/src/instance.rs b/compiler/rustc_ty/src/instance.rs index 75bf8ea0bb816..220f4cec742f1 100644 --- a/compiler/rustc_ty/src/instance.rs +++ b/compiler/rustc_ty/src/instance.rs @@ -119,9 +119,9 @@ fn resolve_associated_item<'tcx>( // Now that we know which impl is being used, we can dispatch to // the actual function: Ok(match vtbl { - traits::ImplSourceUserDefined(impl_data) => { + traits::ImplSource::UserDefined(impl_data) => { debug!( - "resolving ImplSourceUserDefined: {:?}, {:?}, {:?}, {:?}", + "resolving ImplSource::UserDefined: {:?}, {:?}, {:?}, {:?}", param_env, trait_item, rcvr_substs, impl_data ); assert!(!rcvr_substs.needs_infer()); @@ -216,13 +216,13 @@ fn resolve_associated_item<'tcx>( Some(ty::Instance::new(leaf_def.item.def_id, substs)) } - traits::ImplSourceGenerator(generator_data) => Some(Instance { + traits::ImplSource::Generator(generator_data) => Some(Instance { def: ty::InstanceDef::Item(ty::WithOptConstParam::unknown( generator_data.generator_def_id, )), substs: generator_data.substs, }), - traits::ImplSourceClosure(closure_data) => { + traits::ImplSource::Closure(closure_data) => { let trait_closure_kind = tcx.fn_trait_kind_from_lang_item(trait_id).unwrap(); Some(Instance::resolve_closure( tcx, @@ -231,18 +231,18 @@ fn resolve_associated_item<'tcx>( trait_closure_kind, )) } - traits::ImplSourceFnPointer(ref data) => match data.fn_ty.kind() { + traits::ImplSource::FnPointer(ref data) => match data.fn_ty.kind() { ty::FnDef(..) | ty::FnPtr(..) => Some(Instance { def: ty::InstanceDef::FnPtrShim(trait_item.def_id, data.fn_ty), substs: rcvr_substs, }), _ => None, }, - traits::ImplSourceObject(ref data) => { + traits::ImplSource::Object(ref data) => { let index = traits::get_vtable_index_of_object_method(tcx, data, def_id); Some(Instance { def: ty::InstanceDef::Virtual(def_id, index), substs: rcvr_substs }) } - traits::ImplSourceBuiltin(..) => { + traits::ImplSource::Builtin(..) => { if Some(trait_ref.def_id) == tcx.lang_items().clone_trait() { // FIXME(eddyb) use lang items for methods instead of names. let name = tcx.item_name(def_id); @@ -271,10 +271,10 @@ fn resolve_associated_item<'tcx>( None } } - traits::ImplSourceAutoImpl(..) - | traits::ImplSourceParam(..) - | traits::ImplSourceTraitAlias(..) - | traits::ImplSourceDiscriminantKind(..) => None, + traits::ImplSource::AutoImpl(..) + | traits::ImplSource::Param(..) + | traits::ImplSource::TraitAlias(..) + | traits::ImplSource::DiscriminantKind(..) => None, }) } diff --git a/compiler/rustc_typeck/src/check/method/probe.rs b/compiler/rustc_typeck/src/check/method/probe.rs index 8a62031ec887c..c1ba29284da16 100644 --- a/compiler/rustc_typeck/src/check/method/probe.rs +++ b/compiler/rustc_typeck/src/check/method/probe.rs @@ -1306,7 +1306,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { .at(&ObligationCause::dummy(), self.param_env) .sup(candidate.xform_self_ty, self_ty); match self.select_trait_candidate(trait_ref) { - Ok(Some(traits::ImplSource::ImplSourceUserDefined(ref impl_data))) => { + Ok(Some(traits::ImplSource::UserDefined(ref impl_data))) => { // If only a single impl matches, make the error message point // to that impl. ImplSource(impl_data.impl_def_id) From 1d3717d17c8891db85a8316ea869a3ceca60b53d Mon Sep 17 00:00:00 2001 From: Austin Keeley Date: Fri, 25 Sep 2020 00:03:59 -0400 Subject: [PATCH 17/17] Removing erroneous semicolon --- library/core/src/intrinsics.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/core/src/intrinsics.rs b/library/core/src/intrinsics.rs index bcbb760021ee4..581b6af70da61 100644 --- a/library/core/src/intrinsics.rs +++ b/library/core/src/intrinsics.rs @@ -904,7 +904,7 @@ extern "rust-intrinsic" { /// let raw_bytes = [0x78, 0x56, 0x34, 0x12]; /// /// let num = unsafe { - /// std::mem::transmute::<[u8; 4], u32>(raw_bytes); + /// std::mem::transmute::<[u8; 4], u32>(raw_bytes) /// }; /// /// // use `u32::from_ne_bytes` instead