diff --git a/.mailmap b/.mailmap index 113feb3a8f5..5d9bc173364 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_error_codes/src/error_codes/E0094.md b/compiler/rustc_error_codes/src/error_codes/E0094.md index 42baa65bf9f..ec86ec44ece 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0094.md +++ b/compiler/rustc_error_codes/src/error_codes/E0094.md @@ -1,4 +1,4 @@ -An invalid number of type parameters was given to an intrinsic function. +An invalid number of generic parameters was passed to an intrinsic function. Erroneous code example: diff --git a/compiler/rustc_typeck/src/check/intrinsic.rs b/compiler/rustc_typeck/src/check/intrinsic.rs index a259fc6a488..a56aefcef9c 100644 --- a/compiler/rustc_typeck/src/check/intrinsic.rs +++ b/compiler/rustc_typeck/src/check/intrinsic.rs @@ -3,11 +3,11 @@ use crate::errors::{ SimdShuffleMissingLength, UnrecognizedAtomicOperation, UnrecognizedIntrinsicFunction, - WrongNumberOfTypeArgumentsToInstrinsic, + WrongNumberOfGenericArgumentsToIntrinsic, }; use crate::require_same_types; -use rustc_errors::struct_span_err; +use rustc_errors::{pluralize, struct_span_err}; use rustc_hir as hir; use rustc_middle::traits::{ObligationCause, ObligationCauseCode}; use rustc_middle::ty::subst::Subst; @@ -21,36 +21,45 @@ fn equate_intrinsic_type<'tcx>( tcx: TyCtxt<'tcx>, it: &hir::ForeignItem<'_>, n_tps: usize, + n_lts: usize, sig: ty::PolyFnSig<'tcx>, ) { - match it.kind { - hir::ForeignItemKind::Fn(..) => {} + let (own_counts, span) = match &it.kind { + hir::ForeignItemKind::Fn(.., generics) => { + let own_counts = tcx.generics_of(it.def_id.to_def_id()).own_counts(); + (own_counts, generics.span) + } _ => { struct_span_err!(tcx.sess, it.span, E0622, "intrinsic must be a function") .span_label(it.span, "expected a function") .emit(); return; } + }; + + let gen_count_ok = |found: usize, expected: usize, descr: &str| -> bool { + if found != expected { + tcx.sess.emit_err(WrongNumberOfGenericArgumentsToIntrinsic { + span, + found, + expected, + expected_pluralize: pluralize!(expected), + descr, + }); + false + } else { + true + } + }; + + if gen_count_ok(own_counts.lifetimes, n_lts, "lifetime") + && gen_count_ok(own_counts.types, n_tps, "type") + && gen_count_ok(own_counts.consts, 0, "const") + { + let fty = tcx.mk_fn_ptr(sig); + let cause = ObligationCause::new(it.span, it.hir_id(), ObligationCauseCode::IntrinsicType); + require_same_types(tcx, &cause, tcx.mk_fn_ptr(tcx.fn_sig(it.def_id)), fty); } - - let i_n_tps = tcx.generics_of(it.def_id).own_counts().types; - if i_n_tps != n_tps { - let span = match it.kind { - hir::ForeignItemKind::Fn(_, _, ref generics) => generics.span, - _ => bug!(), - }; - - tcx.sess.emit_err(WrongNumberOfTypeArgumentsToInstrinsic { - span, - found: i_n_tps, - expected: n_tps, - }); - return; - } - - let fty = tcx.mk_fn_ptr(sig); - let cause = ObligationCause::new(it.span, it.hir_id(), ObligationCauseCode::IntrinsicType); - require_same_types(tcx, &cause, tcx.mk_fn_ptr(tcx.fn_sig(it.def_id)), fty); } /// Returns the unsafety of the given intrinsic. @@ -121,7 +130,7 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) { }) }; - let (n_tps, inputs, output, unsafety) = if name_str.starts_with("atomic_") { + let (n_tps, n_lts, inputs, output, unsafety) = if name_str.starts_with("atomic_") { let split: Vec<&str> = name_str.split('_').collect(); assert!(split.len() >= 2, "Atomic intrinsic in an incorrect format"); @@ -143,7 +152,7 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) { return; } }; - (n_tps, inputs, output, hir::Unsafety::Unsafe) + (n_tps, 0, inputs, output, hir::Unsafety::Unsafe) } else { let unsafety = intrinsic_operation_unsafety(intrinsic_name); let (n_tps, inputs, output) = match intrinsic_name { @@ -372,11 +381,11 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) { return; } }; - (n_tps, inputs, output, unsafety) + (n_tps, 0, inputs, output, unsafety) }; let sig = tcx.mk_fn_sig(inputs.into_iter(), output, false, unsafety, Abi::RustIntrinsic); let sig = ty::Binder::bind_with_vars(sig, bound_vars); - equate_intrinsic_type(tcx, it, n_tps, sig) + equate_intrinsic_type(tcx, it, n_tps, n_lts, sig) } /// Type-check `extern "platform-intrinsic" { ... }` functions. @@ -472,5 +481,5 @@ pub fn check_platform_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) Abi::PlatformIntrinsic, ); let sig = ty::Binder::dummy(sig); - equate_intrinsic_type(tcx, it, n_tps, sig) + equate_intrinsic_type(tcx, it, n_tps, 0, sig) } diff --git a/compiler/rustc_typeck/src/errors.rs b/compiler/rustc_typeck/src/errors.rs index 1a21c085d53..1e6a240b2f8 100644 --- a/compiler/rustc_typeck/src/errors.rs +++ b/compiler/rustc_typeck/src/errors.rs @@ -24,13 +24,15 @@ pub struct UnrecognizedAtomicOperation<'a> { #[derive(SessionDiagnostic)] #[error = "E0094"] -pub struct WrongNumberOfTypeArgumentsToInstrinsic { - #[message = "intrinsic has wrong number of type \ +pub struct WrongNumberOfGenericArgumentsToIntrinsic<'a> { + #[message = "intrinsic has wrong number of {descr} \ parameters: found {found}, expected {expected}"] - #[label = "expected {expected} type parameter"] + #[label = "expected {expected} {descr} parameter{expected_pluralize}"] pub span: Span, pub found: usize, pub expected: usize, + pub expected_pluralize: &'a str, + pub descr: &'a str, } #[derive(SessionDiagnostic)] diff --git a/library/proc_macro/src/bridge/buffer.rs b/library/proc_macro/src/bridge/buffer.rs index 717201aef10..d82669d3e23 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 e7c5479ab9b..e1d6324c17e 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 4372ece5c01..0734d2670cc 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 6e73b2a5bef..0583efa92ff 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 f6343e4c3d2..a7fc0b831f4 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 00000000000..bf2bb4d2981 --- /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 00000000000..7876622435b --- /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 00000000000..20db117ccd5 --- /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 00000000000..49a80ae2360 --- /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 00000000000..a0dc086e9f9 --- /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 00000000000..734ce17001e --- /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 abd11d8b0e9..00000000000 --- 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 a544c0dd285..30baa385475 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 b79ccc7712f..c28ff638958 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 b86583b9e07..e6a86f251ca 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 00000000000..39a1b6066de --- /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 00000000000..d2ff4ce2001 --- /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 00000000000..91c5469bd90 --- /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/src/test/ui/simd-intrinsic/issue-85855.rs b/src/test/ui/simd-intrinsic/issue-85855.rs new file mode 100644 index 00000000000..f276fbd6694 --- /dev/null +++ b/src/test/ui/simd-intrinsic/issue-85855.rs @@ -0,0 +1,19 @@ +// Check that appropriate errors are reported if an intrinsic is defined +// with the wrong number of generic lifetime/type/const parameters, and +// that no ICE occurs in these cases. + +#![feature(platform_intrinsics)] +#![crate_type="lib"] + +extern "platform-intrinsic" { + fn simd_saturating_add<'a, T: 'a>(x: T, y: T); + //~^ ERROR: intrinsic has wrong number of lifetime parameters + + fn simd_add<'a, T>(x: T, y: T) -> T; + + fn simd_sub(x: T, y: U); + //~^ ERROR: intrinsic has wrong number of type parameters + + fn simd_mul(x: T, y: T); + //~^ ERROR: intrinsic has wrong number of const parameters +} diff --git a/src/test/ui/simd-intrinsic/issue-85855.stderr b/src/test/ui/simd-intrinsic/issue-85855.stderr new file mode 100644 index 00000000000..fb2f1fbc5b1 --- /dev/null +++ b/src/test/ui/simd-intrinsic/issue-85855.stderr @@ -0,0 +1,21 @@ +error[E0094]: intrinsic has wrong number of lifetime parameters: found 1, expected 0 + --> $DIR/issue-85855.rs:9:27 + | +LL | fn simd_saturating_add<'a, T: 'a>(x: T, y: T); + | ^^^^^^^^^^^ expected 0 lifetime parameters + +error[E0094]: intrinsic has wrong number of type parameters: found 2, expected 1 + --> $DIR/issue-85855.rs:14:16 + | +LL | fn simd_sub(x: T, y: U); + | ^^^^^^ expected 1 type parameter + +error[E0094]: intrinsic has wrong number of const parameters: found 1, expected 0 + --> $DIR/issue-85855.rs:17:16 + | +LL | fn simd_mul(x: T, y: T); + | ^^^^^^^^^^^^^^^^^^^ expected 0 const parameters + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0094`. diff --git a/triagebot.toml b/triagebot.toml index 4621adb2ba8..968b80414bc 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",