From 4548eb8fcfa0a3d5dfd2766ee12736f67aca0234 Mon Sep 17 00:00:00 2001 From: Alexis Bourget Date: Tue, 2 Jun 2020 23:30:51 +0200 Subject: [PATCH 01/35] Clarify the behaviour of Pattern when used with methods like str::contains --- src/libcore/str/pattern.rs | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/src/libcore/str/pattern.rs b/src/libcore/str/pattern.rs index 1a2b612b2f95c..263d6b5efdff9 100644 --- a/src/libcore/str/pattern.rs +++ b/src/libcore/str/pattern.rs @@ -60,6 +60,43 @@ use crate::slice::memchr; /// The trait itself acts as a builder for an associated /// `Searcher` type, which does the actual work of finding /// occurrences of the pattern in a string. +/// +/// Depending on the type of the pattern, the behaviour of methods like +/// [`str::find`] and [`str::contains`] can change. The table below describes +/// some of those behaviours. +/// +/// | Pattern type | Match condition | +/// |--------------------------|-------------------------------------------| +/// | `&str` | is substring | +/// | `char` | is contained in string | +/// | `&[char] | any char in slice is contained in string | +/// | `F: FnMut(char) -> bool` | `F` returns `true` for a char in string | +/// | `&&str` | is substring | +/// | `&String` | is substring | +/// +/// # Examples +/// ``` +/// // &str +/// assert_eq!("abaaa".find("ba"), Some(1)); +/// assert_eq!("abaaa".find("bac"), None); +/// +/// // char +/// assert_eq!("abaaa".find('a'), Some(0)); +/// assert_eq!("abaaa".find('b'), Some(1)); +/// assert_eq!("abaaa".find('c'), None); +/// +/// // &[char] +/// assert_eq!("ab".find(&['b', 'a'][..]), Some(0)); +/// assert_eq!("abaaa".find(&['a', 'z'][..]), Some(0)); +/// assert_eq!("abaaa".find(&['c', 'd'][..]), None); +/// +/// // FnMut(char) -> bool +/// assert_eq!("abcdef_z".find(|ch| ch > 'd' && ch < 'y'), Some(4)); +/// assert_eq!("abcddd_z".find(|ch| ch > 'd' && ch < 'y'), None); +/// ``` +/// +/// [`str::find`]: ../../../std/primitive.str.html#method.find +/// [`str::contains`]: ../../../std/primitive.str.html#method.contains pub trait Pattern<'a>: Sized { /// Associated searcher for this pattern type Searcher: Searcher<'a>; From 6f6620b966ce9ea37d034fa9d184d60b84a9ce02 Mon Sep 17 00:00:00 2001 From: Eden Date: Sun, 7 Jun 2020 11:23:15 +0400 Subject: [PATCH 02/35] Rename "cyclone" to "apple-a7" per changes in upstream LLVM See: https://reviews.llvm.org/D70779 https://reviews.llvm.org/D70779#C1703593NL568 LLVM 10 merged into master at: https://github.com/rust-lang/rust/pull/67759 --- src/librustc_target/spec/aarch64_apple_ios.rs | 2 +- src/librustc_target/spec/aarch64_apple_tvos.rs | 2 +- src/librustc_target/spec/apple_sdk_base.rs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/librustc_target/spec/aarch64_apple_ios.rs b/src/librustc_target/spec/aarch64_apple_ios.rs index eac2c3e6aa40c..1447716ca8484 100644 --- a/src/librustc_target/spec/aarch64_apple_ios.rs +++ b/src/librustc_target/spec/aarch64_apple_ios.rs @@ -15,7 +15,7 @@ pub fn target() -> TargetResult { target_vendor: "apple".to_string(), linker_flavor: LinkerFlavor::Gcc, options: TargetOptions { - features: "+neon,+fp-armv8,+cyclone".to_string(), + features: "+neon,+fp-armv8,+apple-a7".to_string(), eliminate_frame_pointer: false, max_atomic_width: Some(128), abi_blacklist: super::arm_base::abi_blacklist(), diff --git a/src/librustc_target/spec/aarch64_apple_tvos.rs b/src/librustc_target/spec/aarch64_apple_tvos.rs index f1cd14ffd11a6..21f660ac8b839 100644 --- a/src/librustc_target/spec/aarch64_apple_tvos.rs +++ b/src/librustc_target/spec/aarch64_apple_tvos.rs @@ -15,7 +15,7 @@ pub fn target() -> TargetResult { target_vendor: "apple".to_string(), linker_flavor: LinkerFlavor::Gcc, options: TargetOptions { - features: "+neon,+fp-armv8,+cyclone".to_string(), + features: "+neon,+fp-armv8,+apple-a7".to_string(), eliminate_frame_pointer: false, max_atomic_width: Some(128), abi_blacklist: super::arm_base::abi_blacklist(), diff --git a/src/librustc_target/spec/apple_sdk_base.rs b/src/librustc_target/spec/apple_sdk_base.rs index c7cff17b1544c..b07c2aef1caca 100644 --- a/src/librustc_target/spec/apple_sdk_base.rs +++ b/src/librustc_target/spec/apple_sdk_base.rs @@ -122,7 +122,7 @@ fn target_cpu(arch: Arch) -> String { match arch { Armv7 => "cortex-a8", // iOS7 is supported on iPhone 4 and higher Armv7s => "cortex-a9", - Arm64 => "cyclone", + Arm64 => "apple-a7", I386 => "yonah", X86_64 => "core2", X86_64_macabi => "core2", From fb58b7bc5d0f641bbd03550da042841f527496b3 Mon Sep 17 00:00:00 2001 From: Jack Huey Date: Wed, 13 May 2020 15:18:50 -0400 Subject: [PATCH 03/35] Add compare-mode=chalk and add a little bit more implementations and fixmes --- src/librustc_middle/traits/chalk.rs | 4 +- .../traits/chalk_fulfill.rs | 6 ++- src/librustc_traits/chalk/db.rs | 33 +++++++++--- src/librustc_traits/chalk/lowering.rs | 51 +++++++++++++++++-- .../coherence/coherence-subtyping.re.stderr | 16 ------ src/test/ui/coherence/coherence-subtyping.rs | 7 +-- ....old.stderr => coherence-subtyping.stderr} | 2 +- src/tools/compiletest/src/common.rs | 3 ++ src/tools/compiletest/src/header.rs | 1 + src/tools/compiletest/src/runtest.rs | 3 ++ 10 files changed, 91 insertions(+), 35 deletions(-) delete mode 100644 src/test/ui/coherence/coherence-subtyping.re.stderr rename src/test/ui/coherence/{coherence-subtyping.old.stderr => coherence-subtyping.stderr} (95%) diff --git a/src/librustc_middle/traits/chalk.rs b/src/librustc_middle/traits/chalk.rs index b963af96f5027..e3ecea69da660 100644 --- a/src/librustc_middle/traits/chalk.rs +++ b/src/librustc_middle/traits/chalk.rs @@ -32,12 +32,10 @@ pub enum RustDefId { RawPtr, Trait(DefId), - Impl(DefId), - FnDef(DefId), - AssocTy(DefId), + Opaque(DefId), } #[derive(Copy, Clone)] diff --git a/src/librustc_trait_selection/traits/chalk_fulfill.rs b/src/librustc_trait_selection/traits/chalk_fulfill.rs index 2d4d582c939b6..cbbff82d35f73 100644 --- a/src/librustc_trait_selection/traits/chalk_fulfill.rs +++ b/src/librustc_trait_selection/traits/chalk_fulfill.rs @@ -87,7 +87,9 @@ fn environment<'tcx>( NodeKind::TraitImpl => { let trait_ref = tcx.impl_trait_ref(def_id).expect("not an impl"); - inputs.extend(trait_ref.substs.iter().flat_map(|arg| arg.walk())); + // FIXME(chalk): this has problems because of late-bound regions + //inputs.extend(trait_ref.substs.iter().flat_map(|arg| arg.walk())); + inputs.extend(trait_ref.substs.iter()); } // In an inherent impl, we assume that the receiver type and all its @@ -136,6 +138,8 @@ fn in_environment( let environment = match obligation.param_env.def_id { Some(def_id) => environment(infcx.tcx, def_id), None if obligation.param_env.caller_bounds.is_empty() => ty::List::empty(), + // FIXME(chalk): this is hit in ui/where-clauses/where-clause-constraints-are-local-for-trait-impl + // and ui/generics/generic-static-methods _ => bug!("non-empty `ParamEnv` with no def-id"), }; diff --git a/src/librustc_traits/chalk/db.rs b/src/librustc_traits/chalk/db.rs index a2aee9b6ef74d..18c690a2f5138 100644 --- a/src/librustc_traits/chalk/db.rs +++ b/src/librustc_traits/chalk/db.rs @@ -168,7 +168,7 @@ impl<'tcx> chalk_solve::RustIrDatabase> for RustIrDatabase<'t }); struct_datum } - RustDefId::Ref(_) => Arc::new(chalk_rust_ir::StructDatum { + RustDefId::Ref(_) | RustDefId::RawPtr => Arc::new(chalk_rust_ir::StructDatum { id: struct_id, binders: chalk_ir::Binders::new( chalk_ir::ParameterKinds::from( @@ -204,7 +204,7 @@ impl<'tcx> chalk_solve::RustIrDatabase> for RustIrDatabase<'t }) } - _ => bug!("Used not struct variant when expecting struct variant."), + v => bug!("Used not struct variant ({:?}) when expecting struct variant.", v), } } @@ -283,6 +283,17 @@ impl<'tcx> chalk_solve::RustIrDatabase> for RustIrDatabase<'t RustDefId::Trait(def_id) => def_id, _ => bug!("Did not use `Trait` variant when expecting trait."), }; + // FIXME(chalk): this match can be removed when builtin types supported + match struct_id.0 { + RustDefId::Adt(_) => {} + RustDefId::Str => return false, + RustDefId::Never => return false, + RustDefId::Slice => return false, + RustDefId::Array => return false, + RustDefId::Ref(_) => return false, + RustDefId::RawPtr => return false, + _ => bug!("Did not use `Adt` variant when expecting adt."), + } let adt_def_id: DefId = match struct_id.0 { RustDefId::Adt(def_id) => def_id, _ => bug!("Did not use `Adt` variant when expecting adt."), @@ -347,9 +358,19 @@ impl<'tcx> chalk_solve::RustIrDatabase> for RustIrDatabase<'t fn opaque_ty_data( &self, - _id: chalk_ir::OpaqueTyId>, + opaque_ty_id: chalk_ir::OpaqueTyId>, ) -> Arc>> { - unimplemented!() + // FIXME(chalk): actually lower opaque ty + let hidden_ty = + self.tcx.mk_ty(ty::Tuple(self.tcx.intern_substs(&[]))).lower_into(&self.interner); + let value = chalk_rust_ir::OpaqueTyDatumBound { + hidden_ty, + bounds: chalk_ir::Binders::new(chalk_ir::ParameterKinds::new(&self.interner), vec![]), + }; + Arc::new(chalk_rust_ir::OpaqueTyDatum { + opaque_ty_id, + bound: chalk_ir::Binders::new(chalk_ir::ParameterKinds::new(&self.interner), value), + }) } /// Since Chalk can't handle all Rust types currently, we have to handle @@ -386,7 +407,7 @@ impl<'tcx> chalk_solve::RustIrDatabase> for RustIrDatabase<'t Str | Slice => Some(false), - Trait(_) | Impl(_) | AssocTy(_) => panic!(), + Trait(_) | Impl(_) | AssocTy(_) | Opaque(_) => panic!(), } } _ => None, @@ -416,7 +437,7 @@ impl<'tcx> chalk_solve::RustIrDatabase> for RustIrDatabase<'t } } } - Trait(_) | Impl(_) | AssocTy(_) => panic!(), + Trait(_) | Impl(_) | AssocTy(_) | Opaque(_) => panic!(), } } _ => None, diff --git a/src/librustc_traits/chalk/lowering.rs b/src/librustc_traits/chalk/lowering.rs index 9530b07e47cdb..f8dab07a30b97 100644 --- a/src/librustc_traits/chalk/lowering.rs +++ b/src/librustc_traits/chalk/lowering.rs @@ -352,7 +352,11 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::Ty>> for Ty<'tcx> { }) .intern(interner) } - Dynamic(_, _) => unimplemented!(), + // FIXME(chalk): add region + Dynamic(predicates, _region) => { + TyData::Dyn(chalk_ir::DynTy { bounds: predicates.lower_into(interner) }) + .intern(interner) + } Closure(_def_id, _) => unimplemented!(), Generator(_def_id, _substs, _) => unimplemented!(), GeneratorWitness(_) => unimplemented!(), @@ -361,7 +365,13 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::Ty>> for Ty<'tcx> { apply(chalk_ir::TypeName::Tuple(substs.len()), substs.lower_into(interner)) } Projection(proj) => TyData::Alias(proj.lower_into(interner)).intern(interner), - Opaque(_def_id, _substs) => unimplemented!(), + Opaque(def_id, substs) => { + TyData::Alias(chalk_ir::AliasTy::Opaque(chalk_ir::OpaqueTy { + opaque_ty_id: chalk_ir::OpaqueTyId(RustDefId::Opaque(def_id)), + substitution: substs.lower_into(interner), + })) + .intern(interner) + } // This should have been done eagerly prior to this, and all Params // should have been substituted to placeholders Param(_) => panic!("Lowering Param when not expected."), @@ -376,7 +386,7 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::Ty>> for Ty<'tcx> { }) .intern(interner), Infer(_infer) => unimplemented!(), - Error => unimplemented!(), + Error => apply(chalk_ir::TypeName::Error, empty()), } } } @@ -401,6 +411,7 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::Lifetime>> for Region<'t ty::BrEnv => unimplemented!(), }, ReFree(_) => unimplemented!(), + // FIXME(chalk): need to handle ReStatic ReStatic => unimplemented!(), ReVar(_) => unimplemented!(), RePlaceholder(placeholder_region) => { @@ -411,6 +422,7 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::Lifetime>> for Region<'t .intern(interner) } ReEmpty(_) => unimplemented!(), + // FIXME(chalk): need to handle ReErased ReErased => unimplemented!(), } } @@ -472,6 +484,39 @@ impl<'tcx> LowerInto<'tcx, Option LowerInto<'tcx, chalk_ir::Binders>>> + for Binder<&'tcx ty::List>> +{ + fn lower_into( + self, + interner: &RustInterner<'tcx>, + ) -> chalk_ir::Binders>> { + let (predicates, binders, _named_regions) = + collect_bound_vars(interner, interner.tcx, &self); + let where_clauses = predicates.into_iter().map(|predicate| match predicate { + ty::ExistentialPredicate::Trait(ty::ExistentialTraitRef { def_id, substs }) => { + chalk_ir::Binders::new( + chalk_ir::ParameterKinds::new(interner), + chalk_ir::WhereClause::Implemented(chalk_ir::TraitRef { + trait_id: chalk_ir::TraitId(RustDefId::Trait(*def_id)), + substitution: substs.lower_into(interner), + }), + ) + } + ty::ExistentialPredicate::Projection(_predicate) => unimplemented!(), + ty::ExistentialPredicate::AutoTrait(def_id) => chalk_ir::Binders::new( + chalk_ir::ParameterKinds::new(interner), + chalk_ir::WhereClause::Implemented(chalk_ir::TraitRef { + trait_id: chalk_ir::TraitId(RustDefId::Trait(*def_id)), + substitution: chalk_ir::Substitution::empty(interner), + }), + ), + }); + let value = chalk_ir::QuantifiedWhereClauses::from(interner, where_clauses); + chalk_ir::Binders::new(binders, value) + } +} + /// To collect bound vars, we have to do two passes. In the first pass, we /// collect all `BoundRegion`s and `ty::Bound`s. In the second pass, we then /// replace `BrNamed` into `BrAnon`. The two separate passes are important, diff --git a/src/test/ui/coherence/coherence-subtyping.re.stderr b/src/test/ui/coherence/coherence-subtyping.re.stderr deleted file mode 100644 index b3c2f4516349e..0000000000000 --- a/src/test/ui/coherence/coherence-subtyping.re.stderr +++ /dev/null @@ -1,16 +0,0 @@ -warning: conflicting implementations of trait `TheTrait` for type `for<'a, 'b> fn(&'a u8, &'b u8) -> &'a u8`: - --> $DIR/coherence-subtyping.rs:16:1 - | -LL | impl TheTrait for for<'a, 'b> fn(&'a u8, &'b u8) -> &'a u8 {} - | ---------------------------------------------------------- first implementation here -LL | -LL | impl TheTrait for for<'a> fn(&'a u8, &'a u8) -> &'a u8 { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `for<'a, 'b> fn(&'a u8, &'b u8) -> &'a u8` - | - = note: `#[warn(coherence_leak_check)]` on by default - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #56105 - = note: this behavior recently changed as a result of a bug fix; see rust-lang/rust#56105 for details - -warning: 1 warning emitted - diff --git a/src/test/ui/coherence/coherence-subtyping.rs b/src/test/ui/coherence/coherence-subtyping.rs index f5c1d92411baa..b3ed728a81c06 100644 --- a/src/test/ui/coherence/coherence-subtyping.rs +++ b/src/test/ui/coherence/coherence-subtyping.rs @@ -4,7 +4,6 @@ // Note: This scenario is currently accepted, but as part of the // universe transition (#56105) may eventually become an error. -// revisions: old re // check-pass trait TheTrait { @@ -14,10 +13,8 @@ trait TheTrait { impl TheTrait for for<'a, 'b> fn(&'a u8, &'b u8) -> &'a u8 {} impl TheTrait for for<'a> fn(&'a u8, &'a u8) -> &'a u8 { - //[re]~^ WARNING conflicting implementation - //[re]~^^ WARNING this was previously accepted by the compiler but is being phased out - //[old]~^^^ WARNING conflicting implementation - //[old]~^^^^ WARNING this was previously accepted by the compiler but is being phased out + //~^ WARNING conflicting implementation + //~^^ WARNING this was previously accepted by the compiler but is being phased out } fn main() {} diff --git a/src/test/ui/coherence/coherence-subtyping.old.stderr b/src/test/ui/coherence/coherence-subtyping.stderr similarity index 95% rename from src/test/ui/coherence/coherence-subtyping.old.stderr rename to src/test/ui/coherence/coherence-subtyping.stderr index b3c2f4516349e..7f751a24c75c9 100644 --- a/src/test/ui/coherence/coherence-subtyping.old.stderr +++ b/src/test/ui/coherence/coherence-subtyping.stderr @@ -1,5 +1,5 @@ warning: conflicting implementations of trait `TheTrait` for type `for<'a, 'b> fn(&'a u8, &'b u8) -> &'a u8`: - --> $DIR/coherence-subtyping.rs:16:1 + --> $DIR/coherence-subtyping.rs:15:1 | LL | impl TheTrait for for<'a, 'b> fn(&'a u8, &'b u8) -> &'a u8 {} | ---------------------------------------------------------- first implementation here diff --git a/src/tools/compiletest/src/common.rs b/src/tools/compiletest/src/common.rs index 64c0298c1fa4e..703b87634cec3 100644 --- a/src/tools/compiletest/src/common.rs +++ b/src/tools/compiletest/src/common.rs @@ -123,6 +123,7 @@ pub enum FailMode { pub enum CompareMode { Nll, Polonius, + Chalk, } impl CompareMode { @@ -130,6 +131,7 @@ impl CompareMode { match *self { CompareMode::Nll => "nll", CompareMode::Polonius => "polonius", + CompareMode::Chalk => "chalk", } } @@ -137,6 +139,7 @@ impl CompareMode { match s.as_str() { "nll" => CompareMode::Nll, "polonius" => CompareMode::Polonius, + "chalk" => CompareMode::Chalk, x => panic!("unknown --compare-mode option: {}", x), } } diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs index 9d1940dd4d6c2..984c7a7c90855 100644 --- a/src/tools/compiletest/src/header.rs +++ b/src/tools/compiletest/src/header.rs @@ -857,6 +857,7 @@ impl Config { match self.compare_mode { Some(CompareMode::Nll) => name == "compare-mode-nll", Some(CompareMode::Polonius) => name == "compare-mode-polonius", + Some(CompareMode::Chalk) => name == "compare-mode-chalk", None => false, } || (cfg!(debug_assertions) && name == "debug") || diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index 4f8cf92b86938..8d92823af99d6 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -1962,6 +1962,9 @@ impl<'test> TestCx<'test> { Some(CompareMode::Polonius) => { rustc.args(&["-Zpolonius", "-Zborrowck=mir"]); } + Some(CompareMode::Chalk) => { + rustc.args(&["-Zchalk"]); + } None => {} } From 045dfc020fa1c282af22042c2942a9b2016e3832 Mon Sep 17 00:00:00 2001 From: Jack Huey Date: Wed, 13 May 2020 16:46:26 -0400 Subject: [PATCH 04/35] Update chalk --- Cargo.lock | 30 ++++++++----------- src/librustc_middle/Cargo.toml | 3 +- src/librustc_middle/traits/chalk.rs | 7 +---- src/librustc_traits/Cargo.toml | 9 ++++-- src/librustc_traits/chalk/db.rs | 42 +++++++++------------------ src/librustc_traits/chalk/lowering.rs | 41 ++++++++++++++++---------- src/librustc_traits/chalk/mod.rs | 10 +++++-- 7 files changed, 69 insertions(+), 73 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 07c354a332416..ae7dbeb3ab88d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -428,9 +428,8 @@ dependencies = [ [[package]] name = "chalk-derive" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d4620afad4d4d9e63f915cfa10c930b7a3c9c3ca5cd88dd771ff8e5bf04ea10" +version = "0.10.1-dev" +source = "git+https://github.com/rust-lang/chalk.git?rev=3e9c2503ae9c5277c2acb74624dc267876dd89b3#3e9c2503ae9c5277c2acb74624dc267876dd89b3" dependencies = [ "proc-macro2 1.0.3", "quote 1.0.2", @@ -440,9 +439,8 @@ dependencies = [ [[package]] name = "chalk-engine" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ca6e5cef10197789da0b4ec310eda58da4c55530613b2323432642a97372735" +version = "0.10.1-dev" +source = "git+https://github.com/rust-lang/chalk.git?rev=3e9c2503ae9c5277c2acb74624dc267876dd89b3#3e9c2503ae9c5277c2acb74624dc267876dd89b3" dependencies = [ "chalk-macros", "rustc-hash", @@ -450,9 +448,8 @@ dependencies = [ [[package]] name = "chalk-ir" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d45df5fb6328527f976e8a32c9e1c9970084d937ebe93d0d34f5bbf4231cb956" +version = "0.10.1-dev" +source = "git+https://github.com/rust-lang/chalk.git?rev=3e9c2503ae9c5277c2acb74624dc267876dd89b3#3e9c2503ae9c5277c2acb74624dc267876dd89b3" dependencies = [ "chalk-derive", "chalk-engine", @@ -461,18 +458,16 @@ dependencies = [ [[package]] name = "chalk-macros" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e4782d108e420a1fcf94d8a919cf248db33c5071678e87d9c2d4f20ed1feb32" +version = "0.10.1-dev" +source = "git+https://github.com/rust-lang/chalk.git?rev=3e9c2503ae9c5277c2acb74624dc267876dd89b3#3e9c2503ae9c5277c2acb74624dc267876dd89b3" dependencies = [ "lazy_static", ] [[package]] name = "chalk-rust-ir" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0ec96dbe0ab5fdbadfca4179ec2e1d35f0439c3b53a74988b1aec239c63eb08" +version = "0.10.1-dev" +source = "git+https://github.com/rust-lang/chalk.git?rev=3e9c2503ae9c5277c2acb74624dc267876dd89b3#3e9c2503ae9c5277c2acb74624dc267876dd89b3" dependencies = [ "chalk-derive", "chalk-engine", @@ -482,9 +477,8 @@ dependencies = [ [[package]] name = "chalk-solve" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfb99fa9530f0e101475fb60adc931f51bdea05b4642a48928b814d7f0141a6b" +version = "0.10.1-dev" +source = "git+https://github.com/rust-lang/chalk.git?rev=3e9c2503ae9c5277c2acb74624dc267876dd89b3#3e9c2503ae9c5277c2acb74624dc267876dd89b3" dependencies = [ "chalk-derive", "chalk-engine", diff --git a/src/librustc_middle/Cargo.toml b/src/librustc_middle/Cargo.toml index 0c22672d5fb7d..6570fe67b3b0e 100644 --- a/src/librustc_middle/Cargo.toml +++ b/src/librustc_middle/Cargo.toml @@ -30,7 +30,8 @@ rustc_serialize = { path = "../librustc_serialize" } rustc_ast = { path = "../librustc_ast" } rustc_span = { path = "../librustc_span" } byteorder = { version = "1.3" } -chalk-ir = "0.10.0" +chalk-ir = { git = "https://github.com/rust-lang/chalk.git", rev = "3e9c2503ae9c5277c2acb74624dc267876dd89b3" } +#chalk-ir = "0.10.0" smallvec = { version = "1.0", features = ["union", "may_dangle"] } measureme = "0.7.1" rustc_session = { path = "../librustc_session" } diff --git a/src/librustc_middle/traits/chalk.rs b/src/librustc_middle/traits/chalk.rs index e3ecea69da660..2bd22ee800444 100644 --- a/src/librustc_middle/traits/chalk.rs +++ b/src/librustc_middle/traits/chalk.rs @@ -7,7 +7,6 @@ use chalk_ir::{GoalData, Parameter}; -use rustc_middle::mir::Mutability; use rustc_middle::ty::fold::{TypeFoldable, TypeFolder, TypeVisitor}; use rustc_middle::ty::{self, Ty, TyCtxt}; @@ -24,16 +23,12 @@ use std::hash::{Hash, Hasher}; #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] pub enum RustDefId { Adt(DefId), - Str, Never, - Slice, Array, - Ref(Mutability), - RawPtr, + FnDef(DefId), Trait(DefId), Impl(DefId), - FnDef(DefId), AssocTy(DefId), Opaque(DefId), } diff --git a/src/librustc_traits/Cargo.toml b/src/librustc_traits/Cargo.toml index e485bc2929bdb..f429ab7cd0964 100644 --- a/src/librustc_traits/Cargo.toml +++ b/src/librustc_traits/Cargo.toml @@ -16,9 +16,12 @@ rustc_hir = { path = "../librustc_hir" } rustc_index = { path = "../librustc_index" } rustc_ast = { path = "../librustc_ast" } rustc_span = { path = "../librustc_span" } -chalk-ir = "0.10.0" -chalk-rust-ir = "0.10.0" -chalk-solve = "0.10.0" +#chalk-ir = "0.10.0" +#chalk-rust-ir = "0.10.0" +#chalk-solve = "0.10.0" +chalk-solve = { git = "https://github.com/rust-lang/chalk.git", rev = "3e9c2503ae9c5277c2acb74624dc267876dd89b3" } +chalk-rust-ir = { git = "https://github.com/rust-lang/chalk.git", rev = "3e9c2503ae9c5277c2acb74624dc267876dd89b3" } +chalk-ir = { git = "https://github.com/rust-lang/chalk.git", rev = "3e9c2503ae9c5277c2acb74624dc267876dd89b3" } smallvec = { version = "1.0", features = ["union", "may_dangle"] } rustc_infer = { path = "../librustc_infer" } rustc_trait_selection = { path = "../librustc_trait_selection" } diff --git a/src/librustc_traits/chalk/db.rs b/src/librustc_traits/chalk/db.rs index 18c690a2f5138..4320436f1e33c 100644 --- a/src/librustc_traits/chalk/db.rs +++ b/src/librustc_traits/chalk/db.rs @@ -168,41 +168,25 @@ impl<'tcx> chalk_solve::RustIrDatabase> for RustIrDatabase<'t }); struct_datum } - RustDefId::Ref(_) | RustDefId::RawPtr => Arc::new(chalk_rust_ir::StructDatum { + RustDefId::Array => Arc::new(chalk_rust_ir::StructDatum { id: struct_id, binders: chalk_ir::Binders::new( chalk_ir::ParameterKinds::from( &self.interner, - vec![ - chalk_ir::ParameterKind::Lifetime(()), - chalk_ir::ParameterKind::Ty(()), - ], + Some(chalk_ir::ParameterKind::Ty(())), ), chalk_rust_ir::StructDatumBound { fields: vec![], where_clauses: vec![] }, ), flags: chalk_rust_ir::StructFlags { upstream: false, fundamental: false }, }), - RustDefId::Array | RustDefId::Slice => Arc::new(chalk_rust_ir::StructDatum { + RustDefId::Never | RustDefId::FnDef(_) => Arc::new(chalk_rust_ir::StructDatum { id: struct_id, binders: chalk_ir::Binders::new( - chalk_ir::ParameterKinds::from( - &self.interner, - Some(chalk_ir::ParameterKind::Ty(())), - ), + chalk_ir::ParameterKinds::new(&self.interner), chalk_rust_ir::StructDatumBound { fields: vec![], where_clauses: vec![] }, ), flags: chalk_rust_ir::StructFlags { upstream: false, fundamental: false }, }), - RustDefId::Str | RustDefId::Never | RustDefId::FnDef(_) => { - Arc::new(chalk_rust_ir::StructDatum { - id: struct_id, - binders: chalk_ir::Binders::new( - chalk_ir::ParameterKinds::new(&self.interner), - chalk_rust_ir::StructDatumBound { fields: vec![], where_clauses: vec![] }, - ), - flags: chalk_rust_ir::StructFlags { upstream: false, fundamental: false }, - }) - } v => bug!("Used not struct variant ({:?}) when expecting struct variant.", v), } @@ -286,12 +270,8 @@ impl<'tcx> chalk_solve::RustIrDatabase> for RustIrDatabase<'t // FIXME(chalk): this match can be removed when builtin types supported match struct_id.0 { RustDefId::Adt(_) => {} - RustDefId::Str => return false, RustDefId::Never => return false, - RustDefId::Slice => return false, RustDefId::Array => return false, - RustDefId::Ref(_) => return false, - RustDefId::RawPtr => return false, _ => bug!("Did not use `Adt` variant when expecting adt."), } let adt_def_id: DefId = match struct_id.0 { @@ -388,7 +368,7 @@ impl<'tcx> chalk_solve::RustIrDatabase> for RustIrDatabase<'t chalk_ir::TypeName::Struct(chalk_ir::StructId(rust_def_id)) => { use rustc_middle::traits::ChalkRustDefId::*; match rust_def_id { - Never | Array | RawPtr | FnDef(_) | Ref(_) => Some(true), + Never | Array | FnDef(_) => Some(true), Adt(adt_def_id) => { let adt_def = self.tcx.adt_def(adt_def_id); @@ -405,8 +385,6 @@ impl<'tcx> chalk_solve::RustIrDatabase> for RustIrDatabase<'t } } - Str | Slice => Some(false), - Trait(_) | Impl(_) | AssocTy(_) | Opaque(_) => panic!(), } } @@ -421,7 +399,7 @@ impl<'tcx> chalk_solve::RustIrDatabase> for RustIrDatabase<'t chalk_ir::TypeName::Struct(chalk_ir::StructId(rust_def_id)) => { use rustc_middle::traits::ChalkRustDefId::*; match rust_def_id { - Never | RawPtr | Ref(_) | Str | Slice => Some(false), + Never => Some(false), FnDef(_) | Array => Some(true), Adt(adt_def_id) => { let adt_def = self.tcx.adt_def(adt_def_id); @@ -489,6 +467,14 @@ impl<'tcx> chalk_solve::RustIrDatabase> for RustIrDatabase<'t }; Some(t) } + + fn is_object_safe(&self, trait_id: chalk_ir::TraitId>) -> bool { + let def_id: DefId = match trait_id.0 { + RustDefId::Trait(def_id) => def_id, + _ => bug!("Did not use `Trait` variant when expecting trait."), + }; + self.tcx.is_object_safe(def_id) + } } /// Creates a `InternalSubsts` that maps each generic parameter to a higher-ranked diff --git a/src/librustc_traits/chalk/lowering.rs b/src/librustc_traits/chalk/lowering.rs index f8dab07a30b97..a293b10fe5b6d 100644 --- a/src/librustc_traits/chalk/lowering.rs +++ b/src/librustc_traits/chalk/lowering.rs @@ -309,7 +309,7 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::Ty>> for Ty<'tcx> { apply(struct_ty(RustDefId::Adt(def.did)), substs.lower_into(interner)) } Foreign(_def_id) => unimplemented!(), - Str => apply(struct_ty(RustDefId::Str), empty()), + Str => apply(chalk_ir::TypeName::Str, empty()), Array(ty, _) => apply( struct_ty(RustDefId::Array), chalk_ir::Substitution::from1( @@ -318,25 +318,36 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::Ty>> for Ty<'tcx> { ), ), Slice(ty) => apply( - struct_ty(RustDefId::Slice), + chalk_ir::TypeName::Slice, chalk_ir::Substitution::from1( interner, chalk_ir::ParameterKind::Ty(ty.lower_into(interner)).intern(interner), ), ), - RawPtr(_) => apply(struct_ty(RustDefId::RawPtr), empty()), - Ref(region, ty, mutability) => apply( - struct_ty(RustDefId::Ref(mutability)), - chalk_ir::Substitution::from( - interner, - [ - chalk_ir::ParameterKind::Lifetime(region.lower_into(interner)) - .intern(interner), - chalk_ir::ParameterKind::Ty(ty.lower_into(interner)).intern(interner), - ] - .iter(), - ), - ), + RawPtr(ptr) => { + let name = match ptr.mutbl { + ast::Mutability::Mut => chalk_ir::TypeName::Raw(chalk_ir::Mutability::Mut), + ast::Mutability::Not => chalk_ir::TypeName::Raw(chalk_ir::Mutability::Not), + }; + apply(name, chalk_ir::Substitution::from1(interner, ptr.ty.lower_into(interner))) + } + Ref(region, ty, mutability) => { + let name = match mutability { + ast::Mutability::Mut => chalk_ir::TypeName::Ref(chalk_ir::Mutability::Mut), + ast::Mutability::Not => chalk_ir::TypeName::Ref(chalk_ir::Mutability::Not), + }; + apply( + name, + chalk_ir::Substitution::from( + interner, + &[ + chalk_ir::ParameterKind::Lifetime(region.lower_into(interner)) + .intern(interner), + chalk_ir::ParameterKind::Ty(ty.lower_into(interner)).intern(interner), + ], + ), + ) + } FnDef(def_id, _) => apply(struct_ty(RustDefId::FnDef(def_id)), empty()), FnPtr(sig) => { let (inputs_and_outputs, binders, _named_regions) = diff --git a/src/librustc_traits/chalk/mod.rs b/src/librustc_traits/chalk/mod.rs index 4e635b9db0901..02c41898eb9cf 100644 --- a/src/librustc_traits/chalk/mod.rs +++ b/src/librustc_traits/chalk/mod.rs @@ -109,9 +109,11 @@ crate fn evaluate_goal<'tcx>( let kind = match _data { TyData::Apply(_application_ty) => match _application_ty.name { chalk_ir::TypeName::Struct(_struct_id) => match _struct_id.0 { + RustDefId::Adt(_) => unimplemented!(), + RustDefId::Never => unimplemented!(), RustDefId::Array => unimplemented!(), - RustDefId::Slice => unimplemented!(), - _ => unimplemented!(), + RustDefId::FnDef(_) => unimplemented!(), + _ => panic!("Unexpected struct id"), }, chalk_ir::TypeName::Scalar(scalar) => match scalar { chalk_ir::Scalar::Bool => ty::Bool, @@ -138,6 +140,10 @@ crate fn evaluate_goal<'tcx>( }, }, chalk_ir::TypeName::Tuple(_size) => unimplemented!(), + chalk_ir::TypeName::Slice => unimplemented!(), + chalk_ir::TypeName::Raw(_) => unimplemented!(), + chalk_ir::TypeName::Ref(_) => unimplemented!(), + chalk_ir::TypeName::Str => unimplemented!(), chalk_ir::TypeName::OpaqueType(_ty) => unimplemented!(), chalk_ir::TypeName::AssociatedType(_assoc_ty) => unimplemented!(), chalk_ir::TypeName::Error => unimplemented!(), From 6ba003ef0488b9768267d962b695626c4ada11dd Mon Sep 17 00:00:00 2001 From: Jack Huey Date: Tue, 26 May 2020 20:19:19 -0400 Subject: [PATCH 05/35] Update chalk --- Cargo.lock | 71 ++++------- src/librustc_data_structures/Cargo.toml | 2 +- src/librustc_middle/Cargo.toml | 2 +- src/librustc_middle/traits/chalk.rs | 67 ++++++---- src/librustc_traits/Cargo.toml | 5 +- src/librustc_traits/chalk/db.rs | 161 ++++++++++++++---------- src/librustc_traits/chalk/lowering.rs | 58 ++++----- src/librustc_traits/chalk/mod.rs | 46 +++---- 8 files changed, 219 insertions(+), 193 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ae7dbeb3ab88d..f7407a5c703f1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -426,10 +426,18 @@ dependencies = [ "rustc-std-workspace-core", ] +[[package]] +name = "chalk-base" +version = "0.10.1-dev" +source = "git+https://github.com/rust-lang/chalk.git?rev=f4977ab4c781e4f3b7fdb9310edbdab6daf56e29#f4977ab4c781e4f3b7fdb9310edbdab6daf56e29" +dependencies = [ + "lazy_static 1.4.0", +] + [[package]] name = "chalk-derive" version = "0.10.1-dev" -source = "git+https://github.com/rust-lang/chalk.git?rev=3e9c2503ae9c5277c2acb74624dc267876dd89b3#3e9c2503ae9c5277c2acb74624dc267876dd89b3" +source = "git+https://github.com/rust-lang/chalk.git?rev=f4977ab4c781e4f3b7fdb9310edbdab6daf56e29#f4977ab4c781e4f3b7fdb9310edbdab6daf56e29" dependencies = [ "proc-macro2 1.0.3", "quote 1.0.2", @@ -440,52 +448,33 @@ dependencies = [ [[package]] name = "chalk-engine" version = "0.10.1-dev" -source = "git+https://github.com/rust-lang/chalk.git?rev=3e9c2503ae9c5277c2acb74624dc267876dd89b3#3e9c2503ae9c5277c2acb74624dc267876dd89b3" +source = "git+https://github.com/rust-lang/chalk.git?rev=f4977ab4c781e4f3b7fdb9310edbdab6daf56e29#f4977ab4c781e4f3b7fdb9310edbdab6daf56e29" dependencies = [ - "chalk-macros", + "chalk-base", + "chalk-derive", + "chalk-ir", "rustc-hash", ] [[package]] name = "chalk-ir" version = "0.10.1-dev" -source = "git+https://github.com/rust-lang/chalk.git?rev=3e9c2503ae9c5277c2acb74624dc267876dd89b3#3e9c2503ae9c5277c2acb74624dc267876dd89b3" -dependencies = [ - "chalk-derive", - "chalk-engine", - "chalk-macros", -] - -[[package]] -name = "chalk-macros" -version = "0.10.1-dev" -source = "git+https://github.com/rust-lang/chalk.git?rev=3e9c2503ae9c5277c2acb74624dc267876dd89b3#3e9c2503ae9c5277c2acb74624dc267876dd89b3" -dependencies = [ - "lazy_static", -] - -[[package]] -name = "chalk-rust-ir" -version = "0.10.1-dev" -source = "git+https://github.com/rust-lang/chalk.git?rev=3e9c2503ae9c5277c2acb74624dc267876dd89b3#3e9c2503ae9c5277c2acb74624dc267876dd89b3" +source = "git+https://github.com/rust-lang/chalk.git?rev=f4977ab4c781e4f3b7fdb9310edbdab6daf56e29#f4977ab4c781e4f3b7fdb9310edbdab6daf56e29" dependencies = [ + "chalk-base", "chalk-derive", - "chalk-engine", - "chalk-ir", - "chalk-macros", ] [[package]] name = "chalk-solve" version = "0.10.1-dev" -source = "git+https://github.com/rust-lang/chalk.git?rev=3e9c2503ae9c5277c2acb74624dc267876dd89b3#3e9c2503ae9c5277c2acb74624dc267876dd89b3" +source = "git+https://github.com/rust-lang/chalk.git?rev=f4977ab4c781e4f3b7fdb9310edbdab6daf56e29#f4977ab4c781e4f3b7fdb9310edbdab6daf56e29" dependencies = [ + "chalk-base", "chalk-derive", "chalk-engine", "chalk-ir", - "chalk-macros", - "chalk-rust-ir", - "ena 0.13.1", + "ena 0.14.0", "itertools 0.9.0", "petgraph", "rustc-hash", @@ -1169,9 +1158,9 @@ dependencies = [ [[package]] name = "fixedbitset" -version = "0.1.9" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86d4de0081402f5e88cdac65c8dcdcc73118c1a7a465e2a05f0da05843a8ea33" +checksum = "37ab347416e802de484e4d03c7316c48f1ecb56574dfd4a46a80f173ce1de04d" [[package]] name = "flate2" @@ -2358,12 +2347,6 @@ dependencies = [ "vcpkg", ] -[[package]] -name = "ordermap" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a86ed3f5f244b372d6b1a00b72ef7f8876d0bc6a78a4c9985c53614041512063" - [[package]] name = "ordslice" version = "0.3.0" @@ -2534,12 +2517,12 @@ dependencies = [ [[package]] name = "petgraph" -version = "0.4.13" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c3659d1ee90221741f65dd128d9998311b0e40c5d3c23a62445938214abce4f" +checksum = "467d164a6de56270bd7c4d070df81d07beace25012d5103ced4e9ff08d6afdb7" dependencies = [ "fixedbitset", - "ordermap", + "indexmap", ] [[package]] @@ -3487,12 +3470,9 @@ dependencies = [ [[package]] name = "rustc-hash" -version = "1.0.1" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7540fc8b0c49f096ee9c961cda096467dce8084bec6bdca2fc83895fd9b28cb8" -dependencies = [ - "byteorder", -] +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" [[package]] name = "rustc-main" @@ -4361,7 +4341,6 @@ name = "rustc_traits" version = "0.0.0" dependencies = [ "chalk-ir", - "chalk-rust-ir", "chalk-solve", "log", "rustc_ast", diff --git a/src/librustc_data_structures/Cargo.toml b/src/librustc_data_structures/Cargo.toml index bf2ab0787cb70..1c2fb90b2d8b4 100644 --- a/src/librustc_data_structures/Cargo.toml +++ b/src/librustc_data_structures/Cargo.toml @@ -23,7 +23,7 @@ crossbeam-utils = { version = "0.7", features = ["nightly"] } stable_deref_trait = "1.0.0" rayon = { version = "0.3.0", package = "rustc-rayon" } rayon-core = { version = "0.3.0", package = "rustc-rayon-core" } -rustc-hash = "1.0.1" +rustc-hash = "1.1.0" smallvec = { version = "1.0", features = ["union", "may_dangle"] } rustc_index = { path = "../librustc_index", package = "rustc_index" } bitflags = "1.2.1" diff --git a/src/librustc_middle/Cargo.toml b/src/librustc_middle/Cargo.toml index 6570fe67b3b0e..8e809e338ea1c 100644 --- a/src/librustc_middle/Cargo.toml +++ b/src/librustc_middle/Cargo.toml @@ -30,7 +30,7 @@ rustc_serialize = { path = "../librustc_serialize" } rustc_ast = { path = "../librustc_ast" } rustc_span = { path = "../librustc_span" } byteorder = { version = "1.3" } -chalk-ir = { git = "https://github.com/rust-lang/chalk.git", rev = "3e9c2503ae9c5277c2acb74624dc267876dd89b3" } +chalk-ir = { git = "https://github.com/rust-lang/chalk.git", rev = "f4977ab4c781e4f3b7fdb9310edbdab6daf56e29" } #chalk-ir = "0.10.0" smallvec = { version = "1.0", features = ["union", "may_dangle"] } measureme = "0.7.1" diff --git a/src/librustc_middle/traits/chalk.rs b/src/librustc_middle/traits/chalk.rs index 2bd22ee800444..a97b6a3ea3625 100644 --- a/src/librustc_middle/traits/chalk.rs +++ b/src/librustc_middle/traits/chalk.rs @@ -5,8 +5,6 @@ //! its name suggest, is to provide an abstraction boundary for creating //! interned Chalk types. -use chalk_ir::{GoalData, Parameter}; - use rustc_middle::ty::fold::{TypeFoldable, TypeFolder, TypeVisitor}; use rustc_middle::ty::{self, Ty, TyCtxt}; @@ -79,16 +77,19 @@ impl fmt::Debug for RustInterner<'_> { impl<'tcx> chalk_ir::interner::Interner for RustInterner<'tcx> { type InternedType = Box>; type InternedLifetime = Box>; - type InternedParameter = Box>; + type InternedConst = Box>; + type InternedConcreteConst = u32; + type InternedGenericArg = Box>; type InternedGoal = Box>; type InternedGoals = Vec>; - type InternedSubstitution = Vec>; + type InternedSubstitution = Vec>; type InternedProgramClause = Box>; type InternedProgramClauses = Vec>; type InternedQuantifiedWhereClauses = Vec>; - type InternedParameterKinds = Vec>; - type InternedCanonicalVarKinds = Vec>; + type InternedVariableKinds = Vec>; + type InternedCanonicalVarKinds = Vec>; type DefId = RustDefId; + type InternedAdtId = RustDefId; type Identifier = (); fn debug_program_clause_implication( @@ -202,25 +203,39 @@ impl<'tcx> chalk_ir::interner::Interner for RustInterner<'tcx> { &lifetime } - fn intern_parameter( + fn intern_const(&self, constant: chalk_ir::ConstData) -> Self::InternedConst { + Box::new(constant) + } + + fn const_data<'a>(&self, constant: &'a Self::InternedConst) -> &'a chalk_ir::ConstData { + &constant + } + + fn const_eq( &self, - parameter: chalk_ir::ParameterData, - ) -> Self::InternedParameter { - Box::new(parameter) + _ty: &Self::InternedType, + c1: &Self::InternedConcreteConst, + c2: &Self::InternedConcreteConst, + ) -> bool { + c1 == c2 + } + + fn intern_generic_arg(&self, data: chalk_ir::GenericArgData) -> Self::InternedGenericArg { + Box::new(data) } - fn parameter_data<'a>( + fn generic_arg_data<'a>( &self, - parameter: &'a Self::InternedParameter, - ) -> &'a chalk_ir::ParameterData { - ¶meter + data: &'a Self::InternedGenericArg, + ) -> &'a chalk_ir::GenericArgData { + &data } - fn intern_goal(&self, goal: GoalData) -> Self::InternedGoal { + fn intern_goal(&self, goal: chalk_ir::GoalData) -> Self::InternedGoal { Box::new(goal) } - fn goal_data<'a>(&self, goal: &'a Self::InternedGoal) -> &'a GoalData { + fn goal_data<'a>(&self, goal: &'a Self::InternedGoal) -> &'a chalk_ir::GoalData { &goal } @@ -237,7 +252,7 @@ impl<'tcx> chalk_ir::interner::Interner for RustInterner<'tcx> { fn intern_substitution( &self, - data: impl IntoIterator, E>>, + data: impl IntoIterator, E>>, ) -> Result { data.into_iter().collect::, _>>() } @@ -245,7 +260,7 @@ impl<'tcx> chalk_ir::interner::Interner for RustInterner<'tcx> { fn substitution_data<'a>( &self, substitution: &'a Self::InternedSubstitution, - ) -> &'a [Parameter] { + ) -> &'a [chalk_ir::GenericArg] { substitution } @@ -291,23 +306,23 @@ impl<'tcx> chalk_ir::interner::Interner for RustInterner<'tcx> { clauses } - fn intern_parameter_kinds( + fn intern_generic_arg_kinds( &self, - data: impl IntoIterator, E>>, - ) -> Result { + data: impl IntoIterator, E>>, + ) -> Result { data.into_iter().collect::, _>>() } - fn parameter_kinds_data<'a>( + fn variable_kinds_data<'a>( &self, - parameter_kinds: &'a Self::InternedParameterKinds, - ) -> &'a [chalk_ir::ParameterKind<()>] { + parameter_kinds: &'a Self::InternedVariableKinds, + ) -> &'a [chalk_ir::VariableKind] { parameter_kinds } fn intern_canonical_var_kinds( &self, - data: impl IntoIterator, E>>, + data: impl IntoIterator, E>>, ) -> Result { data.into_iter().collect::, _>>() } @@ -315,7 +330,7 @@ impl<'tcx> chalk_ir::interner::Interner for RustInterner<'tcx> { fn canonical_var_kinds_data<'a>( &self, canonical_var_kinds: &'a Self::InternedCanonicalVarKinds, - ) -> &'a [chalk_ir::ParameterKind] { + ) -> &'a [chalk_ir::CanonicalVarKind] { canonical_var_kinds } } diff --git a/src/librustc_traits/Cargo.toml b/src/librustc_traits/Cargo.toml index f429ab7cd0964..c85cd1765ab43 100644 --- a/src/librustc_traits/Cargo.toml +++ b/src/librustc_traits/Cargo.toml @@ -19,9 +19,8 @@ rustc_span = { path = "../librustc_span" } #chalk-ir = "0.10.0" #chalk-rust-ir = "0.10.0" #chalk-solve = "0.10.0" -chalk-solve = { git = "https://github.com/rust-lang/chalk.git", rev = "3e9c2503ae9c5277c2acb74624dc267876dd89b3" } -chalk-rust-ir = { git = "https://github.com/rust-lang/chalk.git", rev = "3e9c2503ae9c5277c2acb74624dc267876dd89b3" } -chalk-ir = { git = "https://github.com/rust-lang/chalk.git", rev = "3e9c2503ae9c5277c2acb74624dc267876dd89b3" } +chalk-solve = { git = "https://github.com/rust-lang/chalk.git", rev = "f4977ab4c781e4f3b7fdb9310edbdab6daf56e29" } +chalk-ir = { git = "https://github.com/rust-lang/chalk.git", rev = "f4977ab4c781e4f3b7fdb9310edbdab6daf56e29" } smallvec = { version = "1.0", features = ["union", "may_dangle"] } rustc_infer = { path = "../librustc_infer" } rustc_trait_selection = { path = "../librustc_trait_selection" } diff --git a/src/librustc_traits/chalk/db.rs b/src/librustc_traits/chalk/db.rs index 4320436f1e33c..15125c33f1f53 100644 --- a/src/librustc_traits/chalk/db.rs +++ b/src/librustc_traits/chalk/db.rs @@ -38,7 +38,7 @@ impl<'tcx> chalk_solve::RustIrDatabase> for RustIrDatabase<'t fn associated_ty_data( &self, assoc_type_id: chalk_ir::AssocTypeId>, - ) -> Arc>> { + ) -> Arc>> { let def_id = match assoc_type_id.0 { RustDefId::AssocTy(def_id) => def_id, _ => bug!("Did not use `AssocTy` variant when expecting associated type."), @@ -63,13 +63,13 @@ impl<'tcx> chalk_solve::RustIrDatabase> for RustIrDatabase<'t .map(|(wc, _)| wc.subst(self.tcx, &bound_vars)) .filter_map(|wc| LowerInto::>>>::lower_into(wc, &self.interner)).collect(); - Arc::new(chalk_rust_ir::AssociatedTyDatum { + Arc::new(chalk_solve::rust_ir::AssociatedTyDatum { trait_id: chalk_ir::TraitId(RustDefId::Trait(trait_def_id)), id: assoc_type_id, name: (), binders: chalk_ir::Binders::new( binders, - chalk_rust_ir::AssociatedTyDatumBound { bounds: vec![], where_clauses }, + chalk_solve::rust_ir::AssociatedTyDatumBound { bounds: vec![], where_clauses }, ), }) } @@ -77,7 +77,7 @@ impl<'tcx> chalk_solve::RustIrDatabase> for RustIrDatabase<'t fn trait_datum( &self, trait_id: chalk_ir::TraitId>, - ) -> Arc>> { + ) -> Arc>> { let def_id = match trait_id.0 { RustDefId::Trait(def_id) => def_id, _ => bug!("Did not use `Trait` variant when expecting trait."), @@ -94,21 +94,21 @@ impl<'tcx> chalk_solve::RustIrDatabase> for RustIrDatabase<'t let well_known = if self.tcx.lang_items().sized_trait().map(|t| def_id == t).unwrap_or(false) { - Some(chalk_rust_ir::WellKnownTrait::SizedTrait) + Some(chalk_solve::rust_ir::WellKnownTrait::SizedTrait) } else if self.tcx.lang_items().copy_trait().map(|t| def_id == t).unwrap_or(false) { - Some(chalk_rust_ir::WellKnownTrait::CopyTrait) + Some(chalk_solve::rust_ir::WellKnownTrait::CopyTrait) } else if self.tcx.lang_items().clone_trait().map(|t| def_id == t).unwrap_or(false) { - Some(chalk_rust_ir::WellKnownTrait::CloneTrait) + Some(chalk_solve::rust_ir::WellKnownTrait::CloneTrait) } else { None }; - Arc::new(chalk_rust_ir::TraitDatum { + Arc::new(chalk_solve::rust_ir::TraitDatum { id: trait_id, binders: chalk_ir::Binders::new( binders, - chalk_rust_ir::TraitDatumBound { where_clauses }, + chalk_solve::rust_ir::TraitDatumBound { where_clauses }, ), - flags: chalk_rust_ir::TraitFlags { + flags: chalk_solve::rust_ir::TraitFlags { auto: trait_def.has_auto_impl, marker: trait_def.is_marker, upstream: !def_id.is_local(), @@ -121,10 +121,10 @@ impl<'tcx> chalk_solve::RustIrDatabase> for RustIrDatabase<'t }) } - fn struct_datum( + fn adt_datum( &self, - struct_id: chalk_ir::StructId>, - ) -> Arc>> { + struct_id: chalk_ir::AdtId>, + ) -> Arc>> { match struct_id.0 { RustDefId::Adt(adt_def_id) => { let adt_def = self.tcx.adt_def(adt_def_id); @@ -155,47 +155,64 @@ impl<'tcx> chalk_solve::RustIrDatabase> for RustIrDatabase<'t // FIXME(chalk): handle enums; force_impl_for requires this ty::AdtKind::Enum => vec![], }; - let struct_datum = Arc::new(chalk_rust_ir::StructDatum { + let struct_datum = Arc::new(chalk_solve::rust_ir::AdtDatum { id: struct_id, binders: chalk_ir::Binders::new( binders, - chalk_rust_ir::StructDatumBound { fields, where_clauses }, + chalk_solve::rust_ir::AdtDatumBound { fields, where_clauses }, ), - flags: chalk_rust_ir::StructFlags { + flags: chalk_solve::rust_ir::AdtFlags { upstream: !adt_def_id.is_local(), fundamental: adt_def.is_fundamental(), }, }); struct_datum } - RustDefId::Array => Arc::new(chalk_rust_ir::StructDatum { - id: struct_id, - binders: chalk_ir::Binders::new( - chalk_ir::ParameterKinds::from( - &self.interner, - Some(chalk_ir::ParameterKind::Ty(())), + RustDefId::Array => { + return Arc::new(chalk_solve::rust_ir::AdtDatum { + id: struct_id, + binders: chalk_ir::Binders::new( + chalk_ir::VariableKinds::from( + &self.interner, + Some(chalk_ir::VariableKind::Ty(chalk_ir::TyKind::General)), + ), + chalk_solve::rust_ir::AdtDatumBound { + fields: vec![], + where_clauses: vec![], + }, + ), + flags: chalk_solve::rust_ir::AdtFlags { upstream: false, fundamental: false }, + }); + } + RustDefId::Never | RustDefId::FnDef(_) => { + return Arc::new(chalk_solve::rust_ir::AdtDatum { + id: struct_id, + binders: chalk_ir::Binders::new( + chalk_ir::VariableKinds::new(&self.interner), + chalk_solve::rust_ir::AdtDatumBound { + fields: vec![], + where_clauses: vec![], + }, ), - chalk_rust_ir::StructDatumBound { fields: vec![], where_clauses: vec![] }, - ), - flags: chalk_rust_ir::StructFlags { upstream: false, fundamental: false }, - }), - RustDefId::Never | RustDefId::FnDef(_) => Arc::new(chalk_rust_ir::StructDatum { - id: struct_id, - binders: chalk_ir::Binders::new( - chalk_ir::ParameterKinds::new(&self.interner), - chalk_rust_ir::StructDatumBound { fields: vec![], where_clauses: vec![] }, - ), - flags: chalk_rust_ir::StructFlags { upstream: false, fundamental: false }, - }), + flags: chalk_solve::rust_ir::AdtFlags { upstream: false, fundamental: false }, + }); + } v => bug!("Used not struct variant ({:?}) when expecting struct variant.", v), } } + fn fn_def_datum( + &self, + _fn_def_id: chalk_ir::FnDefId>, + ) -> Arc>> { + unimplemented!() + } + fn impl_datum( &self, impl_id: chalk_ir::ImplId>, - ) -> Arc>> { + ) -> Arc>> { let def_id = match impl_id.0 { RustDefId::Impl(def_id) => def_id, _ => bug!("Did not use `Impl` variant when expecting impl."), @@ -212,15 +229,15 @@ impl<'tcx> chalk_solve::RustIrDatabase> for RustIrDatabase<'t .map(|(wc, _)| wc.subst(self.tcx, bound_vars)) .filter_map(|wc| LowerInto::>>>::lower_into(wc, &self.interner)).collect(); - let value = chalk_rust_ir::ImplDatumBound { + let value = chalk_solve::rust_ir::ImplDatumBound { trait_ref: trait_ref.lower_into(&self.interner), where_clauses, }; - Arc::new(chalk_rust_ir::ImplDatum { - polarity: chalk_rust_ir::Polarity::Positive, + Arc::new(chalk_solve::rust_ir::ImplDatum { + polarity: chalk_solve::rust_ir::Polarity::Positive, binders: chalk_ir::Binders::new(binders, value), - impl_type: chalk_rust_ir::ImplType::Local, + impl_type: chalk_solve::rust_ir::ImplType::Local, associated_ty_value_ids: vec![], }) } @@ -228,7 +245,7 @@ impl<'tcx> chalk_solve::RustIrDatabase> for RustIrDatabase<'t fn impls_for_trait( &self, trait_id: chalk_ir::TraitId>, - parameters: &[chalk_ir::Parameter>], + parameters: &[chalk_ir::GenericArg>], ) -> Vec>> { let def_id: DefId = match trait_id.0 { RustDefId::Trait(def_id) => def_id, @@ -261,7 +278,7 @@ impl<'tcx> chalk_solve::RustIrDatabase> for RustIrDatabase<'t fn impl_provided_for( &self, auto_trait_id: chalk_ir::TraitId>, - struct_id: chalk_ir::StructId>, + struct_id: chalk_ir::AdtId>, ) -> bool { let trait_def_id: DefId = match auto_trait_id.0 { RustDefId::Trait(def_id) => def_id, @@ -296,8 +313,8 @@ impl<'tcx> chalk_solve::RustIrDatabase> for RustIrDatabase<'t fn associated_ty_value( &self, - associated_ty_id: chalk_rust_ir::AssociatedTyValueId>, - ) -> Arc>> { + associated_ty_id: chalk_solve::rust_ir::AssociatedTyValueId>, + ) -> Arc>> { let def_id = match associated_ty_id.0 { RustDefId::AssocTy(def_id) => def_id, _ => bug!("Did not use `AssocTy` variant when expecting associated type."), @@ -315,12 +332,12 @@ impl<'tcx> chalk_solve::RustIrDatabase> for RustIrDatabase<'t let binders = binders_for(&self.interner, bound_vars); let ty = self.tcx.type_of(def_id); - Arc::new(chalk_rust_ir::AssociatedTyValue { + Arc::new(chalk_solve::rust_ir::AssociatedTyValue { impl_id: chalk_ir::ImplId(RustDefId::Impl(impl_id)), associated_ty_id: chalk_ir::AssocTypeId(RustDefId::AssocTy(def_id)), value: chalk_ir::Binders::new( binders, - chalk_rust_ir::AssociatedTyValueBound { ty: ty.lower_into(&self.interner) }, + chalk_solve::rust_ir::AssociatedTyValueBound { ty: ty.lower_into(&self.interner) }, ), }) } @@ -339,17 +356,17 @@ impl<'tcx> chalk_solve::RustIrDatabase> for RustIrDatabase<'t fn opaque_ty_data( &self, opaque_ty_id: chalk_ir::OpaqueTyId>, - ) -> Arc>> { + ) -> Arc>> { // FIXME(chalk): actually lower opaque ty let hidden_ty = self.tcx.mk_ty(ty::Tuple(self.tcx.intern_substs(&[]))).lower_into(&self.interner); - let value = chalk_rust_ir::OpaqueTyDatumBound { + let value = chalk_solve::rust_ir::OpaqueTyDatumBound { hidden_ty, - bounds: chalk_ir::Binders::new(chalk_ir::ParameterKinds::new(&self.interner), vec![]), + bounds: chalk_ir::Binders::new(chalk_ir::VariableKinds::new(&self.interner), vec![]), }; - Arc::new(chalk_rust_ir::OpaqueTyDatum { + Arc::new(chalk_solve::rust_ir::OpaqueTyDatum { opaque_ty_id, - bound: chalk_ir::Binders::new(chalk_ir::ParameterKinds::new(&self.interner), value), + bound: chalk_ir::Binders::new(chalk_ir::VariableKinds::new(&self.interner), value), }) } @@ -358,14 +375,14 @@ impl<'tcx> chalk_solve::RustIrDatabase> for RustIrDatabase<'t /// `None` and eventually this function will be removed. fn force_impl_for( &self, - well_known: chalk_rust_ir::WellKnownTrait, + well_known: chalk_solve::rust_ir::WellKnownTrait, ty: &chalk_ir::TyData>, ) -> Option { use chalk_ir::TyData::*; match well_known { - chalk_rust_ir::WellKnownTrait::SizedTrait => match ty { + chalk_solve::rust_ir::WellKnownTrait::SizedTrait => match ty { Apply(apply) => match apply.name { - chalk_ir::TypeName::Struct(chalk_ir::StructId(rust_def_id)) => { + chalk_ir::TypeName::Adt(chalk_ir::AdtId(rust_def_id)) => { use rustc_middle::traits::ChalkRustDefId::*; match rust_def_id { Never | Array | FnDef(_) => Some(true), @@ -390,13 +407,17 @@ impl<'tcx> chalk_solve::RustIrDatabase> for RustIrDatabase<'t } _ => None, }, - Dyn(_) | Alias(_) | Placeholder(_) | Function(_) | InferenceVar(_) + Dyn(_) + | Alias(_) + | Placeholder(_) + | Function(_) + | InferenceVar(_, _) | BoundVar(_) => None, }, - chalk_rust_ir::WellKnownTrait::CopyTrait - | chalk_rust_ir::WellKnownTrait::CloneTrait => match ty { + chalk_solve::rust_ir::WellKnownTrait::CopyTrait + | chalk_solve::rust_ir::WellKnownTrait::CloneTrait => match ty { Apply(apply) => match apply.name { - chalk_ir::TypeName::Struct(chalk_ir::StructId(rust_def_id)) => { + chalk_ir::TypeName::Adt(chalk_ir::AdtId(rust_def_id)) => { use rustc_middle::traits::ChalkRustDefId::*; match rust_def_id { Never => Some(false), @@ -420,10 +441,14 @@ impl<'tcx> chalk_solve::RustIrDatabase> for RustIrDatabase<'t } _ => None, }, - Dyn(_) | Alias(_) | Placeholder(_) | Function(_) | InferenceVar(_) + Dyn(_) + | Alias(_) + | Placeholder(_) + | Function(_) + | InferenceVar(_, _) | BoundVar(_) => None, }, - chalk_rust_ir::WellKnownTrait::DropTrait => None, + chalk_solve::rust_ir::WellKnownTrait::DropTrait => None, } } @@ -436,9 +461,9 @@ impl<'tcx> chalk_solve::RustIrDatabase> for RustIrDatabase<'t fn well_known_trait_id( &self, - well_known_trait: chalk_rust_ir::WellKnownTrait, + well_known_trait: chalk_solve::rust_ir::WellKnownTrait, ) -> Option>> { - use chalk_rust_ir::WellKnownTrait::*; + use chalk_solve::rust_ir::WellKnownTrait::*; let t = match well_known_trait { SizedTrait => self .tcx @@ -512,13 +537,17 @@ fn bound_vars_for_item(tcx: TyCtxt<'tcx>, def_id: DefId) -> SubstsRef<'tcx> { fn binders_for<'tcx>( interner: &RustInterner<'tcx>, bound_vars: SubstsRef<'tcx>, -) -> chalk_ir::ParameterKinds> { - chalk_ir::ParameterKinds::from( +) -> chalk_ir::VariableKinds> { + chalk_ir::VariableKinds::from( interner, bound_vars.iter().map(|arg| match arg.unpack() { - ty::subst::GenericArgKind::Lifetime(_re) => chalk_ir::ParameterKind::Lifetime(()), - ty::subst::GenericArgKind::Type(_ty) => chalk_ir::ParameterKind::Ty(()), - ty::subst::GenericArgKind::Const(_const) => chalk_ir::ParameterKind::Ty(()), + ty::subst::GenericArgKind::Lifetime(_re) => chalk_ir::VariableKind::Lifetime, + ty::subst::GenericArgKind::Type(_ty) => { + chalk_ir::VariableKind::Ty(chalk_ir::TyKind::General) + } + ty::subst::GenericArgKind::Const(_const) => { + chalk_ir::VariableKind::Ty(chalk_ir::TyKind::General) + } }), ) } diff --git a/src/librustc_traits/chalk/lowering.rs b/src/librustc_traits/chalk/lowering.rs index a293b10fe5b6d..873ce76d4faa6 100644 --- a/src/librustc_traits/chalk/lowering.rs +++ b/src/librustc_traits/chalk/lowering.rs @@ -274,7 +274,7 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::Ty>> for Ty<'tcx> { use TyKind::*; let empty = || chalk_ir::Substitution::empty(interner); - let struct_ty = |def_id| chalk_ir::TypeName::Struct(chalk_ir::StructId(def_id)); + let struct_ty = |def_id| chalk_ir::TypeName::Adt(chalk_ir::AdtId(def_id)); let apply = |name, substitution| { TyData::Apply(chalk_ir::ApplicationTy { name, substitution }).intern(interner) }; @@ -314,14 +314,14 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::Ty>> for Ty<'tcx> { struct_ty(RustDefId::Array), chalk_ir::Substitution::from1( interner, - chalk_ir::ParameterKind::Ty(ty.lower_into(interner)).intern(interner), + chalk_ir::GenericArgData::Ty(ty.lower_into(interner)).intern(interner), ), ), Slice(ty) => apply( chalk_ir::TypeName::Slice, chalk_ir::Substitution::from1( interner, - chalk_ir::ParameterKind::Ty(ty.lower_into(interner)).intern(interner), + chalk_ir::GenericArgData::Ty(ty.lower_into(interner)).intern(interner), ), ), RawPtr(ptr) => { @@ -341,9 +341,9 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::Ty>> for Ty<'tcx> { chalk_ir::Substitution::from( interner, &[ - chalk_ir::ParameterKind::Lifetime(region.lower_into(interner)) + chalk_ir::GenericArgData::Lifetime(region.lower_into(interner)) .intern(interner), - chalk_ir::ParameterKind::Ty(ty.lower_into(interner)).intern(interner), + chalk_ir::GenericArgData::Ty(ty.lower_into(interner)).intern(interner), ], ), ) @@ -357,7 +357,7 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::Ty>> for Ty<'tcx> { substitution: chalk_ir::Substitution::from( interner, inputs_and_outputs.iter().map(|ty| { - chalk_ir::ParameterKind::Ty(ty.lower_into(interner)).intern(interner) + chalk_ir::GenericArgData::Ty(ty.lower_into(interner)).intern(interner) }), ), }) @@ -439,16 +439,16 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::Lifetime>> for Region<'t } } -impl<'tcx> LowerInto<'tcx, chalk_ir::Parameter>> for GenericArg<'tcx> { - fn lower_into(self, interner: &RustInterner<'tcx>) -> chalk_ir::Parameter> { +impl<'tcx> LowerInto<'tcx, chalk_ir::GenericArg>> for GenericArg<'tcx> { + fn lower_into(self, interner: &RustInterner<'tcx>) -> chalk_ir::GenericArg> { match self.unpack() { ty::subst::GenericArgKind::Type(ty) => { - chalk_ir::ParameterKind::Ty(ty.lower_into(interner)) + chalk_ir::GenericArgData::Ty(ty.lower_into(interner)) } ty::subst::GenericArgKind::Lifetime(lifetime) => { - chalk_ir::ParameterKind::Lifetime(lifetime.lower_into(interner)) + chalk_ir::GenericArgData::Lifetime(lifetime.lower_into(interner)) } - ty::subst::GenericArgKind::Const(_) => chalk_ir::ParameterKind::Ty( + ty::subst::GenericArgKind::Const(_) => chalk_ir::GenericArgData::Ty( chalk_ir::TyData::Apply(chalk_ir::ApplicationTy { name: chalk_ir::TypeName::Tuple(0), substitution: chalk_ir::Substitution::empty(interner), @@ -507,7 +507,7 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::Binders { chalk_ir::Binders::new( - chalk_ir::ParameterKinds::new(interner), + chalk_ir::VariableKinds::new(interner), chalk_ir::WhereClause::Implemented(chalk_ir::TraitRef { trait_id: chalk_ir::TraitId(RustDefId::Trait(*def_id)), substitution: substs.lower_into(interner), @@ -516,7 +516,7 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::Binders unimplemented!(), ty::ExistentialPredicate::AutoTrait(def_id) => chalk_ir::Binders::new( - chalk_ir::ParameterKinds::new(interner), + chalk_ir::VariableKinds::new(interner), chalk_ir::WhereClause::Implemented(chalk_ir::TraitRef { trait_id: chalk_ir::TraitId(RustDefId::Trait(*def_id)), substitution: chalk_ir::Substitution::empty(interner), @@ -541,7 +541,7 @@ crate fn collect_bound_vars<'a, 'tcx, T: TypeFoldable<'tcx>>( interner: &RustInterner<'tcx>, tcx: TyCtxt<'tcx>, ty: &'a Binder, -) -> (T, chalk_ir::ParameterKinds>, BTreeMap) { +) -> (T, chalk_ir::VariableKinds>, BTreeMap) { let mut bound_vars_collector = BoundVarsCollector::new(); ty.skip_binder().visit_with(&mut bound_vars_collector); let mut parameters = bound_vars_collector.parameters; @@ -556,25 +556,25 @@ crate fn collect_bound_vars<'a, 'tcx, T: TypeFoldable<'tcx>>( let new_ty = ty.skip_binder().fold_with(&mut bound_var_substitutor); for var in named_parameters.values() { - parameters.insert(*var, chalk_ir::ParameterKind::Lifetime(())); + parameters.insert(*var, chalk_ir::VariableKind::Lifetime); } (0..parameters.len()).for_each(|i| { parameters.get(&(i as u32)).expect("Skipped bound var index."); }); - let binders = chalk_ir::ParameterKinds::from(interner, parameters.into_iter().map(|(_, v)| v)); + let binders = chalk_ir::VariableKinds::from(interner, parameters.into_iter().map(|(_, v)| v)); (new_ty, binders, named_parameters) } -crate struct BoundVarsCollector { +crate struct BoundVarsCollector<'tcx> { binder_index: ty::DebruijnIndex, - crate parameters: BTreeMap>, + crate parameters: BTreeMap>>, crate named_parameters: Vec, } -impl BoundVarsCollector { +impl<'tcx> BoundVarsCollector<'tcx> { crate fn new() -> Self { BoundVarsCollector { binder_index: ty::INNERMOST, @@ -584,7 +584,7 @@ impl BoundVarsCollector { } } -impl<'tcx> TypeVisitor<'tcx> for BoundVarsCollector { +impl<'tcx> TypeVisitor<'tcx> for BoundVarsCollector<'tcx> { fn visit_binder>(&mut self, t: &Binder) -> bool { self.binder_index.shift_in(1); let result = t.super_visit_with(self); @@ -597,11 +597,12 @@ impl<'tcx> TypeVisitor<'tcx> for BoundVarsCollector { ty::Bound(debruijn, bound_ty) if debruijn == self.binder_index => { match self.parameters.entry(bound_ty.var.as_u32()) { Entry::Vacant(entry) => { - entry.insert(chalk_ir::ParameterKind::Ty(())); - } - Entry::Occupied(entry) => { - entry.get().assert_ty_ref(); + entry.insert(chalk_ir::VariableKind::Ty(chalk_ir::TyKind::General)); } + Entry::Occupied(entry) => match entry.get() { + chalk_ir::VariableKind::Ty(_) => {} + _ => panic!(), + }, } } @@ -622,11 +623,12 @@ impl<'tcx> TypeVisitor<'tcx> for BoundVarsCollector { ty::BoundRegion::BrAnon(var) => match self.parameters.entry(*var) { Entry::Vacant(entry) => { - entry.insert(chalk_ir::ParameterKind::Lifetime(())); - } - Entry::Occupied(entry) => { - entry.get().assert_lifetime_ref(); + entry.insert(chalk_ir::VariableKind::Lifetime); } + Entry::Occupied(entry) => match entry.get() { + chalk_ir::VariableKind::Lifetime => {} + _ => panic!(), + }, }, ty::BrEnv => unimplemented!(), diff --git a/src/librustc_traits/chalk/mod.rs b/src/librustc_traits/chalk/mod.rs index 02c41898eb9cf..bfaa161f7aa76 100644 --- a/src/librustc_traits/chalk/mod.rs +++ b/src/librustc_traits/chalk/mod.rs @@ -55,25 +55,23 @@ crate fn evaluate_goal<'tcx>( CanonicalVarKind::PlaceholderTy(_ty) => unimplemented!(), CanonicalVarKind::PlaceholderRegion(_ui) => unimplemented!(), CanonicalVarKind::Ty(ty) => match ty { - CanonicalTyVarKind::General(ui) => { - chalk_ir::ParameterKind::Ty(chalk_ir::UniverseIndex { - counter: ui.index(), - }) - } - CanonicalTyVarKind::Int | CanonicalTyVarKind::Float => { - // FIXME(chalk) - this is actually really important - // These variable kinds put some limits on the - // types that can be substituted (floats or ints). - // While it's unclear exactly the design here, we - // probably want some way to "register" these. - chalk_ir::ParameterKind::Ty(chalk_ir::UniverseIndex::root()) - } + CanonicalTyVarKind::General(ui) => chalk_ir::WithKind::new( + chalk_ir::VariableKind::Ty(chalk_ir::TyKind::General), + chalk_ir::UniverseIndex { counter: ui.index() }, + ), + CanonicalTyVarKind::Int => chalk_ir::WithKind::new( + chalk_ir::VariableKind::Ty(chalk_ir::TyKind::Integer), + chalk_ir::UniverseIndex::root(), + ), + CanonicalTyVarKind::Float => chalk_ir::WithKind::new( + chalk_ir::VariableKind::Ty(chalk_ir::TyKind::Float), + chalk_ir::UniverseIndex::root(), + ), }, - CanonicalVarKind::Region(ui) => { - chalk_ir::ParameterKind::Lifetime(chalk_ir::UniverseIndex { - counter: ui.index(), - }) - } + CanonicalVarKind::Region(ui) => chalk_ir::WithKind::new( + chalk_ir::VariableKind::Lifetime, + chalk_ir::UniverseIndex { counter: ui.index() }, + ), CanonicalVarKind::Const(_ui) => unimplemented!(), CanonicalVarKind::PlaceholderConst(_pc) => unimplemented!(), }), @@ -101,14 +99,14 @@ crate fn evaluate_goal<'tcx>( // essentially inverse of lowering a `GenericArg`. let _data = p.data(&interner); match _data { - chalk_ir::ParameterKind::Ty(_t) => { + chalk_ir::GenericArgData::Ty(_t) => { use chalk_ir::TyData; use rustc_ast::ast; let _data = _t.data(&interner); let kind = match _data { TyData::Apply(_application_ty) => match _application_ty.name { - chalk_ir::TypeName::Struct(_struct_id) => match _struct_id.0 { + chalk_ir::TypeName::Adt(_struct_id) => match _struct_id.0 { RustDefId::Adt(_) => unimplemented!(), RustDefId::Never => unimplemented!(), RustDefId::Array => unimplemented!(), @@ -139,6 +137,9 @@ crate fn evaluate_goal<'tcx>( chalk_ir::FloatTy::F64 => ty::Float(ast::FloatTy::F64), }, }, + chalk_ir::TypeName::Array => unimplemented!(), + chalk_ir::TypeName::FnDef(_) => unimplemented!(), + chalk_ir::TypeName::Never => unimplemented!(), chalk_ir::TypeName::Tuple(_size) => unimplemented!(), chalk_ir::TypeName::Slice => unimplemented!(), chalk_ir::TypeName::Raw(_) => unimplemented!(), @@ -160,14 +161,14 @@ crate fn evaluate_goal<'tcx>( kind: ty::BoundTyKind::Anon, }, ), - TyData::InferenceVar(_) => unimplemented!(), + TyData::InferenceVar(_, _) => unimplemented!(), TyData::Dyn(_) => unimplemented!(), }; let _ty: Ty<'_> = tcx.mk_ty(kind); let _arg: GenericArg<'_> = _ty.into(); var_values.push(_arg); } - chalk_ir::ParameterKind::Lifetime(_l) => { + chalk_ir::GenericArgData::Lifetime(_l) => { let _data = _l.data(&interner); let _lifetime: Region<'_> = match _data { chalk_ir::LifetimeData::BoundVar(_var) => { @@ -185,6 +186,7 @@ crate fn evaluate_goal<'tcx>( let _arg: GenericArg<'_> = _lifetime.into(); var_values.push(_arg); } + chalk_ir::GenericArgData::Const(_) => unimplemented!(), } }); let sol = Canonical { From 3d730308d3db132fb6ac724c99c6a23a6e90bce8 Mon Sep 17 00:00:00 2001 From: Jack Huey Date: Tue, 26 May 2020 20:38:41 -0400 Subject: [PATCH 06/35] Use builtin types for Never, Array, and FnDef --- src/librustc_middle/traits/chalk.rs | 4 +-- src/librustc_traits/chalk/db.rs | 39 ++------------------------- src/librustc_traits/chalk/lowering.rs | 25 +++++++++++++---- src/librustc_traits/chalk/mod.rs | 3 --- 4 files changed, 23 insertions(+), 48 deletions(-) diff --git a/src/librustc_middle/traits/chalk.rs b/src/librustc_middle/traits/chalk.rs index a97b6a3ea3625..ec32bcf8a0b67 100644 --- a/src/librustc_middle/traits/chalk.rs +++ b/src/librustc_middle/traits/chalk.rs @@ -21,10 +21,8 @@ use std::hash::{Hash, Hasher}; #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] pub enum RustDefId { Adt(DefId), - Never, - Array, - FnDef(DefId), + FnDef(DefId), Trait(DefId), Impl(DefId), AssocTy(DefId), diff --git a/src/librustc_traits/chalk/db.rs b/src/librustc_traits/chalk/db.rs index 15125c33f1f53..367c598027934 100644 --- a/src/librustc_traits/chalk/db.rs +++ b/src/librustc_traits/chalk/db.rs @@ -168,35 +168,6 @@ impl<'tcx> chalk_solve::RustIrDatabase> for RustIrDatabase<'t }); struct_datum } - RustDefId::Array => { - return Arc::new(chalk_solve::rust_ir::AdtDatum { - id: struct_id, - binders: chalk_ir::Binders::new( - chalk_ir::VariableKinds::from( - &self.interner, - Some(chalk_ir::VariableKind::Ty(chalk_ir::TyKind::General)), - ), - chalk_solve::rust_ir::AdtDatumBound { - fields: vec![], - where_clauses: vec![], - }, - ), - flags: chalk_solve::rust_ir::AdtFlags { upstream: false, fundamental: false }, - }); - } - RustDefId::Never | RustDefId::FnDef(_) => { - return Arc::new(chalk_solve::rust_ir::AdtDatum { - id: struct_id, - binders: chalk_ir::Binders::new( - chalk_ir::VariableKinds::new(&self.interner), - chalk_solve::rust_ir::AdtDatumBound { - fields: vec![], - where_clauses: vec![], - }, - ), - flags: chalk_solve::rust_ir::AdtFlags { upstream: false, fundamental: false }, - }); - } v => bug!("Used not struct variant ({:?}) when expecting struct variant.", v), } @@ -287,8 +258,6 @@ impl<'tcx> chalk_solve::RustIrDatabase> for RustIrDatabase<'t // FIXME(chalk): this match can be removed when builtin types supported match struct_id.0 { RustDefId::Adt(_) => {} - RustDefId::Never => return false, - RustDefId::Array => return false, _ => bug!("Did not use `Adt` variant when expecting adt."), } let adt_def_id: DefId = match struct_id.0 { @@ -385,8 +354,6 @@ impl<'tcx> chalk_solve::RustIrDatabase> for RustIrDatabase<'t chalk_ir::TypeName::Adt(chalk_ir::AdtId(rust_def_id)) => { use rustc_middle::traits::ChalkRustDefId::*; match rust_def_id { - Never | Array | FnDef(_) => Some(true), - Adt(adt_def_id) => { let adt_def = self.tcx.adt_def(adt_def_id); match adt_def.adt_kind() { @@ -402,7 +369,7 @@ impl<'tcx> chalk_solve::RustIrDatabase> for RustIrDatabase<'t } } - Trait(_) | Impl(_) | AssocTy(_) | Opaque(_) => panic!(), + FnDef(_) | Trait(_) | Impl(_) | AssocTy(_) | Opaque(_) => panic!(), } } _ => None, @@ -420,8 +387,6 @@ impl<'tcx> chalk_solve::RustIrDatabase> for RustIrDatabase<'t chalk_ir::TypeName::Adt(chalk_ir::AdtId(rust_def_id)) => { use rustc_middle::traits::ChalkRustDefId::*; match rust_def_id { - Never => Some(false), - FnDef(_) | Array => Some(true), Adt(adt_def_id) => { let adt_def = self.tcx.adt_def(adt_def_id); match adt_def.adt_kind() { @@ -436,7 +401,7 @@ impl<'tcx> chalk_solve::RustIrDatabase> for RustIrDatabase<'t } } } - Trait(_) | Impl(_) | AssocTy(_) | Opaque(_) => panic!(), + FnDef(_) | Trait(_) | Impl(_) | AssocTy(_) | Opaque(_) => panic!(), } } _ => None, diff --git a/src/librustc_traits/chalk/lowering.rs b/src/librustc_traits/chalk/lowering.rs index 873ce76d4faa6..57ef6ec0a25aa 100644 --- a/src/librustc_traits/chalk/lowering.rs +++ b/src/librustc_traits/chalk/lowering.rs @@ -311,10 +311,22 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::Ty>> for Ty<'tcx> { Foreign(_def_id) => unimplemented!(), Str => apply(chalk_ir::TypeName::Str, empty()), Array(ty, _) => apply( - struct_ty(RustDefId::Array), - chalk_ir::Substitution::from1( + chalk_ir::TypeName::Array, + chalk_ir::Substitution::from( interner, - chalk_ir::GenericArgData::Ty(ty.lower_into(interner)).intern(interner), + &[ + chalk_ir::GenericArgData::Ty(ty.lower_into(interner)).intern(interner), + chalk_ir::GenericArgData::Const( + chalk_ir::ConstData { + ty: apply(chalk_ir::TypeName::Tuple(0), empty()), + value: chalk_ir::ConstValue::Concrete(chalk_ir::ConcreteConst { + interned: 0, + }), + } + .intern(interner), + ) + .intern(interner), + ], ), ), Slice(ty) => apply( @@ -348,7 +360,10 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::Ty>> for Ty<'tcx> { ), ) } - FnDef(def_id, _) => apply(struct_ty(RustDefId::FnDef(def_id)), empty()), + FnDef(def_id, _) => apply( + chalk_ir::TypeName::FnDef(chalk_ir::FnDefId(RustDefId::FnDef(def_id))), + empty(), + ), FnPtr(sig) => { let (inputs_and_outputs, binders, _named_regions) = collect_bound_vars(interner, interner.tcx, &sig.inputs_and_output()); @@ -371,7 +386,7 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::Ty>> for Ty<'tcx> { Closure(_def_id, _) => unimplemented!(), Generator(_def_id, _substs, _) => unimplemented!(), GeneratorWitness(_) => unimplemented!(), - Never => apply(struct_ty(RustDefId::Never), empty()), + Never => apply(chalk_ir::TypeName::Never, empty()), Tuple(substs) => { apply(chalk_ir::TypeName::Tuple(substs.len()), substs.lower_into(interner)) } diff --git a/src/librustc_traits/chalk/mod.rs b/src/librustc_traits/chalk/mod.rs index bfaa161f7aa76..f33ec3a9fb915 100644 --- a/src/librustc_traits/chalk/mod.rs +++ b/src/librustc_traits/chalk/mod.rs @@ -108,9 +108,6 @@ crate fn evaluate_goal<'tcx>( TyData::Apply(_application_ty) => match _application_ty.name { chalk_ir::TypeName::Adt(_struct_id) => match _struct_id.0 { RustDefId::Adt(_) => unimplemented!(), - RustDefId::Never => unimplemented!(), - RustDefId::Array => unimplemented!(), - RustDefId::FnDef(_) => unimplemented!(), _ => panic!("Unexpected struct id"), }, chalk_ir::TypeName::Scalar(scalar) => match scalar { From 2544b8c30a76ff0f07d44619d2d8b6e3c2035c8f Mon Sep 17 00:00:00 2001 From: Jack Huey Date: Wed, 27 May 2020 01:05:09 -0400 Subject: [PATCH 07/35] Implement fn_def_datum --- Cargo.lock | 27 ++++++----------- src/librustc_middle/Cargo.toml | 2 +- src/librustc_traits/Cargo.toml | 4 +-- src/librustc_traits/chalk/db.rs | 34 ++++++++++++++++++++-- src/librustc_traits/chalk/lowering.rs | 21 ++++--------- src/test/ui/chalkify/impl_wf.rs | 7 ++--- src/test/ui/chalkify/impl_wf.stderr | 16 ++++++++-- src/test/ui/chalkify/type_inference.rs | 4 +-- src/test/ui/chalkify/type_inference.stderr | 13 +++++++-- src/test/ui/chalkify/type_wf.rs | 11 ++----- src/test/ui/chalkify/type_wf.stderr | 12 ++++++++ src/tools/tidy/src/deps.rs | 3 +- 12 files changed, 93 insertions(+), 61 deletions(-) create mode 100644 src/test/ui/chalkify/type_wf.stderr diff --git a/Cargo.lock b/Cargo.lock index f7407a5c703f1..8792434e52b7b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -429,15 +429,15 @@ dependencies = [ [[package]] name = "chalk-base" version = "0.10.1-dev" -source = "git+https://github.com/rust-lang/chalk.git?rev=f4977ab4c781e4f3b7fdb9310edbdab6daf56e29#f4977ab4c781e4f3b7fdb9310edbdab6daf56e29" +source = "git+https://github.com/jackh726/chalk.git?rev=58e5a31f48ddd4b940c682e7079d3e79e6ffaa1b#58e5a31f48ddd4b940c682e7079d3e79e6ffaa1b" dependencies = [ - "lazy_static 1.4.0", + "lazy_static", ] [[package]] name = "chalk-derive" version = "0.10.1-dev" -source = "git+https://github.com/rust-lang/chalk.git?rev=f4977ab4c781e4f3b7fdb9310edbdab6daf56e29#f4977ab4c781e4f3b7fdb9310edbdab6daf56e29" +source = "git+https://github.com/jackh726/chalk.git?rev=58e5a31f48ddd4b940c682e7079d3e79e6ffaa1b#58e5a31f48ddd4b940c682e7079d3e79e6ffaa1b" dependencies = [ "proc-macro2 1.0.3", "quote 1.0.2", @@ -448,7 +448,7 @@ dependencies = [ [[package]] name = "chalk-engine" version = "0.10.1-dev" -source = "git+https://github.com/rust-lang/chalk.git?rev=f4977ab4c781e4f3b7fdb9310edbdab6daf56e29#f4977ab4c781e4f3b7fdb9310edbdab6daf56e29" +source = "git+https://github.com/jackh726/chalk.git?rev=58e5a31f48ddd4b940c682e7079d3e79e6ffaa1b#58e5a31f48ddd4b940c682e7079d3e79e6ffaa1b" dependencies = [ "chalk-base", "chalk-derive", @@ -459,7 +459,7 @@ dependencies = [ [[package]] name = "chalk-ir" version = "0.10.1-dev" -source = "git+https://github.com/rust-lang/chalk.git?rev=f4977ab4c781e4f3b7fdb9310edbdab6daf56e29#f4977ab4c781e4f3b7fdb9310edbdab6daf56e29" +source = "git+https://github.com/jackh726/chalk.git?rev=58e5a31f48ddd4b940c682e7079d3e79e6ffaa1b#58e5a31f48ddd4b940c682e7079d3e79e6ffaa1b" dependencies = [ "chalk-base", "chalk-derive", @@ -468,13 +468,13 @@ dependencies = [ [[package]] name = "chalk-solve" version = "0.10.1-dev" -source = "git+https://github.com/rust-lang/chalk.git?rev=f4977ab4c781e4f3b7fdb9310edbdab6daf56e29#f4977ab4c781e4f3b7fdb9310edbdab6daf56e29" +source = "git+https://github.com/jackh726/chalk.git?rev=58e5a31f48ddd4b940c682e7079d3e79e6ffaa1b#58e5a31f48ddd4b940c682e7079d3e79e6ffaa1b" dependencies = [ "chalk-base", "chalk-derive", "chalk-engine", "chalk-ir", - "ena 0.14.0", + "ena", "itertools 0.9.0", "petgraph", "rustc-hash", @@ -1038,15 +1038,6 @@ dependencies = [ "strum_macros", ] -[[package]] -name = "ena" -version = "0.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8944dc8fa28ce4a38f778bd46bf7d923fe73eed5a439398507246c8e017e6f36" -dependencies = [ - "log", -] - [[package]] name = "ena" version = "0.14.0" @@ -3267,7 +3258,7 @@ dependencies = [ "bitflags", "cfg-if", "crossbeam-utils 0.7.2", - "ena 0.14.0", + "ena", "indexmap", "jobserver", "lazy_static", @@ -3723,7 +3714,7 @@ dependencies = [ "bitflags", "cfg-if", "crossbeam-utils 0.7.2", - "ena 0.14.0", + "ena", "indexmap", "jobserver", "lazy_static", diff --git a/src/librustc_middle/Cargo.toml b/src/librustc_middle/Cargo.toml index 8e809e338ea1c..34dece1a2ad7e 100644 --- a/src/librustc_middle/Cargo.toml +++ b/src/librustc_middle/Cargo.toml @@ -30,7 +30,7 @@ rustc_serialize = { path = "../librustc_serialize" } rustc_ast = { path = "../librustc_ast" } rustc_span = { path = "../librustc_span" } byteorder = { version = "1.3" } -chalk-ir = { git = "https://github.com/rust-lang/chalk.git", rev = "f4977ab4c781e4f3b7fdb9310edbdab6daf56e29" } +chalk-ir = { git = "https://github.com/jackh726/chalk.git", rev = "58e5a31f48ddd4b940c682e7079d3e79e6ffaa1b" } #chalk-ir = "0.10.0" smallvec = { version = "1.0", features = ["union", "may_dangle"] } measureme = "0.7.1" diff --git a/src/librustc_traits/Cargo.toml b/src/librustc_traits/Cargo.toml index c85cd1765ab43..cb056dba9eab8 100644 --- a/src/librustc_traits/Cargo.toml +++ b/src/librustc_traits/Cargo.toml @@ -19,8 +19,8 @@ rustc_span = { path = "../librustc_span" } #chalk-ir = "0.10.0" #chalk-rust-ir = "0.10.0" #chalk-solve = "0.10.0" -chalk-solve = { git = "https://github.com/rust-lang/chalk.git", rev = "f4977ab4c781e4f3b7fdb9310edbdab6daf56e29" } -chalk-ir = { git = "https://github.com/rust-lang/chalk.git", rev = "f4977ab4c781e4f3b7fdb9310edbdab6daf56e29" } +chalk-solve = { git = "https://github.com/jackh726/chalk.git", rev = "58e5a31f48ddd4b940c682e7079d3e79e6ffaa1b" } +chalk-ir = { git = "https://github.com/jackh726/chalk.git", rev = "58e5a31f48ddd4b940c682e7079d3e79e6ffaa1b" } smallvec = { version = "1.0", features = ["union", "may_dangle"] } rustc_infer = { path = "../librustc_infer" } rustc_trait_selection = { path = "../librustc_trait_selection" } diff --git a/src/librustc_traits/chalk/db.rs b/src/librustc_traits/chalk/db.rs index 367c598027934..95a6f45f92fa8 100644 --- a/src/librustc_traits/chalk/db.rs +++ b/src/librustc_traits/chalk/db.rs @@ -175,9 +175,39 @@ impl<'tcx> chalk_solve::RustIrDatabase> for RustIrDatabase<'t fn fn_def_datum( &self, - _fn_def_id: chalk_ir::FnDefId>, + fn_def_id: chalk_ir::FnDefId>, ) -> Arc>> { - unimplemented!() + let def_id = match fn_def_id.0 { + RustDefId::FnDef(def_id) => def_id, + _ => bug!("Did not use `FnDef` variant when expecting FnDef."), + }; + let bound_vars = bound_vars_for_item(self.tcx, def_id); + let binders = binders_for(&self.interner, bound_vars); + + let predicates = self.tcx.predicates_defined_on(def_id).predicates; + let where_clauses: Vec<_> = predicates + .into_iter() + .map(|(wc, _)| wc.subst(self.tcx, &bound_vars)) + .filter_map(|wc| LowerInto::>>>::lower_into(wc, &self.interner)).collect(); + + let sig = self.tcx.fn_sig(def_id); + // FIXME(chalk): Why does this have a Binder + let argument_types = sig + .inputs() + .skip_binder() + .iter() + .map(|t| t.subst(self.tcx, &bound_vars).lower_into(&self.interner)) + .collect(); + + let return_type = + sig.output().skip_binder().subst(self.tcx, &bound_vars).lower_into(&self.interner); + + let bound = + chalk_solve::rust_ir::FnDefDatumBound { argument_types, where_clauses, return_type }; + Arc::new(chalk_solve::rust_ir::FnDefDatum { + id: fn_def_id, + binders: chalk_ir::Binders::new(binders, bound), + }) } fn impl_datum( diff --git a/src/librustc_traits/chalk/lowering.rs b/src/librustc_traits/chalk/lowering.rs index 57ef6ec0a25aa..58ea740193860 100644 --- a/src/librustc_traits/chalk/lowering.rs +++ b/src/librustc_traits/chalk/lowering.rs @@ -167,20 +167,11 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::GoalData>> for ty::Predi ty::PredicateKind::Projection(predicate) => predicate.lower_into(interner), ty::PredicateKind::WellFormed(arg) => match arg.unpack() { GenericArgKind::Type(ty) => match ty.kind { - // These types are always WF. - ty::Str | ty::Placeholder(..) | ty::Error | ty::Never => { - chalk_ir::GoalData::All(chalk_ir::Goals::new(interner)) - } - - // FIXME(chalk): Well-formed only if ref lifetime outlives type - ty::Ref(..) => chalk_ir::GoalData::All(chalk_ir::Goals::new(interner)), - - ty::Param(..) => panic!("No Params expected."), + // FIXME(chalk): In Chalk, a placeholder is WellFormed if it + // `FromEnv`. However, when we "lower" Params, we don't update + // the environment. + ty::Placeholder(..) => chalk_ir::GoalData::All(chalk_ir::Goals::new(interner)), - // FIXME(chalk) -- ultimately I think this is what we - // want to do, and we just have rules for how to prove - // `WellFormed` for everything above, instead of - // inlining a bit the rules of the proof here. _ => chalk_ir::GoalData::DomainGoal(chalk_ir::DomainGoal::WellFormed( chalk_ir::WellFormed::Ty(ty.lower_into(interner)), )), @@ -360,9 +351,9 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::Ty>> for Ty<'tcx> { ), ) } - FnDef(def_id, _) => apply( + FnDef(def_id, substs) => apply( chalk_ir::TypeName::FnDef(chalk_ir::FnDefId(RustDefId::FnDef(def_id))), - empty(), + substs.lower_into(interner), ), FnPtr(sig) => { let (inputs_and_outputs, binders, _named_regions) = diff --git a/src/test/ui/chalkify/impl_wf.rs b/src/test/ui/chalkify/impl_wf.rs index 8aa876422924d..fdc94f69bf21a 100644 --- a/src/test/ui/chalkify/impl_wf.rs +++ b/src/test/ui/chalkify/impl_wf.rs @@ -8,12 +8,9 @@ trait Bar { impl Foo for i32 { } -// FIXME(chalk): blocked on better handling of builtin traits for non-struct -// application types (or a workaround) -/* impl Foo for str { } -//^ ERROR the size for values of type `str` cannot be known at compilation time -*/ +//~^ ERROR the size for values of type `str` cannot be known at compilation time + // Implicit `T: Sized` bound. impl Foo for Option { } diff --git a/src/test/ui/chalkify/impl_wf.stderr b/src/test/ui/chalkify/impl_wf.stderr index befd688741c80..5293bbaecd389 100644 --- a/src/test/ui/chalkify/impl_wf.stderr +++ b/src/test/ui/chalkify/impl_wf.stderr @@ -1,5 +1,17 @@ +error[E0277]: the size for values of type `str` cannot be known at compilation time + --> $DIR/impl_wf.rs:11:6 + | +LL | trait Foo: Sized { } + | ----- required by this bound in `Foo` +... +LL | impl Foo for str { } + | ^^^ doesn't have a size known at compile-time + | + = help: the trait `std::marker::Sized` is not implemented for `str` + = note: to learn more, visit + error[E0277]: the trait bound `f32: Foo` is not satisfied - --> $DIR/impl_wf.rs:43:6 + --> $DIR/impl_wf.rs:40:6 | LL | trait Baz where U: Foo { } | --- required by this bound in `Baz` @@ -7,6 +19,6 @@ LL | trait Baz where U: Foo { } LL | impl Baz for f32 { } | ^^^^^^^^ the trait `Foo` is not implemented for `f32` -error: aborting due to previous error +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/chalkify/type_inference.rs b/src/test/ui/chalkify/type_inference.rs index 5175c5d062a6e..171969afc7f22 100644 --- a/src/test/ui/chalkify/type_inference.rs +++ b/src/test/ui/chalkify/type_inference.rs @@ -18,11 +18,9 @@ fn main() { // is expecting a variable of type `i32`. This behavior differs from the // old-style trait solver. I guess this will change, that's why I'm // adding that test. - // FIXME(chalk): partially blocked on float/int special casing only_foo(x); //~ ERROR the trait bound `f64: Foo` is not satisfied // Here we have two solutions so we get back the behavior of the old-style // trait solver. - // FIXME(chalk): blocked on float/int special casing - //only_bar(x); // ERROR the trait bound `{float}: Bar` is not satisfied + only_bar(x); //~ ERROR the trait bound `f64: Bar` is not satisfied } diff --git a/src/test/ui/chalkify/type_inference.stderr b/src/test/ui/chalkify/type_inference.stderr index ee9e67c6c7884..476759292642b 100644 --- a/src/test/ui/chalkify/type_inference.stderr +++ b/src/test/ui/chalkify/type_inference.stderr @@ -1,5 +1,5 @@ error[E0277]: the trait bound `f64: Foo` is not satisfied - --> $DIR/type_inference.rs:22:5 + --> $DIR/type_inference.rs:21:5 | LL | fn only_foo(_x: T) { } | --- required by this bound in `only_foo` @@ -7,6 +7,15 @@ LL | fn only_foo(_x: T) { } LL | only_foo(x); | ^^^^^^^^ the trait `Foo` is not implemented for `f64` -error: aborting due to previous error +error[E0277]: the trait bound `f64: Bar` is not satisfied + --> $DIR/type_inference.rs:25:5 + | +LL | fn only_bar(_x: T) { } + | --- required by this bound in `only_bar` +... +LL | only_bar(x); + | ^^^^^^^^ the trait `Bar` is not implemented for `f64` + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/chalkify/type_wf.rs b/src/test/ui/chalkify/type_wf.rs index 396baf814a0b0..7c469d99c5799 100644 --- a/src/test/ui/chalkify/type_wf.rs +++ b/src/test/ui/chalkify/type_wf.rs @@ -1,5 +1,4 @@ -// FIXME(chalk): should have an error, see below -// check-pass +// check-fail // compile-flags: -Z chalk trait Foo { } @@ -16,17 +15,11 @@ fn main() { x: 5, }; - // FIXME(chalk): blocked on float/int special handling. Needs to know that {float}: !i32 - /* - let s = S { // ERROR the trait bound `{float}: Foo` is not satisfied + let s = S { //~ ERROR the trait bound `f64: Foo` is not satisfied x: 5.0, }; - */ - // FIXME(chalk): blocked on float/int special handling. Needs to know that {float}: Sized - /* let s = S { x: Some(5.0), }; - */ } diff --git a/src/test/ui/chalkify/type_wf.stderr b/src/test/ui/chalkify/type_wf.stderr new file mode 100644 index 0000000000000..ab585a6ed2140 --- /dev/null +++ b/src/test/ui/chalkify/type_wf.stderr @@ -0,0 +1,12 @@ +error[E0277]: the trait bound `f64: Foo` is not satisfied + --> $DIR/type_wf.rs:18:13 + | +LL | struct S { + | ---------------- required by `S` +... +LL | let s = S { + | ^ the trait `Foo` is not implemented for `f64` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs index c08f02b972e8f..aec6b5d25235e 100644 --- a/src/tools/tidy/src/deps.rs +++ b/src/tools/tidy/src/deps.rs @@ -79,10 +79,9 @@ const WHITELIST: &[&str] = &[ "byteorder", "cc", "cfg-if", + "chalk-base", "chalk-derive", - "chalk-engine", "chalk-ir", - "chalk-macros", "cloudabi", "cmake", "compiler_builtins", From 7f2708cf84f9f086cf78d6e930c4b6eb5271e91f Mon Sep 17 00:00:00 2001 From: Jack Huey Date: Wed, 27 May 2020 01:26:51 -0400 Subject: [PATCH 08/35] Remove RustDefId --- src/librustc_middle/traits/chalk.rs | 17 +- src/librustc_middle/traits/mod.rs | 3 +- src/librustc_traits/chalk/db.rs | 223 +++++++++----------------- src/librustc_traits/chalk/lowering.rs | 19 +-- src/librustc_traits/chalk/mod.rs | 7 +- 5 files changed, 86 insertions(+), 183 deletions(-) diff --git a/src/librustc_middle/traits/chalk.rs b/src/librustc_middle/traits/chalk.rs index ec32bcf8a0b67..9ce6cc3a51114 100644 --- a/src/librustc_middle/traits/chalk.rs +++ b/src/librustc_middle/traits/chalk.rs @@ -16,19 +16,6 @@ use std::cmp::Ordering; use std::fmt; use std::hash::{Hash, Hasher}; -/// Since Chalk doesn't have full support for all Rust builtin types yet, we -/// need to use an enum here, rather than just `DefId`. -#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] -pub enum RustDefId { - Adt(DefId), - - FnDef(DefId), - Trait(DefId), - Impl(DefId), - AssocTy(DefId), - Opaque(DefId), -} - #[derive(Copy, Clone)] pub struct RustInterner<'tcx> { pub tcx: TyCtxt<'tcx>, @@ -86,8 +73,8 @@ impl<'tcx> chalk_ir::interner::Interner for RustInterner<'tcx> { type InternedQuantifiedWhereClauses = Vec>; type InternedVariableKinds = Vec>; type InternedCanonicalVarKinds = Vec>; - type DefId = RustDefId; - type InternedAdtId = RustDefId; + type DefId = DefId; + type InternedAdtId = DefId; type Identifier = (); fn debug_program_clause_implication( diff --git a/src/librustc_middle/traits/mod.rs b/src/librustc_middle/traits/mod.rs index 9afab5a4d2fe9..cad0187af87bc 100644 --- a/src/librustc_middle/traits/mod.rs +++ b/src/librustc_middle/traits/mod.rs @@ -32,8 +32,7 @@ pub use self::SelectionError::*; pub use self::Vtable::*; pub use self::chalk::{ - ChalkEnvironmentAndGoal, ChalkEnvironmentClause, RustDefId as ChalkRustDefId, - RustInterner as ChalkRustInterner, + ChalkEnvironmentAndGoal, ChalkEnvironmentClause, RustInterner as ChalkRustInterner, }; /// Depending on the stage of compilation, we want projection to be diff --git a/src/librustc_traits/chalk/db.rs b/src/librustc_traits/chalk/db.rs index 95a6f45f92fa8..818839e2e3b33 100644 --- a/src/librustc_traits/chalk/db.rs +++ b/src/librustc_traits/chalk/db.rs @@ -6,7 +6,7 @@ //! either the `TyCtxt` (for information about types) or //! `crate::chalk::lowering` (to lower rustc types into Chalk types). -use rustc_middle::traits::{ChalkRustDefId as RustDefId, ChalkRustInterner as RustInterner}; +use rustc_middle::traits::ChalkRustInterner as RustInterner; use rustc_middle::ty::subst::{InternalSubsts, Subst, SubstsRef}; use rustc_middle::ty::{self, AssocItemContainer, AssocKind, TyCtxt}; @@ -39,10 +39,7 @@ impl<'tcx> chalk_solve::RustIrDatabase> for RustIrDatabase<'t &self, assoc_type_id: chalk_ir::AssocTypeId>, ) -> Arc>> { - let def_id = match assoc_type_id.0 { - RustDefId::AssocTy(def_id) => def_id, - _ => bug!("Did not use `AssocTy` variant when expecting associated type."), - }; + let def_id = assoc_type_id.0; let assoc_item = self.tcx.associated_item(def_id); let trait_def_id = match assoc_item.container { AssocItemContainer::TraitContainer(def_id) => def_id, @@ -64,7 +61,7 @@ impl<'tcx> chalk_solve::RustIrDatabase> for RustIrDatabase<'t .filter_map(|wc| LowerInto::>>>::lower_into(wc, &self.interner)).collect(); Arc::new(chalk_solve::rust_ir::AssociatedTyDatum { - trait_id: chalk_ir::TraitId(RustDefId::Trait(trait_def_id)), + trait_id: chalk_ir::TraitId(trait_def_id), id: assoc_type_id, name: (), binders: chalk_ir::Binders::new( @@ -78,10 +75,7 @@ impl<'tcx> chalk_solve::RustIrDatabase> for RustIrDatabase<'t &self, trait_id: chalk_ir::TraitId>, ) -> Arc>> { - let def_id = match trait_id.0 { - RustDefId::Trait(def_id) => def_id, - _ => bug!("Did not use `Trait` variant when expecting trait."), - }; + let def_id = trait_id.0; let trait_def = self.tcx.trait_def(def_id); let bound_vars = bound_vars_for_item(self.tcx, def_id); @@ -125,62 +119,54 @@ impl<'tcx> chalk_solve::RustIrDatabase> for RustIrDatabase<'t &self, struct_id: chalk_ir::AdtId>, ) -> Arc>> { - match struct_id.0 { - RustDefId::Adt(adt_def_id) => { - let adt_def = self.tcx.adt_def(adt_def_id); + let adt_def_id = struct_id.0; + let adt_def = self.tcx.adt_def(adt_def_id); - let bound_vars = bound_vars_for_item(self.tcx, adt_def_id); - let binders = binders_for(&self.interner, bound_vars); + let bound_vars = bound_vars_for_item(self.tcx, adt_def_id); + let binders = binders_for(&self.interner, bound_vars); - let predicates = self.tcx.predicates_of(adt_def_id).predicates; - let where_clauses: Vec<_> = predicates + let predicates = self.tcx.predicates_of(adt_def_id).predicates; + let where_clauses: Vec<_> = predicates + .into_iter() + .map(|(wc, _)| wc.subst(self.tcx, bound_vars)) + .filter_map(|wc| LowerInto::>>>::lower_into(wc, &self.interner)) + .collect(); + let fields = match adt_def.adt_kind() { + ty::AdtKind::Struct | ty::AdtKind::Union => { + let variant = adt_def.non_enum_variant(); + variant + .fields .iter() - .map(|(wc, _)| wc.subst(self.tcx, bound_vars)) - .filter_map(|wc| LowerInto::>>>::lower_into(wc, &self.interner)) - .collect(); - let fields = match adt_def.adt_kind() { - ty::AdtKind::Struct | ty::AdtKind::Union => { - let variant = adt_def.non_enum_variant(); - variant - .fields - .iter() - .map(|field| { - self.tcx - .type_of(field.did) - .subst(self.tcx, bound_vars) - .lower_into(&self.interner) - }) - .collect() - } - // FIXME(chalk): handle enums; force_impl_for requires this - ty::AdtKind::Enum => vec![], - }; - let struct_datum = Arc::new(chalk_solve::rust_ir::AdtDatum { - id: struct_id, - binders: chalk_ir::Binders::new( - binders, - chalk_solve::rust_ir::AdtDatumBound { fields, where_clauses }, - ), - flags: chalk_solve::rust_ir::AdtFlags { - upstream: !adt_def_id.is_local(), - fundamental: adt_def.is_fundamental(), - }, - }); - struct_datum + .map(|field| { + self.tcx + .type_of(field.did) + .subst(self.tcx, bound_vars) + .lower_into(&self.interner) + }) + .collect() } - - v => bug!("Used not struct variant ({:?}) when expecting struct variant.", v), - } + // FIXME(chalk): handle enums; force_impl_for requires this + ty::AdtKind::Enum => vec![], + }; + let struct_datum = Arc::new(chalk_solve::rust_ir::AdtDatum { + id: struct_id, + binders: chalk_ir::Binders::new( + binders, + chalk_solve::rust_ir::AdtDatumBound { fields, where_clauses }, + ), + flags: chalk_solve::rust_ir::AdtFlags { + upstream: !adt_def_id.is_local(), + fundamental: adt_def.is_fundamental(), + }, + }); + return struct_datum; } fn fn_def_datum( &self, fn_def_id: chalk_ir::FnDefId>, ) -> Arc>> { - let def_id = match fn_def_id.0 { - RustDefId::FnDef(def_id) => def_id, - _ => bug!("Did not use `FnDef` variant when expecting FnDef."), - }; + let def_id = fn_def_id.0; let bound_vars = bound_vars_for_item(self.tcx, def_id); let binders = binders_for(&self.interner, bound_vars); @@ -214,10 +200,7 @@ impl<'tcx> chalk_solve::RustIrDatabase> for RustIrDatabase<'t &self, impl_id: chalk_ir::ImplId>, ) -> Arc>> { - let def_id = match impl_id.0 { - RustDefId::Impl(def_id) => def_id, - _ => bug!("Did not use `Impl` variant when expecting impl."), - }; + let def_id = impl_id.0; let bound_vars = bound_vars_for_item(self.tcx, def_id); let binders = binders_for(&self.interner, bound_vars); @@ -248,10 +231,7 @@ impl<'tcx> chalk_solve::RustIrDatabase> for RustIrDatabase<'t trait_id: chalk_ir::TraitId>, parameters: &[chalk_ir::GenericArg>], ) -> Vec>> { - let def_id: DefId = match trait_id.0 { - RustDefId::Trait(def_id) => def_id, - _ => bug!("Did not use `Trait` variant when expecting trait."), - }; + let def_id = trait_id.0; // FIXME(chalk): use TraitDef::for_each_relevant_impl, but that will // require us to be able to interconvert `Ty<'tcx>`, and we're @@ -270,9 +250,7 @@ impl<'tcx> chalk_solve::RustIrDatabase> for RustIrDatabase<'t parameters[0].assert_ty_ref(&self.interner).could_match(&self.interner, &lowered_ty) }); - let impls = matched_impls - .map(|matched_impl| chalk_ir::ImplId(RustDefId::Impl(matched_impl))) - .collect(); + let impls = matched_impls.map(|matched_impl| chalk_ir::ImplId(matched_impl)).collect(); impls } @@ -281,19 +259,8 @@ impl<'tcx> chalk_solve::RustIrDatabase> for RustIrDatabase<'t auto_trait_id: chalk_ir::TraitId>, struct_id: chalk_ir::AdtId>, ) -> bool { - let trait_def_id: DefId = match auto_trait_id.0 { - RustDefId::Trait(def_id) => def_id, - _ => bug!("Did not use `Trait` variant when expecting trait."), - }; - // FIXME(chalk): this match can be removed when builtin types supported - match struct_id.0 { - RustDefId::Adt(_) => {} - _ => bug!("Did not use `Adt` variant when expecting adt."), - } - let adt_def_id: DefId = match struct_id.0 { - RustDefId::Adt(def_id) => def_id, - _ => bug!("Did not use `Adt` variant when expecting adt."), - }; + let trait_def_id = auto_trait_id.0; + let adt_def_id = struct_id.0; let all_impls = self.tcx.all_impls(trait_def_id); for impl_def_id in all_impls { let trait_ref = self.tcx.impl_trait_ref(impl_def_id).unwrap(); @@ -314,10 +281,7 @@ impl<'tcx> chalk_solve::RustIrDatabase> for RustIrDatabase<'t &self, associated_ty_id: chalk_solve::rust_ir::AssociatedTyValueId>, ) -> Arc>> { - let def_id = match associated_ty_id.0 { - RustDefId::AssocTy(def_id) => def_id, - _ => bug!("Did not use `AssocTy` variant when expecting associated type."), - }; + let def_id = associated_ty_id.0; let assoc_item = self.tcx.associated_item(def_id); let impl_id = match assoc_item.container { AssocItemContainer::TraitContainer(def_id) => def_id, @@ -332,8 +296,8 @@ impl<'tcx> chalk_solve::RustIrDatabase> for RustIrDatabase<'t let ty = self.tcx.type_of(def_id); Arc::new(chalk_solve::rust_ir::AssociatedTyValue { - impl_id: chalk_ir::ImplId(RustDefId::Impl(impl_id)), - associated_ty_id: chalk_ir::AssocTypeId(RustDefId::AssocTy(def_id)), + impl_id: chalk_ir::ImplId(impl_id), + associated_ty_id: chalk_ir::AssocTypeId(def_id), value: chalk_ir::Binders::new( binders, chalk_solve::rust_ir::AssociatedTyValueBound { ty: ty.lower_into(&self.interner) }, @@ -381,25 +345,14 @@ impl<'tcx> chalk_solve::RustIrDatabase> for RustIrDatabase<'t match well_known { chalk_solve::rust_ir::WellKnownTrait::SizedTrait => match ty { Apply(apply) => match apply.name { - chalk_ir::TypeName::Adt(chalk_ir::AdtId(rust_def_id)) => { - use rustc_middle::traits::ChalkRustDefId::*; - match rust_def_id { - Adt(adt_def_id) => { - let adt_def = self.tcx.adt_def(adt_def_id); - match adt_def.adt_kind() { - ty::AdtKind::Struct | ty::AdtKind::Union => None, - ty::AdtKind::Enum => { - let constraint = self.tcx.adt_sized_constraint(adt_def_id); - if !constraint.0.is_empty() { - unimplemented!() - } else { - Some(true) - } - } - } + chalk_ir::TypeName::Adt(chalk_ir::AdtId(adt_def_id)) => { + let adt_def = self.tcx.adt_def(adt_def_id); + match adt_def.adt_kind() { + ty::AdtKind::Struct | ty::AdtKind::Union => None, + ty::AdtKind::Enum => { + let constraint = self.tcx.adt_sized_constraint(adt_def_id); + if constraint.0.len() > 0 { unimplemented!() } else { Some(true) } } - - FnDef(_) | Trait(_) | Impl(_) | AssocTy(_) | Opaque(_) => panic!(), } } _ => None, @@ -414,24 +367,14 @@ impl<'tcx> chalk_solve::RustIrDatabase> for RustIrDatabase<'t chalk_solve::rust_ir::WellKnownTrait::CopyTrait | chalk_solve::rust_ir::WellKnownTrait::CloneTrait => match ty { Apply(apply) => match apply.name { - chalk_ir::TypeName::Adt(chalk_ir::AdtId(rust_def_id)) => { - use rustc_middle::traits::ChalkRustDefId::*; - match rust_def_id { - Adt(adt_def_id) => { - let adt_def = self.tcx.adt_def(adt_def_id); - match adt_def.adt_kind() { - ty::AdtKind::Struct | ty::AdtKind::Union => None, - ty::AdtKind::Enum => { - let constraint = self.tcx.adt_sized_constraint(adt_def_id); - if !constraint.0.is_empty() { - unimplemented!() - } else { - Some(true) - } - } - } + chalk_ir::TypeName::Adt(chalk_ir::AdtId(adt_def_id)) => { + let adt_def = self.tcx.adt_def(adt_def_id); + match adt_def.adt_kind() { + ty::AdtKind::Struct | ty::AdtKind::Union => None, + ty::AdtKind::Enum => { + let constraint = self.tcx.adt_sized_constraint(adt_def_id); + if constraint.0.len() > 0 { unimplemented!() } else { Some(true) } } - FnDef(_) | Trait(_) | Impl(_) | AssocTy(_) | Opaque(_) => panic!(), } } _ => None, @@ -460,40 +403,20 @@ impl<'tcx> chalk_solve::RustIrDatabase> for RustIrDatabase<'t ) -> Option>> { use chalk_solve::rust_ir::WellKnownTrait::*; let t = match well_known_trait { - SizedTrait => self - .tcx - .lang_items() - .sized_trait() - .map(|t| chalk_ir::TraitId(RustDefId::Trait(t))) - .unwrap(), - CopyTrait => self - .tcx - .lang_items() - .copy_trait() - .map(|t| chalk_ir::TraitId(RustDefId::Trait(t))) - .unwrap(), - CloneTrait => self - .tcx - .lang_items() - .clone_trait() - .map(|t| chalk_ir::TraitId(RustDefId::Trait(t))) - .unwrap(), - DropTrait => self - .tcx - .lang_items() - .drop_trait() - .map(|t| chalk_ir::TraitId(RustDefId::Trait(t))) - .unwrap(), + SizedTrait => { + self.tcx.lang_items().sized_trait().map(|t| chalk_ir::TraitId(t)).unwrap() + } + CopyTrait => self.tcx.lang_items().copy_trait().map(|t| chalk_ir::TraitId(t)).unwrap(), + CloneTrait => { + self.tcx.lang_items().clone_trait().map(|t| chalk_ir::TraitId(t)).unwrap() + } + DropTrait => self.tcx.lang_items().drop_trait().map(|t| chalk_ir::TraitId(t)).unwrap(), }; Some(t) } fn is_object_safe(&self, trait_id: chalk_ir::TraitId>) -> bool { - let def_id: DefId = match trait_id.0 { - RustDefId::Trait(def_id) => def_id, - _ => bug!("Did not use `Trait` variant when expecting trait."), - }; - self.tcx.is_object_safe(def_id) + self.tcx.is_object_safe(trait_id.0) } } diff --git a/src/librustc_traits/chalk/lowering.rs b/src/librustc_traits/chalk/lowering.rs index 58ea740193860..08fbca34177bd 100644 --- a/src/librustc_traits/chalk/lowering.rs +++ b/src/librustc_traits/chalk/lowering.rs @@ -32,8 +32,7 @@ //! variables from the current `Binder`. use rustc_middle::traits::{ - ChalkEnvironmentAndGoal, ChalkEnvironmentClause, ChalkRustDefId as RustDefId, - ChalkRustInterner as RustInterner, + ChalkEnvironmentAndGoal, ChalkEnvironmentClause, ChalkRustInterner as RustInterner, }; use rustc_middle::ty::fold::TypeFolder; use rustc_middle::ty::subst::{GenericArg, GenericArgKind, SubstsRef}; @@ -62,7 +61,7 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::Substitution>> for Subst impl<'tcx> LowerInto<'tcx, chalk_ir::AliasTy>> for ty::ProjectionTy<'tcx> { fn lower_into(self, interner: &RustInterner<'tcx>) -> chalk_ir::AliasTy> { chalk_ir::AliasTy::Projection(chalk_ir::ProjectionTy { - associated_ty_id: chalk_ir::AssocTypeId(RustDefId::AssocTy(self.item_def_id)), + associated_ty_id: chalk_ir::AssocTypeId(self.item_def_id), substitution: self.substs.lower_into(interner), }) } @@ -203,7 +202,7 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::TraitRef>> { fn lower_into(self, interner: &RustInterner<'tcx>) -> chalk_ir::TraitRef> { chalk_ir::TraitRef { - trait_id: chalk_ir::TraitId(RustDefId::Trait(self.def_id)), + trait_id: chalk_ir::TraitId(self.def_id), substitution: self.substs.lower_into(interner), } } @@ -296,9 +295,7 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::Ty>> for Ty<'tcx> { ast::FloatTy::F32 => float(chalk_ir::FloatTy::F32), ast::FloatTy::F64 => float(chalk_ir::FloatTy::F64), }, - Adt(def, substs) => { - apply(struct_ty(RustDefId::Adt(def.did)), substs.lower_into(interner)) - } + Adt(def, substs) => apply(struct_ty(def.did), substs.lower_into(interner)), Foreign(_def_id) => unimplemented!(), Str => apply(chalk_ir::TypeName::Str, empty()), Array(ty, _) => apply( @@ -352,7 +349,7 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::Ty>> for Ty<'tcx> { ) } FnDef(def_id, substs) => apply( - chalk_ir::TypeName::FnDef(chalk_ir::FnDefId(RustDefId::FnDef(def_id))), + chalk_ir::TypeName::FnDef(chalk_ir::FnDefId(def_id)), substs.lower_into(interner), ), FnPtr(sig) => { @@ -384,7 +381,7 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::Ty>> for Ty<'tcx> { Projection(proj) => TyData::Alias(proj.lower_into(interner)).intern(interner), Opaque(def_id, substs) => { TyData::Alias(chalk_ir::AliasTy::Opaque(chalk_ir::OpaqueTy { - opaque_ty_id: chalk_ir::OpaqueTyId(RustDefId::Opaque(def_id)), + opaque_ty_id: chalk_ir::OpaqueTyId(def_id), substitution: substs.lower_into(interner), })) .intern(interner) @@ -515,7 +512,7 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::Binders LowerInto<'tcx, chalk_ir::Binders chalk_ir::Binders::new( chalk_ir::VariableKinds::new(interner), chalk_ir::WhereClause::Implemented(chalk_ir::TraitRef { - trait_id: chalk_ir::TraitId(RustDefId::Trait(*def_id)), + trait_id: chalk_ir::TraitId(*def_id), substitution: chalk_ir::Substitution::empty(interner), }), ), diff --git a/src/librustc_traits/chalk/mod.rs b/src/librustc_traits/chalk/mod.rs index f33ec3a9fb915..4d047d2107af5 100644 --- a/src/librustc_traits/chalk/mod.rs +++ b/src/librustc_traits/chalk/mod.rs @@ -22,7 +22,7 @@ use rustc_middle::ty::{ use rustc_infer::infer::canonical::{ Canonical, CanonicalVarValues, Certainty, QueryRegionConstraints, QueryResponse, }; -use rustc_infer::traits::{self, ChalkCanonicalGoal, ChalkRustDefId as RustDefId}; +use rustc_infer::traits::{self, ChalkCanonicalGoal}; use crate::chalk::db::RustIrDatabase as ChalkRustIrDatabase; use crate::chalk::lowering::{LowerInto, ParamsSubstitutor}; @@ -106,10 +106,7 @@ crate fn evaluate_goal<'tcx>( let _data = _t.data(&interner); let kind = match _data { TyData::Apply(_application_ty) => match _application_ty.name { - chalk_ir::TypeName::Adt(_struct_id) => match _struct_id.0 { - RustDefId::Adt(_) => unimplemented!(), - _ => panic!("Unexpected struct id"), - }, + chalk_ir::TypeName::Adt(_struct_id) => unimplemented!(), chalk_ir::TypeName::Scalar(scalar) => match scalar { chalk_ir::Scalar::Bool => ty::Bool, chalk_ir::Scalar::Char => ty::Char, From ebdc950f0eb73416be5067c143ecaf1d84f0cb02 Mon Sep 17 00:00:00 2001 From: Jack Huey Date: Wed, 27 May 2020 02:23:30 -0400 Subject: [PATCH 09/35] Test error order is non-deterministic --- src/test/ui/chalkify/type_inference.rs | 4 +++- src/test/ui/chalkify/type_inference.stderr | 13 ++----------- 2 files changed, 5 insertions(+), 12 deletions(-) diff --git a/src/test/ui/chalkify/type_inference.rs b/src/test/ui/chalkify/type_inference.rs index 171969afc7f22..2b62bf18a71ce 100644 --- a/src/test/ui/chalkify/type_inference.rs +++ b/src/test/ui/chalkify/type_inference.rs @@ -18,7 +18,9 @@ fn main() { // is expecting a variable of type `i32`. This behavior differs from the // old-style trait solver. I guess this will change, that's why I'm // adding that test. - only_foo(x); //~ ERROR the trait bound `f64: Foo` is not satisfied + // FIXME(chalk): order of these two errors is non-deterministic, + // so let's just hide one for now + //only_foo(x); // ERROR the trait bound `f64: Foo` is not satisfied // Here we have two solutions so we get back the behavior of the old-style // trait solver. diff --git a/src/test/ui/chalkify/type_inference.stderr b/src/test/ui/chalkify/type_inference.stderr index 476759292642b..5cfb968404df6 100644 --- a/src/test/ui/chalkify/type_inference.stderr +++ b/src/test/ui/chalkify/type_inference.stderr @@ -1,14 +1,5 @@ -error[E0277]: the trait bound `f64: Foo` is not satisfied - --> $DIR/type_inference.rs:21:5 - | -LL | fn only_foo(_x: T) { } - | --- required by this bound in `only_foo` -... -LL | only_foo(x); - | ^^^^^^^^ the trait `Foo` is not implemented for `f64` - error[E0277]: the trait bound `f64: Bar` is not satisfied - --> $DIR/type_inference.rs:25:5 + --> $DIR/type_inference.rs:27:5 | LL | fn only_bar(_x: T) { } | --- required by this bound in `only_bar` @@ -16,6 +7,6 @@ LL | fn only_bar(_x: T) { } LL | only_bar(x); | ^^^^^^^^ the trait `Bar` is not implemented for `f64` -error: aborting due to 2 previous errors +error: aborting due to previous error For more information about this error, try `rustc --explain E0277`. From 1d8264a3f596e90d593cf772fcd30081dbd1a47e Mon Sep 17 00:00:00 2001 From: Jack Huey Date: Wed, 27 May 2020 19:27:53 -0400 Subject: [PATCH 10/35] Update Chalk --- Cargo.lock | 10 +++++----- src/librustc_middle/Cargo.toml | 2 +- src/librustc_traits/Cargo.toml | 4 ++-- src/librustc_traits/chalk/db.rs | 11 ++++++++--- 4 files changed, 16 insertions(+), 11 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8792434e52b7b..e827ea30b2e50 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -429,7 +429,7 @@ dependencies = [ [[package]] name = "chalk-base" version = "0.10.1-dev" -source = "git+https://github.com/jackh726/chalk.git?rev=58e5a31f48ddd4b940c682e7079d3e79e6ffaa1b#58e5a31f48ddd4b940c682e7079d3e79e6ffaa1b" +source = "git+https://github.com/jackh726/chalk.git?rev=c8f342bf5e48051333d0b2c7fab81347fc21c474#c8f342bf5e48051333d0b2c7fab81347fc21c474" dependencies = [ "lazy_static", ] @@ -437,7 +437,7 @@ dependencies = [ [[package]] name = "chalk-derive" version = "0.10.1-dev" -source = "git+https://github.com/jackh726/chalk.git?rev=58e5a31f48ddd4b940c682e7079d3e79e6ffaa1b#58e5a31f48ddd4b940c682e7079d3e79e6ffaa1b" +source = "git+https://github.com/jackh726/chalk.git?rev=c8f342bf5e48051333d0b2c7fab81347fc21c474#c8f342bf5e48051333d0b2c7fab81347fc21c474" dependencies = [ "proc-macro2 1.0.3", "quote 1.0.2", @@ -448,7 +448,7 @@ dependencies = [ [[package]] name = "chalk-engine" version = "0.10.1-dev" -source = "git+https://github.com/jackh726/chalk.git?rev=58e5a31f48ddd4b940c682e7079d3e79e6ffaa1b#58e5a31f48ddd4b940c682e7079d3e79e6ffaa1b" +source = "git+https://github.com/jackh726/chalk.git?rev=c8f342bf5e48051333d0b2c7fab81347fc21c474#c8f342bf5e48051333d0b2c7fab81347fc21c474" dependencies = [ "chalk-base", "chalk-derive", @@ -459,7 +459,7 @@ dependencies = [ [[package]] name = "chalk-ir" version = "0.10.1-dev" -source = "git+https://github.com/jackh726/chalk.git?rev=58e5a31f48ddd4b940c682e7079d3e79e6ffaa1b#58e5a31f48ddd4b940c682e7079d3e79e6ffaa1b" +source = "git+https://github.com/jackh726/chalk.git?rev=c8f342bf5e48051333d0b2c7fab81347fc21c474#c8f342bf5e48051333d0b2c7fab81347fc21c474" dependencies = [ "chalk-base", "chalk-derive", @@ -468,7 +468,7 @@ dependencies = [ [[package]] name = "chalk-solve" version = "0.10.1-dev" -source = "git+https://github.com/jackh726/chalk.git?rev=58e5a31f48ddd4b940c682e7079d3e79e6ffaa1b#58e5a31f48ddd4b940c682e7079d3e79e6ffaa1b" +source = "git+https://github.com/jackh726/chalk.git?rev=c8f342bf5e48051333d0b2c7fab81347fc21c474#c8f342bf5e48051333d0b2c7fab81347fc21c474" dependencies = [ "chalk-base", "chalk-derive", diff --git a/src/librustc_middle/Cargo.toml b/src/librustc_middle/Cargo.toml index 34dece1a2ad7e..121491c8cc4bf 100644 --- a/src/librustc_middle/Cargo.toml +++ b/src/librustc_middle/Cargo.toml @@ -30,7 +30,7 @@ rustc_serialize = { path = "../librustc_serialize" } rustc_ast = { path = "../librustc_ast" } rustc_span = { path = "../librustc_span" } byteorder = { version = "1.3" } -chalk-ir = { git = "https://github.com/jackh726/chalk.git", rev = "58e5a31f48ddd4b940c682e7079d3e79e6ffaa1b" } +chalk-ir = { git = "https://github.com/jackh726/chalk.git", rev = "c8f342bf5e48051333d0b2c7fab81347fc21c474" } #chalk-ir = "0.10.0" smallvec = { version = "1.0", features = ["union", "may_dangle"] } measureme = "0.7.1" diff --git a/src/librustc_traits/Cargo.toml b/src/librustc_traits/Cargo.toml index cb056dba9eab8..6bfebecf04cbe 100644 --- a/src/librustc_traits/Cargo.toml +++ b/src/librustc_traits/Cargo.toml @@ -19,8 +19,8 @@ rustc_span = { path = "../librustc_span" } #chalk-ir = "0.10.0" #chalk-rust-ir = "0.10.0" #chalk-solve = "0.10.0" -chalk-solve = { git = "https://github.com/jackh726/chalk.git", rev = "58e5a31f48ddd4b940c682e7079d3e79e6ffaa1b" } -chalk-ir = { git = "https://github.com/jackh726/chalk.git", rev = "58e5a31f48ddd4b940c682e7079d3e79e6ffaa1b" } +chalk-solve = { git = "https://github.com/jackh726/chalk.git", rev = "c8f342bf5e48051333d0b2c7fab81347fc21c474" } +chalk-ir = { git = "https://github.com/jackh726/chalk.git", rev = "c8f342bf5e48051333d0b2c7fab81347fc21c474" } smallvec = { version = "1.0", features = ["union", "may_dangle"] } rustc_infer = { path = "../librustc_infer" } rustc_trait_selection = { path = "../librustc_trait_selection" } diff --git a/src/librustc_traits/chalk/db.rs b/src/librustc_traits/chalk/db.rs index 818839e2e3b33..5b00d32276831 100644 --- a/src/librustc_traits/chalk/db.rs +++ b/src/librustc_traits/chalk/db.rs @@ -321,10 +321,7 @@ impl<'tcx> chalk_solve::RustIrDatabase> for RustIrDatabase<'t opaque_ty_id: chalk_ir::OpaqueTyId>, ) -> Arc>> { // FIXME(chalk): actually lower opaque ty - let hidden_ty = - self.tcx.mk_ty(ty::Tuple(self.tcx.intern_substs(&[]))).lower_into(&self.interner); let value = chalk_solve::rust_ir::OpaqueTyDatumBound { - hidden_ty, bounds: chalk_ir::Binders::new(chalk_ir::VariableKinds::new(&self.interner), vec![]), }; Arc::new(chalk_solve::rust_ir::OpaqueTyDatum { @@ -418,6 +415,14 @@ impl<'tcx> chalk_solve::RustIrDatabase> for RustIrDatabase<'t fn is_object_safe(&self, trait_id: chalk_ir::TraitId>) -> bool { self.tcx.is_object_safe(trait_id.0) } + + fn hidden_opaque_type( + &self, + _id: chalk_ir::OpaqueTyId>, + ) -> chalk_ir::Ty> { + // FIXME(chalk): actually get hidden ty + self.tcx.mk_ty(ty::Tuple(self.tcx.intern_substs(&[]))).lower_into(&self.interner) + } } /// Creates a `InternalSubsts` that maps each generic parameter to a higher-ranked From 6172e9a2aeaf254c8aa32f629bd920bd5299538c Mon Sep 17 00:00:00 2001 From: Jack Huey Date: Fri, 29 May 2020 22:09:34 -0400 Subject: [PATCH 11/35] Update chalk and add LifetimeOutlives and ObjectSafe lowering --- Cargo.lock | 20 +++------ src/librustc_middle/Cargo.toml | 2 +- src/librustc_traits/Cargo.toml | 4 +- src/librustc_traits/chalk/lowering.rs | 65 +++++++++++++++++++++++---- src/librustc_traits/chalk/mod.rs | 2 +- 5 files changed, 66 insertions(+), 27 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e827ea30b2e50..5103e6bfd19b4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -426,18 +426,10 @@ dependencies = [ "rustc-std-workspace-core", ] -[[package]] -name = "chalk-base" -version = "0.10.1-dev" -source = "git+https://github.com/jackh726/chalk.git?rev=c8f342bf5e48051333d0b2c7fab81347fc21c474#c8f342bf5e48051333d0b2c7fab81347fc21c474" -dependencies = [ - "lazy_static", -] - [[package]] name = "chalk-derive" version = "0.10.1-dev" -source = "git+https://github.com/jackh726/chalk.git?rev=c8f342bf5e48051333d0b2c7fab81347fc21c474#c8f342bf5e48051333d0b2c7fab81347fc21c474" +source = "git+https://github.com/rust-lang/chalk.git?rev=ea1ca4ddc43abcfed77420f294a3713fac714e18#ea1ca4ddc43abcfed77420f294a3713fac714e18" dependencies = [ "proc-macro2 1.0.3", "quote 1.0.2", @@ -448,9 +440,8 @@ dependencies = [ [[package]] name = "chalk-engine" version = "0.10.1-dev" -source = "git+https://github.com/jackh726/chalk.git?rev=c8f342bf5e48051333d0b2c7fab81347fc21c474#c8f342bf5e48051333d0b2c7fab81347fc21c474" +source = "git+https://github.com/rust-lang/chalk.git?rev=ea1ca4ddc43abcfed77420f294a3713fac714e18#ea1ca4ddc43abcfed77420f294a3713fac714e18" dependencies = [ - "chalk-base", "chalk-derive", "chalk-ir", "rustc-hash", @@ -459,18 +450,17 @@ dependencies = [ [[package]] name = "chalk-ir" version = "0.10.1-dev" -source = "git+https://github.com/jackh726/chalk.git?rev=c8f342bf5e48051333d0b2c7fab81347fc21c474#c8f342bf5e48051333d0b2c7fab81347fc21c474" +source = "git+https://github.com/rust-lang/chalk.git?rev=ea1ca4ddc43abcfed77420f294a3713fac714e18#ea1ca4ddc43abcfed77420f294a3713fac714e18" dependencies = [ - "chalk-base", "chalk-derive", + "lazy_static 1.4.0", ] [[package]] name = "chalk-solve" version = "0.10.1-dev" -source = "git+https://github.com/jackh726/chalk.git?rev=c8f342bf5e48051333d0b2c7fab81347fc21c474#c8f342bf5e48051333d0b2c7fab81347fc21c474" +source = "git+https://github.com/rust-lang/chalk.git?rev=ea1ca4ddc43abcfed77420f294a3713fac714e18#ea1ca4ddc43abcfed77420f294a3713fac714e18" dependencies = [ - "chalk-base", "chalk-derive", "chalk-engine", "chalk-ir", diff --git a/src/librustc_middle/Cargo.toml b/src/librustc_middle/Cargo.toml index 121491c8cc4bf..9516d449671d6 100644 --- a/src/librustc_middle/Cargo.toml +++ b/src/librustc_middle/Cargo.toml @@ -30,7 +30,7 @@ rustc_serialize = { path = "../librustc_serialize" } rustc_ast = { path = "../librustc_ast" } rustc_span = { path = "../librustc_span" } byteorder = { version = "1.3" } -chalk-ir = { git = "https://github.com/jackh726/chalk.git", rev = "c8f342bf5e48051333d0b2c7fab81347fc21c474" } +chalk-ir = { git = "https://github.com/rust-lang/chalk.git", rev = "ea1ca4ddc43abcfed77420f294a3713fac714e18" } #chalk-ir = "0.10.0" smallvec = { version = "1.0", features = ["union", "may_dangle"] } measureme = "0.7.1" diff --git a/src/librustc_traits/Cargo.toml b/src/librustc_traits/Cargo.toml index 6bfebecf04cbe..f141daa9f936b 100644 --- a/src/librustc_traits/Cargo.toml +++ b/src/librustc_traits/Cargo.toml @@ -19,8 +19,8 @@ rustc_span = { path = "../librustc_span" } #chalk-ir = "0.10.0" #chalk-rust-ir = "0.10.0" #chalk-solve = "0.10.0" -chalk-solve = { git = "https://github.com/jackh726/chalk.git", rev = "c8f342bf5e48051333d0b2c7fab81347fc21c474" } -chalk-ir = { git = "https://github.com/jackh726/chalk.git", rev = "c8f342bf5e48051333d0b2c7fab81347fc21c474" } +chalk-solve = { git = "https://github.com/rust-lang/chalk.git", rev = "ea1ca4ddc43abcfed77420f294a3713fac714e18" } +chalk-ir = { git = "https://github.com/rust-lang/chalk.git", rev = "ea1ca4ddc43abcfed77420f294a3713fac714e18" } smallvec = { version = "1.0", features = ["union", "may_dangle"] } rustc_infer = { path = "../librustc_infer" } rustc_trait_selection = { path = "../librustc_trait_selection" } diff --git a/src/librustc_traits/chalk/lowering.rs b/src/librustc_traits/chalk/lowering.rs index 08fbca34177bd..c8a9a42fc13d4 100644 --- a/src/librustc_traits/chalk/lowering.rs +++ b/src/librustc_traits/chalk/lowering.rs @@ -97,8 +97,28 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::InEnvironment None, + ty::PredicateKind::RegionOutlives(predicate) => { + let (predicate, binders, _named_regions) = + collect_bound_vars(interner, interner.tcx, predicate); + + Some( + chalk_ir::ProgramClauseData::ForAll(chalk_ir::Binders::new( + binders, + chalk_ir::ProgramClauseImplication { + consequence: chalk_ir::DomainGoal::Holds( + chalk_ir::WhereClause::LifetimeOutlives(chalk_ir::LifetimeOutlives { + a: predicate.0.lower_into(interner), + b: predicate.1.lower_into(interner), + }) + ), + conditions: chalk_ir::Goals::new(interner), + priority: chalk_ir::ClausePriority::High, + }, + )) + .intern(interner), + ) + }, + // FIXME(chalk): need to add TypeOutlives ty::PredicateKind::TypeOutlives(_) => None, ty::PredicateKind::Projection(predicate) => { let (predicate, binders, _named_regions) = @@ -156,10 +176,24 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::GoalData>> for ty::Predi fn lower_into(self, interner: &RustInterner<'tcx>) -> chalk_ir::GoalData> { match self.kind() { ty::PredicateKind::Trait(predicate, _) => predicate.lower_into(interner), - // FIXME(chalk): we need to register constraints. - ty::PredicateKind::RegionOutlives(_predicate) => { - chalk_ir::GoalData::All(chalk_ir::Goals::new(interner)) + ty::PredicateKind::RegionOutlives(predicate) => { + let (predicate, binders, _named_regions) = + collect_bound_vars(interner, interner.tcx, predicate); + + chalk_ir::GoalData::Quantified( + chalk_ir::QuantifierKind::ForAll, + chalk_ir::Binders::new( + binders, + chalk_ir::GoalData::DomainGoal(chalk_ir::DomainGoal::Holds( + chalk_ir::WhereClause::LifetimeOutlives(chalk_ir::LifetimeOutlives { + a: predicate.0.lower_into(interner), + b: predicate.1.lower_into(interner), + }) + )).intern(interner) + ) + ) } + // FIXME(chalk): TypeOutlives ty::PredicateKind::TypeOutlives(_predicate) => { chalk_ir::GoalData::All(chalk_ir::Goals::new(interner)) } @@ -182,12 +216,15 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::GoalData>> for ty::Predi GenericArgKind::Lifetime(lt) => bug!("unexpect well formed predicate: {:?}", lt), }, + ty::PredicateKind::ObjectSafe(t) => { + chalk_ir::GoalData::DomainGoal(chalk_ir::DomainGoal::ObjectSafe(chalk_ir::TraitId(*t))) + } + // FIXME(chalk): other predicates // // We can defer this, but ultimately we'll want to express // some of these in terms of chalk operations. - ty::PredicateKind::ObjectSafe(..) - | ty::PredicateKind::ClosureKind(..) + ty::PredicateKind::ClosureKind(..) | ty::PredicateKind::Subtype(..) | ty::PredicateKind::ConstEvaluatable(..) | ty::PredicateKind::ConstEquate(..) => { @@ -484,7 +521,19 @@ impl<'tcx> LowerInto<'tcx, Option None, + ty::PredicateKind::RegionOutlives(predicate) => { + let (predicate, binders, _named_regions) = + collect_bound_vars(interner, interner.tcx, predicate); + + Some(chalk_ir::Binders::new( + binders, + chalk_ir::WhereClause::LifetimeOutlives(chalk_ir::LifetimeOutlives { + a: predicate.0.lower_into(interner), + b: predicate.1.lower_into(interner), + }), + )) + + }, ty::PredicateKind::TypeOutlives(_predicate) => None, ty::PredicateKind::Projection(_predicate) => None, ty::PredicateKind::WellFormed(_ty) => None, diff --git a/src/librustc_traits/chalk/mod.rs b/src/librustc_traits/chalk/mod.rs index 4d047d2107af5..d8f9a40b9432e 100644 --- a/src/librustc_traits/chalk/mod.rs +++ b/src/librustc_traits/chalk/mod.rs @@ -199,7 +199,7 @@ crate fn evaluate_goal<'tcx>( .map(|s| match s { Solution::Unique(_subst) => { // FIXME(chalk): handle constraints - assert!(_subst.value.constraints.is_empty()); + // assert!(_subst.value.constraints.is_empty()); make_solution(_subst.value.subst) } Solution::Ambig(_guidance) => { From 7a5b93977d5d72e88dcbdbec93c0b2860f074e84 Mon Sep 17 00:00:00 2001 From: Jack Huey Date: Sat, 30 May 2020 02:21:33 -0400 Subject: [PATCH 12/35] Lower consts --- src/librustc_middle/traits/chalk.rs | 3 +- src/librustc_traits/chalk/db.rs | 4 +- src/librustc_traits/chalk/lowering.rs | 75 +++++++++++++++------------ 3 files changed, 47 insertions(+), 35 deletions(-) diff --git a/src/librustc_middle/traits/chalk.rs b/src/librustc_middle/traits/chalk.rs index 9ce6cc3a51114..624fc3b3fb7b7 100644 --- a/src/librustc_middle/traits/chalk.rs +++ b/src/librustc_middle/traits/chalk.rs @@ -5,6 +5,7 @@ //! its name suggest, is to provide an abstraction boundary for creating //! interned Chalk types. +use rustc_middle::mir::interpret::ConstValue; use rustc_middle::ty::fold::{TypeFoldable, TypeFolder, TypeVisitor}; use rustc_middle::ty::{self, Ty, TyCtxt}; @@ -63,7 +64,7 @@ impl<'tcx> chalk_ir::interner::Interner for RustInterner<'tcx> { type InternedType = Box>; type InternedLifetime = Box>; type InternedConst = Box>; - type InternedConcreteConst = u32; + type InternedConcreteConst = ConstValue<'tcx>; type InternedGenericArg = Box>; type InternedGoal = Box>; type InternedGoals = Vec>; diff --git a/src/librustc_traits/chalk/db.rs b/src/librustc_traits/chalk/db.rs index 5b00d32276831..4976ba06815c8 100644 --- a/src/librustc_traits/chalk/db.rs +++ b/src/librustc_traits/chalk/db.rs @@ -468,8 +468,8 @@ fn binders_for<'tcx>( ty::subst::GenericArgKind::Type(_ty) => { chalk_ir::VariableKind::Ty(chalk_ir::TyKind::General) } - ty::subst::GenericArgKind::Const(_const) => { - chalk_ir::VariableKind::Ty(chalk_ir::TyKind::General) + ty::subst::GenericArgKind::Const(c) => { + chalk_ir::VariableKind::Const(c.ty.lower_into(interner)) } }), ) diff --git a/src/librustc_traits/chalk/lowering.rs b/src/librustc_traits/chalk/lowering.rs index c8a9a42fc13d4..3ea3a63524954 100644 --- a/src/librustc_traits/chalk/lowering.rs +++ b/src/librustc_traits/chalk/lowering.rs @@ -100,16 +100,18 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::InEnvironment { let (predicate, binders, _named_regions) = collect_bound_vars(interner, interner.tcx, predicate); - + Some( chalk_ir::ProgramClauseData::ForAll(chalk_ir::Binders::new( binders, chalk_ir::ProgramClauseImplication { consequence: chalk_ir::DomainGoal::Holds( - chalk_ir::WhereClause::LifetimeOutlives(chalk_ir::LifetimeOutlives { - a: predicate.0.lower_into(interner), - b: predicate.1.lower_into(interner), - }) + chalk_ir::WhereClause::LifetimeOutlives( + chalk_ir::LifetimeOutlives { + a: predicate.0.lower_into(interner), + b: predicate.1.lower_into(interner), + }, + ), ), conditions: chalk_ir::Goals::new(interner), priority: chalk_ir::ClausePriority::High, @@ -117,7 +119,7 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::InEnvironment None, ty::PredicateKind::Projection(predicate) => { @@ -188,9 +190,10 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::GoalData>> for ty::Predi chalk_ir::WhereClause::LifetimeOutlives(chalk_ir::LifetimeOutlives { a: predicate.0.lower_into(interner), b: predicate.1.lower_into(interner), - }) - )).intern(interner) - ) + }), + )) + .intern(interner), + ), ) } // FIXME(chalk): TypeOutlives @@ -216,9 +219,9 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::GoalData>> for ty::Predi GenericArgKind::Lifetime(lt) => bug!("unexpect well formed predicate: {:?}", lt), }, - ty::PredicateKind::ObjectSafe(t) => { - chalk_ir::GoalData::DomainGoal(chalk_ir::DomainGoal::ObjectSafe(chalk_ir::TraitId(*t))) - } + ty::PredicateKind::ObjectSafe(t) => chalk_ir::GoalData::DomainGoal( + chalk_ir::DomainGoal::ObjectSafe(chalk_ir::TraitId(*t)), + ), // FIXME(chalk): other predicates // @@ -335,25 +338,34 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::Ty>> for Ty<'tcx> { Adt(def, substs) => apply(struct_ty(def.did), substs.lower_into(interner)), Foreign(_def_id) => unimplemented!(), Str => apply(chalk_ir::TypeName::Str, empty()), - Array(ty, _) => apply( - chalk_ir::TypeName::Array, - chalk_ir::Substitution::from( - interner, - &[ - chalk_ir::GenericArgData::Ty(ty.lower_into(interner)).intern(interner), - chalk_ir::GenericArgData::Const( - chalk_ir::ConstData { - ty: apply(chalk_ir::TypeName::Tuple(0), empty()), - value: chalk_ir::ConstValue::Concrete(chalk_ir::ConcreteConst { - interned: 0, - }), - } + Array(ty, len) => { + let value = match len.val { + ty::ConstKind::Value(val) => { + chalk_ir::ConstValue::Concrete(chalk_ir::ConcreteConst { interned: val }) + } + ty::ConstKind::Bound(db, bound) => { + chalk_ir::ConstValue::BoundVar(chalk_ir::BoundVar::new( + chalk_ir::DebruijnIndex::new(db.as_u32()), + bound.index(), + )) + } + _ => unimplemented!("Const not implemented. {:?}", len.val), + }; + apply( + chalk_ir::TypeName::Array, + chalk_ir::Substitution::from( + interner, + &[ + chalk_ir::GenericArgData::Ty(ty.lower_into(interner)).intern(interner), + chalk_ir::GenericArgData::Const( + chalk_ir::ConstData { ty: len.ty.lower_into(interner), value } + .intern(interner), + ) .intern(interner), - ) - .intern(interner), - ], - ), - ), + ], + ), + ) + } Slice(ty) => apply( chalk_ir::TypeName::Slice, chalk_ir::Substitution::from1( @@ -532,8 +544,7 @@ impl<'tcx> LowerInto<'tcx, Option None, ty::PredicateKind::Projection(_predicate) => None, ty::PredicateKind::WellFormed(_ty) => None, From 4028c21026f27899b1100ae160fe2da4819f2b51 Mon Sep 17 00:00:00 2001 From: Jack Huey Date: Sat, 30 May 2020 02:59:29 -0400 Subject: [PATCH 13/35] Fix building --- Cargo.lock | 2 +- src/librustc_traits/chalk/lowering.rs | 4 ++-- src/tools/tidy/src/deps.rs | 1 - 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5103e6bfd19b4..ab36c56a57f9f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -453,7 +453,7 @@ version = "0.10.1-dev" source = "git+https://github.com/rust-lang/chalk.git?rev=ea1ca4ddc43abcfed77420f294a3713fac714e18#ea1ca4ddc43abcfed77420f294a3713fac714e18" dependencies = [ "chalk-derive", - "lazy_static 1.4.0", + "lazy_static", ] [[package]] diff --git a/src/librustc_traits/chalk/lowering.rs b/src/librustc_traits/chalk/lowering.rs index 3ea3a63524954..6f0fa6bcef9e6 100644 --- a/src/librustc_traits/chalk/lowering.rs +++ b/src/librustc_traits/chalk/lowering.rs @@ -572,7 +572,7 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::Binders LowerInto<'tcx, chalk_ir::Binders chalk_ir::Binders::new( chalk_ir::VariableKinds::new(interner), chalk_ir::WhereClause::Implemented(chalk_ir::TraitRef { - trait_id: chalk_ir::TraitId(*def_id), + trait_id: chalk_ir::TraitId(def_id), substitution: chalk_ir::Substitution::empty(interner), }), ), diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs index aec6b5d25235e..093db2a49d029 100644 --- a/src/tools/tidy/src/deps.rs +++ b/src/tools/tidy/src/deps.rs @@ -79,7 +79,6 @@ const WHITELIST: &[&str] = &[ "byteorder", "cc", "cfg-if", - "chalk-base", "chalk-derive", "chalk-ir", "cloudabi", From 8aa289856dc9eb12859ace1ce66420816bc75770 Mon Sep 17 00:00:00 2001 From: Jack Date: Tue, 2 Jun 2020 17:16:39 -0400 Subject: [PATCH 14/35] Update chalk to 0.11.0 --- Cargo.lock | 20 ++++++++++++-------- src/librustc_middle/Cargo.toml | 3 +-- src/librustc_traits/Cargo.toml | 7 ++----- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ab36c56a57f9f..25eb692207266 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -428,8 +428,9 @@ dependencies = [ [[package]] name = "chalk-derive" -version = "0.10.1-dev" -source = "git+https://github.com/rust-lang/chalk.git?rev=ea1ca4ddc43abcfed77420f294a3713fac714e18#ea1ca4ddc43abcfed77420f294a3713fac714e18" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b9bd01eab87277d973183a1d2e56bace1c11f8242c52c20636fb7dddf343ac9" dependencies = [ "proc-macro2 1.0.3", "quote 1.0.2", @@ -439,8 +440,9 @@ dependencies = [ [[package]] name = "chalk-engine" -version = "0.10.1-dev" -source = "git+https://github.com/rust-lang/chalk.git?rev=ea1ca4ddc43abcfed77420f294a3713fac714e18#ea1ca4ddc43abcfed77420f294a3713fac714e18" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c7a637c3d17ed555aef16e16952a5d1e127bd55178cc30be22afeb92da90c7d" dependencies = [ "chalk-derive", "chalk-ir", @@ -449,8 +451,9 @@ dependencies = [ [[package]] name = "chalk-ir" -version = "0.10.1-dev" -source = "git+https://github.com/rust-lang/chalk.git?rev=ea1ca4ddc43abcfed77420f294a3713fac714e18#ea1ca4ddc43abcfed77420f294a3713fac714e18" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "595e5735ded16c3f3dc348f7b15bbb2521a0080b1863cac38ad5271589944670" dependencies = [ "chalk-derive", "lazy_static", @@ -458,8 +461,9 @@ dependencies = [ [[package]] name = "chalk-solve" -version = "0.10.1-dev" -source = "git+https://github.com/rust-lang/chalk.git?rev=ea1ca4ddc43abcfed77420f294a3713fac714e18#ea1ca4ddc43abcfed77420f294a3713fac714e18" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d9d938139db425867a30cc0cfec0269406d8238d0571d829041eaa7a8455d11" dependencies = [ "chalk-derive", "chalk-engine", diff --git a/src/librustc_middle/Cargo.toml b/src/librustc_middle/Cargo.toml index 9516d449671d6..21d0b102a4a66 100644 --- a/src/librustc_middle/Cargo.toml +++ b/src/librustc_middle/Cargo.toml @@ -30,8 +30,7 @@ rustc_serialize = { path = "../librustc_serialize" } rustc_ast = { path = "../librustc_ast" } rustc_span = { path = "../librustc_span" } byteorder = { version = "1.3" } -chalk-ir = { git = "https://github.com/rust-lang/chalk.git", rev = "ea1ca4ddc43abcfed77420f294a3713fac714e18" } -#chalk-ir = "0.10.0" +chalk-ir = "0.11.0" smallvec = { version = "1.0", features = ["union", "may_dangle"] } measureme = "0.7.1" rustc_session = { path = "../librustc_session" } diff --git a/src/librustc_traits/Cargo.toml b/src/librustc_traits/Cargo.toml index f141daa9f936b..8def98a9603d8 100644 --- a/src/librustc_traits/Cargo.toml +++ b/src/librustc_traits/Cargo.toml @@ -16,11 +16,8 @@ rustc_hir = { path = "../librustc_hir" } rustc_index = { path = "../librustc_index" } rustc_ast = { path = "../librustc_ast" } rustc_span = { path = "../librustc_span" } -#chalk-ir = "0.10.0" -#chalk-rust-ir = "0.10.0" -#chalk-solve = "0.10.0" -chalk-solve = { git = "https://github.com/rust-lang/chalk.git", rev = "ea1ca4ddc43abcfed77420f294a3713fac714e18" } -chalk-ir = { git = "https://github.com/rust-lang/chalk.git", rev = "ea1ca4ddc43abcfed77420f294a3713fac714e18" } +chalk-ir = "0.11.0" +chalk-solve = "0.11.0" smallvec = { version = "1.0", features = ["union", "may_dangle"] } rustc_infer = { path = "../librustc_infer" } rustc_trait_selection = { path = "../librustc_trait_selection" } From 852313a46e513cbba4e5f4baf094e4a7088b01ff Mon Sep 17 00:00:00 2001 From: Jack Huey Date: Wed, 3 Jun 2020 12:21:56 -0400 Subject: [PATCH 15/35] Nits and change skip_binder to no_bound_vars for fndef --- src/librustc_traits/chalk/db.rs | 12 +++++++----- src/librustc_traits/chalk/mod.rs | 1 - src/test/ui/chalkify/inherent_impl.rs | 15 +++++++++++++++ 3 files changed, 22 insertions(+), 6 deletions(-) diff --git a/src/librustc_traits/chalk/db.rs b/src/librustc_traits/chalk/db.rs index 4976ba06815c8..78fb787a319ef 100644 --- a/src/librustc_traits/chalk/db.rs +++ b/src/librustc_traits/chalk/db.rs @@ -8,7 +8,7 @@ use rustc_middle::traits::ChalkRustInterner as RustInterner; use rustc_middle::ty::subst::{InternalSubsts, Subst, SubstsRef}; -use rustc_middle::ty::{self, AssocItemContainer, AssocKind, TyCtxt}; +use rustc_middle::ty::{self, AssocItemContainer, AssocKind, Binder, TyCtxt}; use rustc_hir::def_id::DefId; @@ -177,10 +177,12 @@ impl<'tcx> chalk_solve::RustIrDatabase> for RustIrDatabase<'t .filter_map(|wc| LowerInto::>>>::lower_into(wc, &self.interner)).collect(); let sig = self.tcx.fn_sig(def_id); - // FIXME(chalk): Why does this have a Binder - let argument_types = sig - .inputs() - .skip_binder() + // FIXME(chalk): collect into an intermediate SmallVec here since + // we need `TypeFoldable` for `no_bound_vars` + let argument_types: Binder> = sig.map_bound(|i| i.inputs().iter().copied().collect()); + let argument_types = argument_types + .no_bound_vars() + .expect("FIXME(chalk): late-bound fn parameters not supported in chalk") .iter() .map(|t| t.subst(self.tcx, &bound_vars).lower_into(&self.interner)) .collect(); diff --git a/src/librustc_traits/chalk/mod.rs b/src/librustc_traits/chalk/mod.rs index d8f9a40b9432e..6f657be0908b4 100644 --- a/src/librustc_traits/chalk/mod.rs +++ b/src/librustc_traits/chalk/mod.rs @@ -199,7 +199,6 @@ crate fn evaluate_goal<'tcx>( .map(|s| match s { Solution::Unique(_subst) => { // FIXME(chalk): handle constraints - // assert!(_subst.value.constraints.is_empty()); make_solution(_subst.value.subst) } Solution::Ambig(_guidance) => { diff --git a/src/test/ui/chalkify/inherent_impl.rs b/src/test/ui/chalkify/inherent_impl.rs index 44e120c1eebba..9dd9eb320ddd3 100644 --- a/src/test/ui/chalkify/inherent_impl.rs +++ b/src/test/ui/chalkify/inherent_impl.rs @@ -1,5 +1,7 @@ // run-pass // compile-flags: -Z chalk +// FIXME(chalk): remove when uncommented +#![allow(dead_code, unused_variables)] trait Foo { } @@ -9,6 +11,8 @@ struct S { x: T, } +// FIXME(chalk): need late-bound regions on FnDefs +/* fn only_foo(_x: &T) { } impl S { @@ -17,6 +21,7 @@ impl S { only_foo(&self.x) } } +*/ trait Bar { } impl Bar for u32 { } @@ -26,10 +31,16 @@ fn only_bar() { } impl S { // Test that the environment of `dummy_bar` adds up with the environment // of the inherent impl. + // FIXME(chalk): need late-bound regions on FnDefs + /* fn dummy_bar(&self) { only_foo(&self.x); only_bar::(); } + */ + fn dummy_bar() { + only_bar::(); + } } fn main() { @@ -37,6 +48,10 @@ fn main() { x: 5, }; + // FIXME(chalk): need late-bound regions on FnDefs + /* s.dummy_foo(); s.dummy_bar::(); + */ + S::::dummy_bar::(); } From 645af624db5b032aedac035862aeaf2286c90ee1 Mon Sep 17 00:00:00 2001 From: Jack Huey Date: Wed, 3 Jun 2020 13:33:28 -0400 Subject: [PATCH 16/35] Change InternedAdtDef to &'tcx AdtDef --- src/librustc_middle/traits/chalk.rs | 4 +- src/librustc_traits/chalk/db.rs | 54 ++++++++++++--------------- src/librustc_traits/chalk/lowering.rs | 3 +- 3 files changed, 28 insertions(+), 33 deletions(-) diff --git a/src/librustc_middle/traits/chalk.rs b/src/librustc_middle/traits/chalk.rs index 624fc3b3fb7b7..a49a0045812b0 100644 --- a/src/librustc_middle/traits/chalk.rs +++ b/src/librustc_middle/traits/chalk.rs @@ -7,7 +7,7 @@ use rustc_middle::mir::interpret::ConstValue; use rustc_middle::ty::fold::{TypeFoldable, TypeFolder, TypeVisitor}; -use rustc_middle::ty::{self, Ty, TyCtxt}; +use rustc_middle::ty::{self, AdtDef, Ty, TyCtxt}; use rustc_hir::def_id::DefId; @@ -75,7 +75,7 @@ impl<'tcx> chalk_ir::interner::Interner for RustInterner<'tcx> { type InternedVariableKinds = Vec>; type InternedCanonicalVarKinds = Vec>; type DefId = DefId; - type InternedAdtId = DefId; + type InternedAdtId = &'tcx AdtDef; type Identifier = (); fn debug_program_clause_implication( diff --git a/src/librustc_traits/chalk/db.rs b/src/librustc_traits/chalk/db.rs index 78fb787a319ef..3c83c11b3c438 100644 --- a/src/librustc_traits/chalk/db.rs +++ b/src/librustc_traits/chalk/db.rs @@ -117,15 +117,14 @@ impl<'tcx> chalk_solve::RustIrDatabase> for RustIrDatabase<'t fn adt_datum( &self, - struct_id: chalk_ir::AdtId>, + adt_id: chalk_ir::AdtId>, ) -> Arc>> { - let adt_def_id = struct_id.0; - let adt_def = self.tcx.adt_def(adt_def_id); + let adt_def = adt_id.0; - let bound_vars = bound_vars_for_item(self.tcx, adt_def_id); + let bound_vars = bound_vars_for_item(self.tcx, adt_def.did); let binders = binders_for(&self.interner, bound_vars); - let predicates = self.tcx.predicates_of(adt_def_id).predicates; + let predicates = self.tcx.predicates_of(adt_def.did).predicates; let where_clauses: Vec<_> = predicates .into_iter() .map(|(wc, _)| wc.subst(self.tcx, bound_vars)) @@ -149,13 +148,13 @@ impl<'tcx> chalk_solve::RustIrDatabase> for RustIrDatabase<'t ty::AdtKind::Enum => vec![], }; let struct_datum = Arc::new(chalk_solve::rust_ir::AdtDatum { - id: struct_id, + id: adt_id, binders: chalk_ir::Binders::new( binders, chalk_solve::rust_ir::AdtDatumBound { fields, where_clauses }, ), flags: chalk_solve::rust_ir::AdtFlags { - upstream: !adt_def_id.is_local(), + upstream: !adt_def.did.is_local(), fundamental: adt_def.is_fundamental(), }, }); @@ -179,7 +178,8 @@ impl<'tcx> chalk_solve::RustIrDatabase> for RustIrDatabase<'t let sig = self.tcx.fn_sig(def_id); // FIXME(chalk): collect into an intermediate SmallVec here since // we need `TypeFoldable` for `no_bound_vars` - let argument_types: Binder> = sig.map_bound(|i| i.inputs().iter().copied().collect()); + let argument_types: Binder> = + sig.map_bound(|i| i.inputs().iter().copied().collect()); let argument_types = argument_types .no_bound_vars() .expect("FIXME(chalk): late-bound fn parameters not supported in chalk") @@ -259,17 +259,17 @@ impl<'tcx> chalk_solve::RustIrDatabase> for RustIrDatabase<'t fn impl_provided_for( &self, auto_trait_id: chalk_ir::TraitId>, - struct_id: chalk_ir::AdtId>, + adt_id: chalk_ir::AdtId>, ) -> bool { let trait_def_id = auto_trait_id.0; - let adt_def_id = struct_id.0; + let adt_def = adt_id.0; let all_impls = self.tcx.all_impls(trait_def_id); for impl_def_id in all_impls { let trait_ref = self.tcx.impl_trait_ref(impl_def_id).unwrap(); let self_ty = trait_ref.self_ty(); match self_ty.kind { - ty::Adt(adt_def, _) => { - if adt_def.did == adt_def_id { + ty::Adt(impl_adt_def, _) => { + if impl_adt_def == adt_def { return true; } } @@ -344,16 +344,13 @@ impl<'tcx> chalk_solve::RustIrDatabase> for RustIrDatabase<'t match well_known { chalk_solve::rust_ir::WellKnownTrait::SizedTrait => match ty { Apply(apply) => match apply.name { - chalk_ir::TypeName::Adt(chalk_ir::AdtId(adt_def_id)) => { - let adt_def = self.tcx.adt_def(adt_def_id); - match adt_def.adt_kind() { - ty::AdtKind::Struct | ty::AdtKind::Union => None, - ty::AdtKind::Enum => { - let constraint = self.tcx.adt_sized_constraint(adt_def_id); - if constraint.0.len() > 0 { unimplemented!() } else { Some(true) } - } + chalk_ir::TypeName::Adt(chalk_ir::AdtId(adt_def)) => match adt_def.adt_kind() { + ty::AdtKind::Struct | ty::AdtKind::Union => None, + ty::AdtKind::Enum => { + let constraint = self.tcx.adt_sized_constraint(adt_def.did); + if constraint.0.len() > 0 { unimplemented!() } else { Some(true) } } - } + }, _ => None, }, Dyn(_) @@ -366,16 +363,13 @@ impl<'tcx> chalk_solve::RustIrDatabase> for RustIrDatabase<'t chalk_solve::rust_ir::WellKnownTrait::CopyTrait | chalk_solve::rust_ir::WellKnownTrait::CloneTrait => match ty { Apply(apply) => match apply.name { - chalk_ir::TypeName::Adt(chalk_ir::AdtId(adt_def_id)) => { - let adt_def = self.tcx.adt_def(adt_def_id); - match adt_def.adt_kind() { - ty::AdtKind::Struct | ty::AdtKind::Union => None, - ty::AdtKind::Enum => { - let constraint = self.tcx.adt_sized_constraint(adt_def_id); - if constraint.0.len() > 0 { unimplemented!() } else { Some(true) } - } + chalk_ir::TypeName::Adt(chalk_ir::AdtId(adt_def)) => match adt_def.adt_kind() { + ty::AdtKind::Struct | ty::AdtKind::Union => None, + ty::AdtKind::Enum => { + let constraint = self.tcx.adt_sized_constraint(adt_def.did); + if constraint.0.len() > 0 { unimplemented!() } else { Some(true) } } - } + }, _ => None, }, Dyn(_) diff --git a/src/librustc_traits/chalk/lowering.rs b/src/librustc_traits/chalk/lowering.rs index 6f0fa6bcef9e6..8f84acee7e424 100644 --- a/src/librustc_traits/chalk/lowering.rs +++ b/src/librustc_traits/chalk/lowering.rs @@ -304,7 +304,8 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::Ty>> for Ty<'tcx> { use TyKind::*; let empty = || chalk_ir::Substitution::empty(interner); - let struct_ty = |def_id| chalk_ir::TypeName::Adt(chalk_ir::AdtId(def_id)); + let struct_ty = + |def_id| chalk_ir::TypeName::Adt(chalk_ir::AdtId(interner.tcx.adt_def(def_id))); let apply = |name, substitution| { TyData::Apply(chalk_ir::ApplicationTy { name, substitution }).intern(interner) }; From 4cf2833cf4a7fe7e283e9fc4d96ad124705a678b Mon Sep 17 00:00:00 2001 From: Jack Huey Date: Wed, 3 Jun 2020 16:14:18 -0400 Subject: [PATCH 17/35] Return type is bound too --- src/librustc_traits/chalk/db.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/librustc_traits/chalk/db.rs b/src/librustc_traits/chalk/db.rs index 3c83c11b3c438..235497d374098 100644 --- a/src/librustc_traits/chalk/db.rs +++ b/src/librustc_traits/chalk/db.rs @@ -187,8 +187,12 @@ impl<'tcx> chalk_solve::RustIrDatabase> for RustIrDatabase<'t .map(|t| t.subst(self.tcx, &bound_vars).lower_into(&self.interner)) .collect(); - let return_type = - sig.output().skip_binder().subst(self.tcx, &bound_vars).lower_into(&self.interner); + let return_type = sig + .output() + .no_bound_vars() + .expect("FIXME(chalk): late-bound fn parameters not supported in chalk") + .subst(self.tcx, &bound_vars) + .lower_into(&self.interner); let bound = chalk_solve::rust_ir::FnDefDatumBound { argument_types, where_clauses, return_type }; From 687767af728ce111a7aa24f74cd9068aedb2ab18 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Fri, 29 May 2020 15:09:43 -0700 Subject: [PATCH 18/35] Suggest substituting `'static` lifetime in impl/dyn `Trait + 'static` return types --- .../nice_region_error/static_impl_trait.rs | 64 ++++++++-- src/librustc_middle/ty/context.rs | 13 +- src/librustc_middle/ty/diagnostics.rs | 8 +- ...t_outlive_least_region_or_bound.nll.stderr | 38 +++++- .../must_outlive_least_region_or_bound.rs | 21 ++++ .../must_outlive_least_region_or_bound.stderr | 117 ++++++++++++++++-- 6 files changed, 232 insertions(+), 29 deletions(-) diff --git a/src/librustc_infer/infer/error_reporting/nice_region_error/static_impl_trait.rs b/src/librustc_infer/infer/error_reporting/nice_region_error/static_impl_trait.rs index f4c86ddae604e..88d6c23d51441 100644 --- a/src/librustc_infer/infer/error_reporting/nice_region_error/static_impl_trait.rs +++ b/src/librustc_infer/infer/error_reporting/nice_region_error/static_impl_trait.rs @@ -4,6 +4,7 @@ use crate::infer::error_reporting::msg_span_from_free_region; use crate::infer::error_reporting::nice_region_error::NiceRegionError; use crate::infer::lexical_region_resolve::RegionResolutionError; use rustc_errors::{Applicability, ErrorReported}; +use rustc_hir::{GenericBound, ItemKind, Lifetime, LifetimeName, TyKind}; use rustc_middle::ty::RegionKind; impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { @@ -20,8 +21,9 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { ) = error.clone() { let anon_reg_sup = self.tcx().is_suitable_region(sup_r)?; - let (fn_return_span, is_dyn) = - self.tcx().return_type_impl_or_dyn_trait(anon_reg_sup.def_id)?; + let fn_return = self.tcx().return_type_impl_or_dyn_trait(anon_reg_sup.def_id)?; + let is_dyn = matches!(fn_return.kind, TyKind::TraitObject(..)); + let fn_return_span = fn_return.span; if sub_r == &RegionKind::ReStatic { let sp = var_origin.span(); let return_sp = sub_origin.span(); @@ -67,12 +69,58 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { lifetime, ); // FIXME: account for the need of parens in `&(dyn Trait + '_)` - err.span_suggestion_verbose( - fn_return_span.shrink_to_hi(), - &msg, - format!(" + {}", lifetime_name), - Applicability::MaybeIncorrect, - ); + match fn_return.kind { + TyKind::Def(item_id, _) => { + let item = self.tcx().hir().item(item_id.id); + let opaque = if let ItemKind::OpaqueTy(opaque) = &item.kind { + opaque + } else { + err.emit(); + return Some(ErrorReported); + }; + let (span, sugg) = opaque + .bounds + .iter() + .filter_map(|arg| match arg { + GenericBound::Outlives(Lifetime { + name: LifetimeName::Static, + span, + .. + }) => Some((*span, lifetime_name.clone())), + _ => None, + }) + .next() + .unwrap_or_else(|| { + ( + fn_return_span.shrink_to_hi(), + format!(" + {}", lifetime_name), + ) + }); + + err.span_suggestion_verbose( + span, + &msg, + sugg, + Applicability::MaybeIncorrect, + ); + } + TyKind::TraitObject(_, lt) => { + let (span, sugg) = match lt.name { + LifetimeName::ImplicitObjectLifetimeDefault => ( + fn_return_span.shrink_to_hi(), + format!(" + {}", lifetime_name), + ), + _ => (lt.span, lifetime_name), + }; + err.span_suggestion_verbose( + span, + &msg, + sugg, + Applicability::MaybeIncorrect, + ); + } + _ => {} + } } err.emit(); return Some(ErrorReported); diff --git a/src/librustc_middle/ty/context.rs b/src/librustc_middle/ty/context.rs index d5be3508d2d80..4770993d9cb07 100644 --- a/src/librustc_middle/ty/context.rs +++ b/src/librustc_middle/ty/context.rs @@ -1383,7 +1383,10 @@ impl<'tcx> TyCtxt<'tcx> { }) } - pub fn return_type_impl_or_dyn_trait(&self, scope_def_id: DefId) -> Option<(Span, bool)> { + pub fn return_type_impl_or_dyn_trait( + &self, + scope_def_id: DefId, + ) -> Option<&'tcx hir::Ty<'tcx>> { let hir_id = self.hir().as_local_hir_id(scope_def_id.expect_local()); let hir_output = match self.hir().get(hir_id) { Node::Item(hir::Item { @@ -1429,15 +1432,17 @@ impl<'tcx> TyCtxt<'tcx> { let output = self.erase_late_bound_regions(&sig.output()); if output.is_impl_trait() { let fn_decl = self.hir().fn_decl_by_hir_id(hir_id).unwrap(); - Some((fn_decl.output.span(), false)) + if let hir::FnRetTy::Return(ty) = fn_decl.output { + return Some(ty); + } } else { let mut v = TraitObjectVisitor(vec![]); rustc_hir::intravisit::walk_ty(&mut v, hir_output); if v.0.len() == 1 { - return Some((v.0[0], true)); + return Some(v.0[0]); } - None } + None } _ => None, } diff --git a/src/librustc_middle/ty/diagnostics.rs b/src/librustc_middle/ty/diagnostics.rs index 2e9aa724ac5af..3ca506fe0d590 100644 --- a/src/librustc_middle/ty/diagnostics.rs +++ b/src/librustc_middle/ty/diagnostics.rs @@ -236,21 +236,21 @@ pub fn suggest_constraining_type_param( } } -pub struct TraitObjectVisitor(pub Vec); -impl<'v> hir::intravisit::Visitor<'v> for TraitObjectVisitor { +pub struct TraitObjectVisitor<'tcx>(pub Vec<&'tcx hir::Ty<'tcx>>); +impl<'v> hir::intravisit::Visitor<'v> for TraitObjectVisitor<'v> { type Map = rustc_hir::intravisit::ErasedMap<'v>; fn nested_visit_map(&mut self) -> hir::intravisit::NestedVisitorMap { hir::intravisit::NestedVisitorMap::None } - fn visit_ty(&mut self, ty: &hir::Ty<'_>) { + fn visit_ty(&mut self, ty: &'v hir::Ty<'v>) { if let hir::TyKind::TraitObject( _, hir::Lifetime { name: hir::LifetimeName::ImplicitObjectLifetimeDefault, .. }, ) = ty.kind { - self.0.push(ty.span); + self.0.push(ty); } } } diff --git a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.nll.stderr b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.nll.stderr index 1806d2607a3ac..ca9ca8a9debe2 100644 --- a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.nll.stderr +++ b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.nll.stderr @@ -26,7 +26,34 @@ LL | fn explicit<'a>(x: &'a i32) -> impl Copy + 'a { x } | ^^^^^^^^^^^^^^ error: lifetime may not live long enough - --> $DIR/must_outlive_least_region_or_bound.rs:12:69 + --> $DIR/must_outlive_least_region_or_bound.rs:9:46 + | +LL | fn elided2(x: &i32) -> impl Copy + 'static { x } + | - ^ returning this value requires that `'1` must outlive `'static` + | | + | let's call the lifetime of this reference `'1` + | + = help: consider replacing `'1` with `'static` + +error: lifetime may not live long enough + --> $DIR/must_outlive_least_region_or_bound.rs:12:55 + | +LL | fn explicit2<'a>(x: &'a i32) -> impl Copy + 'static { x } + | -- lifetime `'a` defined here ^ returning this value requires that `'a` must outlive `'static` + | + = help: consider replacing `'a` with `'static` + = help: consider replacing `'a` with `'static` + +error[E0621]: explicit lifetime required in the type of `x` + --> $DIR/must_outlive_least_region_or_bound.rs:15:41 + | +LL | fn foo<'a>(x: &i32) -> impl Copy + 'a { x } + | ---- ^ lifetime `'a` required + | | + | help: add explicit lifetime `'a` to the type of `x`: `&'a i32` + +error: lifetime may not live long enough + --> $DIR/must_outlive_least_region_or_bound.rs:33:69 | LL | fn with_bound<'a>(x: &'a i32) -> impl LifetimeTrait<'a> + 'static { x } | -- lifetime `'a` defined here ^ returning this value requires that `'a` must outlive `'static` @@ -35,7 +62,7 @@ LL | fn with_bound<'a>(x: &'a i32) -> impl LifetimeTrait<'a> + 'static { x } = help: consider replacing `'a` with `'static` error: lifetime may not live long enough - --> $DIR/must_outlive_least_region_or_bound.rs:17:61 + --> $DIR/must_outlive_least_region_or_bound.rs:38:61 | LL | fn move_lifetime_into_fn<'a, 'b>(x: &'a u32, y: &'b u32) -> impl Fn(&'a u32) { | -- -- lifetime `'b` defined here ^^^^^^^^^^^^^^^^ opaque type requires that `'b` must outlive `'a` @@ -45,13 +72,14 @@ LL | fn move_lifetime_into_fn<'a, 'b>(x: &'a u32, y: &'b u32) -> impl Fn(&'a u32 = help: consider adding the following bound: `'b: 'a` error[E0310]: the parameter type `T` may not live long enough - --> $DIR/must_outlive_least_region_or_bound.rs:22:51 + --> $DIR/must_outlive_least_region_or_bound.rs:43:51 | LL | fn ty_param_wont_outlive_static(x: T) -> impl Debug + 'static { | ^^^^^^^^^^^^^^^^^^^^ | = help: consider adding an explicit lifetime bound `T: 'static`... -error: aborting due to 5 previous errors +error: aborting due to 8 previous errors -For more information about this error, try `rustc --explain E0310`. +Some errors have detailed explanations: E0310, E0621. +For more information about an error, try `rustc --explain E0310`. diff --git a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.rs b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.rs index 00f3490991b52..beafe9258209d 100644 --- a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.rs +++ b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.rs @@ -6,6 +6,27 @@ fn elided(x: &i32) -> impl Copy { x } fn explicit<'a>(x: &'a i32) -> impl Copy { x } //~^ ERROR cannot infer an appropriate lifetime +fn elided2(x: &i32) -> impl Copy + 'static { x } +//~^ ERROR cannot infer an appropriate lifetime + +fn explicit2<'a>(x: &'a i32) -> impl Copy + 'static { x } +//~^ ERROR cannot infer an appropriate lifetime + +fn foo<'a>(x: &i32) -> impl Copy + 'a { x } +//~^ ERROR explicit lifetime required in the type of `x` + +fn elided3(x: &i32) -> Box { Box::new(x) } +//~^ ERROR cannot infer an appropriate lifetime + +fn explicit3<'a>(x: &'a i32) -> Box { Box::new(x) } +//~^ ERROR cannot infer an appropriate lifetime + +fn elided4(x: &i32) -> Box { Box::new(x) } +//~^ ERROR explicit lifetime required in the type of `x` + +fn explicit4<'a>(x: &'a i32) -> Box { Box::new(x) } +//~^ ERROR cannot infer an appropriate lifetime + trait LifetimeTrait<'a> {} impl<'a> LifetimeTrait<'a> for &'a i32 {} diff --git a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr index d7dae6a08a7b9..525e271bea9c3 100644 --- a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr +++ b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr @@ -27,7 +27,43 @@ LL | fn explicit<'a>(x: &'a i32) -> impl Copy + 'a { x } | ^^^^ error: cannot infer an appropriate lifetime - --> $DIR/must_outlive_least_region_or_bound.rs:12:69 + --> $DIR/must_outlive_least_region_or_bound.rs:9:46 + | +LL | fn elided2(x: &i32) -> impl Copy + 'static { x } + | ---- ------------------- ^ ...and is captured here + | | | + | | ...is required to be `'static` by this... + | data with this lifetime... + | +help: to permit non-static references in an `impl Trait` value, you can add an explicit bound for the anonymous lifetime #1 defined on the function body at 9:1 + | +LL | fn elided2(x: &i32) -> impl Copy + '_ { x } + | ^^ + +error: cannot infer an appropriate lifetime + --> $DIR/must_outlive_least_region_or_bound.rs:12:55 + | +LL | fn explicit2<'a>(x: &'a i32) -> impl Copy + 'static { x } + | ------- ------------------- ^ ...and is captured here + | | | + | | ...is required to be `'static` by this... + | data with this lifetime... + | +help: to permit non-static references in an `impl Trait` value, you can add an explicit bound for the lifetime `'a` as defined on the function body at 12:14 + | +LL | fn explicit2<'a>(x: &'a i32) -> impl Copy + 'a { x } + | ^^ + +error[E0621]: explicit lifetime required in the type of `x` + --> $DIR/must_outlive_least_region_or_bound.rs:15:24 + | +LL | fn foo<'a>(x: &i32) -> impl Copy + 'a { x } + | ---- ^^^^^^^^^^^^^^ lifetime `'a` required + | | + | help: add explicit lifetime `'a` to the type of `x`: `&'a i32` + +error: cannot infer an appropriate lifetime + --> $DIR/must_outlive_least_region_or_bound.rs:33:69 | LL | fn with_bound<'a>(x: &'a i32) -> impl LifetimeTrait<'a> + 'static { x } | ------- -------------------------------- ^ ...and is captured here @@ -35,13 +71,13 @@ LL | fn with_bound<'a>(x: &'a i32) -> impl LifetimeTrait<'a> + 'static { x } | | ...is required to be `'static` by this... | data with this lifetime... | -help: to permit non-static references in an `impl Trait` value, you can add an explicit bound for the lifetime `'a` as defined on the function body at 12:15 +help: to permit non-static references in an `impl Trait` value, you can add an explicit bound for the lifetime `'a` as defined on the function body at 33:15 | -LL | fn with_bound<'a>(x: &'a i32) -> impl LifetimeTrait<'a> + 'static + 'a { x } - | ^^^^ +LL | fn with_bound<'a>(x: &'a i32) -> impl LifetimeTrait<'a> + 'a { x } + | ^^ error[E0623]: lifetime mismatch - --> $DIR/must_outlive_least_region_or_bound.rs:17:61 + --> $DIR/must_outlive_least_region_or_bound.rs:38:61 | LL | fn move_lifetime_into_fn<'a, 'b>(x: &'a u32, y: &'b u32) -> impl Fn(&'a u32) { | ------- ^^^^^^^^^^^^^^^^ @@ -50,14 +86,79 @@ LL | fn move_lifetime_into_fn<'a, 'b>(x: &'a u32, y: &'b u32) -> impl Fn(&'a u32 | this parameter and the return type are declared with different lifetimes... error[E0310]: the parameter type `T` may not live long enough - --> $DIR/must_outlive_least_region_or_bound.rs:22:51 + --> $DIR/must_outlive_least_region_or_bound.rs:43:51 | LL | fn ty_param_wont_outlive_static(x: T) -> impl Debug + 'static { | -- ^^^^^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds | | | help: consider adding an explicit lifetime bound...: `T: 'static +` -error: aborting due to 5 previous errors +error: cannot infer an appropriate lifetime + --> $DIR/must_outlive_least_region_or_bound.rs:18:50 + | +LL | fn elided3(x: &i32) -> Box { Box::new(x) } + | ---- ---------^- + | | | | + | | | ...and is captured here + | | ...is required to be `'static` by this... + | data with this lifetime... + | +help: to permit non-static references in a `dyn Trait` value, you can add an explicit bound for the anonymous lifetime #1 defined on the function body at 18:1 + | +LL | fn elided3(x: &i32) -> Box { Box::new(x) } + | ^^^^ + +error: cannot infer an appropriate lifetime + --> $DIR/must_outlive_least_region_or_bound.rs:21:59 + | +LL | fn explicit3<'a>(x: &'a i32) -> Box { Box::new(x) } + | ------- ---------^- + | | | | + | | | ...and is captured here + | | ...is required to be `'static` by this... + | data with this lifetime... + | +help: to permit non-static references in a `dyn Trait` value, you can add an explicit bound for the lifetime `'a` as defined on the function body at 21:14 + | +LL | fn explicit3<'a>(x: &'a i32) -> Box { Box::new(x) } + | ^^^^ + +error[E0621]: explicit lifetime required in the type of `x` + --> $DIR/must_outlive_least_region_or_bound.rs:24:51 + | +LL | fn elided4(x: &i32) -> Box { Box::new(x) } + | ---- ^^^^^^^^^^^ lifetime `'static` required + | | + | help: add explicit lifetime `'static` to the type of `x`: `&'static i32` + +error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements + --> $DIR/must_outlive_least_region_or_bound.rs:27:69 + | +LL | fn explicit4<'a>(x: &'a i32) -> Box { Box::new(x) } + | ^ + | +note: first, the lifetime cannot outlive the lifetime `'a` as defined on the function body at 27:14... + --> $DIR/must_outlive_least_region_or_bound.rs:27:14 + | +LL | fn explicit4<'a>(x: &'a i32) -> Box { Box::new(x) } + | ^^ +note: ...so that the expression is assignable + --> $DIR/must_outlive_least_region_or_bound.rs:27:69 + | +LL | fn explicit4<'a>(x: &'a i32) -> Box { Box::new(x) } + | ^ + = note: expected `&i32` + found `&'a i32` + = note: but, the lifetime must be valid for the static lifetime... +note: ...so that the expression is assignable + --> $DIR/must_outlive_least_region_or_bound.rs:27:60 + | +LL | fn explicit4<'a>(x: &'a i32) -> Box { Box::new(x) } + | ^^^^^^^^^^^ + = note: expected `std::boxed::Box<(dyn std::fmt::Debug + 'static)>` + found `std::boxed::Box` + +error: aborting due to 12 previous errors -Some errors have detailed explanations: E0310, E0623. +Some errors have detailed explanations: E0310, E0495, E0621, E0623. For more information about an error, try `rustc --explain E0310`. From c91320f06b0b967b662f62a1c00447b9c87d4542 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Fri, 29 May 2020 18:05:20 -0700 Subject: [PATCH 19/35] When `'static` is explicit, suggest constraining argument with it --- .../infer/error_reporting/mod.rs | 3 +- .../nice_region_error/static_impl_trait.rs | 115 +++++++++++------- src/librustc_middle/ty/diagnostics.rs | 5 +- .../must_outlive_least_region_or_bound.rs | 2 +- .../must_outlive_least_region_or_bound.stderr | 75 +++++++----- src/test/ui/issues/issue-16922.stderr | 2 +- ...ect-lifetime-default-from-box-error.stderr | 2 +- ...ion-object-lifetime-in-coercion.nll.stderr | 19 ++- .../region-object-lifetime-in-coercion.rs | 5 +- .../region-object-lifetime-in-coercion.stderr | 61 +++++++--- .../regions-close-object-into-object-2.stderr | 32 ++--- .../regions-close-object-into-object-4.stderr | 32 ++--- .../regions-proc-bound-capture.nll.stderr | 11 ++ .../ui/regions/regions-proc-bound-capture.rs | 4 +- .../regions/regions-proc-bound-capture.stderr | 25 ++-- .../dyn-trait-underscore.stderr | 2 +- 16 files changed, 237 insertions(+), 158 deletions(-) create mode 100644 src/test/ui/regions/regions-proc-bound-capture.nll.stderr diff --git a/src/librustc_infer/infer/error_reporting/mod.rs b/src/librustc_infer/infer/error_reporting/mod.rs index a59a91e3005aa..f7969fe779d33 100644 --- a/src/librustc_infer/infer/error_reporting/mod.rs +++ b/src/librustc_infer/infer/error_reporting/mod.rs @@ -2037,8 +2037,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { self.tcx.sess, var_origin.span(), E0495, - "cannot infer an appropriate lifetime{} \ - due to conflicting requirements", + "cannot infer an appropriate lifetime{} due to conflicting requirements", var_description ) } diff --git a/src/librustc_infer/infer/error_reporting/nice_region_error/static_impl_trait.rs b/src/librustc_infer/infer/error_reporting/nice_region_error/static_impl_trait.rs index 88d6c23d51441..e24535bba5fdc 100644 --- a/src/librustc_infer/infer/error_reporting/nice_region_error/static_impl_trait.rs +++ b/src/librustc_infer/infer/error_reporting/nice_region_error/static_impl_trait.rs @@ -10,6 +10,7 @@ use rustc_middle::ty::RegionKind; impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { /// Print the error message for lifetime errors when the return type is a static impl Trait. pub(super) fn try_report_static_impl_trait(&self) -> Option { + debug!("try_report_static_impl_trait(error={:?})", self.error); if let Some(ref error) = self.error { if let RegionResolutionError::SubSupConflict( _, @@ -18,19 +19,24 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { sub_r, sup_origin, sup_r, - ) = error.clone() + ) = error { + debug!( + "try_report_static_impl_trait(var={:?}, sub={:?} {:?} sup={:?} {:?})", + var_origin, sub_origin, sub_r, sup_origin, sup_r + ); let anon_reg_sup = self.tcx().is_suitable_region(sup_r)?; + debug!("try_report_static_impl_trait: anon_reg_sup={:?}", anon_reg_sup); let fn_return = self.tcx().return_type_impl_or_dyn_trait(anon_reg_sup.def_id)?; - let is_dyn = matches!(fn_return.kind, TyKind::TraitObject(..)); - let fn_return_span = fn_return.span; - if sub_r == &RegionKind::ReStatic { + debug!("try_report_static_impl_trait: fn_return={:?}", fn_return); + if **sub_r == RegionKind::ReStatic { let sp = var_origin.span(); let return_sp = sub_origin.span(); + let param_info = self.find_param_with_region(sup_r, sub_r)?; let mut err = self.tcx().sess.struct_span_err(sp, "cannot infer an appropriate lifetime"); - let param_info = self.find_param_with_region(sup_r, sub_r)?; err.span_label(param_info.param_ty_span, "data with this lifetime..."); + debug!("try_report_static_impl_trait: param_info={:?}", param_info); // We try to make the output have fewer overlapping spans if possible. if (sp == sup_origin.span() || !return_sp.overlaps(sup_origin.span())) @@ -60,14 +66,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { if sup_r.has_name() { sup_r.to_string() } else { "'_".to_owned() }; // only apply this suggestion onto functions with // explicit non-desugar'able return. - if fn_return_span.desugaring_kind().is_none() { - let msg = format!( - "to permit non-static references in {} `{} Trait` value, you can add \ - an explicit bound for {}", - if is_dyn { "a" } else { "an" }, - if is_dyn { "dyn" } else { "impl" }, - lifetime, - ); + if fn_return.span.desugaring_kind().is_none() { // FIXME: account for the need of parens in `&(dyn Trait + '_)` match fn_return.kind { TyKind::Def(item_id, _) => { @@ -78,7 +77,8 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { err.emit(); return Some(ErrorReported); }; - let (span, sugg) = opaque + + if let Some(span) = opaque .bounds .iter() .filter_map(|arg| match arg { @@ -86,38 +86,71 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { name: LifetimeName::Static, span, .. - }) => Some((*span, lifetime_name.clone())), + }) => Some(*span), _ => None, }) .next() - .unwrap_or_else(|| { - ( - fn_return_span.shrink_to_hi(), - format!(" + {}", lifetime_name), - ) - }); - - err.span_suggestion_verbose( - span, - &msg, - sugg, - Applicability::MaybeIncorrect, - ); - } - TyKind::TraitObject(_, lt) => { - let (span, sugg) = match lt.name { - LifetimeName::ImplicitObjectLifetimeDefault => ( - fn_return_span.shrink_to_hi(), + { + err.span_suggestion_verbose( + span, + "consider changing the `impl Trait`'s explicit \ + `'static` bound", + lifetime_name, + Applicability::MaybeIncorrect, + ); + err.span_suggestion_verbose( + param_info.param_ty_span, + "alternatively, set an explicit `'static` lifetime to \ + this parameter", + param_info.param_ty.to_string(), + Applicability::MaybeIncorrect, + ); + } else { + err.span_suggestion_verbose( + fn_return.span.shrink_to_hi(), + &format!( + "to permit non-static references in an `impl Trait` \ + value, you can add an explicit bound for {}", + lifetime, + ), format!(" + {}", lifetime_name), - ), - _ => (lt.span, lifetime_name), + Applicability::MaybeIncorrect, + ); }; - err.span_suggestion_verbose( - span, - &msg, - sugg, - Applicability::MaybeIncorrect, - ); + } + TyKind::TraitObject(_, lt) => { + match lt.name { + LifetimeName::ImplicitObjectLifetimeDefault => { + err.span_suggestion_verbose( + fn_return.span.shrink_to_hi(), + &format!( + "to permit non-static references in a trait object \ + value, you can add an explicit bound for {}", + lifetime, + ), + format!(" + {}", lifetime_name), + Applicability::MaybeIncorrect, + ); + } + _ => { + err.span_suggestion_verbose( + lt.span, + "consider changing the trait object's explicit \ + `'static` bound", + lifetime_name, + Applicability::MaybeIncorrect, + ); + err.span_suggestion_verbose( + param_info.param_ty_span, + &format!( + "alternatively, set an explicit `'static` lifetime \ + in this parameter", + ), + param_info.param_ty.to_string(), + Applicability::MaybeIncorrect, + ); + } + } } _ => {} } diff --git a/src/librustc_middle/ty/diagnostics.rs b/src/librustc_middle/ty/diagnostics.rs index 3ca506fe0d590..a2812e117ed39 100644 --- a/src/librustc_middle/ty/diagnostics.rs +++ b/src/librustc_middle/ty/diagnostics.rs @@ -247,7 +247,10 @@ impl<'v> hir::intravisit::Visitor<'v> for TraitObjectVisitor<'v> { fn visit_ty(&mut self, ty: &'v hir::Ty<'v>) { if let hir::TyKind::TraitObject( _, - hir::Lifetime { name: hir::LifetimeName::ImplicitObjectLifetimeDefault, .. }, + hir::Lifetime { + name: hir::LifetimeName::ImplicitObjectLifetimeDefault | hir::LifetimeName::Static, + .. + }, ) = ty.kind { self.0.push(ty); diff --git a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.rs b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.rs index beafe9258209d..837244b022721 100644 --- a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.rs +++ b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.rs @@ -22,7 +22,7 @@ fn explicit3<'a>(x: &'a i32) -> Box { Box::new(x) } //~^ ERROR cannot infer an appropriate lifetime fn elided4(x: &i32) -> Box { Box::new(x) } -//~^ ERROR explicit lifetime required in the type of `x` +//~^ ERROR cannot infer an appropriate lifetime fn explicit4<'a>(x: &'a i32) -> Box { Box::new(x) } //~^ ERROR cannot infer an appropriate lifetime diff --git a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr index 525e271bea9c3..96d4a121c16af 100644 --- a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr +++ b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr @@ -35,10 +35,14 @@ LL | fn elided2(x: &i32) -> impl Copy + 'static { x } | | ...is required to be `'static` by this... | data with this lifetime... | -help: to permit non-static references in an `impl Trait` value, you can add an explicit bound for the anonymous lifetime #1 defined on the function body at 9:1 +help: consider changing the `impl Trait`'s explicit `'static` bound | LL | fn elided2(x: &i32) -> impl Copy + '_ { x } | ^^ +help: alternatively, set an explicit `'static` lifetime to this parameter + | +LL | fn elided2(x: &'static i32) -> impl Copy + 'static { x } + | ^^^^^^^^^^^^ error: cannot infer an appropriate lifetime --> $DIR/must_outlive_least_region_or_bound.rs:12:55 @@ -49,10 +53,14 @@ LL | fn explicit2<'a>(x: &'a i32) -> impl Copy + 'static { x } | | ...is required to be `'static` by this... | data with this lifetime... | -help: to permit non-static references in an `impl Trait` value, you can add an explicit bound for the lifetime `'a` as defined on the function body at 12:14 +help: consider changing the `impl Trait`'s explicit `'static` bound | LL | fn explicit2<'a>(x: &'a i32) -> impl Copy + 'a { x } | ^^ +help: alternatively, set an explicit `'static` lifetime to this parameter + | +LL | fn explicit2<'a>(x: &'static i32) -> impl Copy + 'static { x } + | ^^^^^^^^^^^^ error[E0621]: explicit lifetime required in the type of `x` --> $DIR/must_outlive_least_region_or_bound.rs:15:24 @@ -71,10 +79,14 @@ LL | fn with_bound<'a>(x: &'a i32) -> impl LifetimeTrait<'a> + 'static { x } | | ...is required to be `'static` by this... | data with this lifetime... | -help: to permit non-static references in an `impl Trait` value, you can add an explicit bound for the lifetime `'a` as defined on the function body at 33:15 +help: consider changing the `impl Trait`'s explicit `'static` bound | LL | fn with_bound<'a>(x: &'a i32) -> impl LifetimeTrait<'a> + 'a { x } | ^^ +help: alternatively, set an explicit `'static` lifetime to this parameter + | +LL | fn with_bound<'a>(x: &'static i32) -> impl LifetimeTrait<'a> + 'static { x } + | ^^^^^^^^^^^^ error[E0623]: lifetime mismatch --> $DIR/must_outlive_least_region_or_bound.rs:38:61 @@ -103,7 +115,7 @@ LL | fn elided3(x: &i32) -> Box { Box::new(x) } | | ...is required to be `'static` by this... | data with this lifetime... | -help: to permit non-static references in a `dyn Trait` value, you can add an explicit bound for the anonymous lifetime #1 defined on the function body at 18:1 +help: to permit non-static references in a trait object value, you can add an explicit bound for the anonymous lifetime #1 defined on the function body at 18:1 | LL | fn elided3(x: &i32) -> Box { Box::new(x) } | ^^^^ @@ -118,47 +130,48 @@ LL | fn explicit3<'a>(x: &'a i32) -> Box { Box::new(x) } | | ...is required to be `'static` by this... | data with this lifetime... | -help: to permit non-static references in a `dyn Trait` value, you can add an explicit bound for the lifetime `'a` as defined on the function body at 21:14 +help: to permit non-static references in a trait object value, you can add an explicit bound for the lifetime `'a` as defined on the function body at 21:14 | LL | fn explicit3<'a>(x: &'a i32) -> Box { Box::new(x) } | ^^^^ -error[E0621]: explicit lifetime required in the type of `x` - --> $DIR/must_outlive_least_region_or_bound.rs:24:51 +error: cannot infer an appropriate lifetime + --> $DIR/must_outlive_least_region_or_bound.rs:24:60 | LL | fn elided4(x: &i32) -> Box { Box::new(x) } - | ---- ^^^^^^^^^^^ lifetime `'static` required - | | - | help: add explicit lifetime `'static` to the type of `x`: `&'static i32` - -error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements - --> $DIR/must_outlive_least_region_or_bound.rs:27:69 + | ---- ---------^- + | | | | + | | | ...and is captured here + | data with this lifetime... ...is required to be `'static` by this... | -LL | fn explicit4<'a>(x: &'a i32) -> Box { Box::new(x) } - | ^ +help: consider changing the trait object's explicit `'static` bound | -note: first, the lifetime cannot outlive the lifetime `'a` as defined on the function body at 27:14... - --> $DIR/must_outlive_least_region_or_bound.rs:27:14 +LL | fn elided4(x: &i32) -> Box { Box::new(x) } + | ^^ +help: alternatively, set an explicit `'static` lifetime in this parameter | -LL | fn explicit4<'a>(x: &'a i32) -> Box { Box::new(x) } - | ^^ -note: ...so that the expression is assignable +LL | fn elided4(x: &'static i32) -> Box { Box::new(x) } + | ^^^^^^^^^^^^ + +error: cannot infer an appropriate lifetime --> $DIR/must_outlive_least_region_or_bound.rs:27:69 | LL | fn explicit4<'a>(x: &'a i32) -> Box { Box::new(x) } - | ^ - = note: expected `&i32` - found `&'a i32` - = note: but, the lifetime must be valid for the static lifetime... -note: ...so that the expression is assignable - --> $DIR/must_outlive_least_region_or_bound.rs:27:60 + | ------- ---------^- + | | | | + | | | ...and is captured here + | data with this lifetime... ...is required to be `'static` by this... | -LL | fn explicit4<'a>(x: &'a i32) -> Box { Box::new(x) } - | ^^^^^^^^^^^ - = note: expected `std::boxed::Box<(dyn std::fmt::Debug + 'static)>` - found `std::boxed::Box` +help: consider changing the trait object's explicit `'static` bound + | +LL | fn explicit4<'a>(x: &'a i32) -> Box { Box::new(x) } + | ^^ +help: alternatively, set an explicit `'static` lifetime in this parameter + | +LL | fn explicit4<'a>(x: &'static i32) -> Box { Box::new(x) } + | ^^^^^^^^^^^^ error: aborting due to 12 previous errors -Some errors have detailed explanations: E0310, E0495, E0621, E0623. +Some errors have detailed explanations: E0310, E0621, E0623. For more information about an error, try `rustc --explain E0310`. diff --git a/src/test/ui/issues/issue-16922.stderr b/src/test/ui/issues/issue-16922.stderr index 02d33aae023ff..038df47e1bd98 100644 --- a/src/test/ui/issues/issue-16922.stderr +++ b/src/test/ui/issues/issue-16922.stderr @@ -9,7 +9,7 @@ LL | Box::new(value) as Box | | ...and is captured here | ...is required to be `'static` by this... | -help: to permit non-static references in a `dyn Trait` value, you can add an explicit bound for the anonymous lifetime #1 defined on the function body at 3:1 +help: to permit non-static references in a trait object value, you can add an explicit bound for the anonymous lifetime #1 defined on the function body at 3:1 | LL | fn foo(value: &T) -> Box { | ^^^^ diff --git a/src/test/ui/object-lifetime/object-lifetime-default-from-box-error.stderr b/src/test/ui/object-lifetime/object-lifetime-default-from-box-error.stderr index 70a9bf22b8db3..555622c9d13c1 100644 --- a/src/test/ui/object-lifetime/object-lifetime-default-from-box-error.stderr +++ b/src/test/ui/object-lifetime/object-lifetime-default-from-box-error.stderr @@ -7,7 +7,7 @@ LL | fn load(ss: &mut SomeStruct) -> Box { LL | ss.r | ^^^^ ...is captured and required to be `'static` here | -help: to permit non-static references in a `dyn Trait` value, you can add an explicit bound for the anonymous lifetime #2 defined on the function body at 14:1 +help: to permit non-static references in a trait object value, you can add an explicit bound for the anonymous lifetime #2 defined on the function body at 14:1 | LL | fn load(ss: &mut SomeStruct) -> Box { | ^^^^ diff --git a/src/test/ui/regions/region-object-lifetime-in-coercion.nll.stderr b/src/test/ui/regions/region-object-lifetime-in-coercion.nll.stderr index bf02ba8eb9199..7e8f78067e08a 100644 --- a/src/test/ui/regions/region-object-lifetime-in-coercion.nll.stderr +++ b/src/test/ui/regions/region-object-lifetime-in-coercion.nll.stderr @@ -1,21 +1,21 @@ -error[E0621]: explicit lifetime required in the type of `v` +error: lifetime may not live long enough --> $DIR/region-object-lifetime-in-coercion.rs:8:12 | LL | fn a(v: &[u8]) -> Box { - | ----- help: add explicit lifetime `'static` to the type of `v`: `&'static [u8]` + | - let's call the lifetime of this reference `'1` LL | let x: Box = Box::new(v); - | ^^^^^^^^^^^^^^^^^^^^^^ lifetime `'static` required + | ^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'1` must outlive `'static` -error[E0621]: explicit lifetime required in the type of `v` - --> $DIR/region-object-lifetime-in-coercion.rs:14:5 +error: lifetime may not live long enough + --> $DIR/region-object-lifetime-in-coercion.rs:13:5 | LL | fn b(v: &[u8]) -> Box { - | ----- help: add explicit lifetime `'static` to the type of `v`: `&'static [u8]` + | - let's call the lifetime of this reference `'1` LL | Box::new(v) - | ^^^^^^^^^^^ lifetime `'static` required + | ^^^^^^^^^^^ returning this value requires that `'1` must outlive `'static` error: lifetime may not live long enough - --> $DIR/region-object-lifetime-in-coercion.rs:20:5 + --> $DIR/region-object-lifetime-in-coercion.rs:19:5 | LL | fn c(v: &[u8]) -> Box { | - let's call the lifetime of this reference `'1` @@ -24,7 +24,7 @@ LL | Box::new(v) | ^^^^^^^^^^^ returning this value requires that `'1` must outlive `'static` error: lifetime may not live long enough - --> $DIR/region-object-lifetime-in-coercion.rs:24:5 + --> $DIR/region-object-lifetime-in-coercion.rs:23:5 | LL | fn d<'a,'b>(v: &'a [u8]) -> Box { | -- -- lifetime `'b` defined here @@ -37,4 +37,3 @@ LL | Box::new(v) error: aborting due to 4 previous errors -For more information about this error, try `rustc --explain E0621`. diff --git a/src/test/ui/regions/region-object-lifetime-in-coercion.rs b/src/test/ui/regions/region-object-lifetime-in-coercion.rs index d56eaf77b6646..5d199149c39b8 100644 --- a/src/test/ui/regions/region-object-lifetime-in-coercion.rs +++ b/src/test/ui/regions/region-object-lifetime-in-coercion.rs @@ -5,13 +5,12 @@ trait Foo {} impl<'a> Foo for &'a [u8] {} fn a(v: &[u8]) -> Box { - let x: Box = Box::new(v); - //~^ ERROR explicit lifetime required in the type of `v` [E0621] + let x: Box = Box::new(v); //~ ERROR cannot infer an appropriate lifetime x } fn b(v: &[u8]) -> Box { - Box::new(v) //~ ERROR explicit lifetime required in the type of `v` [E0621] + Box::new(v) //~ ERROR cannot infer an appropriate lifetime } fn c(v: &[u8]) -> Box { diff --git a/src/test/ui/regions/region-object-lifetime-in-coercion.stderr b/src/test/ui/regions/region-object-lifetime-in-coercion.stderr index 1462af44cb15a..673300cebc26c 100644 --- a/src/test/ui/regions/region-object-lifetime-in-coercion.stderr +++ b/src/test/ui/regions/region-object-lifetime-in-coercion.stderr @@ -1,21 +1,45 @@ -error[E0621]: explicit lifetime required in the type of `v` - --> $DIR/region-object-lifetime-in-coercion.rs:8:37 +error: cannot infer an appropriate lifetime + --> $DIR/region-object-lifetime-in-coercion.rs:8:46 | LL | fn a(v: &[u8]) -> Box { - | ----- help: add explicit lifetime `'static` to the type of `v`: `&'static [u8]` + | ----- data with this lifetime... LL | let x: Box = Box::new(v); - | ^^^^^^^^^^^ lifetime `'static` required + | ---------^- + | | | + | | ...and is captured here + | ...is required to be `'static` by this... + | +help: consider changing the trait object's explicit `'static` bound + | +LL | fn a(v: &[u8]) -> Box { + | ^^ +help: alternatively, set an explicit `'static` lifetime in this parameter + | +LL | fn a(v: &'static [u8]) -> Box { + | ^^^^^^^^^^^^^ -error[E0621]: explicit lifetime required in the type of `v` - --> $DIR/region-object-lifetime-in-coercion.rs:14:5 +error: cannot infer an appropriate lifetime + --> $DIR/region-object-lifetime-in-coercion.rs:13:14 | LL | fn b(v: &[u8]) -> Box { - | ----- help: add explicit lifetime `'static` to the type of `v`: `&'static [u8]` + | ----- data with this lifetime... LL | Box::new(v) - | ^^^^^^^^^^^ lifetime `'static` required + | ---------^- + | | | + | | ...and is captured here + | ...is required to be `'static` by this... + | +help: consider changing the trait object's explicit `'static` bound + | +LL | fn b(v: &[u8]) -> Box { + | ^^ +help: alternatively, set an explicit `'static` lifetime in this parameter + | +LL | fn b(v: &'static [u8]) -> Box { + | ^^^^^^^^^^^^^ error: cannot infer an appropriate lifetime - --> $DIR/region-object-lifetime-in-coercion.rs:20:14 + --> $DIR/region-object-lifetime-in-coercion.rs:19:14 | LL | fn c(v: &[u8]) -> Box { | ----- data with this lifetime... @@ -26,36 +50,36 @@ LL | Box::new(v) | | ...and is captured here | ...is required to be `'static` by this... | -help: to permit non-static references in a `dyn Trait` value, you can add an explicit bound for the anonymous lifetime #1 defined on the function body at 17:1 +help: to permit non-static references in a trait object value, you can add an explicit bound for the anonymous lifetime #1 defined on the function body at 16:1 | LL | fn c(v: &[u8]) -> Box { | ^^^^ error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements - --> $DIR/region-object-lifetime-in-coercion.rs:24:14 + --> $DIR/region-object-lifetime-in-coercion.rs:23:14 | LL | Box::new(v) | ^ | -note: first, the lifetime cannot outlive the lifetime `'a` as defined on the function body at 23:6... - --> $DIR/region-object-lifetime-in-coercion.rs:23:6 +note: first, the lifetime cannot outlive the lifetime `'a` as defined on the function body at 22:6... + --> $DIR/region-object-lifetime-in-coercion.rs:22:6 | LL | fn d<'a,'b>(v: &'a [u8]) -> Box { | ^^ note: ...so that the expression is assignable - --> $DIR/region-object-lifetime-in-coercion.rs:24:14 + --> $DIR/region-object-lifetime-in-coercion.rs:23:14 | LL | Box::new(v) | ^ = note: expected `&[u8]` found `&'a [u8]` -note: but, the lifetime must be valid for the lifetime `'b` as defined on the function body at 23:9... - --> $DIR/region-object-lifetime-in-coercion.rs:23:9 +note: but, the lifetime must be valid for the lifetime `'b` as defined on the function body at 22:9... + --> $DIR/region-object-lifetime-in-coercion.rs:22:9 | LL | fn d<'a,'b>(v: &'a [u8]) -> Box { | ^^ note: ...so that the expression is assignable - --> $DIR/region-object-lifetime-in-coercion.rs:24:5 + --> $DIR/region-object-lifetime-in-coercion.rs:23:5 | LL | Box::new(v) | ^^^^^^^^^^^ @@ -64,5 +88,4 @@ LL | Box::new(v) error: aborting due to 4 previous errors -Some errors have detailed explanations: E0495, E0621. -For more information about an error, try `rustc --explain E0495`. +For more information about this error, try `rustc --explain E0495`. diff --git a/src/test/ui/regions/regions-close-object-into-object-2.stderr b/src/test/ui/regions/regions-close-object-into-object-2.stderr index 147f7f3541816..982ed07232a80 100644 --- a/src/test/ui/regions/regions-close-object-into-object-2.stderr +++ b/src/test/ui/regions/regions-close-object-into-object-2.stderr @@ -1,28 +1,22 @@ -error[E0495]: cannot infer an appropriate lifetime for borrow expression due to conflicting requirements +error: cannot infer an appropriate lifetime --> $DIR/regions-close-object-into-object-2.rs:10:11 | +LL | fn g<'a, T: 'static>(v: Box + 'a>) -> Box { + | ------------------ data with this lifetime... LL | box B(&*v) as Box - | ^^^ - | -note: first, the lifetime cannot outlive the lifetime `'a` as defined on the function body at 9:6... - --> $DIR/regions-close-object-into-object-2.rs:9:6 + | ------^^^--------------- + | | | + | | ...and is captured here + | ...is required to be `'static` by this... | -LL | fn g<'a, T: 'static>(v: Box + 'a>) -> Box { - | ^^ -note: ...so that the type `(dyn A + 'a)` is not borrowed for too long - --> $DIR/regions-close-object-into-object-2.rs:10:11 +help: consider changing the trait object's explicit `'static` bound | -LL | box B(&*v) as Box - | ^^^ - = note: but, the lifetime must be valid for the static lifetime... -note: ...so that the expression is assignable - --> $DIR/regions-close-object-into-object-2.rs:10:5 +LL | fn g<'a, T: 'static>(v: Box + 'a>) -> Box { + | ^^ +help: alternatively, set an explicit `'static` lifetime in this parameter | -LL | box B(&*v) as Box - | ^^^^^^^^^^^^^^^^^^^^^^^^ - = note: expected `std::boxed::Box<(dyn X + 'static)>` - found `std::boxed::Box` +LL | fn g<'a, T: 'static>(v: std::boxed::Box<(dyn A + 'static)>) -> Box { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to previous error -For more information about this error, try `rustc --explain E0495`. diff --git a/src/test/ui/regions/regions-close-object-into-object-4.stderr b/src/test/ui/regions/regions-close-object-into-object-4.stderr index 6e7d6152cd09a..1b82098ee13c2 100644 --- a/src/test/ui/regions/regions-close-object-into-object-4.stderr +++ b/src/test/ui/regions/regions-close-object-into-object-4.stderr @@ -1,28 +1,22 @@ -error[E0495]: cannot infer an appropriate lifetime for borrow expression due to conflicting requirements +error: cannot infer an appropriate lifetime --> $DIR/regions-close-object-into-object-4.rs:10:11 | +LL | fn i<'a, T, U>(v: Box+'a>) -> Box { + | ---------------- data with this lifetime... LL | box B(&*v) as Box - | ^^^ - | -note: first, the lifetime cannot outlive the lifetime `'a` as defined on the function body at 9:6... - --> $DIR/regions-close-object-into-object-4.rs:9:6 + | ------^^^--------------- + | | | + | | ...and is captured here + | ...is required to be `'static` by this... | -LL | fn i<'a, T, U>(v: Box+'a>) -> Box { - | ^^ -note: ...so that the type `(dyn A + 'a)` is not borrowed for too long - --> $DIR/regions-close-object-into-object-4.rs:10:11 +help: consider changing the trait object's explicit `'static` bound | -LL | box B(&*v) as Box - | ^^^ - = note: but, the lifetime must be valid for the static lifetime... -note: ...so that the expression is assignable - --> $DIR/regions-close-object-into-object-4.rs:10:5 +LL | fn i<'a, T, U>(v: Box+'a>) -> Box { + | ^^ +help: alternatively, set an explicit `'static` lifetime in this parameter | -LL | box B(&*v) as Box - | ^^^^^^^^^^^^^^^^^^^^^^^^ - = note: expected `std::boxed::Box<(dyn X + 'static)>` - found `std::boxed::Box` +LL | fn i<'a, T, U>(v: std::boxed::Box<(dyn A + 'static)>) -> Box { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to previous error -For more information about this error, try `rustc --explain E0495`. diff --git a/src/test/ui/regions/regions-proc-bound-capture.nll.stderr b/src/test/ui/regions/regions-proc-bound-capture.nll.stderr new file mode 100644 index 0000000000000..75890b8581537 --- /dev/null +++ b/src/test/ui/regions/regions-proc-bound-capture.nll.stderr @@ -0,0 +1,11 @@ +error: lifetime may not live long enough + --> $DIR/regions-proc-bound-capture.rs:9:5 + | +LL | fn static_proc(x: &isize) -> Box (isize) + 'static> { + | - let's call the lifetime of this reference `'1` +LL | // This is illegal, because the region bound on `proc` is 'static. +LL | Box::new(move || { *x }) + | ^^^^^^^^^^^^^^^^^^^^^^^^ returning this value requires that `'1` must outlive `'static` + +error: aborting due to previous error + diff --git a/src/test/ui/regions/regions-proc-bound-capture.rs b/src/test/ui/regions/regions-proc-bound-capture.rs index 0c903b7384992..8617c0e9da8f7 100644 --- a/src/test/ui/regions/regions-proc-bound-capture.rs +++ b/src/test/ui/regions/regions-proc-bound-capture.rs @@ -4,9 +4,9 @@ fn borrowed_proc<'a>(x: &'a isize) -> Box(isize) + 'a> { Box::new(move|| { *x }) } -fn static_proc(x: &isize) -> Box(isize) + 'static> { +fn static_proc(x: &isize) -> Box (isize) + 'static> { // This is illegal, because the region bound on `proc` is 'static. - Box::new(move|| { *x }) //~ ERROR explicit lifetime required in the type of `x` [E0621] + Box::new(move || { *x }) //~ ERROR cannot infer an appropriate lifetime } fn main() { } diff --git a/src/test/ui/regions/regions-proc-bound-capture.stderr b/src/test/ui/regions/regions-proc-bound-capture.stderr index c53af34456ef3..e7bbfaababe8a 100644 --- a/src/test/ui/regions/regions-proc-bound-capture.stderr +++ b/src/test/ui/regions/regions-proc-bound-capture.stderr @@ -1,12 +1,23 @@ -error[E0621]: explicit lifetime required in the type of `x` - --> $DIR/regions-proc-bound-capture.rs:9:5 +error: cannot infer an appropriate lifetime + --> $DIR/regions-proc-bound-capture.rs:9:14 | -LL | fn static_proc(x: &isize) -> Box(isize) + 'static> { - | ------ help: add explicit lifetime `'static` to the type of `x`: `&'static isize` +LL | fn static_proc(x: &isize) -> Box (isize) + 'static> { + | ------ data with this lifetime... LL | // This is illegal, because the region bound on `proc` is 'static. -LL | Box::new(move|| { *x }) - | ^^^^^^^^^^^^^^^^^^^^^^^ lifetime `'static` required +LL | Box::new(move || { *x }) + | ---------^^^^^^^^^^^^^^- + | | | + | | ...and is captured here + | ...is required to be `'static` by this... + | +help: consider changing the trait object's explicit `'static` bound + | +LL | fn static_proc(x: &isize) -> Box (isize) + '_> { + | ^^ +help: alternatively, set an explicit `'static` lifetime in this parameter + | +LL | fn static_proc(x: &'static isize) -> Box (isize) + 'static> { + | ^^^^^^^^^^^^^^ error: aborting due to previous error -For more information about this error, try `rustc --explain E0621`. diff --git a/src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr b/src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr index 3577dd59289e5..4dc4aac6ceac4 100644 --- a/src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr +++ b/src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr @@ -7,7 +7,7 @@ LL | // ^^^^^^^^^^^^^^^^^^^^^ bound *here* defaults to LL | Box::new(items.iter()) | ---------------^^^^--- ...is captured and required to be `'static` here | -help: to permit non-static references in a `dyn Trait` value, you can add an explicit bound for the anonymous lifetime #1 defined on the function body at 6:1 +help: to permit non-static references in a trait object value, you can add an explicit bound for the anonymous lifetime #1 defined on the function body at 6:1 | LL | fn a(items: &[T]) -> Box + '_> { | ^^^^ From abf74b9e729463a18f5da1d79cecaf9f4fc07d17 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Fri, 29 May 2020 18:59:42 -0700 Subject: [PATCH 20/35] Reduce verbosity of suggestion message and mention lifetime in label --- .../nice_region_error/static_impl_trait.rs | 87 ++++++++++--------- .../ui/async-await/issues/issue-62097.stderr | 2 +- .../must_outlive_least_region_or_bound.stderr | 38 ++++---- .../static-return-lifetime-infered.stderr | 8 +- src/test/ui/issues/issue-16922.stderr | 4 +- ...ect-lifetime-default-from-box-error.stderr | 4 +- .../region-object-lifetime-in-coercion.stderr | 12 +-- .../regions-close-object-into-object-2.stderr | 4 +- .../regions-close-object-into-object-4.stderr | 4 +- .../regions/regions-proc-bound-capture.stderr | 4 +- ...types_pin_lifetime_impl_trait-async.stderr | 2 +- ..._self_types_pin_lifetime_impl_trait.stderr | 4 +- .../missing-lifetimes-in-signature.stderr | 4 +- .../dyn-trait-underscore.stderr | 4 +- 14 files changed, 95 insertions(+), 86 deletions(-) diff --git a/src/librustc_infer/infer/error_reporting/nice_region_error/static_impl_trait.rs b/src/librustc_infer/infer/error_reporting/nice_region_error/static_impl_trait.rs index e24535bba5fdc..e9f165d309f8f 100644 --- a/src/librustc_infer/infer/error_reporting/nice_region_error/static_impl_trait.rs +++ b/src/librustc_infer/infer/error_reporting/nice_region_error/static_impl_trait.rs @@ -1,6 +1,5 @@ //! Error Reporting for static impl Traits. -use crate::infer::error_reporting::msg_span_from_free_region; use crate::infer::error_reporting::nice_region_error::NiceRegionError; use crate::infer::lexical_region_resolve::RegionResolutionError; use rustc_errors::{Applicability, ErrorReported}; @@ -33,9 +32,17 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { let sp = var_origin.span(); let return_sp = sub_origin.span(); let param_info = self.find_param_with_region(sup_r, sub_r)?; + let (lifetime_name, lifetime) = if sup_r.has_name() { + (sup_r.to_string(), format!("lifetime `{}`", sup_r)) + } else { + ("'_".to_owned(), "the anonymous lifetime `'_`".to_string()) + }; let mut err = self.tcx().sess.struct_span_err(sp, "cannot infer an appropriate lifetime"); - err.span_label(param_info.param_ty_span, "data with this lifetime..."); + err.span_label( + param_info.param_ty_span, + &format!("this data with {}...", lifetime), + ); debug!("try_report_static_impl_trait: param_info={:?}", param_info); // We try to make the output have fewer overlapping spans if possible. @@ -60,10 +67,6 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { ); } - let (lifetime, _) = msg_span_from_free_region(self.tcx(), sup_r); - - let lifetime_name = - if sup_r.has_name() { sup_r.to_string() } else { "'_".to_owned() }; // only apply this suggestion onto functions with // explicit non-desugar'able return. if fn_return.span.desugaring_kind().is_none() { @@ -93,8 +96,11 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { { err.span_suggestion_verbose( span, - "consider changing the `impl Trait`'s explicit \ - `'static` bound", + &format!( + "consider changing the `impl Trait`'s explicit \ + `'static` bound to {}", + lifetime, + ), lifetime_name, Applicability::MaybeIncorrect, ); @@ -118,40 +124,41 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { ); }; } - TyKind::TraitObject(_, lt) => { - match lt.name { - LifetimeName::ImplicitObjectLifetimeDefault => { - err.span_suggestion_verbose( - fn_return.span.shrink_to_hi(), - &format!( - "to permit non-static references in a trait object \ - value, you can add an explicit bound for {}", - lifetime, - ), - format!(" + {}", lifetime_name), - Applicability::MaybeIncorrect, - ); - } - _ => { - err.span_suggestion_verbose( - lt.span, + TyKind::TraitObject(_, lt) => match lt.name { + LifetimeName::ImplicitObjectLifetimeDefault => { + err.span_suggestion_verbose( + fn_return.span.shrink_to_hi(), + &format!( + "to permit non-static references in a trait object \ + value, you can add an explicit bound for {}", + lifetime, + ), + format!(" + {}", lifetime_name), + Applicability::MaybeIncorrect, + ); + } + _ => { + err.span_suggestion_verbose( + lt.span, + &format!( "consider changing the trait object's explicit \ - `'static` bound", - lifetime_name, - Applicability::MaybeIncorrect, - ); - err.span_suggestion_verbose( - param_info.param_ty_span, - &format!( - "alternatively, set an explicit `'static` lifetime \ - in this parameter", - ), - param_info.param_ty.to_string(), - Applicability::MaybeIncorrect, - ); - } + `'static` bound to {}", + lifetime, + ), + lifetime_name, + Applicability::MaybeIncorrect, + ); + err.span_suggestion_verbose( + param_info.param_ty_span, + &format!( + "alternatively, set an explicit `'static` lifetime \ + in this parameter", + ), + param_info.param_ty.to_string(), + Applicability::MaybeIncorrect, + ); } - } + }, _ => {} } } diff --git a/src/test/ui/async-await/issues/issue-62097.stderr b/src/test/ui/async-await/issues/issue-62097.stderr index af8fc2cd2ab45..fff43ae9f47bc 100644 --- a/src/test/ui/async-await/issues/issue-62097.stderr +++ b/src/test/ui/async-await/issues/issue-62097.stderr @@ -4,7 +4,7 @@ error: cannot infer an appropriate lifetime LL | pub async fn run_dummy_fn(&self) { | ^^^^^ | | - | data with this lifetime... + | this data with the anonymous lifetime `'_`... | ...is captured here... LL | foo(|| self.bar()).await; | --- ...and required to be `'static` by this diff --git a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr index 96d4a121c16af..00b6ec38323c3 100644 --- a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr +++ b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr @@ -5,9 +5,9 @@ LL | fn elided(x: &i32) -> impl Copy { x } | ---- --------- ^ ...and is captured here | | | | | ...is required to be `'static` by this... - | data with this lifetime... + | this data with the anonymous lifetime `'_`... | -help: to permit non-static references in an `impl Trait` value, you can add an explicit bound for the anonymous lifetime #1 defined on the function body at 3:1 +help: to permit non-static references in an `impl Trait` value, you can add an explicit bound for the anonymous lifetime `'_` | LL | fn elided(x: &i32) -> impl Copy + '_ { x } | ^^^^ @@ -19,9 +19,9 @@ LL | fn explicit<'a>(x: &'a i32) -> impl Copy { x } | ------- --------- ^ ...and is captured here | | | | | ...is required to be `'static` by this... - | data with this lifetime... + | this data with lifetime `'a`... | -help: to permit non-static references in an `impl Trait` value, you can add an explicit bound for the lifetime `'a` as defined on the function body at 6:13 +help: to permit non-static references in an `impl Trait` value, you can add an explicit bound for lifetime `'a` | LL | fn explicit<'a>(x: &'a i32) -> impl Copy + 'a { x } | ^^^^ @@ -33,9 +33,9 @@ LL | fn elided2(x: &i32) -> impl Copy + 'static { x } | ---- ------------------- ^ ...and is captured here | | | | | ...is required to be `'static` by this... - | data with this lifetime... + | this data with the anonymous lifetime `'_`... | -help: consider changing the `impl Trait`'s explicit `'static` bound +help: consider changing the `impl Trait`'s explicit `'static` bound to the anonymous lifetime `'_` | LL | fn elided2(x: &i32) -> impl Copy + '_ { x } | ^^ @@ -51,9 +51,9 @@ LL | fn explicit2<'a>(x: &'a i32) -> impl Copy + 'static { x } | ------- ------------------- ^ ...and is captured here | | | | | ...is required to be `'static` by this... - | data with this lifetime... + | this data with lifetime `'a`... | -help: consider changing the `impl Trait`'s explicit `'static` bound +help: consider changing the `impl Trait`'s explicit `'static` bound to lifetime `'a` | LL | fn explicit2<'a>(x: &'a i32) -> impl Copy + 'a { x } | ^^ @@ -77,9 +77,9 @@ LL | fn with_bound<'a>(x: &'a i32) -> impl LifetimeTrait<'a> + 'static { x } | ------- -------------------------------- ^ ...and is captured here | | | | | ...is required to be `'static` by this... - | data with this lifetime... + | this data with lifetime `'a`... | -help: consider changing the `impl Trait`'s explicit `'static` bound +help: consider changing the `impl Trait`'s explicit `'static` bound to lifetime `'a` | LL | fn with_bound<'a>(x: &'a i32) -> impl LifetimeTrait<'a> + 'a { x } | ^^ @@ -113,9 +113,9 @@ LL | fn elided3(x: &i32) -> Box { Box::new(x) } | | | | | | | ...and is captured here | | ...is required to be `'static` by this... - | data with this lifetime... + | this data with the anonymous lifetime `'_`... | -help: to permit non-static references in a trait object value, you can add an explicit bound for the anonymous lifetime #1 defined on the function body at 18:1 +help: to permit non-static references in a trait object value, you can add an explicit bound for the anonymous lifetime `'_` | LL | fn elided3(x: &i32) -> Box { Box::new(x) } | ^^^^ @@ -128,9 +128,9 @@ LL | fn explicit3<'a>(x: &'a i32) -> Box { Box::new(x) } | | | | | | | ...and is captured here | | ...is required to be `'static` by this... - | data with this lifetime... + | this data with lifetime `'a`... | -help: to permit non-static references in a trait object value, you can add an explicit bound for the lifetime `'a` as defined on the function body at 21:14 +help: to permit non-static references in a trait object value, you can add an explicit bound for lifetime `'a` | LL | fn explicit3<'a>(x: &'a i32) -> Box { Box::new(x) } | ^^^^ @@ -142,9 +142,10 @@ LL | fn elided4(x: &i32) -> Box { Box::new(x) } | ---- ---------^- | | | | | | | ...and is captured here - | data with this lifetime... ...is required to be `'static` by this... + | | ...is required to be `'static` by this... + | this data with the anonymous lifetime `'_`... | -help: consider changing the trait object's explicit `'static` bound +help: consider changing the trait object's explicit `'static` bound to the anonymous lifetime `'_` | LL | fn elided4(x: &i32) -> Box { Box::new(x) } | ^^ @@ -160,9 +161,10 @@ LL | fn explicit4<'a>(x: &'a i32) -> Box { Box::new(x) } | ------- ---------^- | | | | | | | ...and is captured here - | data with this lifetime... ...is required to be `'static` by this... + | | ...is required to be `'static` by this... + | this data with lifetime `'a`... | -help: consider changing the trait object's explicit `'static` bound +help: consider changing the trait object's explicit `'static` bound to lifetime `'a` | LL | fn explicit4<'a>(x: &'a i32) -> Box { Box::new(x) } | ^^ diff --git a/src/test/ui/impl-trait/static-return-lifetime-infered.stderr b/src/test/ui/impl-trait/static-return-lifetime-infered.stderr index 1c3a5979ee55b..67d4f60dff6f1 100644 --- a/src/test/ui/impl-trait/static-return-lifetime-infered.stderr +++ b/src/test/ui/impl-trait/static-return-lifetime-infered.stderr @@ -4,13 +4,13 @@ error: cannot infer an appropriate lifetime LL | fn iter_values_anon(&self) -> impl Iterator { | ----- ----------------------- ...is required to be `'static` by this... | | - | data with this lifetime... + | this data with the anonymous lifetime `'_`... LL | self.x.iter().map(|a| a.0) | ------ ^^^^ | | | ...and is captured here | -help: to permit non-static references in an `impl Trait` value, you can add an explicit bound for the anonymous lifetime #1 defined on the method body at 6:5 +help: to permit non-static references in an `impl Trait` value, you can add an explicit bound for the anonymous lifetime `'_` | LL | fn iter_values_anon(&self) -> impl Iterator + '_ { | ^^^^ @@ -21,13 +21,13 @@ error: cannot infer an appropriate lifetime LL | fn iter_values<'a>(&'a self) -> impl Iterator { | -------- ----------------------- ...is required to be `'static` by this... | | - | data with this lifetime... + | this data with lifetime `'a`... LL | self.x.iter().map(|a| a.0) | ------ ^^^^ | | | ...and is captured here | -help: to permit non-static references in an `impl Trait` value, you can add an explicit bound for the lifetime `'a` as defined on the method body at 10:20 +help: to permit non-static references in an `impl Trait` value, you can add an explicit bound for lifetime `'a` | LL | fn iter_values<'a>(&'a self) -> impl Iterator + 'a { | ^^^^ diff --git a/src/test/ui/issues/issue-16922.stderr b/src/test/ui/issues/issue-16922.stderr index 038df47e1bd98..c533a72dfc014 100644 --- a/src/test/ui/issues/issue-16922.stderr +++ b/src/test/ui/issues/issue-16922.stderr @@ -2,14 +2,14 @@ error: cannot infer an appropriate lifetime --> $DIR/issue-16922.rs:4:14 | LL | fn foo(value: &T) -> Box { - | -- data with this lifetime... + | -- this data with the anonymous lifetime `'_`... LL | Box::new(value) as Box | ---------^^^^^- | | | | | ...and is captured here | ...is required to be `'static` by this... | -help: to permit non-static references in a trait object value, you can add an explicit bound for the anonymous lifetime #1 defined on the function body at 3:1 +help: to permit non-static references in a trait object value, you can add an explicit bound for the anonymous lifetime `'_` | LL | fn foo(value: &T) -> Box { | ^^^^ diff --git a/src/test/ui/object-lifetime/object-lifetime-default-from-box-error.stderr b/src/test/ui/object-lifetime/object-lifetime-default-from-box-error.stderr index 555622c9d13c1..6edef8086b937 100644 --- a/src/test/ui/object-lifetime/object-lifetime-default-from-box-error.stderr +++ b/src/test/ui/object-lifetime/object-lifetime-default-from-box-error.stderr @@ -2,12 +2,12 @@ error: cannot infer an appropriate lifetime --> $DIR/object-lifetime-default-from-box-error.rs:18:5 | LL | fn load(ss: &mut SomeStruct) -> Box { - | --------------- data with this lifetime... + | --------------- this data with the anonymous lifetime `'_`... ... LL | ss.r | ^^^^ ...is captured and required to be `'static` here | -help: to permit non-static references in a trait object value, you can add an explicit bound for the anonymous lifetime #2 defined on the function body at 14:1 +help: to permit non-static references in a trait object value, you can add an explicit bound for the anonymous lifetime `'_` | LL | fn load(ss: &mut SomeStruct) -> Box { | ^^^^ diff --git a/src/test/ui/regions/region-object-lifetime-in-coercion.stderr b/src/test/ui/regions/region-object-lifetime-in-coercion.stderr index 673300cebc26c..4b08c4bff2ebc 100644 --- a/src/test/ui/regions/region-object-lifetime-in-coercion.stderr +++ b/src/test/ui/regions/region-object-lifetime-in-coercion.stderr @@ -2,14 +2,14 @@ error: cannot infer an appropriate lifetime --> $DIR/region-object-lifetime-in-coercion.rs:8:46 | LL | fn a(v: &[u8]) -> Box { - | ----- data with this lifetime... + | ----- this data with the anonymous lifetime `'_`... LL | let x: Box = Box::new(v); | ---------^- | | | | | ...and is captured here | ...is required to be `'static` by this... | -help: consider changing the trait object's explicit `'static` bound +help: consider changing the trait object's explicit `'static` bound to the anonymous lifetime `'_` | LL | fn a(v: &[u8]) -> Box { | ^^ @@ -22,14 +22,14 @@ error: cannot infer an appropriate lifetime --> $DIR/region-object-lifetime-in-coercion.rs:13:14 | LL | fn b(v: &[u8]) -> Box { - | ----- data with this lifetime... + | ----- this data with the anonymous lifetime `'_`... LL | Box::new(v) | ---------^- | | | | | ...and is captured here | ...is required to be `'static` by this... | -help: consider changing the trait object's explicit `'static` bound +help: consider changing the trait object's explicit `'static` bound to the anonymous lifetime `'_` | LL | fn b(v: &[u8]) -> Box { | ^^ @@ -42,7 +42,7 @@ error: cannot infer an appropriate lifetime --> $DIR/region-object-lifetime-in-coercion.rs:19:14 | LL | fn c(v: &[u8]) -> Box { - | ----- data with this lifetime... + | ----- this data with the anonymous lifetime `'_`... ... LL | Box::new(v) | ---------^- @@ -50,7 +50,7 @@ LL | Box::new(v) | | ...and is captured here | ...is required to be `'static` by this... | -help: to permit non-static references in a trait object value, you can add an explicit bound for the anonymous lifetime #1 defined on the function body at 16:1 +help: to permit non-static references in a trait object value, you can add an explicit bound for the anonymous lifetime `'_` | LL | fn c(v: &[u8]) -> Box { | ^^^^ diff --git a/src/test/ui/regions/regions-close-object-into-object-2.stderr b/src/test/ui/regions/regions-close-object-into-object-2.stderr index 982ed07232a80..894be310fd14b 100644 --- a/src/test/ui/regions/regions-close-object-into-object-2.stderr +++ b/src/test/ui/regions/regions-close-object-into-object-2.stderr @@ -2,14 +2,14 @@ error: cannot infer an appropriate lifetime --> $DIR/regions-close-object-into-object-2.rs:10:11 | LL | fn g<'a, T: 'static>(v: Box + 'a>) -> Box { - | ------------------ data with this lifetime... + | ------------------ this data with lifetime `'a`... LL | box B(&*v) as Box | ------^^^--------------- | | | | | ...and is captured here | ...is required to be `'static` by this... | -help: consider changing the trait object's explicit `'static` bound +help: consider changing the trait object's explicit `'static` bound to lifetime `'a` | LL | fn g<'a, T: 'static>(v: Box + 'a>) -> Box { | ^^ diff --git a/src/test/ui/regions/regions-close-object-into-object-4.stderr b/src/test/ui/regions/regions-close-object-into-object-4.stderr index 1b82098ee13c2..ce261d78c2909 100644 --- a/src/test/ui/regions/regions-close-object-into-object-4.stderr +++ b/src/test/ui/regions/regions-close-object-into-object-4.stderr @@ -2,14 +2,14 @@ error: cannot infer an appropriate lifetime --> $DIR/regions-close-object-into-object-4.rs:10:11 | LL | fn i<'a, T, U>(v: Box+'a>) -> Box { - | ---------------- data with this lifetime... + | ---------------- this data with lifetime `'a`... LL | box B(&*v) as Box | ------^^^--------------- | | | | | ...and is captured here | ...is required to be `'static` by this... | -help: consider changing the trait object's explicit `'static` bound +help: consider changing the trait object's explicit `'static` bound to lifetime `'a` | LL | fn i<'a, T, U>(v: Box+'a>) -> Box { | ^^ diff --git a/src/test/ui/regions/regions-proc-bound-capture.stderr b/src/test/ui/regions/regions-proc-bound-capture.stderr index e7bbfaababe8a..a0df1815247c3 100644 --- a/src/test/ui/regions/regions-proc-bound-capture.stderr +++ b/src/test/ui/regions/regions-proc-bound-capture.stderr @@ -2,7 +2,7 @@ error: cannot infer an appropriate lifetime --> $DIR/regions-proc-bound-capture.rs:9:14 | LL | fn static_proc(x: &isize) -> Box (isize) + 'static> { - | ------ data with this lifetime... + | ------ this data with the anonymous lifetime `'_`... LL | // This is illegal, because the region bound on `proc` is 'static. LL | Box::new(move || { *x }) | ---------^^^^^^^^^^^^^^- @@ -10,7 +10,7 @@ LL | Box::new(move || { *x }) | | ...and is captured here | ...is required to be `'static` by this... | -help: consider changing the trait object's explicit `'static` bound +help: consider changing the trait object's explicit `'static` bound to the anonymous lifetime `'_` | LL | fn static_proc(x: &isize) -> Box (isize) + '_> { | ^^ diff --git a/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.stderr b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.stderr index 1aeabce5e8aaf..5520341b5b1c3 100644 --- a/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.stderr +++ b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.stderr @@ -4,7 +4,7 @@ error: cannot infer an appropriate lifetime LL | async fn f(self: Pin<&Self>) -> impl Clone { self } | ^^^^ ---------- ---------- ...and required to be `'static` by this | | | - | | data with this lifetime... + | | this data with the anonymous lifetime `'_`... | ...is captured here... error: aborting due to previous error diff --git a/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait.stderr b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait.stderr index 04c475be787b8..5374929f3a45f 100644 --- a/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait.stderr +++ b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait.stderr @@ -5,9 +5,9 @@ LL | fn f(self: Pin<&Self>) -> impl Clone { self } | ---------- ---------- ^^^^ ...and is captured here | | | | | ...is required to be `'static` by this... - | data with this lifetime... + | this data with the anonymous lifetime `'_`... | -help: to permit non-static references in an `impl Trait` value, you can add an explicit bound for the anonymous lifetime #1 defined on the method body at 6:5 +help: to permit non-static references in an `impl Trait` value, you can add an explicit bound for the anonymous lifetime `'_` | LL | fn f(self: Pin<&Self>) -> impl Clone + '_ { self } | ^^^^ diff --git a/src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature.stderr b/src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature.stderr index 5cf170d566ca9..471f3cd14aa3e 100644 --- a/src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature.stderr +++ b/src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature.stderr @@ -12,14 +12,14 @@ error: cannot infer an appropriate lifetime LL | fn foo(g: G, dest: &mut T) -> impl FnOnce() | ------ ------------- ...is required to be `'static` by this... | | - | data with this lifetime... + | this data with the anonymous lifetime `'_`... ... LL | / move || { LL | | *dest = g.get(); LL | | } | |_____^ ...and is captured here | -help: to permit non-static references in an `impl Trait` value, you can add an explicit bound for the anonymous lifetime #1 defined on the function body at 15:1 +help: to permit non-static references in an `impl Trait` value, you can add an explicit bound for the anonymous lifetime `'_` | LL | fn foo(g: G, dest: &mut T) -> impl FnOnce() + '_ | ^^^^ diff --git a/src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr b/src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr index 4dc4aac6ceac4..5fd03f9770e5d 100644 --- a/src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr +++ b/src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr @@ -2,12 +2,12 @@ error: cannot infer an appropriate lifetime --> $DIR/dyn-trait-underscore.rs:8:20 | LL | fn a(items: &[T]) -> Box> { - | ---- data with this lifetime... + | ---- this data with the anonymous lifetime `'_`... LL | // ^^^^^^^^^^^^^^^^^^^^^ bound *here* defaults to `'static` LL | Box::new(items.iter()) | ---------------^^^^--- ...is captured and required to be `'static` here | -help: to permit non-static references in a trait object value, you can add an explicit bound for the anonymous lifetime #1 defined on the function body at 6:1 +help: to permit non-static references in a trait object value, you can add an explicit bound for the anonymous lifetime `'_` | LL | fn a(items: &[T]) -> Box + '_> { | ^^^^ From 50c422e028dd7b66302eabb987fe1da482bee8fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Fri, 29 May 2020 19:46:22 -0700 Subject: [PATCH 21/35] Move overlapping span to a note --- .../nice_region_error/static_impl_trait.rs | 31 ++++++++++++- .../must_outlive_least_region_or_bound.stderr | 44 ++++++++++++------- src/test/ui/issues/issue-16922.stderr | 10 +++-- .../region-object-lifetime-in-coercion.stderr | 30 ++++++++----- .../regions-close-object-into-object-2.stderr | 10 +++-- .../regions-close-object-into-object-4.stderr | 10 +++-- .../regions/regions-proc-bound-capture.stderr | 10 +++-- 7 files changed, 99 insertions(+), 46 deletions(-) diff --git a/src/librustc_infer/infer/error_reporting/nice_region_error/static_impl_trait.rs b/src/librustc_infer/infer/error_reporting/nice_region_error/static_impl_trait.rs index e9f165d309f8f..cc95441b68a03 100644 --- a/src/librustc_infer/infer/error_reporting/nice_region_error/static_impl_trait.rs +++ b/src/librustc_infer/infer/error_reporting/nice_region_error/static_impl_trait.rs @@ -53,7 +53,36 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { // Customize the spans and labels depending on their relative order so // that split sentences flow correctly. - if sup_origin.span().shrink_to_hi() <= return_sp.shrink_to_lo() { + if sup_origin.span().overlaps(return_sp) && sp == sup_origin.span() { + // Avoid the following: + // + // error: cannot infer an appropriate lifetime + // --> $DIR/must_outlive_least_region_or_bound.rs:18:50 + // | + // LL | fn foo(x: &i32) -> Box { Box::new(x) } + // | ---- ---------^- + // | | | | + // | | | ...and is captured here + // | | ...is required to be `'static` by this... + // | this data with the anonymous lifetime `'_`... + // + // and instead show: + // + // error: cannot infer an appropriate lifetime + // --> $DIR/must_outlive_least_region_or_bound.rs:18:50 + // | + // LL | fn foo(x: &i32) -> Box { Box::new(x) } + // | ---- ^ ...is captured here with a `'static` requirement + // | | + // | this data with the anonymous lifetime `'_`... + // | + // note: ...is required to be `'static` by this + // | + // LL | fn elided3(x: &i32) -> Box { Box::new(x) } + // | ^^^^^^^^^^^ + err.span_label(sup_origin.span(), "...is captured here..."); + err.span_note(return_sp, "...and required to be `'static` by this"); + } else if sup_origin.span() <= return_sp { err.span_label(sup_origin.span(), "...is captured here..."); err.span_label(return_sp, "...and required to be `'static` by this"); } else { diff --git a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr index 00b6ec38323c3..2da49379ea8c2 100644 --- a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr +++ b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr @@ -109,12 +109,15 @@ error: cannot infer an appropriate lifetime --> $DIR/must_outlive_least_region_or_bound.rs:18:50 | LL | fn elided3(x: &i32) -> Box { Box::new(x) } - | ---- ---------^- - | | | | - | | | ...and is captured here - | | ...is required to be `'static` by this... + | ---- ^ ...is captured here... + | | | this data with the anonymous lifetime `'_`... | +note: ...and required to be `'static` by this + --> $DIR/must_outlive_least_region_or_bound.rs:18:41 + | +LL | fn elided3(x: &i32) -> Box { Box::new(x) } + | ^^^^^^^^^^^ help: to permit non-static references in a trait object value, you can add an explicit bound for the anonymous lifetime `'_` | LL | fn elided3(x: &i32) -> Box { Box::new(x) } @@ -124,12 +127,15 @@ error: cannot infer an appropriate lifetime --> $DIR/must_outlive_least_region_or_bound.rs:21:59 | LL | fn explicit3<'a>(x: &'a i32) -> Box { Box::new(x) } - | ------- ---------^- - | | | | - | | | ...and is captured here - | | ...is required to be `'static` by this... + | ------- ^ ...is captured here... + | | | this data with lifetime `'a`... | +note: ...and required to be `'static` by this + --> $DIR/must_outlive_least_region_or_bound.rs:21:50 + | +LL | fn explicit3<'a>(x: &'a i32) -> Box { Box::new(x) } + | ^^^^^^^^^^^ help: to permit non-static references in a trait object value, you can add an explicit bound for lifetime `'a` | LL | fn explicit3<'a>(x: &'a i32) -> Box { Box::new(x) } @@ -139,12 +145,15 @@ error: cannot infer an appropriate lifetime --> $DIR/must_outlive_least_region_or_bound.rs:24:60 | LL | fn elided4(x: &i32) -> Box { Box::new(x) } - | ---- ---------^- - | | | | - | | | ...and is captured here - | | ...is required to be `'static` by this... + | ---- ^ ...is captured here... + | | | this data with the anonymous lifetime `'_`... | +note: ...and required to be `'static` by this + --> $DIR/must_outlive_least_region_or_bound.rs:24:51 + | +LL | fn elided4(x: &i32) -> Box { Box::new(x) } + | ^^^^^^^^^^^ help: consider changing the trait object's explicit `'static` bound to the anonymous lifetime `'_` | LL | fn elided4(x: &i32) -> Box { Box::new(x) } @@ -158,12 +167,13 @@ error: cannot infer an appropriate lifetime --> $DIR/must_outlive_least_region_or_bound.rs:27:69 | LL | fn explicit4<'a>(x: &'a i32) -> Box { Box::new(x) } - | ------- ---------^- - | | | | - | | | ...and is captured here - | | ...is required to be `'static` by this... - | this data with lifetime `'a`... + | ------- this data with lifetime `'a`... ^ ...is captured here... | +note: ...and required to be `'static` by this + --> $DIR/must_outlive_least_region_or_bound.rs:27:60 + | +LL | fn explicit4<'a>(x: &'a i32) -> Box { Box::new(x) } + | ^^^^^^^^^^^ help: consider changing the trait object's explicit `'static` bound to lifetime `'a` | LL | fn explicit4<'a>(x: &'a i32) -> Box { Box::new(x) } diff --git a/src/test/ui/issues/issue-16922.stderr b/src/test/ui/issues/issue-16922.stderr index c533a72dfc014..6c0b26a86b651 100644 --- a/src/test/ui/issues/issue-16922.stderr +++ b/src/test/ui/issues/issue-16922.stderr @@ -4,11 +4,13 @@ error: cannot infer an appropriate lifetime LL | fn foo(value: &T) -> Box { | -- this data with the anonymous lifetime `'_`... LL | Box::new(value) as Box - | ---------^^^^^- - | | | - | | ...and is captured here - | ...is required to be `'static` by this... + | ^^^^^ ...is captured here... | +note: ...and required to be `'static` by this + --> $DIR/issue-16922.rs:4:5 + | +LL | Box::new(value) as Box + | ^^^^^^^^^^^^^^^ help: to permit non-static references in a trait object value, you can add an explicit bound for the anonymous lifetime `'_` | LL | fn foo(value: &T) -> Box { diff --git a/src/test/ui/regions/region-object-lifetime-in-coercion.stderr b/src/test/ui/regions/region-object-lifetime-in-coercion.stderr index 4b08c4bff2ebc..b333c314c57c9 100644 --- a/src/test/ui/regions/region-object-lifetime-in-coercion.stderr +++ b/src/test/ui/regions/region-object-lifetime-in-coercion.stderr @@ -4,11 +4,13 @@ error: cannot infer an appropriate lifetime LL | fn a(v: &[u8]) -> Box { | ----- this data with the anonymous lifetime `'_`... LL | let x: Box = Box::new(v); - | ---------^- - | | | - | | ...and is captured here - | ...is required to be `'static` by this... + | ^ ...is captured here... | +note: ...and required to be `'static` by this + --> $DIR/region-object-lifetime-in-coercion.rs:8:37 + | +LL | let x: Box = Box::new(v); + | ^^^^^^^^^^^ help: consider changing the trait object's explicit `'static` bound to the anonymous lifetime `'_` | LL | fn a(v: &[u8]) -> Box { @@ -24,11 +26,13 @@ error: cannot infer an appropriate lifetime LL | fn b(v: &[u8]) -> Box { | ----- this data with the anonymous lifetime `'_`... LL | Box::new(v) - | ---------^- - | | | - | | ...and is captured here - | ...is required to be `'static` by this... + | ^ ...is captured here... | +note: ...and required to be `'static` by this + --> $DIR/region-object-lifetime-in-coercion.rs:13:5 + | +LL | Box::new(v) + | ^^^^^^^^^^^ help: consider changing the trait object's explicit `'static` bound to the anonymous lifetime `'_` | LL | fn b(v: &[u8]) -> Box { @@ -45,11 +49,13 @@ LL | fn c(v: &[u8]) -> Box { | ----- this data with the anonymous lifetime `'_`... ... LL | Box::new(v) - | ---------^- - | | | - | | ...and is captured here - | ...is required to be `'static` by this... + | ^ ...is captured here... + | +note: ...and required to be `'static` by this + --> $DIR/region-object-lifetime-in-coercion.rs:19:5 | +LL | Box::new(v) + | ^^^^^^^^^^^ help: to permit non-static references in a trait object value, you can add an explicit bound for the anonymous lifetime `'_` | LL | fn c(v: &[u8]) -> Box { diff --git a/src/test/ui/regions/regions-close-object-into-object-2.stderr b/src/test/ui/regions/regions-close-object-into-object-2.stderr index 894be310fd14b..3127ae65ace7d 100644 --- a/src/test/ui/regions/regions-close-object-into-object-2.stderr +++ b/src/test/ui/regions/regions-close-object-into-object-2.stderr @@ -4,11 +4,13 @@ error: cannot infer an appropriate lifetime LL | fn g<'a, T: 'static>(v: Box + 'a>) -> Box { | ------------------ this data with lifetime `'a`... LL | box B(&*v) as Box - | ------^^^--------------- - | | | - | | ...and is captured here - | ...is required to be `'static` by this... + | ^^^ ...is captured here... | +note: ...and required to be `'static` by this + --> $DIR/regions-close-object-into-object-2.rs:10:5 + | +LL | box B(&*v) as Box + | ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider changing the trait object's explicit `'static` bound to lifetime `'a` | LL | fn g<'a, T: 'static>(v: Box + 'a>) -> Box { diff --git a/src/test/ui/regions/regions-close-object-into-object-4.stderr b/src/test/ui/regions/regions-close-object-into-object-4.stderr index ce261d78c2909..b18c61f137694 100644 --- a/src/test/ui/regions/regions-close-object-into-object-4.stderr +++ b/src/test/ui/regions/regions-close-object-into-object-4.stderr @@ -4,11 +4,13 @@ error: cannot infer an appropriate lifetime LL | fn i<'a, T, U>(v: Box+'a>) -> Box { | ---------------- this data with lifetime `'a`... LL | box B(&*v) as Box - | ------^^^--------------- - | | | - | | ...and is captured here - | ...is required to be `'static` by this... + | ^^^ ...is captured here... | +note: ...and required to be `'static` by this + --> $DIR/regions-close-object-into-object-4.rs:10:5 + | +LL | box B(&*v) as Box + | ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider changing the trait object's explicit `'static` bound to lifetime `'a` | LL | fn i<'a, T, U>(v: Box+'a>) -> Box { diff --git a/src/test/ui/regions/regions-proc-bound-capture.stderr b/src/test/ui/regions/regions-proc-bound-capture.stderr index a0df1815247c3..5cb9506afd351 100644 --- a/src/test/ui/regions/regions-proc-bound-capture.stderr +++ b/src/test/ui/regions/regions-proc-bound-capture.stderr @@ -5,11 +5,13 @@ LL | fn static_proc(x: &isize) -> Box (isize) + 'static> { | ------ this data with the anonymous lifetime `'_`... LL | // This is illegal, because the region bound on `proc` is 'static. LL | Box::new(move || { *x }) - | ---------^^^^^^^^^^^^^^- - | | | - | | ...and is captured here - | ...is required to be `'static` by this... + | ^^^^^^^^^^^^^^ ...is captured here... | +note: ...and required to be `'static` by this + --> $DIR/regions-proc-bound-capture.rs:9:5 + | +LL | Box::new(move || { *x }) + | ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider changing the trait object's explicit `'static` bound to the anonymous lifetime `'_` | LL | fn static_proc(x: &isize) -> Box (isize) + '_> { From 17951e21d4c690ad70e79a40d223a0d0984c0f35 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sat, 30 May 2020 09:54:05 -0700 Subject: [PATCH 22/35] Tweak output for overlapping required/captured spans --- .../nice_region_error/static_impl_trait.rs | 10 +++---- .../must_outlive_least_region_or_bound.stderr | 28 +++---------------- src/test/ui/issues/issue-16922.stderr | 7 +---- .../region-object-lifetime-in-coercion.stderr | 21 ++------------ .../regions-close-object-into-object-2.stderr | 7 +---- .../regions-close-object-into-object-4.stderr | 7 +---- .../regions/regions-proc-bound-capture.stderr | 7 +---- 7 files changed, 15 insertions(+), 72 deletions(-) diff --git a/src/librustc_infer/infer/error_reporting/nice_region_error/static_impl_trait.rs b/src/librustc_infer/infer/error_reporting/nice_region_error/static_impl_trait.rs index cc95441b68a03..253057536f133 100644 --- a/src/librustc_infer/infer/error_reporting/nice_region_error/static_impl_trait.rs +++ b/src/librustc_infer/infer/error_reporting/nice_region_error/static_impl_trait.rs @@ -76,12 +76,10 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { // | | // | this data with the anonymous lifetime `'_`... // | - // note: ...is required to be `'static` by this - // | - // LL | fn elided3(x: &i32) -> Box { Box::new(x) } - // | ^^^^^^^^^^^ - err.span_label(sup_origin.span(), "...is captured here..."); - err.span_note(return_sp, "...and required to be `'static` by this"); + err.span_label( + sup_origin.span(), + "...is captured here with a `'static` requirement", + ); } else if sup_origin.span() <= return_sp { err.span_label(sup_origin.span(), "...is captured here..."); err.span_label(return_sp, "...and required to be `'static` by this"); diff --git a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr index 2da49379ea8c2..82e44cff9cc44 100644 --- a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr +++ b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr @@ -109,15 +109,10 @@ error: cannot infer an appropriate lifetime --> $DIR/must_outlive_least_region_or_bound.rs:18:50 | LL | fn elided3(x: &i32) -> Box { Box::new(x) } - | ---- ^ ...is captured here... + | ---- ^ ...is captured here with a `'static` requirement | | | this data with the anonymous lifetime `'_`... | -note: ...and required to be `'static` by this - --> $DIR/must_outlive_least_region_or_bound.rs:18:41 - | -LL | fn elided3(x: &i32) -> Box { Box::new(x) } - | ^^^^^^^^^^^ help: to permit non-static references in a trait object value, you can add an explicit bound for the anonymous lifetime `'_` | LL | fn elided3(x: &i32) -> Box { Box::new(x) } @@ -127,15 +122,10 @@ error: cannot infer an appropriate lifetime --> $DIR/must_outlive_least_region_or_bound.rs:21:59 | LL | fn explicit3<'a>(x: &'a i32) -> Box { Box::new(x) } - | ------- ^ ...is captured here... + | ------- ^ ...is captured here with a `'static` requirement | | | this data with lifetime `'a`... | -note: ...and required to be `'static` by this - --> $DIR/must_outlive_least_region_or_bound.rs:21:50 - | -LL | fn explicit3<'a>(x: &'a i32) -> Box { Box::new(x) } - | ^^^^^^^^^^^ help: to permit non-static references in a trait object value, you can add an explicit bound for lifetime `'a` | LL | fn explicit3<'a>(x: &'a i32) -> Box { Box::new(x) } @@ -145,15 +135,10 @@ error: cannot infer an appropriate lifetime --> $DIR/must_outlive_least_region_or_bound.rs:24:60 | LL | fn elided4(x: &i32) -> Box { Box::new(x) } - | ---- ^ ...is captured here... + | ---- ^ ...is captured here with a `'static` requirement | | | this data with the anonymous lifetime `'_`... | -note: ...and required to be `'static` by this - --> $DIR/must_outlive_least_region_or_bound.rs:24:51 - | -LL | fn elided4(x: &i32) -> Box { Box::new(x) } - | ^^^^^^^^^^^ help: consider changing the trait object's explicit `'static` bound to the anonymous lifetime `'_` | LL | fn elided4(x: &i32) -> Box { Box::new(x) } @@ -167,13 +152,8 @@ error: cannot infer an appropriate lifetime --> $DIR/must_outlive_least_region_or_bound.rs:27:69 | LL | fn explicit4<'a>(x: &'a i32) -> Box { Box::new(x) } - | ------- this data with lifetime `'a`... ^ ...is captured here... + | ------- this data with lifetime `'a`... ^ ...is captured here with a `'static` requirement | -note: ...and required to be `'static` by this - --> $DIR/must_outlive_least_region_or_bound.rs:27:60 - | -LL | fn explicit4<'a>(x: &'a i32) -> Box { Box::new(x) } - | ^^^^^^^^^^^ help: consider changing the trait object's explicit `'static` bound to lifetime `'a` | LL | fn explicit4<'a>(x: &'a i32) -> Box { Box::new(x) } diff --git a/src/test/ui/issues/issue-16922.stderr b/src/test/ui/issues/issue-16922.stderr index 6c0b26a86b651..a254343cd1bb7 100644 --- a/src/test/ui/issues/issue-16922.stderr +++ b/src/test/ui/issues/issue-16922.stderr @@ -4,13 +4,8 @@ error: cannot infer an appropriate lifetime LL | fn foo(value: &T) -> Box { | -- this data with the anonymous lifetime `'_`... LL | Box::new(value) as Box - | ^^^^^ ...is captured here... + | ^^^^^ ...is captured here with a `'static` requirement | -note: ...and required to be `'static` by this - --> $DIR/issue-16922.rs:4:5 - | -LL | Box::new(value) as Box - | ^^^^^^^^^^^^^^^ help: to permit non-static references in a trait object value, you can add an explicit bound for the anonymous lifetime `'_` | LL | fn foo(value: &T) -> Box { diff --git a/src/test/ui/regions/region-object-lifetime-in-coercion.stderr b/src/test/ui/regions/region-object-lifetime-in-coercion.stderr index b333c314c57c9..97d1f3579fcd8 100644 --- a/src/test/ui/regions/region-object-lifetime-in-coercion.stderr +++ b/src/test/ui/regions/region-object-lifetime-in-coercion.stderr @@ -4,13 +4,8 @@ error: cannot infer an appropriate lifetime LL | fn a(v: &[u8]) -> Box { | ----- this data with the anonymous lifetime `'_`... LL | let x: Box = Box::new(v); - | ^ ...is captured here... + | ^ ...is captured here with a `'static` requirement | -note: ...and required to be `'static` by this - --> $DIR/region-object-lifetime-in-coercion.rs:8:37 - | -LL | let x: Box = Box::new(v); - | ^^^^^^^^^^^ help: consider changing the trait object's explicit `'static` bound to the anonymous lifetime `'_` | LL | fn a(v: &[u8]) -> Box { @@ -26,13 +21,8 @@ error: cannot infer an appropriate lifetime LL | fn b(v: &[u8]) -> Box { | ----- this data with the anonymous lifetime `'_`... LL | Box::new(v) - | ^ ...is captured here... + | ^ ...is captured here with a `'static` requirement | -note: ...and required to be `'static` by this - --> $DIR/region-object-lifetime-in-coercion.rs:13:5 - | -LL | Box::new(v) - | ^^^^^^^^^^^ help: consider changing the trait object's explicit `'static` bound to the anonymous lifetime `'_` | LL | fn b(v: &[u8]) -> Box { @@ -49,13 +39,8 @@ LL | fn c(v: &[u8]) -> Box { | ----- this data with the anonymous lifetime `'_`... ... LL | Box::new(v) - | ^ ...is captured here... - | -note: ...and required to be `'static` by this - --> $DIR/region-object-lifetime-in-coercion.rs:19:5 + | ^ ...is captured here with a `'static` requirement | -LL | Box::new(v) - | ^^^^^^^^^^^ help: to permit non-static references in a trait object value, you can add an explicit bound for the anonymous lifetime `'_` | LL | fn c(v: &[u8]) -> Box { diff --git a/src/test/ui/regions/regions-close-object-into-object-2.stderr b/src/test/ui/regions/regions-close-object-into-object-2.stderr index 3127ae65ace7d..3d707f2d99941 100644 --- a/src/test/ui/regions/regions-close-object-into-object-2.stderr +++ b/src/test/ui/regions/regions-close-object-into-object-2.stderr @@ -4,13 +4,8 @@ error: cannot infer an appropriate lifetime LL | fn g<'a, T: 'static>(v: Box + 'a>) -> Box { | ------------------ this data with lifetime `'a`... LL | box B(&*v) as Box - | ^^^ ...is captured here... + | ^^^ ...is captured here with a `'static` requirement | -note: ...and required to be `'static` by this - --> $DIR/regions-close-object-into-object-2.rs:10:5 - | -LL | box B(&*v) as Box - | ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider changing the trait object's explicit `'static` bound to lifetime `'a` | LL | fn g<'a, T: 'static>(v: Box + 'a>) -> Box { diff --git a/src/test/ui/regions/regions-close-object-into-object-4.stderr b/src/test/ui/regions/regions-close-object-into-object-4.stderr index b18c61f137694..70282c8cbdb30 100644 --- a/src/test/ui/regions/regions-close-object-into-object-4.stderr +++ b/src/test/ui/regions/regions-close-object-into-object-4.stderr @@ -4,13 +4,8 @@ error: cannot infer an appropriate lifetime LL | fn i<'a, T, U>(v: Box+'a>) -> Box { | ---------------- this data with lifetime `'a`... LL | box B(&*v) as Box - | ^^^ ...is captured here... + | ^^^ ...is captured here with a `'static` requirement | -note: ...and required to be `'static` by this - --> $DIR/regions-close-object-into-object-4.rs:10:5 - | -LL | box B(&*v) as Box - | ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider changing the trait object's explicit `'static` bound to lifetime `'a` | LL | fn i<'a, T, U>(v: Box+'a>) -> Box { diff --git a/src/test/ui/regions/regions-proc-bound-capture.stderr b/src/test/ui/regions/regions-proc-bound-capture.stderr index 5cb9506afd351..8f93fad7fe9d8 100644 --- a/src/test/ui/regions/regions-proc-bound-capture.stderr +++ b/src/test/ui/regions/regions-proc-bound-capture.stderr @@ -5,13 +5,8 @@ LL | fn static_proc(x: &isize) -> Box (isize) + 'static> { | ------ this data with the anonymous lifetime `'_`... LL | // This is illegal, because the region bound on `proc` is 'static. LL | Box::new(move || { *x }) - | ^^^^^^^^^^^^^^ ...is captured here... + | ^^^^^^^^^^^^^^ ...is captured here with a `'static` requirement | -note: ...and required to be `'static` by this - --> $DIR/regions-proc-bound-capture.rs:9:5 - | -LL | Box::new(move || { *x }) - | ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider changing the trait object's explicit `'static` bound to the anonymous lifetime `'_` | LL | fn static_proc(x: &isize) -> Box (isize) + '_> { From 19bb589410f2ab0ff14178992ef4b44fbe5e297b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sat, 30 May 2020 10:15:58 -0700 Subject: [PATCH 23/35] Tweak wording and add error code --- .../nice_region_error/static_impl_trait.rs | 35 +++++++------ .../ui/async-await/issues/issue-62097.stderr | 6 +-- .../must_outlive_least_region_or_bound.stderr | 52 +++++++++---------- .../static-return-lifetime-infered.stderr | 12 ++--- src/test/ui/issues/issue-16922.stderr | 8 +-- ...ect-lifetime-default-from-box-error.stderr | 8 +-- .../region-object-lifetime-in-coercion.stderr | 24 ++++----- .../regions-close-object-into-object-2.stderr | 4 +- .../regions-close-object-into-object-4.stderr | 4 +- .../regions/regions-proc-bound-capture.stderr | 8 +-- ...types_pin_lifetime_impl_trait-async.stderr | 6 +-- ..._self_types_pin_lifetime_impl_trait.stderr | 8 +-- .../missing-lifetimes-in-signature.stderr | 8 +-- .../dyn-trait-underscore.stderr | 8 +-- 14 files changed, 97 insertions(+), 94 deletions(-) diff --git a/src/librustc_infer/infer/error_reporting/nice_region_error/static_impl_trait.rs b/src/librustc_infer/infer/error_reporting/nice_region_error/static_impl_trait.rs index 253057536f133..4e16e8c2c5717 100644 --- a/src/librustc_infer/infer/error_reporting/nice_region_error/static_impl_trait.rs +++ b/src/librustc_infer/infer/error_reporting/nice_region_error/static_impl_trait.rs @@ -2,7 +2,7 @@ use crate::infer::error_reporting::nice_region_error::NiceRegionError; use crate::infer::lexical_region_resolve::RegionResolutionError; -use rustc_errors::{Applicability, ErrorReported}; +use rustc_errors::{struct_span_err, Applicability, ErrorReported}; use rustc_hir::{GenericBound, ItemKind, Lifetime, LifetimeName, TyKind}; use rustc_middle::ty::RegionKind; @@ -35,10 +35,14 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { let (lifetime_name, lifetime) = if sup_r.has_name() { (sup_r.to_string(), format!("lifetime `{}`", sup_r)) } else { - ("'_".to_owned(), "the anonymous lifetime `'_`".to_string()) + ("'_".to_owned(), "an anonymous lifetime `'_`".to_string()) }; - let mut err = - self.tcx().sess.struct_span_err(sp, "cannot infer an appropriate lifetime"); + let mut err = struct_span_err!( + self.tcx().sess, + sp, + E0758, + "cannot infer an appropriate lifetime" + ); err.span_label( param_info.param_ty_span, &format!("this data with {}...", lifetime), @@ -61,10 +65,6 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { // | // LL | fn foo(x: &i32) -> Box { Box::new(x) } // | ---- ---------^- - // | | | | - // | | | ...and is captured here - // | | ...is required to be `'static` by this... - // | this data with the anonymous lifetime `'_`... // // and instead show: // @@ -72,25 +72,28 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { // --> $DIR/must_outlive_least_region_or_bound.rs:18:50 // | // LL | fn foo(x: &i32) -> Box { Box::new(x) } - // | ---- ^ ...is captured here with a `'static` requirement - // | | - // | this data with the anonymous lifetime `'_`... - // | + // | ---- ^ err.span_label( sup_origin.span(), - "...is captured here with a `'static` requirement", + "...is captured here requiring it to live as long as `'static`", ); } else if sup_origin.span() <= return_sp { err.span_label(sup_origin.span(), "...is captured here..."); - err.span_label(return_sp, "...and required to be `'static` by this"); + err.span_label( + return_sp, + "...and required to live as long as `'static` by this", + ); } else { - err.span_label(return_sp, "...is required to be `'static` by this..."); + err.span_label( + return_sp, + "...is required to live as long as `'static` by this...", + ); err.span_label(sup_origin.span(), "...and is captured here"); } } else { err.span_label( return_sp, - "...is captured and required to be `'static` here", + "...is captured and required live as long as `'static` here", ); } diff --git a/src/test/ui/async-await/issues/issue-62097.stderr b/src/test/ui/async-await/issues/issue-62097.stderr index fff43ae9f47bc..558d89f928945 100644 --- a/src/test/ui/async-await/issues/issue-62097.stderr +++ b/src/test/ui/async-await/issues/issue-62097.stderr @@ -1,13 +1,13 @@ -error: cannot infer an appropriate lifetime +error[E0758]: cannot infer an appropriate lifetime --> $DIR/issue-62097.rs:12:31 | LL | pub async fn run_dummy_fn(&self) { | ^^^^^ | | - | this data with the anonymous lifetime `'_`... + | this data with an anonymous lifetime `'_`... | ...is captured here... LL | foo(|| self.bar()).await; - | --- ...and required to be `'static` by this + | --- ...and required to live as long as `'static` by this error: aborting due to previous error diff --git a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr index 82e44cff9cc44..eff56ddc440d4 100644 --- a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr +++ b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr @@ -1,24 +1,24 @@ -error: cannot infer an appropriate lifetime +error[E0758]: cannot infer an appropriate lifetime --> $DIR/must_outlive_least_region_or_bound.rs:3:35 | LL | fn elided(x: &i32) -> impl Copy { x } | ---- --------- ^ ...and is captured here | | | - | | ...is required to be `'static` by this... - | this data with the anonymous lifetime `'_`... + | | ...is required to live as long as `'static` by this... + | this data with an anonymous lifetime `'_`... | -help: to permit non-static references in an `impl Trait` value, you can add an explicit bound for the anonymous lifetime `'_` +help: to permit non-static references in an `impl Trait` value, you can add an explicit bound for an anonymous lifetime `'_` | LL | fn elided(x: &i32) -> impl Copy + '_ { x } | ^^^^ -error: cannot infer an appropriate lifetime +error[E0758]: cannot infer an appropriate lifetime --> $DIR/must_outlive_least_region_or_bound.rs:6:44 | LL | fn explicit<'a>(x: &'a i32) -> impl Copy { x } | ------- --------- ^ ...and is captured here | | | - | | ...is required to be `'static` by this... + | | ...is required to live as long as `'static` by this... | this data with lifetime `'a`... | help: to permit non-static references in an `impl Trait` value, you can add an explicit bound for lifetime `'a` @@ -26,16 +26,16 @@ help: to permit non-static references in an `impl Trait` value, you can add an e LL | fn explicit<'a>(x: &'a i32) -> impl Copy + 'a { x } | ^^^^ -error: cannot infer an appropriate lifetime +error[E0758]: cannot infer an appropriate lifetime --> $DIR/must_outlive_least_region_or_bound.rs:9:46 | LL | fn elided2(x: &i32) -> impl Copy + 'static { x } | ---- ------------------- ^ ...and is captured here | | | - | | ...is required to be `'static` by this... - | this data with the anonymous lifetime `'_`... + | | ...is required to live as long as `'static` by this... + | this data with an anonymous lifetime `'_`... | -help: consider changing the `impl Trait`'s explicit `'static` bound to the anonymous lifetime `'_` +help: consider changing the `impl Trait`'s explicit `'static` bound to an anonymous lifetime `'_` | LL | fn elided2(x: &i32) -> impl Copy + '_ { x } | ^^ @@ -44,13 +44,13 @@ help: alternatively, set an explicit `'static` lifetime to this parameter LL | fn elided2(x: &'static i32) -> impl Copy + 'static { x } | ^^^^^^^^^^^^ -error: cannot infer an appropriate lifetime +error[E0758]: cannot infer an appropriate lifetime --> $DIR/must_outlive_least_region_or_bound.rs:12:55 | LL | fn explicit2<'a>(x: &'a i32) -> impl Copy + 'static { x } | ------- ------------------- ^ ...and is captured here | | | - | | ...is required to be `'static` by this... + | | ...is required to live as long as `'static` by this... | this data with lifetime `'a`... | help: consider changing the `impl Trait`'s explicit `'static` bound to lifetime `'a` @@ -70,13 +70,13 @@ LL | fn foo<'a>(x: &i32) -> impl Copy + 'a { x } | | | help: add explicit lifetime `'a` to the type of `x`: `&'a i32` -error: cannot infer an appropriate lifetime +error[E0758]: cannot infer an appropriate lifetime --> $DIR/must_outlive_least_region_or_bound.rs:33:69 | LL | fn with_bound<'a>(x: &'a i32) -> impl LifetimeTrait<'a> + 'static { x } | ------- -------------------------------- ^ ...and is captured here | | | - | | ...is required to be `'static` by this... + | | ...is required to live as long as `'static` by this... | this data with lifetime `'a`... | help: consider changing the `impl Trait`'s explicit `'static` bound to lifetime `'a` @@ -105,24 +105,24 @@ LL | fn ty_param_wont_outlive_static(x: T) -> impl Debug + 'static { | | | help: consider adding an explicit lifetime bound...: `T: 'static +` -error: cannot infer an appropriate lifetime +error[E0758]: cannot infer an appropriate lifetime --> $DIR/must_outlive_least_region_or_bound.rs:18:50 | LL | fn elided3(x: &i32) -> Box { Box::new(x) } - | ---- ^ ...is captured here with a `'static` requirement + | ---- ^ ...is captured here requiring it to live as long as `'static` | | - | this data with the anonymous lifetime `'_`... + | this data with an anonymous lifetime `'_`... | -help: to permit non-static references in a trait object value, you can add an explicit bound for the anonymous lifetime `'_` +help: to permit non-static references in a trait object value, you can add an explicit bound for an anonymous lifetime `'_` | LL | fn elided3(x: &i32) -> Box { Box::new(x) } | ^^^^ -error: cannot infer an appropriate lifetime +error[E0758]: cannot infer an appropriate lifetime --> $DIR/must_outlive_least_region_or_bound.rs:21:59 | LL | fn explicit3<'a>(x: &'a i32) -> Box { Box::new(x) } - | ------- ^ ...is captured here with a `'static` requirement + | ------- ^ ...is captured here requiring it to live as long as `'static` | | | this data with lifetime `'a`... | @@ -131,15 +131,15 @@ help: to permit non-static references in a trait object value, you can add an ex LL | fn explicit3<'a>(x: &'a i32) -> Box { Box::new(x) } | ^^^^ -error: cannot infer an appropriate lifetime +error[E0758]: cannot infer an appropriate lifetime --> $DIR/must_outlive_least_region_or_bound.rs:24:60 | LL | fn elided4(x: &i32) -> Box { Box::new(x) } - | ---- ^ ...is captured here with a `'static` requirement + | ---- ^ ...is captured here requiring it to live as long as `'static` | | - | this data with the anonymous lifetime `'_`... + | this data with an anonymous lifetime `'_`... | -help: consider changing the trait object's explicit `'static` bound to the anonymous lifetime `'_` +help: consider changing the trait object's explicit `'static` bound to an anonymous lifetime `'_` | LL | fn elided4(x: &i32) -> Box { Box::new(x) } | ^^ @@ -148,11 +148,11 @@ help: alternatively, set an explicit `'static` lifetime in this parameter LL | fn elided4(x: &'static i32) -> Box { Box::new(x) } | ^^^^^^^^^^^^ -error: cannot infer an appropriate lifetime +error[E0758]: cannot infer an appropriate lifetime --> $DIR/must_outlive_least_region_or_bound.rs:27:69 | LL | fn explicit4<'a>(x: &'a i32) -> Box { Box::new(x) } - | ------- this data with lifetime `'a`... ^ ...is captured here with a `'static` requirement + | ------- this data with lifetime `'a`... ^ ...is captured here requiring it to live as long as `'static` | help: consider changing the trait object's explicit `'static` bound to lifetime `'a` | diff --git a/src/test/ui/impl-trait/static-return-lifetime-infered.stderr b/src/test/ui/impl-trait/static-return-lifetime-infered.stderr index 67d4f60dff6f1..a48580ee2d2fc 100644 --- a/src/test/ui/impl-trait/static-return-lifetime-infered.stderr +++ b/src/test/ui/impl-trait/static-return-lifetime-infered.stderr @@ -1,25 +1,25 @@ -error: cannot infer an appropriate lifetime +error[E0758]: cannot infer an appropriate lifetime --> $DIR/static-return-lifetime-infered.rs:7:16 | LL | fn iter_values_anon(&self) -> impl Iterator { - | ----- ----------------------- ...is required to be `'static` by this... + | ----- ----------------------- ...is required to live as long as `'static` by this... | | - | this data with the anonymous lifetime `'_`... + | this data with an anonymous lifetime `'_`... LL | self.x.iter().map(|a| a.0) | ------ ^^^^ | | | ...and is captured here | -help: to permit non-static references in an `impl Trait` value, you can add an explicit bound for the anonymous lifetime `'_` +help: to permit non-static references in an `impl Trait` value, you can add an explicit bound for an anonymous lifetime `'_` | LL | fn iter_values_anon(&self) -> impl Iterator + '_ { | ^^^^ -error: cannot infer an appropriate lifetime +error[E0758]: cannot infer an appropriate lifetime --> $DIR/static-return-lifetime-infered.rs:11:16 | LL | fn iter_values<'a>(&'a self) -> impl Iterator { - | -------- ----------------------- ...is required to be `'static` by this... + | -------- ----------------------- ...is required to live as long as `'static` by this... | | | this data with lifetime `'a`... LL | self.x.iter().map(|a| a.0) diff --git a/src/test/ui/issues/issue-16922.stderr b/src/test/ui/issues/issue-16922.stderr index a254343cd1bb7..53fd658800a7a 100644 --- a/src/test/ui/issues/issue-16922.stderr +++ b/src/test/ui/issues/issue-16922.stderr @@ -1,12 +1,12 @@ -error: cannot infer an appropriate lifetime +error[E0758]: cannot infer an appropriate lifetime --> $DIR/issue-16922.rs:4:14 | LL | fn foo(value: &T) -> Box { - | -- this data with the anonymous lifetime `'_`... + | -- this data with an anonymous lifetime `'_`... LL | Box::new(value) as Box - | ^^^^^ ...is captured here with a `'static` requirement + | ^^^^^ ...is captured here requiring it to live as long as `'static` | -help: to permit non-static references in a trait object value, you can add an explicit bound for the anonymous lifetime `'_` +help: to permit non-static references in a trait object value, you can add an explicit bound for an anonymous lifetime `'_` | LL | fn foo(value: &T) -> Box { | ^^^^ diff --git a/src/test/ui/object-lifetime/object-lifetime-default-from-box-error.stderr b/src/test/ui/object-lifetime/object-lifetime-default-from-box-error.stderr index 6edef8086b937..04a06104faf99 100644 --- a/src/test/ui/object-lifetime/object-lifetime-default-from-box-error.stderr +++ b/src/test/ui/object-lifetime/object-lifetime-default-from-box-error.stderr @@ -1,13 +1,13 @@ -error: cannot infer an appropriate lifetime +error[E0758]: cannot infer an appropriate lifetime --> $DIR/object-lifetime-default-from-box-error.rs:18:5 | LL | fn load(ss: &mut SomeStruct) -> Box { - | --------------- this data with the anonymous lifetime `'_`... + | --------------- this data with an anonymous lifetime `'_`... ... LL | ss.r - | ^^^^ ...is captured and required to be `'static` here + | ^^^^ ...is captured and required live as long as `'static` here | -help: to permit non-static references in a trait object value, you can add an explicit bound for the anonymous lifetime `'_` +help: to permit non-static references in a trait object value, you can add an explicit bound for an anonymous lifetime `'_` | LL | fn load(ss: &mut SomeStruct) -> Box { | ^^^^ diff --git a/src/test/ui/regions/region-object-lifetime-in-coercion.stderr b/src/test/ui/regions/region-object-lifetime-in-coercion.stderr index 97d1f3579fcd8..34cf131319a1c 100644 --- a/src/test/ui/regions/region-object-lifetime-in-coercion.stderr +++ b/src/test/ui/regions/region-object-lifetime-in-coercion.stderr @@ -1,12 +1,12 @@ -error: cannot infer an appropriate lifetime +error[E0758]: cannot infer an appropriate lifetime --> $DIR/region-object-lifetime-in-coercion.rs:8:46 | LL | fn a(v: &[u8]) -> Box { - | ----- this data with the anonymous lifetime `'_`... + | ----- this data with an anonymous lifetime `'_`... LL | let x: Box = Box::new(v); - | ^ ...is captured here with a `'static` requirement + | ^ ...is captured here requiring it to live as long as `'static` | -help: consider changing the trait object's explicit `'static` bound to the anonymous lifetime `'_` +help: consider changing the trait object's explicit `'static` bound to an anonymous lifetime `'_` | LL | fn a(v: &[u8]) -> Box { | ^^ @@ -15,15 +15,15 @@ help: alternatively, set an explicit `'static` lifetime in this parameter LL | fn a(v: &'static [u8]) -> Box { | ^^^^^^^^^^^^^ -error: cannot infer an appropriate lifetime +error[E0758]: cannot infer an appropriate lifetime --> $DIR/region-object-lifetime-in-coercion.rs:13:14 | LL | fn b(v: &[u8]) -> Box { - | ----- this data with the anonymous lifetime `'_`... + | ----- this data with an anonymous lifetime `'_`... LL | Box::new(v) - | ^ ...is captured here with a `'static` requirement + | ^ ...is captured here requiring it to live as long as `'static` | -help: consider changing the trait object's explicit `'static` bound to the anonymous lifetime `'_` +help: consider changing the trait object's explicit `'static` bound to an anonymous lifetime `'_` | LL | fn b(v: &[u8]) -> Box { | ^^ @@ -32,16 +32,16 @@ help: alternatively, set an explicit `'static` lifetime in this parameter LL | fn b(v: &'static [u8]) -> Box { | ^^^^^^^^^^^^^ -error: cannot infer an appropriate lifetime +error[E0758]: cannot infer an appropriate lifetime --> $DIR/region-object-lifetime-in-coercion.rs:19:14 | LL | fn c(v: &[u8]) -> Box { - | ----- this data with the anonymous lifetime `'_`... + | ----- this data with an anonymous lifetime `'_`... ... LL | Box::new(v) - | ^ ...is captured here with a `'static` requirement + | ^ ...is captured here requiring it to live as long as `'static` | -help: to permit non-static references in a trait object value, you can add an explicit bound for the anonymous lifetime `'_` +help: to permit non-static references in a trait object value, you can add an explicit bound for an anonymous lifetime `'_` | LL | fn c(v: &[u8]) -> Box { | ^^^^ diff --git a/src/test/ui/regions/regions-close-object-into-object-2.stderr b/src/test/ui/regions/regions-close-object-into-object-2.stderr index 3d707f2d99941..be47ef589af8c 100644 --- a/src/test/ui/regions/regions-close-object-into-object-2.stderr +++ b/src/test/ui/regions/regions-close-object-into-object-2.stderr @@ -1,10 +1,10 @@ -error: cannot infer an appropriate lifetime +error[E0758]: cannot infer an appropriate lifetime --> $DIR/regions-close-object-into-object-2.rs:10:11 | LL | fn g<'a, T: 'static>(v: Box + 'a>) -> Box { | ------------------ this data with lifetime `'a`... LL | box B(&*v) as Box - | ^^^ ...is captured here with a `'static` requirement + | ^^^ ...is captured here requiring it to live as long as `'static` | help: consider changing the trait object's explicit `'static` bound to lifetime `'a` | diff --git a/src/test/ui/regions/regions-close-object-into-object-4.stderr b/src/test/ui/regions/regions-close-object-into-object-4.stderr index 70282c8cbdb30..1b099c7d8bdf0 100644 --- a/src/test/ui/regions/regions-close-object-into-object-4.stderr +++ b/src/test/ui/regions/regions-close-object-into-object-4.stderr @@ -1,10 +1,10 @@ -error: cannot infer an appropriate lifetime +error[E0758]: cannot infer an appropriate lifetime --> $DIR/regions-close-object-into-object-4.rs:10:11 | LL | fn i<'a, T, U>(v: Box+'a>) -> Box { | ---------------- this data with lifetime `'a`... LL | box B(&*v) as Box - | ^^^ ...is captured here with a `'static` requirement + | ^^^ ...is captured here requiring it to live as long as `'static` | help: consider changing the trait object's explicit `'static` bound to lifetime `'a` | diff --git a/src/test/ui/regions/regions-proc-bound-capture.stderr b/src/test/ui/regions/regions-proc-bound-capture.stderr index 8f93fad7fe9d8..e8baf44bd10aa 100644 --- a/src/test/ui/regions/regions-proc-bound-capture.stderr +++ b/src/test/ui/regions/regions-proc-bound-capture.stderr @@ -1,13 +1,13 @@ -error: cannot infer an appropriate lifetime +error[E0758]: cannot infer an appropriate lifetime --> $DIR/regions-proc-bound-capture.rs:9:14 | LL | fn static_proc(x: &isize) -> Box (isize) + 'static> { - | ------ this data with the anonymous lifetime `'_`... + | ------ this data with an anonymous lifetime `'_`... LL | // This is illegal, because the region bound on `proc` is 'static. LL | Box::new(move || { *x }) - | ^^^^^^^^^^^^^^ ...is captured here with a `'static` requirement + | ^^^^^^^^^^^^^^ ...is captured here requiring it to live as long as `'static` | -help: consider changing the trait object's explicit `'static` bound to the anonymous lifetime `'_` +help: consider changing the trait object's explicit `'static` bound to an anonymous lifetime `'_` | LL | fn static_proc(x: &isize) -> Box (isize) + '_> { | ^^ diff --git a/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.stderr b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.stderr index 5520341b5b1c3..92e1473a5da73 100644 --- a/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.stderr +++ b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.stderr @@ -1,10 +1,10 @@ -error: cannot infer an appropriate lifetime +error[E0758]: cannot infer an appropriate lifetime --> $DIR/arbitrary_self_types_pin_lifetime_impl_trait-async.rs:8:16 | LL | async fn f(self: Pin<&Self>) -> impl Clone { self } - | ^^^^ ---------- ---------- ...and required to be `'static` by this + | ^^^^ ---------- ---------- ...and required to live as long as `'static` by this | | | - | | this data with the anonymous lifetime `'_`... + | | this data with an anonymous lifetime `'_`... | ...is captured here... error: aborting due to previous error diff --git a/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait.stderr b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait.stderr index 5374929f3a45f..6721d41bb73c9 100644 --- a/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait.stderr +++ b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait.stderr @@ -1,13 +1,13 @@ -error: cannot infer an appropriate lifetime +error[E0758]: cannot infer an appropriate lifetime --> $DIR/arbitrary_self_types_pin_lifetime_impl_trait.rs:6:44 | LL | fn f(self: Pin<&Self>) -> impl Clone { self } | ---------- ---------- ^^^^ ...and is captured here | | | - | | ...is required to be `'static` by this... - | this data with the anonymous lifetime `'_`... + | | ...is required to live as long as `'static` by this... + | this data with an anonymous lifetime `'_`... | -help: to permit non-static references in an `impl Trait` value, you can add an explicit bound for the anonymous lifetime `'_` +help: to permit non-static references in an `impl Trait` value, you can add an explicit bound for an anonymous lifetime `'_` | LL | fn f(self: Pin<&Self>) -> impl Clone + '_ { self } | ^^^^ diff --git a/src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature.stderr b/src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature.stderr index 471f3cd14aa3e..ba56255af5b0c 100644 --- a/src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature.stderr +++ b/src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature.stderr @@ -6,20 +6,20 @@ LL | fn baz(g: G, dest: &mut T) -> impl FnOnce() + '_ | | | help: consider introducing lifetime `'a` here: `'a,` -error: cannot infer an appropriate lifetime +error[E0758]: cannot infer an appropriate lifetime --> $DIR/missing-lifetimes-in-signature.rs:19:5 | LL | fn foo(g: G, dest: &mut T) -> impl FnOnce() - | ------ ------------- ...is required to be `'static` by this... + | ------ ------------- ...is required to live as long as `'static` by this... | | - | this data with the anonymous lifetime `'_`... + | this data with an anonymous lifetime `'_`... ... LL | / move || { LL | | *dest = g.get(); LL | | } | |_____^ ...and is captured here | -help: to permit non-static references in an `impl Trait` value, you can add an explicit bound for the anonymous lifetime `'_` +help: to permit non-static references in an `impl Trait` value, you can add an explicit bound for an anonymous lifetime `'_` | LL | fn foo(g: G, dest: &mut T) -> impl FnOnce() + '_ | ^^^^ diff --git a/src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr b/src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr index 5fd03f9770e5d..20d3640d4118e 100644 --- a/src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr +++ b/src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr @@ -1,13 +1,13 @@ -error: cannot infer an appropriate lifetime +error[E0758]: cannot infer an appropriate lifetime --> $DIR/dyn-trait-underscore.rs:8:20 | LL | fn a(items: &[T]) -> Box> { - | ---- this data with the anonymous lifetime `'_`... + | ---- this data with an anonymous lifetime `'_`... LL | // ^^^^^^^^^^^^^^^^^^^^^ bound *here* defaults to `'static` LL | Box::new(items.iter()) - | ---------------^^^^--- ...is captured and required to be `'static` here + | ---------------^^^^--- ...is captured and required live as long as `'static` here | -help: to permit non-static references in a trait object value, you can add an explicit bound for the anonymous lifetime `'_` +help: to permit non-static references in a trait object value, you can add an explicit bound for an anonymous lifetime `'_` | LL | fn a(items: &[T]) -> Box + '_> { | ^^^^ From 3cfecdee0d677e0982cd160991130a997ffc619e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Mon, 1 Jun 2020 16:15:10 -0700 Subject: [PATCH 24/35] review comments: wording --- .../nice_region_error/static_impl_trait.rs | 58 ++++++++++--------- .../ui/async-await/issues/issue-62097.stderr | 2 +- .../must_outlive_least_region_or_bound.stderr | 46 +++++++-------- .../static-return-lifetime-infered.stderr | 8 +-- src/test/ui/issues/issue-16922.stderr | 4 +- ...ect-lifetime-default-from-box-error.stderr | 2 +- .../region-object-lifetime-in-coercion.stderr | 16 ++--- .../regions-close-object-into-object-2.stderr | 6 +- .../regions-close-object-into-object-4.stderr | 6 +- .../regions/regions-proc-bound-capture.stderr | 6 +- ...types_pin_lifetime_impl_trait-async.stderr | 2 +- ..._self_types_pin_lifetime_impl_trait.stderr | 4 +- .../missing-lifetimes-in-signature.stderr | 4 +- .../dyn-trait-underscore.stderr | 2 +- 14 files changed, 85 insertions(+), 81 deletions(-) diff --git a/src/librustc_infer/infer/error_reporting/nice_region_error/static_impl_trait.rs b/src/librustc_infer/infer/error_reporting/nice_region_error/static_impl_trait.rs index 4e16e8c2c5717..86f310eb71d76 100644 --- a/src/librustc_infer/infer/error_reporting/nice_region_error/static_impl_trait.rs +++ b/src/librustc_infer/infer/error_reporting/nice_region_error/static_impl_trait.rs @@ -75,18 +75,18 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { // | ---- ^ err.span_label( sup_origin.span(), - "...is captured here requiring it to live as long as `'static`", + "...is captured here, requiring it to live as long as `'static`", ); } else if sup_origin.span() <= return_sp { err.span_label(sup_origin.span(), "...is captured here..."); err.span_label( return_sp, - "...and required to live as long as `'static` by this", + "...and is required to live as long as `'static` here", ); } else { err.span_label( return_sp, - "...is required to live as long as `'static` by this...", + "...is required to live as long as `'static` here...", ); err.span_label(sup_origin.span(), "...and is captured here"); } @@ -101,6 +101,20 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { // explicit non-desugar'able return. if fn_return.span.desugaring_kind().is_none() { // FIXME: account for the need of parens in `&(dyn Trait + '_)` + + let consider = "consider changing the"; + let declare = "to declare that the"; + let arg = match param_info.param.pat.simple_ident() { + Some(simple_ident) => format!("argument `{}`", simple_ident), + None => "the argument".to_string(), + }; + let explicit = + format!("you can add an explicit `{}` lifetime bound", lifetime_name); + let explicit_static = format!("explicit `'static` bound to {}", arg); + let captures = format!("captures data from {}", arg); + let add_static_bound = + "alternatively, add an explicit `'static` bound to this reference"; + let plus_lt = format!(" + {}", lifetime_name); match fn_return.kind { TyKind::Def(item_id, _) => { let item = self.tcx().hir().item(item_id.id); @@ -126,18 +140,13 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { { err.span_suggestion_verbose( span, - &format!( - "consider changing the `impl Trait`'s explicit \ - `'static` bound to {}", - lifetime, - ), + &format!("{} `impl Trait`'s {}", consider, explicit_static), lifetime_name, Applicability::MaybeIncorrect, ); err.span_suggestion_verbose( param_info.param_ty_span, - "alternatively, set an explicit `'static` lifetime to \ - this parameter", + add_static_bound, param_info.param_ty.to_string(), Applicability::MaybeIncorrect, ); @@ -145,11 +154,12 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { err.span_suggestion_verbose( fn_return.span.shrink_to_hi(), &format!( - "to permit non-static references in an `impl Trait` \ - value, you can add an explicit bound for {}", - lifetime, + "{declare} `impl Trait` {captures}, {explicit}", + declare = declare, + captures = captures, + explicit = explicit, ), - format!(" + {}", lifetime_name), + plus_lt, Applicability::MaybeIncorrect, ); }; @@ -159,31 +169,25 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { err.span_suggestion_verbose( fn_return.span.shrink_to_hi(), &format!( - "to permit non-static references in a trait object \ - value, you can add an explicit bound for {}", - lifetime, + "{declare} trait object {captures}, {explicit}", + declare = declare, + captures = captures, + explicit = explicit, ), - format!(" + {}", lifetime_name), + plus_lt, Applicability::MaybeIncorrect, ); } _ => { err.span_suggestion_verbose( lt.span, - &format!( - "consider changing the trait object's explicit \ - `'static` bound to {}", - lifetime, - ), + &format!("{} trait object's {}", consider, explicit_static), lifetime_name, Applicability::MaybeIncorrect, ); err.span_suggestion_verbose( param_info.param_ty_span, - &format!( - "alternatively, set an explicit `'static` lifetime \ - in this parameter", - ), + add_static_bound, param_info.param_ty.to_string(), Applicability::MaybeIncorrect, ); diff --git a/src/test/ui/async-await/issues/issue-62097.stderr b/src/test/ui/async-await/issues/issue-62097.stderr index 558d89f928945..e9f155c6ced31 100644 --- a/src/test/ui/async-await/issues/issue-62097.stderr +++ b/src/test/ui/async-await/issues/issue-62097.stderr @@ -7,7 +7,7 @@ LL | pub async fn run_dummy_fn(&self) { | this data with an anonymous lifetime `'_`... | ...is captured here... LL | foo(|| self.bar()).await; - | --- ...and required to live as long as `'static` by this + | --- ...and is required to live as long as `'static` here error: aborting due to previous error diff --git a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr index eff56ddc440d4..a9fa0e93fed61 100644 --- a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr +++ b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr @@ -4,10 +4,10 @@ error[E0758]: cannot infer an appropriate lifetime LL | fn elided(x: &i32) -> impl Copy { x } | ---- --------- ^ ...and is captured here | | | - | | ...is required to live as long as `'static` by this... + | | ...is required to live as long as `'static` here... | this data with an anonymous lifetime `'_`... | -help: to permit non-static references in an `impl Trait` value, you can add an explicit bound for an anonymous lifetime `'_` +help: to declare that the `impl Trait` captures data from argument `x`, you can add an explicit `'_` lifetime bound | LL | fn elided(x: &i32) -> impl Copy + '_ { x } | ^^^^ @@ -18,10 +18,10 @@ error[E0758]: cannot infer an appropriate lifetime LL | fn explicit<'a>(x: &'a i32) -> impl Copy { x } | ------- --------- ^ ...and is captured here | | | - | | ...is required to live as long as `'static` by this... + | | ...is required to live as long as `'static` here... | this data with lifetime `'a`... | -help: to permit non-static references in an `impl Trait` value, you can add an explicit bound for lifetime `'a` +help: to declare that the `impl Trait` captures data from argument `x`, you can add an explicit `'a` lifetime bound | LL | fn explicit<'a>(x: &'a i32) -> impl Copy + 'a { x } | ^^^^ @@ -32,14 +32,14 @@ error[E0758]: cannot infer an appropriate lifetime LL | fn elided2(x: &i32) -> impl Copy + 'static { x } | ---- ------------------- ^ ...and is captured here | | | - | | ...is required to live as long as `'static` by this... + | | ...is required to live as long as `'static` here... | this data with an anonymous lifetime `'_`... | -help: consider changing the `impl Trait`'s explicit `'static` bound to an anonymous lifetime `'_` +help: consider changing the `impl Trait`'s explicit `'static` bound to argument `x` | LL | fn elided2(x: &i32) -> impl Copy + '_ { x } | ^^ -help: alternatively, set an explicit `'static` lifetime to this parameter +help: alternatively, add an explicit `'static` bound to this reference | LL | fn elided2(x: &'static i32) -> impl Copy + 'static { x } | ^^^^^^^^^^^^ @@ -50,14 +50,14 @@ error[E0758]: cannot infer an appropriate lifetime LL | fn explicit2<'a>(x: &'a i32) -> impl Copy + 'static { x } | ------- ------------------- ^ ...and is captured here | | | - | | ...is required to live as long as `'static` by this... + | | ...is required to live as long as `'static` here... | this data with lifetime `'a`... | -help: consider changing the `impl Trait`'s explicit `'static` bound to lifetime `'a` +help: consider changing the `impl Trait`'s explicit `'static` bound to argument `x` | LL | fn explicit2<'a>(x: &'a i32) -> impl Copy + 'a { x } | ^^ -help: alternatively, set an explicit `'static` lifetime to this parameter +help: alternatively, add an explicit `'static` bound to this reference | LL | fn explicit2<'a>(x: &'static i32) -> impl Copy + 'static { x } | ^^^^^^^^^^^^ @@ -76,14 +76,14 @@ error[E0758]: cannot infer an appropriate lifetime LL | fn with_bound<'a>(x: &'a i32) -> impl LifetimeTrait<'a> + 'static { x } | ------- -------------------------------- ^ ...and is captured here | | | - | | ...is required to live as long as `'static` by this... + | | ...is required to live as long as `'static` here... | this data with lifetime `'a`... | -help: consider changing the `impl Trait`'s explicit `'static` bound to lifetime `'a` +help: consider changing the `impl Trait`'s explicit `'static` bound to argument `x` | LL | fn with_bound<'a>(x: &'a i32) -> impl LifetimeTrait<'a> + 'a { x } | ^^ -help: alternatively, set an explicit `'static` lifetime to this parameter +help: alternatively, add an explicit `'static` bound to this reference | LL | fn with_bound<'a>(x: &'static i32) -> impl LifetimeTrait<'a> + 'static { x } | ^^^^^^^^^^^^ @@ -109,11 +109,11 @@ error[E0758]: cannot infer an appropriate lifetime --> $DIR/must_outlive_least_region_or_bound.rs:18:50 | LL | fn elided3(x: &i32) -> Box { Box::new(x) } - | ---- ^ ...is captured here requiring it to live as long as `'static` + | ---- ^ ...is captured here, requiring it to live as long as `'static` | | | this data with an anonymous lifetime `'_`... | -help: to permit non-static references in a trait object value, you can add an explicit bound for an anonymous lifetime `'_` +help: to declare that the trait object captures data from argument `x`, you can add an explicit `'_` lifetime bound | LL | fn elided3(x: &i32) -> Box { Box::new(x) } | ^^^^ @@ -122,11 +122,11 @@ error[E0758]: cannot infer an appropriate lifetime --> $DIR/must_outlive_least_region_or_bound.rs:21:59 | LL | fn explicit3<'a>(x: &'a i32) -> Box { Box::new(x) } - | ------- ^ ...is captured here requiring it to live as long as `'static` + | ------- ^ ...is captured here, requiring it to live as long as `'static` | | | this data with lifetime `'a`... | -help: to permit non-static references in a trait object value, you can add an explicit bound for lifetime `'a` +help: to declare that the trait object captures data from argument `x`, you can add an explicit `'a` lifetime bound | LL | fn explicit3<'a>(x: &'a i32) -> Box { Box::new(x) } | ^^^^ @@ -135,15 +135,15 @@ error[E0758]: cannot infer an appropriate lifetime --> $DIR/must_outlive_least_region_or_bound.rs:24:60 | LL | fn elided4(x: &i32) -> Box { Box::new(x) } - | ---- ^ ...is captured here requiring it to live as long as `'static` + | ---- ^ ...is captured here, requiring it to live as long as `'static` | | | this data with an anonymous lifetime `'_`... | -help: consider changing the trait object's explicit `'static` bound to an anonymous lifetime `'_` +help: consider changing the trait object's explicit `'static` bound to argument `x` | LL | fn elided4(x: &i32) -> Box { Box::new(x) } | ^^ -help: alternatively, set an explicit `'static` lifetime in this parameter +help: alternatively, add an explicit `'static` bound to this reference | LL | fn elided4(x: &'static i32) -> Box { Box::new(x) } | ^^^^^^^^^^^^ @@ -152,13 +152,13 @@ error[E0758]: cannot infer an appropriate lifetime --> $DIR/must_outlive_least_region_or_bound.rs:27:69 | LL | fn explicit4<'a>(x: &'a i32) -> Box { Box::new(x) } - | ------- this data with lifetime `'a`... ^ ...is captured here requiring it to live as long as `'static` + | ------- this data with lifetime `'a`... ^ ...is captured here, requiring it to live as long as `'static` | -help: consider changing the trait object's explicit `'static` bound to lifetime `'a` +help: consider changing the trait object's explicit `'static` bound to argument `x` | LL | fn explicit4<'a>(x: &'a i32) -> Box { Box::new(x) } | ^^ -help: alternatively, set an explicit `'static` lifetime in this parameter +help: alternatively, add an explicit `'static` bound to this reference | LL | fn explicit4<'a>(x: &'static i32) -> Box { Box::new(x) } | ^^^^^^^^^^^^ diff --git a/src/test/ui/impl-trait/static-return-lifetime-infered.stderr b/src/test/ui/impl-trait/static-return-lifetime-infered.stderr index a48580ee2d2fc..6681eaa909ee0 100644 --- a/src/test/ui/impl-trait/static-return-lifetime-infered.stderr +++ b/src/test/ui/impl-trait/static-return-lifetime-infered.stderr @@ -2,7 +2,7 @@ error[E0758]: cannot infer an appropriate lifetime --> $DIR/static-return-lifetime-infered.rs:7:16 | LL | fn iter_values_anon(&self) -> impl Iterator { - | ----- ----------------------- ...is required to live as long as `'static` by this... + | ----- ----------------------- ...is required to live as long as `'static` here... | | | this data with an anonymous lifetime `'_`... LL | self.x.iter().map(|a| a.0) @@ -10,7 +10,7 @@ LL | self.x.iter().map(|a| a.0) | | | ...and is captured here | -help: to permit non-static references in an `impl Trait` value, you can add an explicit bound for an anonymous lifetime `'_` +help: to declare that the `impl Trait` captures data from argument `self`, you can add an explicit `'_` lifetime bound | LL | fn iter_values_anon(&self) -> impl Iterator + '_ { | ^^^^ @@ -19,7 +19,7 @@ error[E0758]: cannot infer an appropriate lifetime --> $DIR/static-return-lifetime-infered.rs:11:16 | LL | fn iter_values<'a>(&'a self) -> impl Iterator { - | -------- ----------------------- ...is required to live as long as `'static` by this... + | -------- ----------------------- ...is required to live as long as `'static` here... | | | this data with lifetime `'a`... LL | self.x.iter().map(|a| a.0) @@ -27,7 +27,7 @@ LL | self.x.iter().map(|a| a.0) | | | ...and is captured here | -help: to permit non-static references in an `impl Trait` value, you can add an explicit bound for lifetime `'a` +help: to declare that the `impl Trait` captures data from argument `self`, you can add an explicit `'a` lifetime bound | LL | fn iter_values<'a>(&'a self) -> impl Iterator + 'a { | ^^^^ diff --git a/src/test/ui/issues/issue-16922.stderr b/src/test/ui/issues/issue-16922.stderr index 53fd658800a7a..95f46bd7f3eb6 100644 --- a/src/test/ui/issues/issue-16922.stderr +++ b/src/test/ui/issues/issue-16922.stderr @@ -4,9 +4,9 @@ error[E0758]: cannot infer an appropriate lifetime LL | fn foo(value: &T) -> Box { | -- this data with an anonymous lifetime `'_`... LL | Box::new(value) as Box - | ^^^^^ ...is captured here requiring it to live as long as `'static` + | ^^^^^ ...is captured here, requiring it to live as long as `'static` | -help: to permit non-static references in a trait object value, you can add an explicit bound for an anonymous lifetime `'_` +help: to declare that the trait object captures data from argument `value`, you can add an explicit `'_` lifetime bound | LL | fn foo(value: &T) -> Box { | ^^^^ diff --git a/src/test/ui/object-lifetime/object-lifetime-default-from-box-error.stderr b/src/test/ui/object-lifetime/object-lifetime-default-from-box-error.stderr index 04a06104faf99..e585db262f2d8 100644 --- a/src/test/ui/object-lifetime/object-lifetime-default-from-box-error.stderr +++ b/src/test/ui/object-lifetime/object-lifetime-default-from-box-error.stderr @@ -7,7 +7,7 @@ LL | fn load(ss: &mut SomeStruct) -> Box { LL | ss.r | ^^^^ ...is captured and required live as long as `'static` here | -help: to permit non-static references in a trait object value, you can add an explicit bound for an anonymous lifetime `'_` +help: to declare that the trait object captures data from argument `ss`, you can add an explicit `'_` lifetime bound | LL | fn load(ss: &mut SomeStruct) -> Box { | ^^^^ diff --git a/src/test/ui/regions/region-object-lifetime-in-coercion.stderr b/src/test/ui/regions/region-object-lifetime-in-coercion.stderr index 34cf131319a1c..8d048d90cb345 100644 --- a/src/test/ui/regions/region-object-lifetime-in-coercion.stderr +++ b/src/test/ui/regions/region-object-lifetime-in-coercion.stderr @@ -4,13 +4,13 @@ error[E0758]: cannot infer an appropriate lifetime LL | fn a(v: &[u8]) -> Box { | ----- this data with an anonymous lifetime `'_`... LL | let x: Box = Box::new(v); - | ^ ...is captured here requiring it to live as long as `'static` + | ^ ...is captured here, requiring it to live as long as `'static` | -help: consider changing the trait object's explicit `'static` bound to an anonymous lifetime `'_` +help: consider changing the trait object's explicit `'static` bound to argument `v` | LL | fn a(v: &[u8]) -> Box { | ^^ -help: alternatively, set an explicit `'static` lifetime in this parameter +help: alternatively, add an explicit `'static` bound to this reference | LL | fn a(v: &'static [u8]) -> Box { | ^^^^^^^^^^^^^ @@ -21,13 +21,13 @@ error[E0758]: cannot infer an appropriate lifetime LL | fn b(v: &[u8]) -> Box { | ----- this data with an anonymous lifetime `'_`... LL | Box::new(v) - | ^ ...is captured here requiring it to live as long as `'static` + | ^ ...is captured here, requiring it to live as long as `'static` | -help: consider changing the trait object's explicit `'static` bound to an anonymous lifetime `'_` +help: consider changing the trait object's explicit `'static` bound to argument `v` | LL | fn b(v: &[u8]) -> Box { | ^^ -help: alternatively, set an explicit `'static` lifetime in this parameter +help: alternatively, add an explicit `'static` bound to this reference | LL | fn b(v: &'static [u8]) -> Box { | ^^^^^^^^^^^^^ @@ -39,9 +39,9 @@ LL | fn c(v: &[u8]) -> Box { | ----- this data with an anonymous lifetime `'_`... ... LL | Box::new(v) - | ^ ...is captured here requiring it to live as long as `'static` + | ^ ...is captured here, requiring it to live as long as `'static` | -help: to permit non-static references in a trait object value, you can add an explicit bound for an anonymous lifetime `'_` +help: to declare that the trait object captures data from argument `v`, you can add an explicit `'_` lifetime bound | LL | fn c(v: &[u8]) -> Box { | ^^^^ diff --git a/src/test/ui/regions/regions-close-object-into-object-2.stderr b/src/test/ui/regions/regions-close-object-into-object-2.stderr index be47ef589af8c..5dfe384112b2a 100644 --- a/src/test/ui/regions/regions-close-object-into-object-2.stderr +++ b/src/test/ui/regions/regions-close-object-into-object-2.stderr @@ -4,13 +4,13 @@ error[E0758]: cannot infer an appropriate lifetime LL | fn g<'a, T: 'static>(v: Box + 'a>) -> Box { | ------------------ this data with lifetime `'a`... LL | box B(&*v) as Box - | ^^^ ...is captured here requiring it to live as long as `'static` + | ^^^ ...is captured here, requiring it to live as long as `'static` | -help: consider changing the trait object's explicit `'static` bound to lifetime `'a` +help: consider changing the trait object's explicit `'static` bound to argument `v` | LL | fn g<'a, T: 'static>(v: Box + 'a>) -> Box { | ^^ -help: alternatively, set an explicit `'static` lifetime in this parameter +help: alternatively, add an explicit `'static` bound to this reference | LL | fn g<'a, T: 'static>(v: std::boxed::Box<(dyn A + 'static)>) -> Box { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/regions/regions-close-object-into-object-4.stderr b/src/test/ui/regions/regions-close-object-into-object-4.stderr index 1b099c7d8bdf0..4d23118ba06f0 100644 --- a/src/test/ui/regions/regions-close-object-into-object-4.stderr +++ b/src/test/ui/regions/regions-close-object-into-object-4.stderr @@ -4,13 +4,13 @@ error[E0758]: cannot infer an appropriate lifetime LL | fn i<'a, T, U>(v: Box+'a>) -> Box { | ---------------- this data with lifetime `'a`... LL | box B(&*v) as Box - | ^^^ ...is captured here requiring it to live as long as `'static` + | ^^^ ...is captured here, requiring it to live as long as `'static` | -help: consider changing the trait object's explicit `'static` bound to lifetime `'a` +help: consider changing the trait object's explicit `'static` bound to argument `v` | LL | fn i<'a, T, U>(v: Box+'a>) -> Box { | ^^ -help: alternatively, set an explicit `'static` lifetime in this parameter +help: alternatively, add an explicit `'static` bound to this reference | LL | fn i<'a, T, U>(v: std::boxed::Box<(dyn A + 'static)>) -> Box { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/regions/regions-proc-bound-capture.stderr b/src/test/ui/regions/regions-proc-bound-capture.stderr index e8baf44bd10aa..e36f77ec1da96 100644 --- a/src/test/ui/regions/regions-proc-bound-capture.stderr +++ b/src/test/ui/regions/regions-proc-bound-capture.stderr @@ -5,13 +5,13 @@ LL | fn static_proc(x: &isize) -> Box (isize) + 'static> { | ------ this data with an anonymous lifetime `'_`... LL | // This is illegal, because the region bound on `proc` is 'static. LL | Box::new(move || { *x }) - | ^^^^^^^^^^^^^^ ...is captured here requiring it to live as long as `'static` + | ^^^^^^^^^^^^^^ ...is captured here, requiring it to live as long as `'static` | -help: consider changing the trait object's explicit `'static` bound to an anonymous lifetime `'_` +help: consider changing the trait object's explicit `'static` bound to argument `x` | LL | fn static_proc(x: &isize) -> Box (isize) + '_> { | ^^ -help: alternatively, set an explicit `'static` lifetime in this parameter +help: alternatively, add an explicit `'static` bound to this reference | LL | fn static_proc(x: &'static isize) -> Box (isize) + 'static> { | ^^^^^^^^^^^^^^ diff --git a/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.stderr b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.stderr index 92e1473a5da73..365e38515b12c 100644 --- a/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.stderr +++ b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.stderr @@ -2,7 +2,7 @@ error[E0758]: cannot infer an appropriate lifetime --> $DIR/arbitrary_self_types_pin_lifetime_impl_trait-async.rs:8:16 | LL | async fn f(self: Pin<&Self>) -> impl Clone { self } - | ^^^^ ---------- ---------- ...and required to live as long as `'static` by this + | ^^^^ ---------- ---------- ...and is required to live as long as `'static` here | | | | | this data with an anonymous lifetime `'_`... | ...is captured here... diff --git a/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait.stderr b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait.stderr index 6721d41bb73c9..bd3f3efad82f2 100644 --- a/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait.stderr +++ b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait.stderr @@ -4,10 +4,10 @@ error[E0758]: cannot infer an appropriate lifetime LL | fn f(self: Pin<&Self>) -> impl Clone { self } | ---------- ---------- ^^^^ ...and is captured here | | | - | | ...is required to live as long as `'static` by this... + | | ...is required to live as long as `'static` here... | this data with an anonymous lifetime `'_`... | -help: to permit non-static references in an `impl Trait` value, you can add an explicit bound for an anonymous lifetime `'_` +help: to declare that the `impl Trait` captures data from argument `self`, you can add an explicit `'_` lifetime bound | LL | fn f(self: Pin<&Self>) -> impl Clone + '_ { self } | ^^^^ diff --git a/src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature.stderr b/src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature.stderr index ba56255af5b0c..d96a5f961bdb8 100644 --- a/src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature.stderr +++ b/src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature.stderr @@ -10,7 +10,7 @@ error[E0758]: cannot infer an appropriate lifetime --> $DIR/missing-lifetimes-in-signature.rs:19:5 | LL | fn foo(g: G, dest: &mut T) -> impl FnOnce() - | ------ ------------- ...is required to live as long as `'static` by this... + | ------ ------------- ...is required to live as long as `'static` here... | | | this data with an anonymous lifetime `'_`... ... @@ -19,7 +19,7 @@ LL | | *dest = g.get(); LL | | } | |_____^ ...and is captured here | -help: to permit non-static references in an `impl Trait` value, you can add an explicit bound for an anonymous lifetime `'_` +help: to declare that the `impl Trait` captures data from argument `dest`, you can add an explicit `'_` lifetime bound | LL | fn foo(g: G, dest: &mut T) -> impl FnOnce() + '_ | ^^^^ diff --git a/src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr b/src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr index 20d3640d4118e..7c649f9c08d64 100644 --- a/src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr +++ b/src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr @@ -7,7 +7,7 @@ LL | // ^^^^^^^^^^^^^^^^^^^^^ bound *here* defaults to LL | Box::new(items.iter()) | ---------------^^^^--- ...is captured and required live as long as `'static` here | -help: to permit non-static references in a trait object value, you can add an explicit bound for an anonymous lifetime `'_` +help: to declare that the trait object captures data from argument `items`, you can add an explicit `'_` lifetime bound | LL | fn a(items: &[T]) -> Box + '_> { | ^^^^ From bdfb9b18ab7ba6c4fc27c79dde62d678c25f3b38 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Mon, 1 Jun 2020 17:51:12 -0700 Subject: [PATCH 25/35] Use note for requirement source span --- .../nice_region_error/static_impl_trait.rs | 10 +--- .../ui/async-await/issues/issue-62097.stderr | 6 ++- .../must_outlive_least_region_or_bound.stderr | 50 +++++++++++++------ .../static-return-lifetime-infered.stderr | 22 +++++--- ...types_pin_lifetime_impl_trait-async.stderr | 11 ++-- ..._self_types_pin_lifetime_impl_trait.stderr | 10 ++-- .../missing-lifetimes-in-signature.stderr | 11 ++-- 7 files changed, 77 insertions(+), 43 deletions(-) diff --git a/src/librustc_infer/infer/error_reporting/nice_region_error/static_impl_trait.rs b/src/librustc_infer/infer/error_reporting/nice_region_error/static_impl_trait.rs index 86f310eb71d76..74267a8dec059 100644 --- a/src/librustc_infer/infer/error_reporting/nice_region_error/static_impl_trait.rs +++ b/src/librustc_infer/infer/error_reporting/nice_region_error/static_impl_trait.rs @@ -77,18 +77,12 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { sup_origin.span(), "...is captured here, requiring it to live as long as `'static`", ); - } else if sup_origin.span() <= return_sp { + } else { err.span_label(sup_origin.span(), "...is captured here..."); - err.span_label( + err.span_note( return_sp, "...and is required to live as long as `'static` here", ); - } else { - err.span_label( - return_sp, - "...is required to live as long as `'static` here...", - ); - err.span_label(sup_origin.span(), "...and is captured here"); } } else { err.span_label( diff --git a/src/test/ui/async-await/issues/issue-62097.stderr b/src/test/ui/async-await/issues/issue-62097.stderr index e9f155c6ced31..ff7007dd30b1b 100644 --- a/src/test/ui/async-await/issues/issue-62097.stderr +++ b/src/test/ui/async-await/issues/issue-62097.stderr @@ -6,8 +6,12 @@ LL | pub async fn run_dummy_fn(&self) { | | | this data with an anonymous lifetime `'_`... | ...is captured here... + | +note: ...and is required to live as long as `'static` here + --> $DIR/issue-62097.rs:13:9 + | LL | foo(|| self.bar()).await; - | --- ...and is required to live as long as `'static` here + | ^^^ error: aborting due to previous error diff --git a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr index a9fa0e93fed61..698464b4971a7 100644 --- a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr +++ b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr @@ -2,11 +2,15 @@ error[E0758]: cannot infer an appropriate lifetime --> $DIR/must_outlive_least_region_or_bound.rs:3:35 | LL | fn elided(x: &i32) -> impl Copy { x } - | ---- --------- ^ ...and is captured here - | | | - | | ...is required to live as long as `'static` here... + | ---- ^ ...is captured here... + | | | this data with an anonymous lifetime `'_`... | +note: ...and is required to live as long as `'static` here + --> $DIR/must_outlive_least_region_or_bound.rs:3:23 + | +LL | fn elided(x: &i32) -> impl Copy { x } + | ^^^^^^^^^ help: to declare that the `impl Trait` captures data from argument `x`, you can add an explicit `'_` lifetime bound | LL | fn elided(x: &i32) -> impl Copy + '_ { x } @@ -16,11 +20,15 @@ error[E0758]: cannot infer an appropriate lifetime --> $DIR/must_outlive_least_region_or_bound.rs:6:44 | LL | fn explicit<'a>(x: &'a i32) -> impl Copy { x } - | ------- --------- ^ ...and is captured here - | | | - | | ...is required to live as long as `'static` here... + | ------- ^ ...is captured here... + | | | this data with lifetime `'a`... | +note: ...and is required to live as long as `'static` here + --> $DIR/must_outlive_least_region_or_bound.rs:6:32 + | +LL | fn explicit<'a>(x: &'a i32) -> impl Copy { x } + | ^^^^^^^^^ help: to declare that the `impl Trait` captures data from argument `x`, you can add an explicit `'a` lifetime bound | LL | fn explicit<'a>(x: &'a i32) -> impl Copy + 'a { x } @@ -30,11 +38,15 @@ error[E0758]: cannot infer an appropriate lifetime --> $DIR/must_outlive_least_region_or_bound.rs:9:46 | LL | fn elided2(x: &i32) -> impl Copy + 'static { x } - | ---- ------------------- ^ ...and is captured here - | | | - | | ...is required to live as long as `'static` here... + | ---- ^ ...is captured here... + | | | this data with an anonymous lifetime `'_`... | +note: ...and is required to live as long as `'static` here + --> $DIR/must_outlive_least_region_or_bound.rs:9:24 + | +LL | fn elided2(x: &i32) -> impl Copy + 'static { x } + | ^^^^^^^^^^^^^^^^^^^ help: consider changing the `impl Trait`'s explicit `'static` bound to argument `x` | LL | fn elided2(x: &i32) -> impl Copy + '_ { x } @@ -48,11 +60,15 @@ error[E0758]: cannot infer an appropriate lifetime --> $DIR/must_outlive_least_region_or_bound.rs:12:55 | LL | fn explicit2<'a>(x: &'a i32) -> impl Copy + 'static { x } - | ------- ------------------- ^ ...and is captured here - | | | - | | ...is required to live as long as `'static` here... + | ------- ^ ...is captured here... + | | | this data with lifetime `'a`... | +note: ...and is required to live as long as `'static` here + --> $DIR/must_outlive_least_region_or_bound.rs:12:33 + | +LL | fn explicit2<'a>(x: &'a i32) -> impl Copy + 'static { x } + | ^^^^^^^^^^^^^^^^^^^ help: consider changing the `impl Trait`'s explicit `'static` bound to argument `x` | LL | fn explicit2<'a>(x: &'a i32) -> impl Copy + 'a { x } @@ -74,11 +90,13 @@ error[E0758]: cannot infer an appropriate lifetime --> $DIR/must_outlive_least_region_or_bound.rs:33:69 | LL | fn with_bound<'a>(x: &'a i32) -> impl LifetimeTrait<'a> + 'static { x } - | ------- -------------------------------- ^ ...and is captured here - | | | - | | ...is required to live as long as `'static` here... - | this data with lifetime `'a`... + | ------- this data with lifetime `'a`... ^ ...is captured here... + | +note: ...and is required to live as long as `'static` here + --> $DIR/must_outlive_least_region_or_bound.rs:33:34 | +LL | fn with_bound<'a>(x: &'a i32) -> impl LifetimeTrait<'a> + 'static { x } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider changing the `impl Trait`'s explicit `'static` bound to argument `x` | LL | fn with_bound<'a>(x: &'a i32) -> impl LifetimeTrait<'a> + 'a { x } diff --git a/src/test/ui/impl-trait/static-return-lifetime-infered.stderr b/src/test/ui/impl-trait/static-return-lifetime-infered.stderr index 6681eaa909ee0..bcc46785c5918 100644 --- a/src/test/ui/impl-trait/static-return-lifetime-infered.stderr +++ b/src/test/ui/impl-trait/static-return-lifetime-infered.stderr @@ -2,14 +2,17 @@ error[E0758]: cannot infer an appropriate lifetime --> $DIR/static-return-lifetime-infered.rs:7:16 | LL | fn iter_values_anon(&self) -> impl Iterator { - | ----- ----------------------- ...is required to live as long as `'static` here... - | | - | this data with an anonymous lifetime `'_`... + | ----- this data with an anonymous lifetime `'_`... LL | self.x.iter().map(|a| a.0) | ------ ^^^^ | | - | ...and is captured here + | ...is captured here... | +note: ...and is required to live as long as `'static` here + --> $DIR/static-return-lifetime-infered.rs:6:35 + | +LL | fn iter_values_anon(&self) -> impl Iterator { + | ^^^^^^^^^^^^^^^^^^^^^^^ help: to declare that the `impl Trait` captures data from argument `self`, you can add an explicit `'_` lifetime bound | LL | fn iter_values_anon(&self) -> impl Iterator + '_ { @@ -19,14 +22,17 @@ error[E0758]: cannot infer an appropriate lifetime --> $DIR/static-return-lifetime-infered.rs:11:16 | LL | fn iter_values<'a>(&'a self) -> impl Iterator { - | -------- ----------------------- ...is required to live as long as `'static` here... - | | - | this data with lifetime `'a`... + | -------- this data with lifetime `'a`... LL | self.x.iter().map(|a| a.0) | ------ ^^^^ | | - | ...and is captured here + | ...is captured here... | +note: ...and is required to live as long as `'static` here + --> $DIR/static-return-lifetime-infered.rs:10:37 + | +LL | fn iter_values<'a>(&'a self) -> impl Iterator { + | ^^^^^^^^^^^^^^^^^^^^^^^ help: to declare that the `impl Trait` captures data from argument `self`, you can add an explicit `'a` lifetime bound | LL | fn iter_values<'a>(&'a self) -> impl Iterator + 'a { diff --git a/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.stderr b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.stderr index 365e38515b12c..2ffbf6e08158e 100644 --- a/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.stderr +++ b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.stderr @@ -2,10 +2,15 @@ error[E0758]: cannot infer an appropriate lifetime --> $DIR/arbitrary_self_types_pin_lifetime_impl_trait-async.rs:8:16 | LL | async fn f(self: Pin<&Self>) -> impl Clone { self } - | ^^^^ ---------- ---------- ...and is required to live as long as `'static` here - | | | - | | this data with an anonymous lifetime `'_`... + | ^^^^ ---------- this data with an anonymous lifetime `'_`... + | | | ...is captured here... + | +note: ...and is required to live as long as `'static` here + --> $DIR/arbitrary_self_types_pin_lifetime_impl_trait-async.rs:8:37 + | +LL | async fn f(self: Pin<&Self>) -> impl Clone { self } + | ^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait.stderr b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait.stderr index bd3f3efad82f2..2da7bcf543d66 100644 --- a/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait.stderr +++ b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait.stderr @@ -2,11 +2,15 @@ error[E0758]: cannot infer an appropriate lifetime --> $DIR/arbitrary_self_types_pin_lifetime_impl_trait.rs:6:44 | LL | fn f(self: Pin<&Self>) -> impl Clone { self } - | ---------- ---------- ^^^^ ...and is captured here - | | | - | | ...is required to live as long as `'static` here... + | ---------- ^^^^ ...is captured here... + | | | this data with an anonymous lifetime `'_`... | +note: ...and is required to live as long as `'static` here + --> $DIR/arbitrary_self_types_pin_lifetime_impl_trait.rs:6:31 + | +LL | fn f(self: Pin<&Self>) -> impl Clone { self } + | ^^^^^^^^^^ help: to declare that the `impl Trait` captures data from argument `self`, you can add an explicit `'_` lifetime bound | LL | fn f(self: Pin<&Self>) -> impl Clone + '_ { self } diff --git a/src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature.stderr b/src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature.stderr index d96a5f961bdb8..95d905af05089 100644 --- a/src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature.stderr +++ b/src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature.stderr @@ -10,15 +10,18 @@ error[E0758]: cannot infer an appropriate lifetime --> $DIR/missing-lifetimes-in-signature.rs:19:5 | LL | fn foo(g: G, dest: &mut T) -> impl FnOnce() - | ------ ------------- ...is required to live as long as `'static` here... - | | - | this data with an anonymous lifetime `'_`... + | ------ this data with an anonymous lifetime `'_`... ... LL | / move || { LL | | *dest = g.get(); LL | | } - | |_____^ ...and is captured here + | |_____^ ...is captured here... | +note: ...and is required to live as long as `'static` here + --> $DIR/missing-lifetimes-in-signature.rs:15:37 + | +LL | fn foo(g: G, dest: &mut T) -> impl FnOnce() + | ^^^^^^^^^^^^^ help: to declare that the `impl Trait` captures data from argument `dest`, you can add an explicit `'_` lifetime bound | LL | fn foo(g: G, dest: &mut T) -> impl FnOnce() + '_ From 215de3b3c5105982978582861b95b0b449dbff94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Tue, 2 Jun 2020 10:47:58 -0700 Subject: [PATCH 26/35] Register new eror code --- src/test/ui/async-await/issues/issue-62097.stderr | 1 + .../ui/impl-trait/must_outlive_least_region_or_bound.stderr | 2 +- src/test/ui/impl-trait/static-return-lifetime-infered.stderr | 1 + src/test/ui/issues/issue-16922.stderr | 1 + .../object-lifetime-default-from-box-error.stderr | 3 ++- src/test/ui/regions/region-object-lifetime-in-coercion.stderr | 3 ++- src/test/ui/regions/regions-close-object-into-object-2.stderr | 1 + src/test/ui/regions/regions-close-object-into-object-4.stderr | 1 + src/test/ui/regions/regions-proc-bound-capture.stderr | 1 + .../arbitrary_self_types_pin_lifetime_impl_trait-async.stderr | 1 + .../self/arbitrary_self_types_pin_lifetime_impl_trait.stderr | 1 + .../lifetimes/missing-lifetimes-in-signature.stderr | 2 +- src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr | 1 + 13 files changed, 15 insertions(+), 4 deletions(-) diff --git a/src/test/ui/async-await/issues/issue-62097.stderr b/src/test/ui/async-await/issues/issue-62097.stderr index ff7007dd30b1b..b3754cce40833 100644 --- a/src/test/ui/async-await/issues/issue-62097.stderr +++ b/src/test/ui/async-await/issues/issue-62097.stderr @@ -15,3 +15,4 @@ LL | foo(|| self.bar()).await; error: aborting due to previous error +For more information about this error, try `rustc --explain E0758`. diff --git a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr index 698464b4971a7..5ab450a85d9e1 100644 --- a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr +++ b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr @@ -183,5 +183,5 @@ LL | fn explicit4<'a>(x: &'static i32) -> Box { Box::new(x) error: aborting due to 12 previous errors -Some errors have detailed explanations: E0310, E0621, E0623. +Some errors have detailed explanations: E0310, E0621, E0623, E0758. For more information about an error, try `rustc --explain E0310`. diff --git a/src/test/ui/impl-trait/static-return-lifetime-infered.stderr b/src/test/ui/impl-trait/static-return-lifetime-infered.stderr index bcc46785c5918..90aada01d9917 100644 --- a/src/test/ui/impl-trait/static-return-lifetime-infered.stderr +++ b/src/test/ui/impl-trait/static-return-lifetime-infered.stderr @@ -40,3 +40,4 @@ LL | fn iter_values<'a>(&'a self) -> impl Iterator + 'a { error: aborting due to 2 previous errors +For more information about this error, try `rustc --explain E0758`. diff --git a/src/test/ui/issues/issue-16922.stderr b/src/test/ui/issues/issue-16922.stderr index 95f46bd7f3eb6..ec80f6569f5ac 100644 --- a/src/test/ui/issues/issue-16922.stderr +++ b/src/test/ui/issues/issue-16922.stderr @@ -13,3 +13,4 @@ LL | fn foo(value: &T) -> Box { error: aborting due to previous error +For more information about this error, try `rustc --explain E0758`. diff --git a/src/test/ui/object-lifetime/object-lifetime-default-from-box-error.stderr b/src/test/ui/object-lifetime/object-lifetime-default-from-box-error.stderr index e585db262f2d8..ac7502e004c44 100644 --- a/src/test/ui/object-lifetime/object-lifetime-default-from-box-error.stderr +++ b/src/test/ui/object-lifetime/object-lifetime-default-from-box-error.stderr @@ -23,4 +23,5 @@ LL | ss.r = b; error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0621`. +Some errors have detailed explanations: E0621, E0758. +For more information about an error, try `rustc --explain E0621`. diff --git a/src/test/ui/regions/region-object-lifetime-in-coercion.stderr b/src/test/ui/regions/region-object-lifetime-in-coercion.stderr index 8d048d90cb345..fe191e9b69565 100644 --- a/src/test/ui/regions/region-object-lifetime-in-coercion.stderr +++ b/src/test/ui/regions/region-object-lifetime-in-coercion.stderr @@ -79,4 +79,5 @@ LL | Box::new(v) error: aborting due to 4 previous errors -For more information about this error, try `rustc --explain E0495`. +Some errors have detailed explanations: E0495, E0758. +For more information about an error, try `rustc --explain E0495`. diff --git a/src/test/ui/regions/regions-close-object-into-object-2.stderr b/src/test/ui/regions/regions-close-object-into-object-2.stderr index 5dfe384112b2a..2ea970afcede2 100644 --- a/src/test/ui/regions/regions-close-object-into-object-2.stderr +++ b/src/test/ui/regions/regions-close-object-into-object-2.stderr @@ -17,3 +17,4 @@ LL | fn g<'a, T: 'static>(v: std::boxed::Box<(dyn A + 'static)>) -> Box(v: std::boxed::Box<(dyn A + 'static)>) -> Box Box (isize) + 'static> error: aborting due to previous error +For more information about this error, try `rustc --explain E0758`. diff --git a/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.stderr b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.stderr index 2ffbf6e08158e..69022607bd19e 100644 --- a/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.stderr +++ b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.stderr @@ -14,3 +14,4 @@ LL | async fn f(self: Pin<&Self>) -> impl Clone { self } error: aborting due to previous error +For more information about this error, try `rustc --explain E0758`. diff --git a/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait.stderr b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait.stderr index 2da7bcf543d66..c37eb2d136ef1 100644 --- a/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait.stderr +++ b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait.stderr @@ -18,3 +18,4 @@ LL | fn f(self: Pin<&Self>) -> impl Clone + '_ { self } error: aborting due to previous error +For more information about this error, try `rustc --explain E0758`. diff --git a/src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature.stderr b/src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature.stderr index 95d905af05089..7e8ab1bfe1633 100644 --- a/src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature.stderr +++ b/src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature.stderr @@ -125,5 +125,5 @@ LL | fn bak<'a, G, T>(g: G, dest: &'a mut T) -> impl FnOnce() + 'a error: aborting due to 7 previous errors -Some errors have detailed explanations: E0261, E0309, E0621. +Some errors have detailed explanations: E0261, E0309, E0621, E0758. For more information about an error, try `rustc --explain E0261`. diff --git a/src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr b/src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr index 7c649f9c08d64..e768d7c8ab99f 100644 --- a/src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr +++ b/src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr @@ -14,3 +14,4 @@ LL | fn a(items: &[T]) -> Box + '_> { error: aborting due to previous error +For more information about this error, try `rustc --explain E0758`. From 187e1050a2d0ffd822e2ccc0baf8df9679bbde20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Tue, 2 Jun 2020 16:05:48 -0700 Subject: [PATCH 27/35] small tweaks --- .../nice_region_error/static_impl_trait.rs | 20 +++++++++++++------ .../ui/async-await/issues/issue-62097.stderr | 6 +----- .../must_outlive_least_region_or_bound.stderr | 10 +++++----- ...ect-lifetime-default-from-box-error.stderr | 2 +- .../region-object-lifetime-in-coercion.stderr | 4 ++-- .../regions-close-object-into-object-2.stderr | 2 +- .../regions-close-object-into-object-4.stderr | 2 +- .../regions/regions-proc-bound-capture.stderr | 2 +- ...types_pin_lifetime_impl_trait-async.stderr | 11 +++------- .../dyn-trait-underscore.stderr | 2 +- 10 files changed, 30 insertions(+), 31 deletions(-) diff --git a/src/librustc_infer/infer/error_reporting/nice_region_error/static_impl_trait.rs b/src/librustc_infer/infer/error_reporting/nice_region_error/static_impl_trait.rs index 74267a8dec059..5ad76e3964038 100644 --- a/src/librustc_infer/infer/error_reporting/nice_region_error/static_impl_trait.rs +++ b/src/librustc_infer/infer/error_reporting/nice_region_error/static_impl_trait.rs @@ -79,15 +79,22 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { ); } else { err.span_label(sup_origin.span(), "...is captured here..."); - err.span_note( - return_sp, - "...and is required to live as long as `'static` here", - ); + if return_sp < sup_origin.span() { + err.span_note( + return_sp, + "...and is required to live as long as `'static` here", + ); + } else { + err.span_label( + return_sp, + "...and is required to live as long as `'static` here", + ); + } } } else { err.span_label( return_sp, - "...is captured and required live as long as `'static` here", + "...is captured and required to live as long as `'static` here", ); } @@ -104,7 +111,8 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { }; let explicit = format!("you can add an explicit `{}` lifetime bound", lifetime_name); - let explicit_static = format!("explicit `'static` bound to {}", arg); + let explicit_static = + format!("explicit `'static` bound to the lifetime of {}", arg); let captures = format!("captures data from {}", arg); let add_static_bound = "alternatively, add an explicit `'static` bound to this reference"; diff --git a/src/test/ui/async-await/issues/issue-62097.stderr b/src/test/ui/async-await/issues/issue-62097.stderr index b3754cce40833..aa443b9d2fc16 100644 --- a/src/test/ui/async-await/issues/issue-62097.stderr +++ b/src/test/ui/async-await/issues/issue-62097.stderr @@ -6,12 +6,8 @@ LL | pub async fn run_dummy_fn(&self) { | | | this data with an anonymous lifetime `'_`... | ...is captured here... - | -note: ...and is required to live as long as `'static` here - --> $DIR/issue-62097.rs:13:9 - | LL | foo(|| self.bar()).await; - | ^^^ + | --- ...and is required to live as long as `'static` here error: aborting due to previous error diff --git a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr index 5ab450a85d9e1..baed43783a13c 100644 --- a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr +++ b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr @@ -47,7 +47,7 @@ note: ...and is required to live as long as `'static` here | LL | fn elided2(x: &i32) -> impl Copy + 'static { x } | ^^^^^^^^^^^^^^^^^^^ -help: consider changing the `impl Trait`'s explicit `'static` bound to argument `x` +help: consider changing the `impl Trait`'s explicit `'static` bound to the lifetime of argument `x` | LL | fn elided2(x: &i32) -> impl Copy + '_ { x } | ^^ @@ -69,7 +69,7 @@ note: ...and is required to live as long as `'static` here | LL | fn explicit2<'a>(x: &'a i32) -> impl Copy + 'static { x } | ^^^^^^^^^^^^^^^^^^^ -help: consider changing the `impl Trait`'s explicit `'static` bound to argument `x` +help: consider changing the `impl Trait`'s explicit `'static` bound to the lifetime of argument `x` | LL | fn explicit2<'a>(x: &'a i32) -> impl Copy + 'a { x } | ^^ @@ -97,7 +97,7 @@ note: ...and is required to live as long as `'static` here | LL | fn with_bound<'a>(x: &'a i32) -> impl LifetimeTrait<'a> + 'static { x } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -help: consider changing the `impl Trait`'s explicit `'static` bound to argument `x` +help: consider changing the `impl Trait`'s explicit `'static` bound to the lifetime of argument `x` | LL | fn with_bound<'a>(x: &'a i32) -> impl LifetimeTrait<'a> + 'a { x } | ^^ @@ -157,7 +157,7 @@ LL | fn elided4(x: &i32) -> Box { Box::new(x) } | | | this data with an anonymous lifetime `'_`... | -help: consider changing the trait object's explicit `'static` bound to argument `x` +help: consider changing the trait object's explicit `'static` bound to the lifetime of argument `x` | LL | fn elided4(x: &i32) -> Box { Box::new(x) } | ^^ @@ -172,7 +172,7 @@ error[E0758]: cannot infer an appropriate lifetime LL | fn explicit4<'a>(x: &'a i32) -> Box { Box::new(x) } | ------- this data with lifetime `'a`... ^ ...is captured here, requiring it to live as long as `'static` | -help: consider changing the trait object's explicit `'static` bound to argument `x` +help: consider changing the trait object's explicit `'static` bound to the lifetime of argument `x` | LL | fn explicit4<'a>(x: &'a i32) -> Box { Box::new(x) } | ^^ diff --git a/src/test/ui/object-lifetime/object-lifetime-default-from-box-error.stderr b/src/test/ui/object-lifetime/object-lifetime-default-from-box-error.stderr index ac7502e004c44..d461001adead9 100644 --- a/src/test/ui/object-lifetime/object-lifetime-default-from-box-error.stderr +++ b/src/test/ui/object-lifetime/object-lifetime-default-from-box-error.stderr @@ -5,7 +5,7 @@ LL | fn load(ss: &mut SomeStruct) -> Box { | --------------- this data with an anonymous lifetime `'_`... ... LL | ss.r - | ^^^^ ...is captured and required live as long as `'static` here + | ^^^^ ...is captured and required to live as long as `'static` here | help: to declare that the trait object captures data from argument `ss`, you can add an explicit `'_` lifetime bound | diff --git a/src/test/ui/regions/region-object-lifetime-in-coercion.stderr b/src/test/ui/regions/region-object-lifetime-in-coercion.stderr index fe191e9b69565..c684373c67e9d 100644 --- a/src/test/ui/regions/region-object-lifetime-in-coercion.stderr +++ b/src/test/ui/regions/region-object-lifetime-in-coercion.stderr @@ -6,7 +6,7 @@ LL | fn a(v: &[u8]) -> Box { LL | let x: Box = Box::new(v); | ^ ...is captured here, requiring it to live as long as `'static` | -help: consider changing the trait object's explicit `'static` bound to argument `v` +help: consider changing the trait object's explicit `'static` bound to the lifetime of argument `v` | LL | fn a(v: &[u8]) -> Box { | ^^ @@ -23,7 +23,7 @@ LL | fn b(v: &[u8]) -> Box { LL | Box::new(v) | ^ ...is captured here, requiring it to live as long as `'static` | -help: consider changing the trait object's explicit `'static` bound to argument `v` +help: consider changing the trait object's explicit `'static` bound to the lifetime of argument `v` | LL | fn b(v: &[u8]) -> Box { | ^^ diff --git a/src/test/ui/regions/regions-close-object-into-object-2.stderr b/src/test/ui/regions/regions-close-object-into-object-2.stderr index 2ea970afcede2..c4ba395179831 100644 --- a/src/test/ui/regions/regions-close-object-into-object-2.stderr +++ b/src/test/ui/regions/regions-close-object-into-object-2.stderr @@ -6,7 +6,7 @@ LL | fn g<'a, T: 'static>(v: Box + 'a>) -> Box { LL | box B(&*v) as Box | ^^^ ...is captured here, requiring it to live as long as `'static` | -help: consider changing the trait object's explicit `'static` bound to argument `v` +help: consider changing the trait object's explicit `'static` bound to the lifetime of argument `v` | LL | fn g<'a, T: 'static>(v: Box + 'a>) -> Box { | ^^ diff --git a/src/test/ui/regions/regions-close-object-into-object-4.stderr b/src/test/ui/regions/regions-close-object-into-object-4.stderr index 493b7a1df9920..e45930bd95710 100644 --- a/src/test/ui/regions/regions-close-object-into-object-4.stderr +++ b/src/test/ui/regions/regions-close-object-into-object-4.stderr @@ -6,7 +6,7 @@ LL | fn i<'a, T, U>(v: Box+'a>) -> Box { LL | box B(&*v) as Box | ^^^ ...is captured here, requiring it to live as long as `'static` | -help: consider changing the trait object's explicit `'static` bound to argument `v` +help: consider changing the trait object's explicit `'static` bound to the lifetime of argument `v` | LL | fn i<'a, T, U>(v: Box+'a>) -> Box { | ^^ diff --git a/src/test/ui/regions/regions-proc-bound-capture.stderr b/src/test/ui/regions/regions-proc-bound-capture.stderr index c10b9850a4e99..69c7256364d70 100644 --- a/src/test/ui/regions/regions-proc-bound-capture.stderr +++ b/src/test/ui/regions/regions-proc-bound-capture.stderr @@ -7,7 +7,7 @@ LL | // This is illegal, because the region bound on `proc` is 'static. LL | Box::new(move || { *x }) | ^^^^^^^^^^^^^^ ...is captured here, requiring it to live as long as `'static` | -help: consider changing the trait object's explicit `'static` bound to argument `x` +help: consider changing the trait object's explicit `'static` bound to the lifetime of argument `x` | LL | fn static_proc(x: &isize) -> Box (isize) + '_> { | ^^ diff --git a/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.stderr b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.stderr index 69022607bd19e..9b04069136be2 100644 --- a/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.stderr +++ b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.stderr @@ -2,15 +2,10 @@ error[E0758]: cannot infer an appropriate lifetime --> $DIR/arbitrary_self_types_pin_lifetime_impl_trait-async.rs:8:16 | LL | async fn f(self: Pin<&Self>) -> impl Clone { self } - | ^^^^ ---------- this data with an anonymous lifetime `'_`... - | | + | ^^^^ ---------- ---------- ...and is required to live as long as `'static` here + | | | + | | this data with an anonymous lifetime `'_`... | ...is captured here... - | -note: ...and is required to live as long as `'static` here - --> $DIR/arbitrary_self_types_pin_lifetime_impl_trait-async.rs:8:37 - | -LL | async fn f(self: Pin<&Self>) -> impl Clone { self } - | ^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr b/src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr index e768d7c8ab99f..fc4c801949512 100644 --- a/src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr +++ b/src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr @@ -5,7 +5,7 @@ LL | fn a(items: &[T]) -> Box> { | ---- this data with an anonymous lifetime `'_`... LL | // ^^^^^^^^^^^^^^^^^^^^^ bound *here* defaults to `'static` LL | Box::new(items.iter()) - | ---------------^^^^--- ...is captured and required live as long as `'static` here + | ---------------^^^^--- ...is captured and required to live as long as `'static` here | help: to declare that the trait object captures data from argument `items`, you can add an explicit `'_` lifetime bound | From 6145918c83d10e9679805b8feff0286ce9e58afc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Wed, 3 Jun 2020 11:34:04 -0700 Subject: [PATCH 28/35] Change E0758 to E0759 to avoid conflict with #72912 --- src/librustc_error_codes/error_codes.rs | 1 + src/librustc_error_codes/error_codes/E0759.md | 67 +++++++++++++++++++ .../nice_region_error/static_impl_trait.rs | 2 +- .../ui/async-await/issues/issue-62097.stderr | 4 +- .../must_outlive_least_region_or_bound.stderr | 20 +++--- .../static-return-lifetime-infered.stderr | 6 +- src/test/ui/issues/issue-16922.stderr | 4 +- ...ect-lifetime-default-from-box-error.stderr | 4 +- .../region-object-lifetime-in-coercion.stderr | 8 +-- .../regions-close-object-into-object-2.stderr | 4 +- .../regions-close-object-into-object-4.stderr | 4 +- .../regions/regions-proc-bound-capture.stderr | 4 +- ...types_pin_lifetime_impl_trait-async.stderr | 4 +- ..._self_types_pin_lifetime_impl_trait.stderr | 4 +- .../missing-lifetimes-in-signature.stderr | 4 +- .../dyn-trait-underscore.stderr | 4 +- 16 files changed, 106 insertions(+), 38 deletions(-) create mode 100644 src/librustc_error_codes/error_codes/E0759.md diff --git a/src/librustc_error_codes/error_codes.rs b/src/librustc_error_codes/error_codes.rs index 760b4d7ba00a3..2e3ba13f37911 100644 --- a/src/librustc_error_codes/error_codes.rs +++ b/src/librustc_error_codes/error_codes.rs @@ -438,6 +438,7 @@ E0752: include_str!("./error_codes/E0752.md"), E0753: include_str!("./error_codes/E0753.md"), E0754: include_str!("./error_codes/E0754.md"), E0758: include_str!("./error_codes/E0758.md"), +E0759: include_str!("./error_codes/E0759.md"), E0760: include_str!("./error_codes/E0760.md"), ; // E0006, // merged with E0005 diff --git a/src/librustc_error_codes/error_codes/E0759.md b/src/librustc_error_codes/error_codes/E0759.md new file mode 100644 index 0000000000000..a74759bdf634b --- /dev/null +++ b/src/librustc_error_codes/error_codes/E0759.md @@ -0,0 +1,67 @@ +A `'static` requirement in a return type involving a trait is not fulfilled. + +Erroneous code examples: + +```compile_fail,E0759 +use std::fmt::Debug; + +fn foo(x: &i32) -> impl Debug { + x +} +``` + +```compile_fail,E0759 +# use std::fmt::Debug; +fn bar(x: &i32) -> Box { + Box::new(x) +} +``` + +These examples have the same semantics as the following: + +```compile_fail,E0759 +# use std::fmt::Debug; +fn foo(x: &i32) -> impl Debug + 'static { + x +} +``` + +```compile_fail,E0759 +# use std::fmt::Debug; +fn bar(x: &i32) -> Box { + Box::new(x) +} +``` + +Both [`dyn Trait`] and [`impl Trait`] in return types have a an implicit +`'static` requirement, meaning that the value implementing them that is being +returned has to be either a `'static` borrow or an owned value. + +In order to change the requirement from `'static` to be a lifetime derived from +its arguments, you can add an explicit bound, either to an anonymous lifetime +`'_` or some appropriate named lifetime. + +``` +# use std::fmt::Debug; +fn foo(x: &i32) -> impl Debug + '_ { + x +} +fn bar(x: &i32) -> Box { + Box::new(x) +} +``` + +These are equivalent to the following explicit lifetime annotations: + +``` +# use std::fmt::Debug; +fn foo<'a>(x: &'a i32) -> impl Debug + 'a { + x +} +fn bar<'a>(x: &'a i32) -> Box { + Box::new(x) +} +``` + +[`dyn Trait`]: https://doc.rust-lang.org/book/ch17-02-trait-objects.html#using-trait-objects-that-allow-for-values-of-different-types +[`impl Trait`]: https://doc.rust-lang.org/book/ch10-02-traits.html#returning-types-that-implement-traits diff --git a/src/librustc_infer/infer/error_reporting/nice_region_error/static_impl_trait.rs b/src/librustc_infer/infer/error_reporting/nice_region_error/static_impl_trait.rs index 5ad76e3964038..853a414290704 100644 --- a/src/librustc_infer/infer/error_reporting/nice_region_error/static_impl_trait.rs +++ b/src/librustc_infer/infer/error_reporting/nice_region_error/static_impl_trait.rs @@ -40,7 +40,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { let mut err = struct_span_err!( self.tcx().sess, sp, - E0758, + E0759, "cannot infer an appropriate lifetime" ); err.span_label( diff --git a/src/test/ui/async-await/issues/issue-62097.stderr b/src/test/ui/async-await/issues/issue-62097.stderr index aa443b9d2fc16..0f58b158904db 100644 --- a/src/test/ui/async-await/issues/issue-62097.stderr +++ b/src/test/ui/async-await/issues/issue-62097.stderr @@ -1,4 +1,4 @@ -error[E0758]: cannot infer an appropriate lifetime +error[E0759]: cannot infer an appropriate lifetime --> $DIR/issue-62097.rs:12:31 | LL | pub async fn run_dummy_fn(&self) { @@ -11,4 +11,4 @@ LL | foo(|| self.bar()).await; error: aborting due to previous error -For more information about this error, try `rustc --explain E0758`. +For more information about this error, try `rustc --explain E0759`. diff --git a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr index baed43783a13c..e1fa4f02b6fcf 100644 --- a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr +++ b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr @@ -1,4 +1,4 @@ -error[E0758]: cannot infer an appropriate lifetime +error[E0759]: cannot infer an appropriate lifetime --> $DIR/must_outlive_least_region_or_bound.rs:3:35 | LL | fn elided(x: &i32) -> impl Copy { x } @@ -16,7 +16,7 @@ help: to declare that the `impl Trait` captures data from argument `x`, you can LL | fn elided(x: &i32) -> impl Copy + '_ { x } | ^^^^ -error[E0758]: cannot infer an appropriate lifetime +error[E0759]: cannot infer an appropriate lifetime --> $DIR/must_outlive_least_region_or_bound.rs:6:44 | LL | fn explicit<'a>(x: &'a i32) -> impl Copy { x } @@ -34,7 +34,7 @@ help: to declare that the `impl Trait` captures data from argument `x`, you can LL | fn explicit<'a>(x: &'a i32) -> impl Copy + 'a { x } | ^^^^ -error[E0758]: cannot infer an appropriate lifetime +error[E0759]: cannot infer an appropriate lifetime --> $DIR/must_outlive_least_region_or_bound.rs:9:46 | LL | fn elided2(x: &i32) -> impl Copy + 'static { x } @@ -56,7 +56,7 @@ help: alternatively, add an explicit `'static` bound to this reference LL | fn elided2(x: &'static i32) -> impl Copy + 'static { x } | ^^^^^^^^^^^^ -error[E0758]: cannot infer an appropriate lifetime +error[E0759]: cannot infer an appropriate lifetime --> $DIR/must_outlive_least_region_or_bound.rs:12:55 | LL | fn explicit2<'a>(x: &'a i32) -> impl Copy + 'static { x } @@ -86,7 +86,7 @@ LL | fn foo<'a>(x: &i32) -> impl Copy + 'a { x } | | | help: add explicit lifetime `'a` to the type of `x`: `&'a i32` -error[E0758]: cannot infer an appropriate lifetime +error[E0759]: cannot infer an appropriate lifetime --> $DIR/must_outlive_least_region_or_bound.rs:33:69 | LL | fn with_bound<'a>(x: &'a i32) -> impl LifetimeTrait<'a> + 'static { x } @@ -123,7 +123,7 @@ LL | fn ty_param_wont_outlive_static(x: T) -> impl Debug + 'static { | | | help: consider adding an explicit lifetime bound...: `T: 'static +` -error[E0758]: cannot infer an appropriate lifetime +error[E0759]: cannot infer an appropriate lifetime --> $DIR/must_outlive_least_region_or_bound.rs:18:50 | LL | fn elided3(x: &i32) -> Box { Box::new(x) } @@ -136,7 +136,7 @@ help: to declare that the trait object captures data from argument `x`, you can LL | fn elided3(x: &i32) -> Box { Box::new(x) } | ^^^^ -error[E0758]: cannot infer an appropriate lifetime +error[E0759]: cannot infer an appropriate lifetime --> $DIR/must_outlive_least_region_or_bound.rs:21:59 | LL | fn explicit3<'a>(x: &'a i32) -> Box { Box::new(x) } @@ -149,7 +149,7 @@ help: to declare that the trait object captures data from argument `x`, you can LL | fn explicit3<'a>(x: &'a i32) -> Box { Box::new(x) } | ^^^^ -error[E0758]: cannot infer an appropriate lifetime +error[E0759]: cannot infer an appropriate lifetime --> $DIR/must_outlive_least_region_or_bound.rs:24:60 | LL | fn elided4(x: &i32) -> Box { Box::new(x) } @@ -166,7 +166,7 @@ help: alternatively, add an explicit `'static` bound to this reference LL | fn elided4(x: &'static i32) -> Box { Box::new(x) } | ^^^^^^^^^^^^ -error[E0758]: cannot infer an appropriate lifetime +error[E0759]: cannot infer an appropriate lifetime --> $DIR/must_outlive_least_region_or_bound.rs:27:69 | LL | fn explicit4<'a>(x: &'a i32) -> Box { Box::new(x) } @@ -183,5 +183,5 @@ LL | fn explicit4<'a>(x: &'static i32) -> Box { Box::new(x) error: aborting due to 12 previous errors -Some errors have detailed explanations: E0310, E0621, E0623, E0758. +Some errors have detailed explanations: E0310, E0621, E0623, E0759. For more information about an error, try `rustc --explain E0310`. diff --git a/src/test/ui/impl-trait/static-return-lifetime-infered.stderr b/src/test/ui/impl-trait/static-return-lifetime-infered.stderr index 90aada01d9917..df0db6e4fc6df 100644 --- a/src/test/ui/impl-trait/static-return-lifetime-infered.stderr +++ b/src/test/ui/impl-trait/static-return-lifetime-infered.stderr @@ -1,4 +1,4 @@ -error[E0758]: cannot infer an appropriate lifetime +error[E0759]: cannot infer an appropriate lifetime --> $DIR/static-return-lifetime-infered.rs:7:16 | LL | fn iter_values_anon(&self) -> impl Iterator { @@ -18,7 +18,7 @@ help: to declare that the `impl Trait` captures data from argument `self`, you c LL | fn iter_values_anon(&self) -> impl Iterator + '_ { | ^^^^ -error[E0758]: cannot infer an appropriate lifetime +error[E0759]: cannot infer an appropriate lifetime --> $DIR/static-return-lifetime-infered.rs:11:16 | LL | fn iter_values<'a>(&'a self) -> impl Iterator { @@ -40,4 +40,4 @@ LL | fn iter_values<'a>(&'a self) -> impl Iterator + 'a { error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0758`. +For more information about this error, try `rustc --explain E0759`. diff --git a/src/test/ui/issues/issue-16922.stderr b/src/test/ui/issues/issue-16922.stderr index ec80f6569f5ac..919594fc9af4b 100644 --- a/src/test/ui/issues/issue-16922.stderr +++ b/src/test/ui/issues/issue-16922.stderr @@ -1,4 +1,4 @@ -error[E0758]: cannot infer an appropriate lifetime +error[E0759]: cannot infer an appropriate lifetime --> $DIR/issue-16922.rs:4:14 | LL | fn foo(value: &T) -> Box { @@ -13,4 +13,4 @@ LL | fn foo(value: &T) -> Box { error: aborting due to previous error -For more information about this error, try `rustc --explain E0758`. +For more information about this error, try `rustc --explain E0759`. diff --git a/src/test/ui/object-lifetime/object-lifetime-default-from-box-error.stderr b/src/test/ui/object-lifetime/object-lifetime-default-from-box-error.stderr index d461001adead9..1b1e0d9610724 100644 --- a/src/test/ui/object-lifetime/object-lifetime-default-from-box-error.stderr +++ b/src/test/ui/object-lifetime/object-lifetime-default-from-box-error.stderr @@ -1,4 +1,4 @@ -error[E0758]: cannot infer an appropriate lifetime +error[E0759]: cannot infer an appropriate lifetime --> $DIR/object-lifetime-default-from-box-error.rs:18:5 | LL | fn load(ss: &mut SomeStruct) -> Box { @@ -23,5 +23,5 @@ LL | ss.r = b; error: aborting due to 2 previous errors -Some errors have detailed explanations: E0621, E0758. +Some errors have detailed explanations: E0621, E0759. For more information about an error, try `rustc --explain E0621`. diff --git a/src/test/ui/regions/region-object-lifetime-in-coercion.stderr b/src/test/ui/regions/region-object-lifetime-in-coercion.stderr index c684373c67e9d..7f5a3a47976c7 100644 --- a/src/test/ui/regions/region-object-lifetime-in-coercion.stderr +++ b/src/test/ui/regions/region-object-lifetime-in-coercion.stderr @@ -1,4 +1,4 @@ -error[E0758]: cannot infer an appropriate lifetime +error[E0759]: cannot infer an appropriate lifetime --> $DIR/region-object-lifetime-in-coercion.rs:8:46 | LL | fn a(v: &[u8]) -> Box { @@ -15,7 +15,7 @@ help: alternatively, add an explicit `'static` bound to this reference LL | fn a(v: &'static [u8]) -> Box { | ^^^^^^^^^^^^^ -error[E0758]: cannot infer an appropriate lifetime +error[E0759]: cannot infer an appropriate lifetime --> $DIR/region-object-lifetime-in-coercion.rs:13:14 | LL | fn b(v: &[u8]) -> Box { @@ -32,7 +32,7 @@ help: alternatively, add an explicit `'static` bound to this reference LL | fn b(v: &'static [u8]) -> Box { | ^^^^^^^^^^^^^ -error[E0758]: cannot infer an appropriate lifetime +error[E0759]: cannot infer an appropriate lifetime --> $DIR/region-object-lifetime-in-coercion.rs:19:14 | LL | fn c(v: &[u8]) -> Box { @@ -79,5 +79,5 @@ LL | Box::new(v) error: aborting due to 4 previous errors -Some errors have detailed explanations: E0495, E0758. +Some errors have detailed explanations: E0495, E0759. For more information about an error, try `rustc --explain E0495`. diff --git a/src/test/ui/regions/regions-close-object-into-object-2.stderr b/src/test/ui/regions/regions-close-object-into-object-2.stderr index c4ba395179831..114e4052aae09 100644 --- a/src/test/ui/regions/regions-close-object-into-object-2.stderr +++ b/src/test/ui/regions/regions-close-object-into-object-2.stderr @@ -1,4 +1,4 @@ -error[E0758]: cannot infer an appropriate lifetime +error[E0759]: cannot infer an appropriate lifetime --> $DIR/regions-close-object-into-object-2.rs:10:11 | LL | fn g<'a, T: 'static>(v: Box + 'a>) -> Box { @@ -17,4 +17,4 @@ LL | fn g<'a, T: 'static>(v: std::boxed::Box<(dyn A + 'static)>) -> Box $DIR/regions-close-object-into-object-4.rs:10:11 | LL | fn i<'a, T, U>(v: Box+'a>) -> Box { @@ -17,4 +17,4 @@ LL | fn i<'a, T, U>(v: std::boxed::Box<(dyn A + 'static)>) -> Box $DIR/regions-proc-bound-capture.rs:9:14 | LL | fn static_proc(x: &isize) -> Box (isize) + 'static> { @@ -18,4 +18,4 @@ LL | fn static_proc(x: &'static isize) -> Box (isize) + 'static> error: aborting due to previous error -For more information about this error, try `rustc --explain E0758`. +For more information about this error, try `rustc --explain E0759`. diff --git a/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.stderr b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.stderr index 9b04069136be2..88bd990b1e81b 100644 --- a/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.stderr +++ b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.stderr @@ -1,4 +1,4 @@ -error[E0758]: cannot infer an appropriate lifetime +error[E0759]: cannot infer an appropriate lifetime --> $DIR/arbitrary_self_types_pin_lifetime_impl_trait-async.rs:8:16 | LL | async fn f(self: Pin<&Self>) -> impl Clone { self } @@ -9,4 +9,4 @@ LL | async fn f(self: Pin<&Self>) -> impl Clone { self } error: aborting due to previous error -For more information about this error, try `rustc --explain E0758`. +For more information about this error, try `rustc --explain E0759`. diff --git a/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait.stderr b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait.stderr index c37eb2d136ef1..2e10ab3d3f9b8 100644 --- a/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait.stderr +++ b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait.stderr @@ -1,4 +1,4 @@ -error[E0758]: cannot infer an appropriate lifetime +error[E0759]: cannot infer an appropriate lifetime --> $DIR/arbitrary_self_types_pin_lifetime_impl_trait.rs:6:44 | LL | fn f(self: Pin<&Self>) -> impl Clone { self } @@ -18,4 +18,4 @@ LL | fn f(self: Pin<&Self>) -> impl Clone + '_ { self } error: aborting due to previous error -For more information about this error, try `rustc --explain E0758`. +For more information about this error, try `rustc --explain E0759`. diff --git a/src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature.stderr b/src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature.stderr index 7e8ab1bfe1633..9ab060328537b 100644 --- a/src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature.stderr +++ b/src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature.stderr @@ -6,7 +6,7 @@ LL | fn baz(g: G, dest: &mut T) -> impl FnOnce() + '_ | | | help: consider introducing lifetime `'a` here: `'a,` -error[E0758]: cannot infer an appropriate lifetime +error[E0759]: cannot infer an appropriate lifetime --> $DIR/missing-lifetimes-in-signature.rs:19:5 | LL | fn foo(g: G, dest: &mut T) -> impl FnOnce() @@ -125,5 +125,5 @@ LL | fn bak<'a, G, T>(g: G, dest: &'a mut T) -> impl FnOnce() + 'a error: aborting due to 7 previous errors -Some errors have detailed explanations: E0261, E0309, E0621, E0758. +Some errors have detailed explanations: E0261, E0309, E0621, E0759. For more information about an error, try `rustc --explain E0261`. diff --git a/src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr b/src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr index fc4c801949512..dda5de431d309 100644 --- a/src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr +++ b/src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr @@ -1,4 +1,4 @@ -error[E0758]: cannot infer an appropriate lifetime +error[E0759]: cannot infer an appropriate lifetime --> $DIR/dyn-trait-underscore.rs:8:20 | LL | fn a(items: &[T]) -> Box> { @@ -14,4 +14,4 @@ LL | fn a(items: &[T]) -> Box + '_> { error: aborting due to previous error -For more information about this error, try `rustc --explain E0758`. +For more information about this error, try `rustc --explain E0759`. From 754da8849c18c45ff2fd2e77213f8371de488f80 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Thu, 11 Jun 2020 13:42:22 -0400 Subject: [PATCH 29/35] Make `fn_arg_names` return `Ident` instead of symbol Also, implement this query for the local crate, not just foreign crates. --- src/librustc_metadata/rmeta/decoder.rs | 4 ++-- src/librustc_metadata/rmeta/encoder.rs | 16 +++++----------- src/librustc_metadata/rmeta/mod.rs | 4 ++-- src/librustc_middle/hir/map/mod.rs | 9 ++++++++- src/librustc_middle/hir/mod.rs | 20 ++++++++++++++++---- src/librustc_middle/query/mod.rs | 2 +- 6 files changed, 34 insertions(+), 21 deletions(-) diff --git a/src/librustc_metadata/rmeta/decoder.rs b/src/librustc_metadata/rmeta/decoder.rs index f5a9dceb78295..b2afdd0b4e13f 100644 --- a/src/librustc_metadata/rmeta/decoder.rs +++ b/src/librustc_metadata/rmeta/decoder.rs @@ -1317,13 +1317,13 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { } } - fn get_fn_param_names(&self, tcx: TyCtxt<'tcx>, id: DefIndex) -> &'tcx [Symbol] { + fn get_fn_param_names(&self, tcx: TyCtxt<'tcx>, id: DefIndex) -> &'tcx [Ident] { let param_names = match self.kind(id) { EntryKind::Fn(data) | EntryKind::ForeignFn(data) => data.decode(self).param_names, EntryKind::AssocFn(data) => data.decode(self).fn_data.param_names, _ => Lazy::empty(), }; - tcx.arena.alloc_from_iter(param_names.decode(self)) + tcx.arena.alloc_from_iter(param_names.decode((self, tcx))) } fn exported_symbols( diff --git a/src/librustc_metadata/rmeta/encoder.rs b/src/librustc_metadata/rmeta/encoder.rs index 64ccd46a744f5..60a5bb4340513 100644 --- a/src/librustc_metadata/rmeta/encoder.rs +++ b/src/librustc_metadata/rmeta/encoder.rs @@ -30,7 +30,7 @@ use rustc_middle::ty::{self, SymbolName, Ty, TyCtxt}; use rustc_serialize::{opaque, Encodable, Encoder, SpecializedEncoder}; use rustc_session::config::CrateType; use rustc_span::source_map::Spanned; -use rustc_span::symbol::{kw, sym, Ident, Symbol}; +use rustc_span::symbol::{sym, Ident, Symbol}; use rustc_span::{self, ExternalSource, FileName, SourceFile, Span}; use rustc_target::abi::VariantIdx; use std::hash::Hash; @@ -997,18 +997,12 @@ impl EncodeContext<'tcx> { } } - fn encode_fn_param_names_for_body(&mut self, body_id: hir::BodyId) -> Lazy<[Symbol]> { - self.tcx.dep_graph.with_ignore(|| { - let body = self.tcx.hir().body(body_id); - self.lazy(body.params.iter().map(|arg| match arg.pat.kind { - hir::PatKind::Binding(_, _, ident, _) => ident.name, - _ => kw::Invalid, - })) - }) + fn encode_fn_param_names_for_body(&mut self, body_id: hir::BodyId) -> Lazy<[Ident]> { + self.tcx.dep_graph.with_ignore(|| self.lazy(self.tcx.hir().body_param_names(body_id))) } - fn encode_fn_param_names(&mut self, param_names: &[Ident]) -> Lazy<[Symbol]> { - self.lazy(param_names.iter().map(|ident| ident.name)) + fn encode_fn_param_names(&mut self, param_names: &[Ident]) -> Lazy<[Ident]> { + self.lazy(param_names.iter()) } fn encode_optimized_mir(&mut self, def_id: LocalDefId) { diff --git a/src/librustc_metadata/rmeta/mod.rs b/src/librustc_metadata/rmeta/mod.rs index 89d525eb80b8c..1cf86c7660ee4 100644 --- a/src/librustc_metadata/rmeta/mod.rs +++ b/src/librustc_metadata/rmeta/mod.rs @@ -19,7 +19,7 @@ use rustc_serialize::opaque::Encoder; use rustc_session::config::SymbolManglingVersion; use rustc_session::CrateDisambiguator; use rustc_span::edition::Edition; -use rustc_span::symbol::Symbol; +use rustc_span::symbol::{Ident, Symbol}; use rustc_span::{self, Span}; use rustc_target::spec::{PanicStrategy, TargetTriple}; @@ -327,7 +327,7 @@ struct ModData { struct FnData { asyncness: hir::IsAsync, constness: hir::Constness, - param_names: Lazy<[Symbol]>, + param_names: Lazy<[Ident]>, } #[derive(RustcEncodable, RustcDecodable)] diff --git a/src/librustc_middle/hir/map/mod.rs b/src/librustc_middle/hir/map/mod.rs index b1dafb3c88585..12c7b18d06988 100644 --- a/src/librustc_middle/hir/map/mod.rs +++ b/src/librustc_middle/hir/map/mod.rs @@ -14,7 +14,7 @@ use rustc_hir::*; use rustc_index::vec::IndexVec; use rustc_span::hygiene::MacroKind; use rustc_span::source_map::Spanned; -use rustc_span::symbol::{kw, Symbol}; +use rustc_span::symbol::{kw, Ident, Symbol}; use rustc_span::Span; use rustc_target::spec::abi::Abi; @@ -375,6 +375,13 @@ impl<'hir> Map<'hir> { }) } + pub fn body_param_names(&self, id: BodyId) -> impl Iterator + 'hir { + self.body(id).params.iter().map(|arg| match arg.pat.kind { + PatKind::Binding(_, _, ident, _) => ident, + _ => Ident::new(kw::Invalid, rustc_span::DUMMY_SP), + }) + } + /// Returns the `BodyOwnerKind` of this `LocalDefId`. /// /// Panics if `LocalDefId` does not have an associated body. diff --git a/src/librustc_middle/hir/mod.rs b/src/librustc_middle/hir/mod.rs index 1e3676496ce39..e152d11c081a1 100644 --- a/src/librustc_middle/hir/mod.rs +++ b/src/librustc_middle/hir/mod.rs @@ -12,10 +12,7 @@ use rustc_data_structures::fingerprint::Fingerprint; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_hir::def_id::{LocalDefId, LOCAL_CRATE}; -use rustc_hir::Body; -use rustc_hir::HirId; -use rustc_hir::ItemLocalId; -use rustc_hir::Node; +use rustc_hir::*; use rustc_index::vec::IndexVec; pub struct Owner<'tcx> { @@ -79,5 +76,20 @@ pub fn provide(providers: &mut Providers<'_>) { }; providers.hir_owner = |tcx, id| tcx.index_hir(LOCAL_CRATE).map[id].signature; providers.hir_owner_nodes = |tcx, id| tcx.index_hir(LOCAL_CRATE).map[id].with_bodies.as_deref(); + providers.fn_arg_names = |tcx, id| { + let hir = tcx.hir(); + let hir_id = hir.as_local_hir_id(id.expect_local()); + if let Some(body_id) = hir.maybe_body_owned_by(hir_id) { + tcx.arena.alloc_from_iter(hir.body_param_names(body_id)) + } else if let Node::TraitItem(&TraitItem { + kind: TraitItemKind::Fn(_, TraitFn::Required(idents)), + .. + }) = hir.get(hir_id) + { + tcx.arena.alloc_slice(idents) + } else { + span_bug!(hir.span(hir_id), "fn_arg_names: unexpected item {:?}", id); + } + }; map::provide(providers); } diff --git a/src/librustc_middle/query/mod.rs b/src/librustc_middle/query/mod.rs index 4d7e7882e426c..d65e01b145ac6 100644 --- a/src/librustc_middle/query/mod.rs +++ b/src/librustc_middle/query/mod.rs @@ -700,7 +700,7 @@ rustc_queries! { } Other { - query fn_arg_names(def_id: DefId) -> &'tcx [Symbol] { + query fn_arg_names(def_id: DefId) -> &'tcx [rustc_span::symbol::Ident] { desc { |tcx| "looking up function parameter names for `{}`", tcx.def_path_str(def_id) } } /// Gets the rendered value of the specified constant or associated constant. From 2c11c35f8982a9a5fd654f0499cc72b70208d62f Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Thu, 11 Jun 2020 13:48:46 -0400 Subject: [PATCH 30/35] Explain move errors that occur due to method calls involving `self` --- src/librustc_ast_lowering/expr.rs | 24 ++- .../infer/error_reporting/need_type_info.rs | 2 +- src/librustc_middle/lint.rs | 4 +- .../diagnostics/conflict_errors.rs | 72 +++++++- .../diagnostics/explain_borrow.rs | 2 +- .../borrow_check/diagnostics/mod.rs | 152 ++++++++++++++--- .../borrow_check/diagnostics/move_errors.rs | 2 +- .../diagnostics/mutability_errors.rs | 2 +- src/librustc_mir/borrow_check/mod.rs | 6 + src/librustc_mir/transform/const_prop.rs | 1 + src/librustc_span/hygiene.rs | 13 +- src/librustc_span/lib.rs | 4 +- src/test/ui/binop/binop-consume-args.stderr | 70 ++++++-- src/test/ui/binop/binop-move-semantics.stderr | 21 ++- .../borrowck/borrowck-unboxed-closures.stderr | 7 +- .../ui/closure_context/issue-42065.stderr | 7 +- src/test/ui/codemap_tests/tab_3.stderr | 8 +- .../ui/consts/miri_unleashed/ptr_arith.rs | 5 +- .../ui/consts/miri_unleashed/ptr_arith.stderr | 4 +- src/test/ui/hygiene/unpretty-debug.stdout | 4 + src/test/ui/issues/issue-12127.stderr | 7 +- src/test/ui/issues/issue-33941.rs | 1 + src/test/ui/issues/issue-33941.stderr | 12 +- src/test/ui/issues/issue-34721.stderr | 9 +- src/test/ui/issues/issue-61108.stderr | 8 +- src/test/ui/issues/issue-64559.stderr | 8 +- src/test/ui/moves/move-fn-self-receiver.rs | 74 ++++++++ .../ui/moves/move-fn-self-receiver.stderr | 158 ++++++++++++++++++ ...moves-based-on-type-access-to-field.stderr | 8 +- .../ui/moves/moves-based-on-type-exprs.stderr | 16 +- .../ui/once-cant-call-twice-on-heap.stderr | 7 +- ...ed-closures-infer-fnonce-call-twice.stderr | 7 +- ...osures-infer-fnonce-move-call-twice.stderr | 7 +- src/test/ui/unop-move-semantics.stderr | 7 +- .../unsized-locals/borrow-after-move.stderr | 8 +- src/test/ui/unsized-locals/double-move.stderr | 8 +- .../use-after-move-self-based-on-type.stderr | 8 +- src/test/ui/use/use-after-move-self.stderr | 8 +- src/test/ui/walk-struct-literal-with.stderr | 8 +- 39 files changed, 697 insertions(+), 82 deletions(-) create mode 100644 src/test/ui/moves/move-fn-self-receiver.rs create mode 100644 src/test/ui/moves/move-fn-self-receiver.stderr diff --git a/src/librustc_ast_lowering/expr.rs b/src/librustc_ast_lowering/expr.rs index b7894eb145b0a..e59cacfffc926 100644 --- a/src/librustc_ast_lowering/expr.rs +++ b/src/librustc_ast_lowering/expr.rs @@ -9,7 +9,7 @@ use rustc_data_structures::thin_vec::ThinVec; use rustc_errors::struct_span_err; use rustc_hir as hir; use rustc_hir::def::Res; -use rustc_span::source_map::{respan, DesugaringKind, Span, Spanned}; +use rustc_span::source_map::{respan, DesugaringKind, ForLoopLoc, Span, Spanned}; use rustc_span::symbol::{sym, Ident, Symbol}; use rustc_target::asm; use std::collections::hash_map::Entry; @@ -25,6 +25,7 @@ impl<'hir> LoweringContext<'_, 'hir> { } pub(super) fn lower_expr_mut(&mut self, e: &Expr) -> hir::Expr<'hir> { + let mut span = e.span; ensure_sufficient_stack(|| { let kind = match e.kind { ExprKind::Box(ref inner) => hir::ExprKind::Box(self.lower_expr(inner)), @@ -53,6 +54,7 @@ impl<'hir> LoweringContext<'_, 'hir> { hir::ExprKind::MethodCall(hir_seg, seg.ident.span, args, span) } ExprKind::Binary(binop, ref lhs, ref rhs) => { + span = self.mark_span_with_reason(DesugaringKind::Operator, e.span, None); let binop = self.lower_binop(binop); let lhs = self.lower_expr(lhs); let rhs = self.lower_expr(rhs); @@ -222,7 +224,7 @@ impl<'hir> LoweringContext<'_, 'hir> { hir::Expr { hir_id: self.lower_node_id(e.id), kind, - span: e.span, + span, attrs: e.attrs.iter().map(|a| self.lower_attr(a)).collect::>().into(), } }) @@ -237,6 +239,7 @@ impl<'hir> LoweringContext<'_, 'hir> { } fn lower_binop(&mut self, b: BinOp) -> hir::BinOp { + let span = self.mark_span_with_reason(DesugaringKind::Operator, b.span, None); Spanned { node: match b.node { BinOpKind::Add => hir::BinOpKind::Add, @@ -258,7 +261,7 @@ impl<'hir> LoweringContext<'_, 'hir> { BinOpKind::Ge => hir::BinOpKind::Ge, BinOpKind::Gt => hir::BinOpKind::Gt, }, - span: b.span, + span, } } @@ -1360,9 +1363,14 @@ impl<'hir> LoweringContext<'_, 'hir> { body: &Block, opt_label: Option