diff --git a/src/librustc_typeck/outlives/utils.rs b/src/librustc_typeck/outlives/utils.rs index 5cb1822b04e..0d833c50d7e 100644 --- a/src/librustc_typeck/outlives/utils.rs +++ b/src/librustc_typeck/outlives/utils.rs @@ -27,7 +27,7 @@ pub fn insert_outlives_predicate<'tcx>( ) { // If the `'a` region is bound within the field type itself, we // don't want to propagate this constraint to the header. - if !is_free_region(outlived_region) { + if !is_free_region(tcx, outlived_region) { return; } @@ -120,7 +120,7 @@ pub fn insert_outlives_predicate<'tcx>( } UnpackedKind::Lifetime(r) => { - if !is_free_region(r) { + if !is_free_region(tcx, r) { return; } required_predicates.insert(ty::OutlivesPredicate(kind, outlived_region)); @@ -128,19 +128,36 @@ pub fn insert_outlives_predicate<'tcx>( } } -fn is_free_region(region: Region<'_>) -> bool { +fn is_free_region<'tcx>(tcx: TyCtxt<'_, 'tcx, 'tcx>, region: Region<'_>) -> bool { // First, screen for regions that might appear in a type header. match region { - // *These* correspond to `T: 'a` relationships where `'a` is - // either declared on the type or `'static`: + // These correspond to `T: 'a` relationships: // // struct Foo<'a, T> { // field: &'a T, // this would generate a ReEarlyBound referencing `'a` - // field2: &'static T, // this would generate a ReStatic // } // // We care about these, so fall through. - RegionKind::ReStatic | RegionKind::ReEarlyBound(_) => true, + RegionKind::ReEarlyBound(_) => true, + + // These correspond to `T: 'static` relationships which can be + // rather surprising. We are therefore putting this behind a + // feature flag: + // + // struct Foo<'a, T> { + // field: &'static T, // this would generate a ReStatic + // } + RegionKind::ReStatic => { + if tcx + .sess + .features_untracked() + .infer_static_outlives_requirements + { + true + } else { + false + } + } // Late-bound regions can appear in `fn` types: // diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index 30137439e77..087fec09719 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -396,6 +396,9 @@ declare_features! ( // Infer outlives requirements; RFC 2093 (active, infer_outlives_requirements, "1.26.0", Some(44493), None), + // Infer outlives requirements; RFC 2093 + (active, infer_static_outlives_requirements, "1.26.0", Some(44493), None), + // Multiple patterns with `|` in `if let` and `while let` (active, if_while_or_patterns, "1.26.0", Some(48215), None), @@ -1057,6 +1060,12 @@ pub const BUILTIN_ATTRIBUTES: &'static [(&'static str, AttributeType, AttributeG "infer outlives requirements is an experimental feature", cfg_fn!(infer_outlives_requirements))), + // RFC #2093 + ("infer_static_outlives_requirements", Normal, Gated(Stability::Unstable, + "infer_static_outlives_requirements", + "infer 'static lifetime requirements", + cfg_fn!(infer_static_outlives_requirements))), + // RFC 2070 ("panic_implementation", Normal, Gated(Stability::Unstable, "panic_implementation", diff --git a/src/test/ui/rfc-2093-infer-outlives/dont-infer-static.rs b/src/test/ui/rfc-2093-infer-outlives/dont-infer-static.rs new file mode 100644 index 00000000000..c7017011277 --- /dev/null +++ b/src/test/ui/rfc-2093-infer-outlives/dont-infer-static.rs @@ -0,0 +1,23 @@ +// Copyright 2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// ignore-tidy-linelength + +#![feature(infer_outlives_requirements)] + +struct Foo { + bar: Bar //~ ERROR 16:5: 16:16: the parameter type `U` may not live long enough [E0310] +} +struct Bar { + x: T, +} + +fn main() {} + diff --git a/src/test/ui/rfc-2093-infer-outlives/dont-infer-static.stderr b/src/test/ui/rfc-2093-infer-outlives/dont-infer-static.stderr new file mode 100644 index 00000000000..38cc215ea99 --- /dev/null +++ b/src/test/ui/rfc-2093-infer-outlives/dont-infer-static.stderr @@ -0,0 +1,17 @@ +error[E0310]: the parameter type `U` may not live long enough + --> $DIR/dont-infer-static.rs:16:5 + | +LL | struct Foo { + | - help: consider adding an explicit lifetime bound `U: 'static`... +LL | bar: Bar //~ ERROR 16:5: 16:16: the parameter type `U` may not live long enough [E0310] + | ^^^^^^^^^^^ + | +note: ...so that the type `U` will meet its required lifetime bounds + --> $DIR/dont-infer-static.rs:16:5 + | +LL | bar: Bar //~ ERROR 16:5: 16:16: the parameter type `U` may not live long enough [E0310] + | ^^^^^^^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0310`. diff --git a/src/test/ui/rfc-2093-infer-outlives/infer-static.rs b/src/test/ui/rfc-2093-infer-outlives/infer-static.rs new file mode 100644 index 00000000000..bdcf31491ae --- /dev/null +++ b/src/test/ui/rfc-2093-infer-outlives/infer-static.rs @@ -0,0 +1,25 @@ +// Copyright 2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(rustc_attrs)] +#![feature(infer_outlives_requirements)] +#![feature(infer_static_outlives_requirements)] + +#[rustc_outlives] +struct Foo { //~ ERROR 16:1: 18:2: rustc_outlives + bar: Bar +} +struct Bar { + x: T, +} + +fn main() {} + + diff --git a/src/test/ui/rfc-2093-infer-outlives/infer-static.stderr b/src/test/ui/rfc-2093-infer-outlives/infer-static.stderr new file mode 100644 index 00000000000..f167e522df6 --- /dev/null +++ b/src/test/ui/rfc-2093-infer-outlives/infer-static.stderr @@ -0,0 +1,12 @@ +error: rustc_outlives + --> $DIR/infer-static.rs:16:1 + | +LL | / struct Foo { //~ ERROR 16:1: 18:2: rustc_outlives +LL | | bar: Bar +LL | | } + | |_^ + | + = note: U : 'static + +error: aborting due to previous error +