diff --git a/.mailmap b/.mailmap index 113feb3a8f58a..5d9bc173364da 100644 --- a/.mailmap +++ b/.mailmap @@ -72,6 +72,7 @@ Daniel Ramos David Klein David Manescu David Ross +Deadbeef Derek Chiang Derek Chiang (Enchi Jiang) Diggory Hardy Diggory Hardy Donough Liu diff --git a/compiler/rustc_ty_utils/src/ty.rs b/compiler/rustc_ty_utils/src/ty.rs index ebc7b0d0d99cf..0373033bd28db 100644 --- a/compiler/rustc_ty_utils/src/ty.rs +++ b/compiler/rustc_ty_utils/src/ty.rs @@ -402,7 +402,7 @@ fn instance_def_size_estimate<'tcx>( match instance_def { InstanceDef::Item(..) | InstanceDef::DropGlue(..) => { let mir = tcx.instance_mir(instance_def); - mir.basic_blocks().iter().map(|bb| bb.statements.len()).sum() + mir.basic_blocks().iter().map(|bb| bb.statements.len() + 1).sum() } // Estimate the size of other compiler-generated shims to be 1. _ => 1, diff --git a/library/proc_macro/src/bridge/buffer.rs b/library/proc_macro/src/bridge/buffer.rs index 717201aef102b..d82669d3e2336 100644 --- a/library/proc_macro/src/bridge/buffer.rs +++ b/library/proc_macro/src/bridge/buffer.rs @@ -5,35 +5,6 @@ use std::mem; use std::ops::{Deref, DerefMut}; use std::slice; -#[repr(C)] -struct Slice<'a, T> { - data: &'a [T; 0], - len: usize, -} - -unsafe impl<'a, T: Sync> Sync for Slice<'a, T> {} -unsafe impl<'a, T: Sync> Send for Slice<'a, T> {} - -impl Copy for Slice<'a, T> {} -impl Clone for Slice<'a, T> { - fn clone(&self) -> Self { - *self - } -} - -impl From<&'a [T]> for Slice<'a, T> { - fn from(xs: &'a [T]) -> Self { - Slice { data: unsafe { &*(xs.as_ptr() as *const [T; 0]) }, len: xs.len() } - } -} - -impl Deref for Slice<'a, T> { - type Target = [T]; - fn deref(&self) -> &[T] { - unsafe { slice::from_raw_parts(self.data.as_ptr(), self.len) } - } -} - #[repr(C)] pub struct Buffer { data: *mut T, diff --git a/library/std/src/sync/mutex.rs b/library/std/src/sync/mutex.rs index e7c5479ab9bb6..e1d6324c17e33 100644 --- a/library/std/src/sync/mutex.rs +++ b/library/std/src/sync/mutex.rs @@ -217,26 +217,6 @@ impl Mutex { data: UnsafeCell::new(t), } } - - /// Immediately drops the guard, and consequently unlocks the mutex. - /// - /// This function is equivalent to calling [`drop`] on the guard but is more self-documenting. - /// Alternately, the guard will be automatically dropped when it goes out of scope. - /// - /// ``` - /// #![feature(mutex_unlock)] - /// - /// use std::sync::Mutex; - /// let mutex = Mutex::new(0); - /// - /// let mut guard = mutex.lock().unwrap(); - /// *guard += 20; - /// Mutex::unlock(guard); - /// ``` - #[unstable(feature = "mutex_unlock", issue = "81872")] - pub fn unlock(guard: MutexGuard<'_, T>) { - drop(guard); - } } impl Mutex { @@ -333,6 +313,26 @@ impl Mutex { } } + /// Immediately drops the guard, and consequently unlocks the mutex. + /// + /// This function is equivalent to calling [`drop`] on the guard but is more self-documenting. + /// Alternately, the guard will be automatically dropped when it goes out of scope. + /// + /// ``` + /// #![feature(mutex_unlock)] + /// + /// use std::sync::Mutex; + /// let mutex = Mutex::new(0); + /// + /// let mut guard = mutex.lock().unwrap(); + /// *guard += 20; + /// Mutex::unlock(guard); + /// ``` + #[unstable(feature = "mutex_unlock", issue = "81872")] + pub fn unlock(guard: MutexGuard<'_, T>) { + drop(guard); + } + /// Determines whether the mutex is poisoned. /// /// If another thread is active, the mutex can still become poisoned at any diff --git a/src/librustdoc/html/render/cache.rs b/src/librustdoc/html/render/cache.rs index 4372ece5c0105..0734d2670ccfa 100644 --- a/src/librustdoc/html/render/cache.rs +++ b/src/librustdoc/html/render/cache.rs @@ -219,6 +219,7 @@ crate fn get_index_search_type<'tcx>( fn get_index_type(clean_type: &clean::Type) -> RenderType { RenderType { name: get_index_type_name(clean_type, true).map(|s| s.as_str().to_ascii_lowercase()), + generics: get_generics(clean_type), } } @@ -251,6 +252,23 @@ fn get_index_type_name(clean_type: &clean::Type, accept_generic: bool) -> Option } } +/// Return a list of generic parameters for use in the search index. +/// +/// This function replaces bounds with types, so that `T where T: Debug` just becomes `Debug`. +/// It does return duplicates, and that's intentional, since search queries like `Result` +/// are supposed to match only results where both parameters are `usize`. +fn get_generics(clean_type: &clean::Type) -> Option> { + clean_type.generics().and_then(|types| { + let r = types + .iter() + .filter_map(|t| { + get_index_type_name(t, false).map(|name| name.as_str().to_ascii_lowercase()) + }) + .collect::>(); + if r.is_empty() { None } else { Some(r) } + }) +} + /// The point of this function is to replace bounds with types. /// /// i.e. `[T, U]` when you have the following bounds: `T: Display, U: Option` will return diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index 6e73b2a5bef46..0583efa92ffad 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -96,6 +96,7 @@ crate struct IndexItem { #[derive(Debug)] crate struct RenderType { name: Option, + generics: Option>, } /// Full type of functions/methods in the search index. @@ -149,7 +150,13 @@ impl Serialize for TypeWithKind { where S: Serializer, { - (&self.ty.name, self.kind).serialize(serializer) + let mut seq = serializer.serialize_seq(None)?; + seq.serialize_element(&self.ty.name)?; + seq.serialize_element(&self.kind)?; + if let Some(generics) = &self.ty.generics { + seq.serialize_element(generics)?; + } + seq.end() } } diff --git a/src/librustdoc/html/static/search.js b/src/librustdoc/html/static/search.js index f6343e4c3d246..a7fc0b831f410 100644 --- a/src/librustdoc/html/static/search.js +++ b/src/librustdoc/html/static/search.js @@ -106,7 +106,7 @@ function levenshtein(s1, s2) { window.initSearch = function(rawSearchIndex) { var MAX_LEV_DISTANCE = 3; var MAX_RESULTS = 200; - var GENERICS_DATA = 1; + var GENERICS_DATA = 2; var NAME = 0; var INPUTS_DATA = 0; var OUTPUT_DATA = 1; @@ -306,6 +306,9 @@ window.initSearch = function(rawSearchIndex) { var elems = Object.create(null); var elength = obj[GENERICS_DATA].length; for (var x = 0; x < elength; ++x) { + if (!elems[getObjectNameFromId(obj[GENERICS_DATA][x])]) { + elems[getObjectNameFromId(obj[GENERICS_DATA][x])] = 0; + } elems[getObjectNameFromId(obj[GENERICS_DATA][x])] += 1; } var total = 0; @@ -354,10 +357,13 @@ window.initSearch = function(rawSearchIndex) { if (literalSearch) { if (val.generics && val.generics.length !== 0) { if (obj.length > GENERICS_DATA && - obj[GENERICS_DATA].length >= val.generics.length) { + obj[GENERICS_DATA].length > 0) { var elems = Object.create(null); len = obj[GENERICS_DATA].length; for (x = 0; x < len; ++x) { + if (!elems[getObjectNameFromId(obj[GENERICS_DATA][x])]) { + elems[getObjectNameFromId(obj[GENERICS_DATA][x])] = 0; + } elems[getObjectNameFromId(obj[GENERICS_DATA][x])] += 1; } @@ -375,26 +381,23 @@ window.initSearch = function(rawSearchIndex) { if (allFound) { return true; } - } else { - return false; } + return false; } return true; - } - // If the type has generics but don't match, then it won't return at this point. - // Otherwise, `checkGenerics` will return 0 and it'll return. - if (obj.length > GENERICS_DATA && obj[GENERICS_DATA].length !== 0) { - var tmp_lev = checkGenerics(obj, val); - if (tmp_lev <= MAX_LEV_DISTANCE) { - return tmp_lev; - } } else { - return 0; + // If the type has generics but don't match, then it won't return at this point. + // Otherwise, `checkGenerics` will return 0 and it'll return. + if (obj.length > GENERICS_DATA && obj[GENERICS_DATA].length !== 0) { + var tmp_lev = checkGenerics(obj, val); + if (tmp_lev <= MAX_LEV_DISTANCE) { + return tmp_lev; + } + } } - } - // Names didn't match so let's check if one of the generic types could. - if (literalSearch) { - if (obj.length > GENERICS_DATA && obj[GENERICS_DATA].length > 0) { + } else if (literalSearch) { + if ((!val.generics || val.generics.length === 0) && + obj.length > GENERICS_DATA && obj[GENERICS_DATA].length > 0) { return obj[GENERICS_DATA].some( function(name) { return name === val.name; @@ -1167,7 +1170,48 @@ window.initSearch = function(rawSearchIndex) { return ret; } - var queries = query.raw.split(","); + // Split search query by ",", while respecting angle bracket nesting. + // Since "<" is an alias for the Ord family of traits, it also uses + // lookahead to distinguish "<"-as-less-than from "<"-as-angle-bracket. + // + // tokenizeQuery("A, D") == ["A", "D"] + // tokenizeQuery("A)/g; + var ret = []; + var start = 0; + for (i = 0; i < l; ++i) { + switch (raw[i]) { + case "<": + nextAngle.lastIndex = i + 1; + matched = nextAngle.exec(raw); + if (matched && matched[1] === '>') { + depth += 1; + } + break; + case ">": + if (depth > 0) { + depth -= 1; + } + break; + case ",": + if (depth === 0) { + ret.push(raw.substring(start, i)); + start = i + 1; + } + break; + } + } + if (start !== i) { + ret.push(raw.substring(start, i)); + } + return ret; + } + + var queries = tokenizeQuery(query.raw); var results = { "in_args": [], "returned": [], diff --git a/src/test/rustdoc-js-std/alias-4.js b/src/test/rustdoc-js-std/alias-4.js new file mode 100644 index 0000000000000..bf2bb4d2981fc --- /dev/null +++ b/src/test/rustdoc-js-std/alias-4.js @@ -0,0 +1,7 @@ +const QUERY = '<'; + +const EXPECTED = { + 'others': [ + { 'name': 'Ord' }, + ], +}; diff --git a/src/test/rustdoc-js/generics-trait.js b/src/test/rustdoc-js/generics-trait.js new file mode 100644 index 0000000000000..7876622435b60 --- /dev/null +++ b/src/test/rustdoc-js/generics-trait.js @@ -0,0 +1,23 @@ +const QUERY = [ + 'Result', + 'OtherThingxxxxxxxx', +]; + +const EXPECTED = [ + { + 'in_args': [ + { 'path': 'generics_trait', 'name': 'beta' }, + ], + 'returned': [ + { 'path': 'generics_trait', 'name': 'bet' }, + ], + }, + { + 'in_args': [ + { 'path': 'generics_trait', 'name': 'alpha' }, + ], + 'returned': [ + { 'path': 'generics_trait', 'name': 'alef' }, + ], + }, +]; diff --git a/src/test/rustdoc-js/generics-trait.rs b/src/test/rustdoc-js/generics-trait.rs new file mode 100644 index 0000000000000..20db117ccd5ce --- /dev/null +++ b/src/test/rustdoc-js/generics-trait.rs @@ -0,0 +1,8 @@ +pub trait SomeTrait {} +pub trait OtherThingxxxxxxxx {} + +pub fn alef() -> Result { loop {} } +pub fn bet() -> Result { loop {} } + +pub fn alpha(_param: Result) { loop {} } +pub fn beta(_param: Result) { loop {} } diff --git a/src/test/rustdoc-js/generics.js b/src/test/rustdoc-js/generics.js new file mode 100644 index 0000000000000..49a80ae2360f5 --- /dev/null +++ b/src/test/rustdoc-js/generics.js @@ -0,0 +1,44 @@ +// exact-check + +const QUERY = [ + '"R

"', + '"P"', + 'P', + '"ExtraCreditStructMulti"', +]; + +const EXPECTED = [ + { + 'returned': [ + { 'path': 'generics', 'name': 'alef' }, + ], + 'in_args': [ + { 'path': 'generics', 'name': 'alpha' }, + ], + }, + { + 'others': [ + { 'path': 'generics', 'name': 'P' }, + ], + 'returned': [ + { 'path': 'generics', 'name': 'alef' }, + ], + 'in_args': [ + { 'path': 'generics', 'name': 'alpha' }, + ], + }, + { + 'returned': [ + { 'path': 'generics', 'name': 'alef' }, + ], + 'in_args': [ + { 'path': 'generics', 'name': 'alpha' }, + ], + }, + { + 'in_args': [ + { 'path': 'generics', 'name': 'extracreditlabhomework' }, + ], + 'returned': [], + }, +]; diff --git a/src/test/rustdoc-js/generics.rs b/src/test/rustdoc-js/generics.rs new file mode 100644 index 0000000000000..a0dc086e9f9cf --- /dev/null +++ b/src/test/rustdoc-js/generics.rs @@ -0,0 +1,21 @@ +pub struct P; +pub struct Q; +pub struct R(T); + +// returns test +pub fn alef() -> R

{ loop {} } +pub fn bet() -> R { loop {} } + +// in_args test +pub fn alpha(_x: R

) { loop {} } +pub fn beta(_x: R) { loop {} } + +// test case with multiple appearances of the same type +pub struct ExtraCreditStructMulti { t: T, u: U } +pub struct ExtraCreditInnerMulti {} +pub fn extracreditlabhomework( + _param: ExtraCreditStructMulti +) { loop {} } +pub fn redherringmatchforextracredit( + _param: ExtraCreditStructMulti +) { loop {} } diff --git a/src/test/ui/rfc-2632-const-trait-impl/auxiliary/staged-api.rs b/src/test/ui/rfc-2632-const-trait-impl/auxiliary/staged-api.rs new file mode 100644 index 0000000000000..734ce17001edd --- /dev/null +++ b/src/test/ui/rfc-2632-const-trait-impl/auxiliary/staged-api.rs @@ -0,0 +1,22 @@ +#![feature(const_trait_impl)] +#![allow(incomplete_features)] + +#![feature(staged_api)] +#![stable(feature = "rust1", since = "1.0.0")] + +#[stable(feature = "rust1", since = "1.0.0")] +pub trait MyTrait { + #[stable(feature = "rust1", since = "1.0.0")] + fn func(); +} + +#[stable(feature = "rust1", since = "1.0.0")] +pub struct Unstable; + +#[stable(feature = "rust1", since = "1.0.0")] +#[rustc_const_unstable(feature = "staged", issue = "none")] +impl const MyTrait for Unstable { + fn func() { + + } +} diff --git a/src/test/ui/rfc-2632-const-trait-impl/cross-crate-feature-disabled.rs b/src/test/ui/rfc-2632-const-trait-impl/cross-crate-feature-disabled.rs deleted file mode 100644 index abd11d8b0e923..0000000000000 --- a/src/test/ui/rfc-2632-const-trait-impl/cross-crate-feature-disabled.rs +++ /dev/null @@ -1,18 +0,0 @@ -// aux-build: cross-crate.rs -extern crate cross_crate; - -use cross_crate::*; - -fn non_const_context() { - NonConst.func(); - Const.func(); -} - -const fn const_context() { - NonConst.func(); - //~^ ERROR: calls in constant functions are limited to constant functions, tuple structs and tuple variants - Const.func(); - //~^ ERROR: calls in constant functions are limited to constant functions, tuple structs and tuple variants -} - -fn main() {} diff --git a/src/test/ui/rfc-2632-const-trait-impl/cross-crate-feature-enabled.stderr b/src/test/ui/rfc-2632-const-trait-impl/cross-crate.gated.stderr similarity index 85% rename from src/test/ui/rfc-2632-const-trait-impl/cross-crate-feature-enabled.stderr rename to src/test/ui/rfc-2632-const-trait-impl/cross-crate.gated.stderr index a544c0dd285fc..30baa38547580 100644 --- a/src/test/ui/rfc-2632-const-trait-impl/cross-crate-feature-enabled.stderr +++ b/src/test/ui/rfc-2632-const-trait-impl/cross-crate.gated.stderr @@ -1,5 +1,5 @@ error[E0015]: calls in constant functions are limited to constant functions, tuple structs and tuple variants - --> $DIR/cross-crate-feature-enabled.rs:15:5 + --> $DIR/cross-crate.rs:16:5 | LL | NonConst.func(); | ^^^^^^^^^^^^^^^ diff --git a/src/test/ui/rfc-2632-const-trait-impl/cross-crate-feature-enabled.rs b/src/test/ui/rfc-2632-const-trait-impl/cross-crate.rs similarity index 65% rename from src/test/ui/rfc-2632-const-trait-impl/cross-crate-feature-enabled.rs rename to src/test/ui/rfc-2632-const-trait-impl/cross-crate.rs index b79ccc7712ff2..c28ff63895841 100644 --- a/src/test/ui/rfc-2632-const-trait-impl/cross-crate-feature-enabled.rs +++ b/src/test/ui/rfc-2632-const-trait-impl/cross-crate.rs @@ -1,4 +1,5 @@ -#![feature(const_trait_impl)] +// revisions: stock gated +#![cfg_attr(gated, feature(const_trait_impl))] #![allow(incomplete_features)] // aux-build: cross-crate.rs @@ -15,6 +16,7 @@ const fn const_context() { NonConst.func(); //~^ ERROR: calls in constant functions are limited to constant functions, tuple structs and tuple variants Const.func(); + //[stock]~^ ERROR: calls in constant functions are limited to constant functions, tuple structs and tuple variants } fn main() {} diff --git a/src/test/ui/rfc-2632-const-trait-impl/cross-crate-feature-disabled.stderr b/src/test/ui/rfc-2632-const-trait-impl/cross-crate.stock.stderr similarity index 82% rename from src/test/ui/rfc-2632-const-trait-impl/cross-crate-feature-disabled.stderr rename to src/test/ui/rfc-2632-const-trait-impl/cross-crate.stock.stderr index b86583b9e079f..e6a86f251ca3c 100644 --- a/src/test/ui/rfc-2632-const-trait-impl/cross-crate-feature-disabled.stderr +++ b/src/test/ui/rfc-2632-const-trait-impl/cross-crate.stock.stderr @@ -1,11 +1,11 @@ error[E0015]: calls in constant functions are limited to constant functions, tuple structs and tuple variants - --> $DIR/cross-crate-feature-disabled.rs:12:5 + --> $DIR/cross-crate.rs:16:5 | LL | NonConst.func(); | ^^^^^^^^^^^^^^^ error[E0015]: calls in constant functions are limited to constant functions, tuple structs and tuple variants - --> $DIR/cross-crate-feature-disabled.rs:14:5 + --> $DIR/cross-crate.rs:18:5 | LL | Const.func(); | ^^^^^^^^^^^^ diff --git a/src/test/ui/rfc-2632-const-trait-impl/staged-api.rs b/src/test/ui/rfc-2632-const-trait-impl/staged-api.rs new file mode 100644 index 0000000000000..39a1b6066dea3 --- /dev/null +++ b/src/test/ui/rfc-2632-const-trait-impl/staged-api.rs @@ -0,0 +1,39 @@ +// revisions: stock staged +#![cfg_attr(staged, feature(staged))] + +#![feature(const_trait_impl)] +#![allow(incomplete_features)] + +#![feature(staged_api)] +#![stable(feature = "rust1", since = "1.0.0")] + +// aux-build: staged-api.rs +extern crate staged_api; + +use staged_api::*; + +#[stable(feature = "rust1", since = "1.0.0")] +pub struct Stable; + +#[stable(feature = "rust1", since = "1.0.0")] +#[cfg_attr(staged, rustc_const_stable(feature = "rust1", since = "1.0.0"))] +// ^ should trigger error with or without the attribute +impl const MyTrait for Stable { + fn func() { //~ ERROR trait methods cannot be stable const fn + + } +} + +fn non_const_context() { + Unstable::func(); + Stable::func(); +} + +#[unstable(feature = "none", issue = "none")] +const fn const_context() { + Unstable::func(); + //[stock]~^ ERROR `::func` is not yet stable as a const fn + Stable::func(); +} + +fn main() {} diff --git a/src/test/ui/rfc-2632-const-trait-impl/staged-api.staged.stderr b/src/test/ui/rfc-2632-const-trait-impl/staged-api.staged.stderr new file mode 100644 index 0000000000000..d2ff4ce200130 --- /dev/null +++ b/src/test/ui/rfc-2632-const-trait-impl/staged-api.staged.stderr @@ -0,0 +1,10 @@ +error: trait methods cannot be stable const fn + --> $DIR/staged-api.rs:22:5 + | +LL | / fn func() { +LL | | +LL | | } + | |_____^ + +error: aborting due to previous error + diff --git a/src/test/ui/rfc-2632-const-trait-impl/staged-api.stock.stderr b/src/test/ui/rfc-2632-const-trait-impl/staged-api.stock.stderr new file mode 100644 index 0000000000000..91c5469bd90a5 --- /dev/null +++ b/src/test/ui/rfc-2632-const-trait-impl/staged-api.stock.stderr @@ -0,0 +1,18 @@ +error: trait methods cannot be stable const fn + --> $DIR/staged-api.rs:22:5 + | +LL | / fn func() { +LL | | +LL | | } + | |_____^ + +error: `::func` is not yet stable as a const fn + --> $DIR/staged-api.rs:34:5 + | +LL | Unstable::func(); + | ^^^^^^^^^^^^^^^^ + | + = help: add `#![feature(staged)]` to the crate attributes to enable + +error: aborting due to 2 previous errors + diff --git a/triagebot.toml b/triagebot.toml index 4621adb2ba837..968b80414bcfe 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -4,7 +4,7 @@ allow-unauthenticated = [ "D-*", "requires-nightly", "regression-*", - "perf-regression", + "perf-*", # I-* without I-nominated "I-*", "!I-nominated", "AsyncAwait-OnDeck",