diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs
index 49aa1fc17357e..b9f380dc4e835 100644
--- a/compiler/rustc_ast/src/ast.rs
+++ b/compiler/rustc_ast/src/ast.rs
@@ -2289,12 +2289,15 @@ impl FnRetTy {
/// Module declaration.
///
/// E.g., `mod foo;` or `mod foo { .. }`.
-#[derive(Clone, Encodable, Decodable, Debug, Default)]
+#[derive(Clone, Encodable, Decodable, Debug)]
pub struct Mod {
/// A span from the first token past `{` to the last token until `}`.
/// For `mod foo;`, the inner span ranges from the first token
/// to the last token in the external file.
pub inner: Span,
+ /// `unsafe` keyword accepted syntactically for macro DSLs, but not
+ /// semantically by Rust.
+ pub unsafety: Unsafe,
pub items: Vec
>,
/// `true` for `mod foo { .. }`; `false` for `mod foo;`.
pub inline: bool,
@@ -2302,9 +2305,12 @@ pub struct Mod {
/// Foreign module declaration.
///
-/// E.g., `extern { .. }` or `extern C { .. }`.
+/// E.g., `extern { .. }` or `extern "C" { .. }`.
#[derive(Clone, Encodable, Decodable, Debug)]
pub struct ForeignMod {
+ /// `unsafe` keyword accepted syntactically for macro DSLs, but not
+ /// semantically by Rust.
+ pub unsafety: Unsafe,
pub abi: Option,
pub items: Vec>,
}
diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs
index 3ef83ef3fc973..3119c5e0a12fa 100644
--- a/compiler/rustc_ast/src/mut_visit.rs
+++ b/compiler/rustc_ast/src/mut_visit.rs
@@ -490,7 +490,7 @@ pub fn noop_visit_ty(ty: &mut P, vis: &mut T) {
}
pub fn noop_visit_foreign_mod(foreign_mod: &mut ForeignMod, vis: &mut T) {
- let ForeignMod { abi: _, items } = foreign_mod;
+ let ForeignMod { unsafety: _, abi: _, items } = foreign_mod;
items.flat_map_in_place(|item| vis.flat_map_foreign_item(item));
}
@@ -970,7 +970,8 @@ pub fn noop_visit_fn_header(header: &mut FnHeader, vis: &mut T) {
vis.visit_asyncness(asyncness);
}
-pub fn noop_visit_mod(Mod { inner, items, inline: _ }: &mut Mod, vis: &mut T) {
+pub fn noop_visit_mod(module: &mut Mod, vis: &mut T) {
+ let Mod { inner, unsafety: _, items, inline: _ } = module;
vis.visit_span(inner);
items.flat_map_in_place(|item| vis.flat_map_item(item));
}
@@ -990,7 +991,7 @@ pub fn noop_visit_crate(krate: &mut Crate, vis: &mut T) {
let len = items.len();
if len == 0 {
- let module = Mod { inner: span, items: vec![], inline: true };
+ let module = Mod { inner: span, unsafety: Unsafe::No, items: vec![], inline: true };
Crate { module, attrs: vec![], span, proc_macros }
} else if len == 1 {
let Item { attrs, span, kind, .. } = items.into_iter().next().unwrap().into_inner();
diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs
index a01dd8c939cf6..998acf4fd10cb 100644
--- a/compiler/rustc_ast_passes/src/ast_validation.rs
+++ b/compiler/rustc_ast_passes/src/ast_validation.rs
@@ -990,12 +990,15 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
self.error_item_without_body(item.span, "function", msg, " { }");
}
}
- ItemKind::ForeignMod(_) => {
+ ItemKind::ForeignMod(ForeignMod { unsafety, .. }) => {
let old_item = mem::replace(&mut self.extern_mod, Some(item));
self.invalid_visibility(
&item.vis,
Some("place qualifiers on individual foreign items instead"),
);
+ if let Unsafe::Yes(span) = unsafety {
+ self.err_handler().span_err(span, "extern block cannot be declared unsafe");
+ }
visit::walk_item(self, item);
self.extern_mod = old_item;
return; // Avoid visiting again.
@@ -1029,7 +1032,10 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
walk_list!(self, visit_attribute, &item.attrs);
return;
}
- ItemKind::Mod(Mod { inline, .. }) => {
+ ItemKind::Mod(Mod { inline, unsafety, .. }) => {
+ if let Unsafe::Yes(span) = unsafety {
+ self.err_handler().span_err(span, "module cannot be declared unsafe");
+ }
// Ensure that `path` attributes on modules are recorded as used (cf. issue #35584).
if !inline && !self.session.contains_name(&item.attrs, sym::path) {
self.check_mod_file_item_asciionly(item.ident);
diff --git a/compiler/rustc_ast_pretty/src/pprust.rs b/compiler/rustc_ast_pretty/src/pprust.rs
index 9743a00042969..955d1677647ec 100644
--- a/compiler/rustc_ast_pretty/src/pprust.rs
+++ b/compiler/rustc_ast_pretty/src/pprust.rs
@@ -1139,7 +1139,11 @@ impl<'a> State<'a> {
self.print_fn_full(sig, item.ident, gen, &item.vis, def, body, &item.attrs);
}
ast::ItemKind::Mod(ref _mod) => {
- self.head(visibility_qualified(&item.vis, "mod"));
+ self.head(to_string(|s| {
+ s.print_visibility(&item.vis);
+ s.print_unsafety(_mod.unsafety);
+ s.word("mod");
+ }));
self.print_ident(item.ident);
if _mod.inline || self.is_expanded {
@@ -1154,7 +1158,10 @@ impl<'a> State<'a> {
}
}
ast::ItemKind::ForeignMod(ref nmod) => {
- self.head("extern");
+ self.head(to_string(|s| {
+ s.print_unsafety(nmod.unsafety);
+ s.word("extern");
+ }));
if let Some(abi) = nmod.abi {
self.print_literal(&abi.as_lit());
self.nbsp();
diff --git a/compiler/rustc_builtin_macros/src/format_foreign.rs b/compiler/rustc_builtin_macros/src/format_foreign.rs
index 85cf4c42e9435..b39423b86e7b5 100644
--- a/compiler/rustc_builtin_macros/src/format_foreign.rs
+++ b/compiler/rustc_builtin_macros/src/format_foreign.rs
@@ -166,14 +166,14 @@ pub mod printf {
let cap = self.span.len() + if has_options { 2 } else { 0 };
let mut s = String::with_capacity(cap);
- s.push_str("{");
+ s.push('{');
if let Some(arg) = self.parameter {
write!(s, "{}", arg.checked_sub(1)?).ok()?;
}
if has_options {
- s.push_str(":");
+ s.push(':');
let align = if let Some(fill) = fill {
s.push_str(fill);
@@ -191,11 +191,11 @@ pub mod printf {
}
if alt {
- s.push_str("#");
+ s.push('#');
}
if zero_fill {
- s.push_str("0");
+ s.push('0');
}
if let Some(width) = width {
@@ -203,7 +203,7 @@ pub mod printf {
}
if let Some(precision) = precision {
- s.push_str(".");
+ s.push('.');
precision.translate(&mut s).ok()?;
}
@@ -212,7 +212,7 @@ pub mod printf {
}
}
- s.push_str("}");
+ s.push('}');
Some(s)
}
}
diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs
index c044020d9301b..faeb727202cd6 100644
--- a/compiler/rustc_codegen_ssa/src/back/link.rs
+++ b/compiler/rustc_codegen_ssa/src/back/link.rs
@@ -1076,7 +1076,7 @@ fn exec_linker(
}
.to_string(),
);
- args.push_str("\n");
+ args.push('\n');
}
let file = tmpdir.join("linker-arguments");
let bytes = if sess.target.target.options.is_like_msvc {
diff --git a/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs b/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs
index 54e5d4d00f6e4..0c0f1bc681cf8 100644
--- a/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs
+++ b/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs
@@ -37,7 +37,7 @@ pub fn push_debuginfo_type_name<'tcx>(
ty::Bool => output.push_str("bool"),
ty::Char => output.push_str("char"),
ty::Str => output.push_str("str"),
- ty::Never => output.push_str("!"),
+ ty::Never => output.push('!'),
ty::Int(int_ty) => output.push_str(int_ty.name_str()),
ty::Uint(uint_ty) => output.push_str(uint_ty.name_str()),
ty::Float(float_ty) => output.push_str(float_ty.name_str()),
diff --git a/compiler/rustc_expand/src/config.rs b/compiler/rustc_expand/src/config.rs
index 97608a389035b..dd087ab91509b 100644
--- a/compiler/rustc_expand/src/config.rs
+++ b/compiler/rustc_expand/src/config.rs
@@ -399,7 +399,7 @@ impl<'a> StripUnconfigured<'a> {
}
pub fn configure_foreign_mod(&mut self, foreign_mod: &mut ast::ForeignMod) {
- let ast::ForeignMod { abi: _, items } = foreign_mod;
+ let ast::ForeignMod { unsafety: _, abi: _, items } = foreign_mod;
items.flat_map_in_place(|item| self.configure(item));
}
diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs
index ca6f7324ca40f..241566a042a0e 100644
--- a/compiler/rustc_expand/src/expand.rs
+++ b/compiler/rustc_expand/src/expand.rs
@@ -13,7 +13,7 @@ use rustc_ast::token;
use rustc_ast::tokenstream::TokenStream;
use rustc_ast::visit::{self, AssocCtxt, Visitor};
use rustc_ast::{self as ast, AttrItem, Block, LitKind, NodeId, PatKind, Path};
-use rustc_ast::{ItemKind, MacArgs, MacCallStmt, MacStmtStyle, StmtKind};
+use rustc_ast::{ItemKind, MacArgs, MacCallStmt, MacStmtStyle, StmtKind, Unsafe};
use rustc_ast_pretty::pprust;
use rustc_attr::{self as attr, is_builtin_attr, HasAttrs};
use rustc_data_structures::map_in_place::MapInPlace;
@@ -370,11 +370,21 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
None => {
// Resolution failed so we return an empty expansion
krate.attrs = vec![];
- krate.module = ast::Mod { inner: orig_mod_span, items: vec![], inline: true };
+ krate.module = ast::Mod {
+ inner: orig_mod_span,
+ unsafety: Unsafe::No,
+ items: vec![],
+ inline: true,
+ };
}
Some(ast::Item { span, kind, .. }) => {
krate.attrs = vec![];
- krate.module = ast::Mod { inner: orig_mod_span, items: vec![], inline: true };
+ krate.module = ast::Mod {
+ inner: orig_mod_span,
+ unsafety: Unsafe::No,
+ items: vec![],
+ inline: true,
+ };
self.cx.span_err(
span,
&format!(
@@ -1441,8 +1451,15 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
push_directory(&self.cx.sess, ident, &item.attrs, dir)
} else {
// We have an outline `mod foo;` so we need to parse the file.
- let (new_mod, dir) =
- parse_external_mod(&self.cx.sess, ident, span, dir, &mut attrs, pushed);
+ let (new_mod, dir) = parse_external_mod(
+ &self.cx.sess,
+ ident,
+ span,
+ old_mod.unsafety,
+ dir,
+ &mut attrs,
+ pushed,
+ );
let krate = ast::Crate {
span: new_mod.inner,
diff --git a/compiler/rustc_expand/src/module.rs b/compiler/rustc_expand/src/module.rs
index fefc0bdeb7cc2..171cb3fa8e6e9 100644
--- a/compiler/rustc_expand/src/module.rs
+++ b/compiler/rustc_expand/src/module.rs
@@ -1,4 +1,4 @@
-use rustc_ast::{token, Attribute, Mod};
+use rustc_ast::{token, Attribute, Mod, Unsafe};
use rustc_errors::{struct_span_err, PResult};
use rustc_parse::new_parser_from_file;
use rustc_session::parse::ParseSess;
@@ -42,6 +42,7 @@ crate fn parse_external_mod(
sess: &Session,
id: Ident,
span: Span, // The span to blame on errors.
+ unsafety: Unsafe,
Directory { mut ownership, path }: Directory,
attrs: &mut Vec,
pop_mod_stack: &mut bool,
@@ -60,13 +61,16 @@ crate fn parse_external_mod(
drop(included_mod_stack);
// Actually parse the external file as a module.
- let mut module =
- new_parser_from_file(&sess.parse_sess, &mp.path, Some(span)).parse_mod(&token::Eof)?;
+ let mut parser = new_parser_from_file(&sess.parse_sess, &mp.path, Some(span));
+ let mut module = parser.parse_mod(&token::Eof, unsafety)?;
module.0.inline = false;
module
};
// (1) ...instead, we return a dummy module.
- let (module, mut new_attrs) = result.map_err(|mut err| err.emit()).unwrap_or_default();
+ let (module, mut new_attrs) = result.map_err(|mut err| err.emit()).unwrap_or_else(|_| {
+ let module = Mod { inner: Span::default(), unsafety, items: Vec::new(), inline: false };
+ (module, Vec::new())
+ });
attrs.append(&mut new_attrs);
// Extract the directory path for submodules of `module`.
diff --git a/compiler/rustc_feature/src/active.rs b/compiler/rustc_feature/src/active.rs
index 3d7b3da45ccb9..1aeb0bd5ad9aa 100644
--- a/compiler/rustc_feature/src/active.rs
+++ b/compiler/rustc_feature/src/active.rs
@@ -585,6 +585,9 @@ declare_features! (
/// Allows `if let` guard in match arms.
(active, if_let_guard, "1.47.0", Some(51114), None),
+ /// Allows non trivial generic constants which have to be manually propageted upwards.
+ (active, const_evaluatable_checked, "1.48.0", Some(76560), None),
+
// -------------------------------------------------------------------------
// feature-group-end: actual feature gates
// -------------------------------------------------------------------------
@@ -600,6 +603,7 @@ pub const INCOMPLETE_FEATURES: &[Symbol] = &[
sym::const_generics,
sym::let_chains,
sym::raw_dylib,
+ sym::const_evaluatable_checked,
sym::const_trait_impl,
sym::const_trait_bound_opt_out,
sym::lazy_normalization_consts,
@@ -607,6 +611,6 @@ pub const INCOMPLETE_FEATURES: &[Symbol] = &[
];
/// Some features are not allowed to be used together at the same time, if
-/// the two are present, produce an error
+/// the two are present, produce an error.
pub const INCOMPATIBLE_FEATURES: &[(Symbol, Symbol)] =
&[(sym::const_generics, sym::min_const_generics)];
diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
index b53605b0796c9..1225776db4590 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
@@ -2093,7 +2093,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
_ => String::new(),
};
if !s.is_empty() {
- s.push_str(" ");
+ s.push(' ');
}
s
};
diff --git a/compiler/rustc_infer/src/infer/lub.rs b/compiler/rustc_infer/src/infer/lub.rs
index 3e2ea3d0f8fbf..9f43fac0916b5 100644
--- a/compiler/rustc_infer/src/infer/lub.rs
+++ b/compiler/rustc_infer/src/infer/lub.rs
@@ -50,7 +50,7 @@ impl TypeRelation<'tcx> for Lub<'combine, 'infcx, 'tcx> {
ty::Invariant => self.fields.equate(self.a_is_expected).relate(a, b),
ty::Covariant => self.relate(a, b),
// FIXME(#41044) -- not correct, need test
- ty::Bivariant => Ok(a.clone()),
+ ty::Bivariant => Ok(a),
ty::Contravariant => self.fields.glb(self.a_is_expected).relate(a, b),
}
}
diff --git a/compiler/rustc_mir/src/borrow_check/diagnostics/mod.rs b/compiler/rustc_mir/src/borrow_check/diagnostics/mod.rs
index f51bf7730ea09..3cee32834beb7 100644
--- a/compiler/rustc_mir/src/borrow_check/diagnostics/mod.rs
+++ b/compiler/rustc_mir/src/borrow_check/diagnostics/mod.rs
@@ -150,8 +150,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
Some(mut descr) => {
// Surround descr with `backticks`.
descr.reserve(2);
- descr.insert_str(0, "`");
- descr.push_str("`");
+ descr.insert(0, '`');
+ descr.push('`');
descr
}
None => "value".to_string(),
@@ -222,7 +222,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
if self.upvars[var_index].by_ref {
buf.push_str(&name);
} else {
- buf.push_str(&format!("*{}", &name));
+ buf.push('*');
+ buf.push_str(&name);
}
} else {
if autoderef {
@@ -234,7 +235,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
&including_downcast,
)?;
} else {
- buf.push_str(&"*");
+ buf.push('*');
self.append_place_to_string(
PlaceRef { local, projection: proj_base },
buf,
@@ -272,7 +273,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
autoderef,
&including_downcast,
)?;
- buf.push_str(&format!(".{}", field_name));
+ buf.push('.');
+ buf.push_str(&field_name);
}
}
ProjectionElem::Index(index) => {
@@ -284,11 +286,11 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
autoderef,
&including_downcast,
)?;
- buf.push_str("[");
+ buf.push('[');
if self.append_local_to_string(*index, buf).is_err() {
- buf.push_str("_");
+ buf.push('_');
}
- buf.push_str("]");
+ buf.push(']');
}
ProjectionElem::ConstantIndex { .. } | ProjectionElem::Subslice { .. } => {
autoderef = true;
@@ -301,7 +303,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
autoderef,
&including_downcast,
)?;
- buf.push_str(&"[..]");
+ buf.push_str("[..]");
}
};
}
@@ -648,7 +650,7 @@ impl UseSpans {
" in closure".to_string()
}
}
- _ => "".to_string(),
+ _ => String::new(),
}
}
diff --git a/compiler/rustc_mir/src/borrow_check/region_infer/values.rs b/compiler/rustc_mir/src/borrow_check/region_infer/values.rs
index 8a5a600cfdd8a..f247d07e1f05e 100644
--- a/compiler/rustc_mir/src/borrow_check/region_infer/values.rs
+++ b/compiler/rustc_mir/src/borrow_check/region_infer/values.rs
@@ -417,7 +417,7 @@ crate fn location_set_str(
fn region_value_str(elements: impl IntoIterator- ) -> String {
let mut result = String::new();
- result.push_str("{");
+ result.push('{');
// Set to Some(l1, l2) when we have observed all the locations
// from l1..=l2 (inclusive) but not yet printed them. This
@@ -478,7 +478,7 @@ fn region_value_str(elements: impl IntoIterator
- ) -> String
push_location_range(&mut result, location1, location2);
}
- result.push_str("}");
+ result.push('}');
return result;
diff --git a/compiler/rustc_mir/src/monomorphize/partitioning/mod.rs b/compiler/rustc_mir/src/monomorphize/partitioning/mod.rs
index e96af77bbb8e0..0f6f078d9686f 100644
--- a/compiler/rustc_mir/src/monomorphize/partitioning/mod.rs
+++ b/compiler/rustc_mir/src/monomorphize/partitioning/mod.rs
@@ -382,7 +382,7 @@ fn collect_and_partition_mono_items<'tcx>(
cgus.sort_by_key(|(name, _)| *name);
cgus.dedup();
for &(ref cgu_name, (linkage, _)) in cgus.iter() {
- output.push_str(" ");
+ output.push(' ');
output.push_str(&cgu_name.as_str());
let linkage_abbrev = match linkage {
@@ -399,9 +399,9 @@ fn collect_and_partition_mono_items<'tcx>(
Linkage::Common => "Common",
};
- output.push_str("[");
+ output.push('[');
output.push_str(linkage_abbrev);
- output.push_str("]");
+ output.push(']');
}
output
})
diff --git a/compiler/rustc_mir/src/transform/instrument_coverage.rs b/compiler/rustc_mir/src/transform/instrument_coverage.rs
index 8f43df8a6cbd1..a5b30a25a9bdf 100644
--- a/compiler/rustc_mir/src/transform/instrument_coverage.rs
+++ b/compiler/rustc_mir/src/transform/instrument_coverage.rs
@@ -353,7 +353,7 @@ impl<'a, 'tcx> Instrumentor<'a, 'tcx> {
if !INCLUDE_COVERAGE_STATEMENTS {
continue;
}
- format!("unreachable")
+ String::from("unreachable")
}
},
_ => format!("{:?}", statement),
diff --git a/compiler/rustc_mir/src/transform/simplify_try.rs b/compiler/rustc_mir/src/transform/simplify_try.rs
index a7a3548189e1c..a320d00614d40 100644
--- a/compiler/rustc_mir/src/transform/simplify_try.rs
+++ b/compiler/rustc_mir/src/transform/simplify_try.rs
@@ -674,7 +674,7 @@ impl<'a, 'tcx> SimplifyBranchSameOptimizationFinder<'a, 'tcx> {
y_bb_idx: BasicBlock,
) -> StatementEquality {
let helper = |rhs: &Rvalue<'tcx>,
- place: &Box>,
+ place: &Place<'tcx>,
variant_index: &VariantIdx,
side_to_choose| {
let place_type = place.ty(self.body, self.tcx).ty;
diff --git a/compiler/rustc_mir/src/transform/validate.rs b/compiler/rustc_mir/src/transform/validate.rs
index 8f01e94280116..d3ca14abdcab2 100644
--- a/compiler/rustc_mir/src/transform/validate.rs
+++ b/compiler/rustc_mir/src/transform/validate.rs
@@ -4,8 +4,8 @@ use super::{MirPass, MirSource};
use rustc_middle::mir::visit::Visitor;
use rustc_middle::{
mir::{
- AggregateKind, BasicBlock, Body, Location, MirPhase, Operand, Rvalue, Statement,
- StatementKind, Terminator, TerminatorKind,
+ AggregateKind, BasicBlock, Body, BorrowKind, Location, MirPhase, Operand, Rvalue,
+ Statement, StatementKind, Terminator, TerminatorKind,
},
ty::{
self,
@@ -274,9 +274,33 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
)
}
}
+ Rvalue::Ref(_, BorrowKind::Shallow, _) => {
+ if self.mir_phase > MirPhase::DropLowering {
+ self.fail(
+ location,
+ "`Assign` statement with a `Shallow` borrow should have been removed after drop lowering phase",
+ );
+ }
+ }
_ => {}
}
}
+ StatementKind::AscribeUserType(..) => {
+ if self.mir_phase > MirPhase::DropLowering {
+ self.fail(
+ location,
+ "`AscribeUserType` should have been removed after drop lowering phase",
+ );
+ }
+ }
+ StatementKind::FakeRead(..) => {
+ if self.mir_phase > MirPhase::DropLowering {
+ self.fail(
+ location,
+ "`FakeRead` should have been removed after drop lowering phase",
+ );
+ }
+ }
_ => {}
}
}
diff --git a/compiler/rustc_mir/src/util/pretty.rs b/compiler/rustc_mir/src/util/pretty.rs
index 54bc248bc5b4a..75567181b6916 100644
--- a/compiler/rustc_mir/src/util/pretty.rs
+++ b/compiler/rustc_mir/src/util/pretty.rs
@@ -514,7 +514,7 @@ fn write_scope_tree(
write!(indented_decl, " as {:?}", user_ty).unwrap();
}
}
- indented_decl.push_str(";");
+ indented_decl.push(';');
let local_name =
if local == RETURN_PLACE { " return place".to_string() } else { String::new() };
diff --git a/compiler/rustc_parse/src/lib.rs b/compiler/rustc_parse/src/lib.rs
index e7fd74f551aaa..12afc48356cce 100644
--- a/compiler/rustc_parse/src/lib.rs
+++ b/compiler/rustc_parse/src/lib.rs
@@ -109,7 +109,7 @@ pub fn maybe_new_parser_from_source_str(
}
/// Creates a new parser, handling errors as appropriate if the file doesn't exist.
-/// If a span is given, that is used on an error as the as the source of the problem.
+/// If a span is given, that is used on an error as the source of the problem.
pub fn new_parser_from_file<'a>(sess: &'a ParseSess, path: &Path, sp: Option) -> Parser<'a> {
source_file_to_parser(sess, file_to_source_file(sess, path, sp))
}
diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs
index 9143af651df2d..1a428f8bb0ab5 100644
--- a/compiler/rustc_parse/src/parser/item.rs
+++ b/compiler/rustc_parse/src/parser/item.rs
@@ -28,7 +28,7 @@ impl<'a> Parser<'a> {
/// Parses a source module as a crate. This is the main entry point for the parser.
pub fn parse_crate_mod(&mut self) -> PResult<'a, ast::Crate> {
let lo = self.token.span;
- let (module, attrs) = self.parse_mod(&token::Eof)?;
+ let (module, attrs) = self.parse_mod(&token::Eof, Unsafe::No)?;
let span = lo.to(self.token.span);
let proc_macros = Vec::new(); // Filled in by `proc_macro_harness::inject()`.
Ok(ast::Crate { attrs, module, span, proc_macros })
@@ -36,27 +36,38 @@ impl<'a> Parser<'a> {
/// Parses a `mod { ... }` or `mod ;` item.
fn parse_item_mod(&mut self, attrs: &mut Vec) -> PResult<'a, ItemInfo> {
+ let unsafety = self.parse_unsafety();
+ self.expect_keyword(kw::Mod)?;
let id = self.parse_ident()?;
let (module, mut inner_attrs) = if self.eat(&token::Semi) {
- Default::default()
+ (Mod { inner: Span::default(), unsafety, items: Vec::new(), inline: false }, Vec::new())
} else {
self.expect(&token::OpenDelim(token::Brace))?;
- self.parse_mod(&token::CloseDelim(token::Brace))?
+ self.parse_mod(&token::CloseDelim(token::Brace), unsafety)?
};
attrs.append(&mut inner_attrs);
Ok((id, ItemKind::Mod(module)))
}
/// Parses the contents of a module (inner attributes followed by module items).
- pub fn parse_mod(&mut self, term: &TokenKind) -> PResult<'a, (Mod, Vec)> {
+ pub fn parse_mod(
+ &mut self,
+ term: &TokenKind,
+ unsafety: Unsafe,
+ ) -> PResult<'a, (Mod, Vec)> {
let lo = self.token.span;
let attrs = self.parse_inner_attributes()?;
- let module = self.parse_mod_items(term, lo)?;
+ let module = self.parse_mod_items(term, lo, unsafety)?;
Ok((module, attrs))
}
/// Given a termination token, parses all of the items in a module.
- fn parse_mod_items(&mut self, term: &TokenKind, inner_lo: Span) -> PResult<'a, Mod> {
+ fn parse_mod_items(
+ &mut self,
+ term: &TokenKind,
+ inner_lo: Span,
+ unsafety: Unsafe,
+ ) -> PResult<'a, Mod> {
let mut items = vec![];
while let Some(item) = self.parse_item()? {
items.push(item);
@@ -75,7 +86,7 @@ impl<'a> Parser<'a> {
let hi = if self.token.span.is_dummy() { inner_lo } else { self.prev_token.span };
- Ok(Mod { inner: inner_lo.to(hi), items, inline: true })
+ Ok(Mod { inner: inner_lo.to(hi), unsafety, items, inline: true })
}
}
@@ -235,8 +246,13 @@ impl<'a> Parser<'a> {
self.parse_item_extern_crate()?
} else {
// EXTERN BLOCK
- self.parse_item_foreign_mod(attrs)?
+ self.parse_item_foreign_mod(attrs, Unsafe::No)?
}
+ } else if self.is_unsafe_foreign_mod() {
+ // EXTERN BLOCK
+ let unsafety = self.parse_unsafety();
+ self.expect_keyword(kw::Extern)?;
+ self.parse_item_foreign_mod(attrs, unsafety)?
} else if self.is_static_global() {
// STATIC ITEM
self.bump(); // `static`
@@ -256,7 +272,9 @@ impl<'a> Parser<'a> {
{
// IMPL ITEM
self.parse_item_impl(attrs, def())?
- } else if self.eat_keyword(kw::Mod) {
+ } else if self.check_keyword(kw::Mod)
+ || self.check_keyword(kw::Unsafe) && self.is_keyword_ahead(1, &[kw::Mod])
+ {
// MODULE ITEM
self.parse_item_mod(attrs)?
} else if self.eat_keyword(kw::Type) {
@@ -893,10 +911,14 @@ impl<'a> Parser<'a> {
/// extern "C" {}
/// extern {}
/// ```
- fn parse_item_foreign_mod(&mut self, attrs: &mut Vec) -> PResult<'a, ItemInfo> {
+ fn parse_item_foreign_mod(
+ &mut self,
+ attrs: &mut Vec,
+ unsafety: Unsafe,
+ ) -> PResult<'a, ItemInfo> {
let abi = self.parse_abi(); // ABI?
let items = self.parse_item_list(attrs, |p| p.parse_foreign_item())?;
- let module = ast::ForeignMod { abi, items };
+ let module = ast::ForeignMod { unsafety, abi, items };
Ok((Ident::invalid(), ItemKind::ForeignMod(module)))
}
@@ -938,6 +960,15 @@ impl<'a> Parser<'a> {
.emit();
}
+ fn is_unsafe_foreign_mod(&self) -> bool {
+ self.token.is_keyword(kw::Unsafe)
+ && self.is_keyword_ahead(1, &[kw::Extern])
+ && self.look_ahead(
+ 2 + self.look_ahead(2, |t| t.can_begin_literal_maybe_minus() as usize),
+ |t| t.kind == token::OpenDelim(token::Brace),
+ )
+ }
+
fn is_static_global(&mut self) -> bool {
if self.check_keyword(kw::Static) {
// Check if this could be a closure.
@@ -1552,10 +1583,14 @@ impl<'a> Parser<'a> {
// `$qual fn` or `$qual $qual`:
|| QUALS.iter().any(|&kw| self.check_keyword(kw))
&& self.look_ahead(1, |t| {
- // ...qualified and then `fn`, e.g. `const fn`.
+ // `$qual fn`, e.g. `const fn` or `async fn`.
t.is_keyword(kw::Fn)
- // Two qualifiers. This is enough. Due `async` we need to check that it's reserved.
- || t.is_non_raw_ident_where(|i| QUALS.contains(&i.name) && i.is_reserved())
+ // Two qualifiers `$qual $qual` is enough, e.g. `async unsafe`.
+ || t.is_non_raw_ident_where(|i| QUALS.contains(&i.name)
+ // Rule out 2015 `const async: T = val`.
+ && i.is_reserved()
+ // Rule out unsafe extern block.
+ && !self.is_unsafe_foreign_mod())
})
// `extern ABI fn`
|| self.check_keyword(kw::Extern)
@@ -1567,9 +1602,9 @@ impl<'a> Parser<'a> {
/// up to and including the `fn` keyword. The formal grammar is:
///
/// ```
- /// Extern = "extern" StringLit ;
+ /// Extern = "extern" StringLit? ;
/// FnQual = "const"? "async"? "unsafe"? Extern? ;
- /// FnFrontMatter = FnQual? "fn" ;
+ /// FnFrontMatter = FnQual "fn" ;
/// ```
pub(super) fn parse_fn_front_matter(&mut self) -> PResult<'a, FnHeader> {
let constness = self.parse_constness();
diff --git a/compiler/rustc_save_analysis/src/lib.rs b/compiler/rustc_save_analysis/src/lib.rs
index c95e7e193be30..032d7cb3ed6b7 100644
--- a/compiler/rustc_save_analysis/src/lib.rs
+++ b/compiler/rustc_save_analysis/src/lib.rs
@@ -438,7 +438,7 @@ impl<'tcx> SaveContext<'tcx> {
.next()
.map(|item| item.def_id);
}
- qualname.push_str(">");
+ qualname.push('>');
(qualname, trait_id, decl_id, docs, attrs)
}
diff --git a/compiler/rustc_save_analysis/src/sig.rs b/compiler/rustc_save_analysis/src/sig.rs
index 6dd7f89d59486..747e198cd9324 100644
--- a/compiler/rustc_save_analysis/src/sig.rs
+++ b/compiler/rustc_save_analysis/src/sig.rs
@@ -497,7 +497,7 @@ impl<'hir> Sig for hir::Item<'hir> {
sig.text.push_str(&bounds_to_string(bounds));
}
// FIXME where clause
- sig.text.push_str(";");
+ sig.text.push(';');
Ok(sig)
}
diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs
index 19cd238599210..4aecb35294a07 100644
--- a/compiler/rustc_session/src/config.rs
+++ b/compiler/rustc_session/src/config.rs
@@ -581,9 +581,9 @@ impl OutputFilenames {
if !ext.is_empty() {
if !extension.is_empty() {
- extension.push_str(".");
+ extension.push('.');
extension.push_str(RUST_CGU_EXT);
- extension.push_str(".");
+ extension.push('.');
}
extension.push_str(ext);
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index 5092b945f72c4..407663e57577a 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -348,6 +348,7 @@ symbols! {
const_compare_raw_pointers,
const_constructor,
const_eval_limit,
+ const_evaluatable_checked,
const_extern_fn,
const_fn,
const_fn_transmute,
diff --git a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs
index 013cd71ea305d..fdb87c085b54e 100644
--- a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs
+++ b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs
@@ -14,6 +14,24 @@ pub fn is_const_evaluatable<'cx, 'tcx>(
param_env: ty::ParamEnv<'tcx>,
span: Span,
) -> Result<(), ErrorHandled> {
+ debug!("is_const_evaluatable({:?}, {:?})", def, substs);
+ if infcx.tcx.features().const_evaluatable_checked {
+ // FIXME(const_evaluatable_checked): Actually look into generic constants to
+ // implement const equality.
+ for pred in param_env.caller_bounds() {
+ match pred.skip_binders() {
+ ty::PredicateAtom::ConstEvaluatable(b_def, b_substs) => {
+ debug!("is_const_evaluatable: caller_bound={:?}, {:?}", b_def, b_substs);
+ if b_def == def && b_substs == substs {
+ debug!("is_const_evaluatable: caller_bound ~~> ok");
+ return Ok(());
+ }
+ }
+ _ => {} // don't care
+ }
+ }
+ }
+
let future_compat_lint = || {
if let Some(local_def_id) = def.did.as_local() {
infcx.tcx.struct_span_lint_hir(
@@ -38,24 +56,23 @@ pub fn is_const_evaluatable<'cx, 'tcx>(
// See #74595 for more details about this.
let concrete = infcx.const_eval_resolve(param_env, def, substs, None, Some(span));
- let def_kind = infcx.tcx.def_kind(def.did);
- match def_kind {
- DefKind::AnonConst => {
- let mir_body = if let Some(def) = def.as_const_arg() {
- infcx.tcx.optimized_mir_of_const_arg(def)
- } else {
- infcx.tcx.optimized_mir(def.did)
- };
- if mir_body.is_polymorphic && concrete.is_ok() {
- future_compat_lint();
- }
- }
- _ => {
- if substs.has_param_types_or_consts() && concrete.is_ok() {
- future_compat_lint();
+ if concrete.is_ok() && substs.has_param_types_or_consts() {
+ match infcx.tcx.def_kind(def.did) {
+ DefKind::AnonConst => {
+ let mir_body = if let Some(def) = def.as_const_arg() {
+ infcx.tcx.optimized_mir_of_const_arg(def)
+ } else {
+ infcx.tcx.optimized_mir(def.did)
+ };
+
+ if mir_body.is_polymorphic {
+ future_compat_lint();
+ }
}
+ _ => future_compat_lint(),
}
}
+ debug!(?concrete, "is_const_evaluatable");
concrete.map(drop)
}
diff --git a/compiler/rustc_typeck/src/check/expr.rs b/compiler/rustc_typeck/src/check/expr.rs
index fa8b8dbd9f8d4..dba46f35dca92 100644
--- a/compiler/rustc_typeck/src/check/expr.rs
+++ b/compiler/rustc_typeck/src/check/expr.rs
@@ -1241,42 +1241,21 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
tcx.sess.span_err(span, "union expressions should have exactly one field");
}
} else if check_completeness && !error_happened && !remaining_fields.is_empty() {
- let len = remaining_fields.len();
-
- let mut displayable_field_names =
- remaining_fields.keys().map(|ident| ident.as_str()).collect::>();
-
- displayable_field_names.sort();
+ let no_accessible_remaining_fields = remaining_fields
+ .iter()
+ .filter(|(_, (_, field))| {
+ field.vis.is_accessible_from(tcx.parent_module(expr_id).to_def_id(), tcx)
+ })
+ .next()
+ .is_none();
- let truncated_fields_error = if len <= 3 {
- String::new()
+ if no_accessible_remaining_fields {
+ self.report_no_accessible_fields(adt_ty, span);
} else {
- format!(" and {} other field{}", (len - 3), if len - 3 == 1 { "" } else { "s" })
- };
-
- let remaining_fields_names = displayable_field_names
- .iter()
- .take(3)
- .map(|n| format!("`{}`", n))
- .collect::>()
- .join(", ");
-
- struct_span_err!(
- tcx.sess,
- span,
- E0063,
- "missing field{} {}{} in initializer of `{}`",
- pluralize!(remaining_fields.len()),
- remaining_fields_names,
- truncated_fields_error,
- adt_ty
- )
- .span_label(
- span,
- format!("missing {}{}", remaining_fields_names, truncated_fields_error),
- )
- .emit();
+ self.report_missing_field(adt_ty, span, remaining_fields);
+ }
}
+
error_happened
}
@@ -1293,6 +1272,79 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
}
+ /// Report an error for a struct field expression when there are fields which aren't provided.
+ ///
+ /// ```ignore (diagnostic)
+ /// error: missing field `you_can_use_this_field` in initializer of `foo::Foo`
+ /// --> src/main.rs:8:5
+ /// |
+ /// 8 | foo::Foo {};
+ /// | ^^^^^^^^ missing `you_can_use_this_field`
+ ///
+ /// error: aborting due to previous error
+ /// ```
+ fn report_missing_field(
+ &self,
+ adt_ty: Ty<'tcx>,
+ span: Span,
+ remaining_fields: FxHashMap,
+ ) {
+ let tcx = self.tcx;
+ let len = remaining_fields.len();
+
+ let mut displayable_field_names =
+ remaining_fields.keys().map(|ident| ident.as_str()).collect::>();
+
+ displayable_field_names.sort();
+
+ let truncated_fields_error = if len <= 3 {
+ String::new()
+ } else {
+ format!(" and {} other field{}", (len - 3), if len - 3 == 1 { "" } else { "s" })
+ };
+
+ let remaining_fields_names = displayable_field_names
+ .iter()
+ .take(3)
+ .map(|n| format!("`{}`", n))
+ .collect::>()
+ .join(", ");
+
+ struct_span_err!(
+ tcx.sess,
+ span,
+ E0063,
+ "missing field{} {}{} in initializer of `{}`",
+ pluralize!(remaining_fields.len()),
+ remaining_fields_names,
+ truncated_fields_error,
+ adt_ty
+ )
+ .span_label(span, format!("missing {}{}", remaining_fields_names, truncated_fields_error))
+ .emit();
+ }
+
+ /// Report an error for a struct field expression when there are no visible fields.
+ ///
+ /// ```ignore (diagnostic)
+ /// error: cannot construct `Foo` with struct literal syntax due to inaccessible fields
+ /// --> src/main.rs:8:5
+ /// |
+ /// 8 | foo::Foo {};
+ /// | ^^^^^^^^
+ ///
+ /// error: aborting due to previous error
+ /// ```
+ fn report_no_accessible_fields(&self, adt_ty: Ty<'tcx>, span: Span) {
+ self.tcx.sess.span_err(
+ span,
+ &format!(
+ "cannot construct `{}` with struct literal syntax due to inaccessible fields",
+ adt_ty,
+ ),
+ );
+ }
+
fn report_unknown_field(
&self,
ty: Ty<'tcx>,
diff --git a/compiler/rustc_typeck/src/check/pat.rs b/compiler/rustc_typeck/src/check/pat.rs
index f06929aa98ff4..1896155e327d8 100644
--- a/compiler/rustc_typeck/src/check/pat.rs
+++ b/compiler/rustc_typeck/src/check/pat.rs
@@ -1078,8 +1078,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let mut unmentioned_fields = variant
.fields
.iter()
- .map(|field| field.ident.normalize_to_macros_2_0())
- .filter(|ident| !used_fields.contains_key(&ident))
+ .map(|field| (field, field.ident.normalize_to_macros_2_0()))
+ .filter(|(_, ident)| !used_fields.contains_key(&ident))
.collect::>();
let inexistent_fields_err = if !(inexistent_fields.is_empty() || variant.is_recovered()) {
@@ -1110,7 +1110,19 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
tcx.sess.struct_span_err(pat.span, "`..` cannot be used in union patterns").emit();
}
} else if !etc && !unmentioned_fields.is_empty() {
- unmentioned_err = Some(self.error_unmentioned_fields(pat, &unmentioned_fields));
+ let no_accessible_unmentioned_fields = unmentioned_fields
+ .iter()
+ .filter(|(field, _)| {
+ field.vis.is_accessible_from(tcx.parent_module(pat.hir_id).to_def_id(), tcx)
+ })
+ .next()
+ .is_none();
+
+ if no_accessible_unmentioned_fields {
+ unmentioned_err = Some(self.error_no_accessible_fields(pat, &fields));
+ } else {
+ unmentioned_err = Some(self.error_unmentioned_fields(pat, &unmentioned_fields));
+ }
}
match (inexistent_fields_err, unmentioned_err) {
(Some(mut i), Some(mut u)) => {
@@ -1173,7 +1185,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
&self,
kind_name: &str,
inexistent_fields: &[Ident],
- unmentioned_fields: &mut Vec,
+ unmentioned_fields: &mut Vec<(&ty::FieldDef, Ident)>,
variant: &ty::VariantDef,
) -> DiagnosticBuilder<'tcx> {
let tcx = self.tcx;
@@ -1215,7 +1227,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
),
);
if plural == "" {
- let input = unmentioned_fields.iter().map(|field| &field.name);
+ let input = unmentioned_fields.iter().map(|(_, field)| &field.name);
let suggested_name = find_best_match_for_name(input, ident.name, None);
if let Some(suggested_name) = suggested_name {
err.span_suggestion(
@@ -1232,7 +1244,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// `smart_resolve_context_dependent_help`.
if suggested_name.to_ident_string().parse::().is_err() {
// We don't want to throw `E0027` in case we have thrown `E0026` for them.
- unmentioned_fields.retain(|&x| x.name != suggested_name);
+ unmentioned_fields.retain(|&(_, x)| x.name != suggested_name);
}
}
}
@@ -1300,17 +1312,77 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
None
}
+ /// Returns a diagnostic reporting a struct pattern which is missing an `..` due to
+ /// inaccessible fields.
+ ///
+ /// ```ignore (diagnostic)
+ /// error: pattern requires `..` due to inaccessible fields
+ /// --> src/main.rs:10:9
+ /// |
+ /// LL | let foo::Foo {} = foo::Foo::default();
+ /// | ^^^^^^^^^^^
+ /// |
+ /// help: add a `..`
+ /// |
+ /// LL | let foo::Foo { .. } = foo::Foo::default();
+ /// | ^^^^^^
+ /// ```
+ fn error_no_accessible_fields(
+ &self,
+ pat: &Pat<'_>,
+ fields: &'tcx [hir::FieldPat<'tcx>],
+ ) -> DiagnosticBuilder<'tcx> {
+ let mut err = self
+ .tcx
+ .sess
+ .struct_span_err(pat.span, "pattern requires `..` due to inaccessible fields");
+
+ if let Some(field) = fields.last() {
+ err.span_suggestion_verbose(
+ field.span.shrink_to_hi(),
+ "ignore the inaccessible and unused fields",
+ ", ..".to_string(),
+ Applicability::MachineApplicable,
+ );
+ } else {
+ let qpath_span = if let PatKind::Struct(qpath, ..) = &pat.kind {
+ qpath.span()
+ } else {
+ bug!("`error_no_accessible_fields` called on non-struct pattern");
+ };
+
+ // Shrink the span to exclude the `foo:Foo` in `foo::Foo { }`.
+ let span = pat.span.with_lo(qpath_span.shrink_to_hi().hi());
+ err.span_suggestion_verbose(
+ span,
+ "ignore the inaccessible and unused fields",
+ " { .. }".to_string(),
+ Applicability::MachineApplicable,
+ );
+ }
+ err
+ }
+
+ /// Returns a diagnostic reporting a struct pattern which does not mention some fields.
+ ///
+ /// ```ignore (diagnostic)
+ /// error[E0027]: pattern does not mention field `you_cant_use_this_field`
+ /// --> src/main.rs:15:9
+ /// |
+ /// LL | let foo::Foo {} = foo::Foo::new();
+ /// | ^^^^^^^^^^^ missing field `you_cant_use_this_field`
+ /// ```
fn error_unmentioned_fields(
&self,
pat: &Pat<'_>,
- unmentioned_fields: &[Ident],
+ unmentioned_fields: &[(&ty::FieldDef, Ident)],
) -> DiagnosticBuilder<'tcx> {
let field_names = if unmentioned_fields.len() == 1 {
- format!("field `{}`", unmentioned_fields[0])
+ format!("field `{}`", unmentioned_fields[0].1)
} else {
let fields = unmentioned_fields
.iter()
- .map(|name| format!("`{}`", name))
+ .map(|(_, name)| format!("`{}`", name))
.collect::>()
.join(", ");
format!("fields {}", fields)
diff --git a/compiler/rustc_typeck/src/collect.rs b/compiler/rustc_typeck/src/collect.rs
index ea59375bad736..7d6b3df03b064 100644
--- a/compiler/rustc_typeck/src/collect.rs
+++ b/compiler/rustc_typeck/src/collect.rs
@@ -37,11 +37,12 @@ use rustc_middle::hir::map::Map;
use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs};
use rustc_middle::mir::mono::Linkage;
use rustc_middle::ty::query::Providers;
-use rustc_middle::ty::subst::InternalSubsts;
+use rustc_middle::ty::subst::{InternalSubsts, SubstsRef};
use rustc_middle::ty::util::Discr;
use rustc_middle::ty::util::IntTypeExt;
use rustc_middle::ty::{self, AdtKind, Const, ToPolyTraitRef, Ty, TyCtxt};
use rustc_middle::ty::{ReprOptions, ToPredicate, WithConstness};
+use rustc_middle::ty::{TypeFoldable, TypeVisitor};
use rustc_session::config::SanitizerSet;
use rustc_session::lint;
use rustc_session::parse::feature_err;
@@ -50,6 +51,8 @@ use rustc_span::{Span, DUMMY_SP};
use rustc_target::spec::abi;
use rustc_trait_selection::traits::error_reporting::suggestions::NextTypeParamName;
+use smallvec::SmallVec;
+
mod type_of;
struct OnlySelfBounds(bool);
@@ -1672,10 +1675,46 @@ fn predicates_defined_on(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericPredicate
.alloc_from_iter(result.predicates.iter().chain(inferred_outlives).copied());
}
}
+
+ if tcx.features().const_evaluatable_checked {
+ let const_evaluatable = const_evaluatable_predicates_of(tcx, def_id, &result);
+ result.predicates =
+ tcx.arena.alloc_from_iter(result.predicates.iter().copied().chain(const_evaluatable));
+ }
+
debug!("predicates_defined_on({:?}) = {:?}", def_id, result);
result
}
+pub fn const_evaluatable_predicates_of<'tcx>(
+ tcx: TyCtxt<'tcx>,
+ def_id: DefId,
+ predicates: &ty::GenericPredicates<'tcx>,
+) -> impl Iterator
- , Span)> {
+ #[derive(Default)]
+ struct ConstCollector<'tcx> {
+ ct: SmallVec<[(ty::WithOptConstParam, SubstsRef<'tcx>); 4]>,
+ }
+
+ impl<'tcx> TypeVisitor<'tcx> for ConstCollector<'tcx> {
+ fn visit_const(&mut self, ct: &'tcx Const<'tcx>) -> bool {
+ if let ty::ConstKind::Unevaluated(def, substs, None) = ct.val {
+ self.ct.push((def, substs));
+ }
+ false
+ }
+ }
+
+ let mut collector = ConstCollector::default();
+ for (pred, _span) in predicates.predicates.iter() {
+ pred.visit_with(&mut collector);
+ }
+ warn!("const_evaluatable_predicates_of({:?}) = {:?}", def_id, collector.ct);
+ collector.ct.into_iter().map(move |(def_id, subst)| {
+ (ty::PredicateAtom::ConstEvaluatable(def_id, subst).to_predicate(tcx), DUMMY_SP)
+ })
+}
+
/// Returns a list of all type predicates (explicit and implicit) for the definition with
/// ID `def_id`. This includes all predicates returned by `predicates_defined_on`, plus
/// `Self: Trait` predicates for traits.
diff --git a/library/core/src/ops/arith.rs b/library/core/src/ops/arith.rs
index 622a138abe9d1..bdf93baa1b8f9 100644
--- a/library/core/src/ops/arith.rs
+++ b/library/core/src/ops/arith.rs
@@ -78,6 +78,12 @@ pub trait Add {
type Output;
/// Performs the `+` operation.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// assert_eq!(12 + 1, 13);
+ /// ```
#[must_use]
#[stable(feature = "rust1", since = "1.0.0")]
fn add(self, rhs: Rhs) -> Self::Output;
@@ -178,6 +184,12 @@ pub trait Sub {
type Output;
/// Performs the `-` operation.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// assert_eq!(12 - 1, 11);
+ /// ```
#[must_use]
#[stable(feature = "rust1", since = "1.0.0")]
fn sub(self, rhs: Rhs) -> Self::Output;
@@ -300,6 +312,12 @@ pub trait Mul {
type Output;
/// Performs the `*` operation.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// assert_eq!(12 * 2, 24);
+ /// ```
#[must_use]
#[stable(feature = "rust1", since = "1.0.0")]
fn mul(self, rhs: Rhs) -> Self::Output;
@@ -426,6 +444,12 @@ pub trait Div {
type Output;
/// Performs the `/` operation.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// assert_eq!(12 / 2, 6);
+ /// ```
#[must_use]
#[stable(feature = "rust1", since = "1.0.0")]
fn div(self, rhs: Rhs) -> Self::Output;
@@ -513,6 +537,12 @@ pub trait Rem {
type Output;
/// Performs the `%` operation.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// assert_eq!(12 % 10, 2);
+ /// ```
#[must_use]
#[stable(feature = "rust1", since = "1.0.0")]
fn rem(self, rhs: Rhs) -> Self::Output;
@@ -612,6 +642,13 @@ pub trait Neg {
type Output;
/// Performs the unary `-` operation.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// let x: i32 = 12;
+ /// assert_eq!(-x, -12);
+ /// ```
#[must_use]
#[stable(feature = "rust1", since = "1.0.0")]
fn neg(self) -> Self::Output;
@@ -673,6 +710,14 @@ neg_impl! { isize i8 i16 i32 i64 i128 f32 f64 }
#[doc(alias = "+=")]
pub trait AddAssign {
/// Performs the `+=` operation.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// let mut x: u32 = 12;
+ /// x += 1;
+ /// assert_eq!(x, 13);
+ /// ```
#[stable(feature = "op_assign_traits", since = "1.8.0")]
fn add_assign(&mut self, rhs: Rhs);
}
@@ -731,6 +776,14 @@ add_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
#[doc(alias = "-=")]
pub trait SubAssign {
/// Performs the `-=` operation.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// let mut x: u32 = 12;
+ /// x -= 1;
+ /// assert_eq!(x, 11);
+ /// ```
#[stable(feature = "op_assign_traits", since = "1.8.0")]
fn sub_assign(&mut self, rhs: Rhs);
}
@@ -780,6 +833,14 @@ sub_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
#[doc(alias = "*=")]
pub trait MulAssign {
/// Performs the `*=` operation.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// let mut x: u32 = 12;
+ /// x *= 2;
+ /// assert_eq!(x, 24);
+ /// ```
#[stable(feature = "op_assign_traits", since = "1.8.0")]
fn mul_assign(&mut self, rhs: Rhs);
}
@@ -829,6 +890,14 @@ mul_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
#[doc(alias = "/=")]
pub trait DivAssign {
/// Performs the `/=` operation.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// let mut x: u32 = 12;
+ /// x /= 2;
+ /// assert_eq!(x, 6);
+ /// ```
#[stable(feature = "op_assign_traits", since = "1.8.0")]
fn div_assign(&mut self, rhs: Rhs);
}
@@ -881,6 +950,14 @@ div_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
#[doc(alias = "%=")]
pub trait RemAssign {
/// Performs the `%=` operation.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// let mut x: u32 = 12;
+ /// x %= 10;
+ /// assert_eq!(x, 2);
+ /// ```
#[stable(feature = "op_assign_traits", since = "1.8.0")]
fn rem_assign(&mut self, rhs: Rhs);
}
diff --git a/src/doc/rustc/src/lints/listing/allowed-by-default.md b/src/doc/rustc/src/lints/listing/allowed-by-default.md
index d3dfc3197e2f6..d2d8c471efc96 100644
--- a/src/doc/rustc/src/lints/listing/allowed-by-default.md
+++ b/src/doc/rustc/src/lints/listing/allowed-by-default.md
@@ -232,7 +232,8 @@ error: lifetime name `'x` only used once
## trivial-casts
-This lint detects trivial casts which could be removed. Some example code
+This lint detects trivial casts which could be replaced with coercion, which may require
+type ascription or a temporary variable. Some example code
that triggers this lint:
```rust
diff --git a/src/doc/rustdoc/src/what-is-rustdoc.md b/src/doc/rustdoc/src/what-is-rustdoc.md
index adcebc832bc0b..7a38c96d7147b 100644
--- a/src/doc/rustdoc/src/what-is-rustdoc.md
+++ b/src/doc/rustdoc/src/what-is-rustdoc.md
@@ -93,6 +93,29 @@ passes `-L`, a flag that helps rustdoc find the dependencies
your code relies on. If our project used dependencies, we'd get
documentation for them as well!
+## Outer and inner documentation
+
+The `///` syntax is used to document the item present after it.
+That's why it is called an outer documentation.
+There is another syntax: `//!`, which is used to document the
+item it is present inside. It is called an inner documentation.
+It is often used when documenting the entire crate,
+because nothing comes before it: it is the root of the crate.
+So in order to document an entire crate, you need to use `//!` syntax.
+For example:
+
+``` rust
+//! This is my first rust crate
+```
+
+When used in the crate root, it documents the item it is inside,
+which is the crate itself.
+
+For more information about the `//!` syntax, see [the Book].
+
+[the Book]: https://doc.rust-lang.org/book/ch14-02-publishing-to-crates-io.html#commenting-contained-items
+
+
## Using standalone Markdown files
`rustdoc` can also generate HTML from standalone Markdown files. Let's
diff --git a/src/test/ui/ast-json/ast-json-noexpand-output.stdout b/src/test/ui/ast-json/ast-json-noexpand-output.stdout
index 031c0d0cae51c..0e5a3a14ac7b5 100644
--- a/src/test/ui/ast-json/ast-json-noexpand-output.stdout
+++ b/src/test/ui/ast-json/ast-json-noexpand-output.stdout
@@ -1 +1 @@
-{"module":{"inner":{"lo":0,"hi":0},"items":[{"attrs":[],"id":0,"span":{"lo":0,"hi":0},"vis":{"node":"Inherited","span":{"lo":0,"hi":0}},"ident":{"name":"core","span":{"lo":0,"hi":0}},"kind":{"variant":"ExternCrate","fields":[null]},"tokens":null}],"inline":true},"attrs":[{"kind":{"variant":"Normal","fields":[{"path":{"span":{"lo":0,"hi":0},"segments":[{"ident":{"name":"crate_type","span":{"lo":0,"hi":0}},"id":0,"args":null}]},"args":{"variant":"Eq","fields":[{"lo":0,"hi":0},{"0":[[{"variant":"Token","fields":[{"kind":{"variant":"Literal","fields":[{"kind":"Str","symbol":"lib","suffix":null}]},"span":{"lo":0,"hi":0}}]},"Alone"]]}]}}]},"id":null,"style":"Inner","span":{"lo":0,"hi":0}}],"span":{"lo":0,"hi":0},"proc_macros":[]}
+{"module":{"inner":{"lo":0,"hi":0},"unsafety":"No","items":[{"attrs":[],"id":0,"span":{"lo":0,"hi":0},"vis":{"node":"Inherited","span":{"lo":0,"hi":0}},"ident":{"name":"core","span":{"lo":0,"hi":0}},"kind":{"variant":"ExternCrate","fields":[null]},"tokens":null}],"inline":true},"attrs":[{"kind":{"variant":"Normal","fields":[{"path":{"span":{"lo":0,"hi":0},"segments":[{"ident":{"name":"crate_type","span":{"lo":0,"hi":0}},"id":0,"args":null}]},"args":{"variant":"Eq","fields":[{"lo":0,"hi":0},{"0":[[{"variant":"Token","fields":[{"kind":{"variant":"Literal","fields":[{"kind":"Str","symbol":"lib","suffix":null}]},"span":{"lo":0,"hi":0}}]},"Alone"]]}]}}]},"id":null,"style":"Inner","span":{"lo":0,"hi":0}}],"span":{"lo":0,"hi":0},"proc_macros":[]}
diff --git a/src/test/ui/ast-json/ast-json-output.stdout b/src/test/ui/ast-json/ast-json-output.stdout
index 9b3b6870cbe7e..8752ed2ae9993 100644
--- a/src/test/ui/ast-json/ast-json-output.stdout
+++ b/src/test/ui/ast-json/ast-json-output.stdout
@@ -1 +1 @@
-{"module":{"inner":{"lo":0,"hi":0},"items":[{"attrs":[{"kind":{"variant":"Normal","fields":[{"path":{"span":{"lo":0,"hi":0},"segments":[{"ident":{"name":"prelude_import","span":{"lo":0,"hi":0}},"id":0,"args":null}]},"args":"Empty"}]},"id":null,"style":"Outer","span":{"lo":0,"hi":0}}],"id":0,"span":{"lo":0,"hi":0},"vis":{"node":"Inherited","span":{"lo":0,"hi":0}},"ident":{"name":"","span":{"lo":0,"hi":0}},"kind":{"variant":"Use","fields":[{"prefix":{"span":{"lo":0,"hi":0},"segments":[{"ident":{"name":"{{root}}","span":{"lo":0,"hi":0}},"id":0,"args":null},{"ident":{"name":"std","span":{"lo":0,"hi":0}},"id":0,"args":null},{"ident":{"name":"prelude","span":{"lo":0,"hi":0}},"id":0,"args":null},{"ident":{"name":"v1","span":{"lo":0,"hi":0}},"id":0,"args":null}]},"kind":"Glob","span":{"lo":0,"hi":0}}]},"tokens":null},{"attrs":[{"kind":{"variant":"Normal","fields":[{"path":{"span":{"lo":0,"hi":0},"segments":[{"ident":{"name":"macro_use","span":{"lo":0,"hi":0}},"id":0,"args":null}]},"args":"Empty"}]},"id":null,"style":"Outer","span":{"lo":0,"hi":0}}],"id":0,"span":{"lo":0,"hi":0},"vis":{"node":"Inherited","span":{"lo":0,"hi":0}},"ident":{"name":"std","span":{"lo":0,"hi":0}},"kind":{"variant":"ExternCrate","fields":[null]},"tokens":null},{"attrs":[],"id":0,"span":{"lo":0,"hi":0},"vis":{"node":"Inherited","span":{"lo":0,"hi":0}},"ident":{"name":"core","span":{"lo":0,"hi":0}},"kind":{"variant":"ExternCrate","fields":[null]},"tokens":null}],"inline":true},"attrs":[{"kind":{"variant":"Normal","fields":[{"path":{"span":{"lo":0,"hi":0},"segments":[{"ident":{"name":"crate_type","span":{"lo":0,"hi":0}},"id":0,"args":null}]},"args":{"variant":"Eq","fields":[{"lo":0,"hi":0},{"0":[[{"variant":"Token","fields":[{"kind":{"variant":"Literal","fields":[{"kind":"Str","symbol":"lib","suffix":null}]},"span":{"lo":0,"hi":0}}]},"Alone"]]}]}}]},"id":null,"style":"Inner","span":{"lo":0,"hi":0}}],"span":{"lo":0,"hi":0},"proc_macros":[]}
+{"module":{"inner":{"lo":0,"hi":0},"unsafety":"No","items":[{"attrs":[{"kind":{"variant":"Normal","fields":[{"path":{"span":{"lo":0,"hi":0},"segments":[{"ident":{"name":"prelude_import","span":{"lo":0,"hi":0}},"id":0,"args":null}]},"args":"Empty"}]},"id":null,"style":"Outer","span":{"lo":0,"hi":0}}],"id":0,"span":{"lo":0,"hi":0},"vis":{"node":"Inherited","span":{"lo":0,"hi":0}},"ident":{"name":"","span":{"lo":0,"hi":0}},"kind":{"variant":"Use","fields":[{"prefix":{"span":{"lo":0,"hi":0},"segments":[{"ident":{"name":"{{root}}","span":{"lo":0,"hi":0}},"id":0,"args":null},{"ident":{"name":"std","span":{"lo":0,"hi":0}},"id":0,"args":null},{"ident":{"name":"prelude","span":{"lo":0,"hi":0}},"id":0,"args":null},{"ident":{"name":"v1","span":{"lo":0,"hi":0}},"id":0,"args":null}]},"kind":"Glob","span":{"lo":0,"hi":0}}]},"tokens":null},{"attrs":[{"kind":{"variant":"Normal","fields":[{"path":{"span":{"lo":0,"hi":0},"segments":[{"ident":{"name":"macro_use","span":{"lo":0,"hi":0}},"id":0,"args":null}]},"args":"Empty"}]},"id":null,"style":"Outer","span":{"lo":0,"hi":0}}],"id":0,"span":{"lo":0,"hi":0},"vis":{"node":"Inherited","span":{"lo":0,"hi":0}},"ident":{"name":"std","span":{"lo":0,"hi":0}},"kind":{"variant":"ExternCrate","fields":[null]},"tokens":null},{"attrs":[],"id":0,"span":{"lo":0,"hi":0},"vis":{"node":"Inherited","span":{"lo":0,"hi":0}},"ident":{"name":"core","span":{"lo":0,"hi":0}},"kind":{"variant":"ExternCrate","fields":[null]},"tokens":null}],"inline":true},"attrs":[{"kind":{"variant":"Normal","fields":[{"path":{"span":{"lo":0,"hi":0},"segments":[{"ident":{"name":"crate_type","span":{"lo":0,"hi":0}},"id":0,"args":null}]},"args":{"variant":"Eq","fields":[{"lo":0,"hi":0},{"0":[[{"variant":"Token","fields":[{"kind":{"variant":"Literal","fields":[{"kind":"Str","symbol":"lib","suffix":null}]},"span":{"lo":0,"hi":0}}]},"Alone"]]}]}}]},"id":null,"style":"Inner","span":{"lo":0,"hi":0}}],"span":{"lo":0,"hi":0},"proc_macros":[]}
diff --git a/src/test/ui/const-generics/auxiliary/const_generic_lib.rs b/src/test/ui/const-generics/auxiliary/const_generic_lib.rs
index 901fb5dd054e2..899a5a1836c33 100644
--- a/src/test/ui/const-generics/auxiliary/const_generic_lib.rs
+++ b/src/test/ui/const-generics/auxiliary/const_generic_lib.rs
@@ -1,4 +1,6 @@
-#![feature(const_generics)]
+#![cfg_attr(full, feature(const_generics))]
+#![cfg_attr(full, allow(incomplete_features))]
+#![cfg_attr(min, feature(min_const_generics))]
pub struct Struct(pub [u8; N]);
diff --git a/src/test/ui/const-generics/auxiliary/impl-const.rs b/src/test/ui/const-generics/auxiliary/impl-const.rs
index fc993d63927c3..2e25dadf119c4 100644
--- a/src/test/ui/const-generics/auxiliary/impl-const.rs
+++ b/src/test/ui/const-generics/auxiliary/impl-const.rs
@@ -1,4 +1,6 @@
-#![feature(const_generics)]
+#![cfg_attr(full, feature(const_generics))]
+#![cfg_attr(full, allow(incomplete_features))]
+#![cfg_attr(min, feature(min_const_generics))]
pub struct Num;
diff --git a/src/test/ui/const-generics/const-argument-cross-crate-mismatch.stderr b/src/test/ui/const-generics/const-argument-cross-crate-mismatch.full.stderr
similarity index 86%
rename from src/test/ui/const-generics/const-argument-cross-crate-mismatch.stderr
rename to src/test/ui/const-generics/const-argument-cross-crate-mismatch.full.stderr
index aefd514f7a68e..a35c3abc113b9 100644
--- a/src/test/ui/const-generics/const-argument-cross-crate-mismatch.stderr
+++ b/src/test/ui/const-generics/const-argument-cross-crate-mismatch.full.stderr
@@ -1,11 +1,11 @@
error[E0308]: mismatched types
- --> $DIR/const-argument-cross-crate-mismatch.rs:6:67
+ --> $DIR/const-argument-cross-crate-mismatch.rs:7:67
|
LL | let _ = const_generic_lib::function(const_generic_lib::Struct([0u8, 1u8]));
| ^^^^^^^^^^ expected an array with a fixed size of 3 elements, found one with 2 elements
error[E0308]: mismatched types
- --> $DIR/const-argument-cross-crate-mismatch.rs:8:65
+ --> $DIR/const-argument-cross-crate-mismatch.rs:9:65
|
LL | let _: const_generic_lib::Alias = const_generic_lib::Struct([0u8, 1u8, 2u8]);
| ^^^^^^^^^^^^^^^ expected an array with a fixed size of 2 elements, found one with 3 elements
diff --git a/src/test/ui/const-generics/const-argument-cross-crate-mismatch.min.stderr b/src/test/ui/const-generics/const-argument-cross-crate-mismatch.min.stderr
new file mode 100644
index 0000000000000..a35c3abc113b9
--- /dev/null
+++ b/src/test/ui/const-generics/const-argument-cross-crate-mismatch.min.stderr
@@ -0,0 +1,15 @@
+error[E0308]: mismatched types
+ --> $DIR/const-argument-cross-crate-mismatch.rs:7:67
+ |
+LL | let _ = const_generic_lib::function(const_generic_lib::Struct([0u8, 1u8]));
+ | ^^^^^^^^^^ expected an array with a fixed size of 3 elements, found one with 2 elements
+
+error[E0308]: mismatched types
+ --> $DIR/const-argument-cross-crate-mismatch.rs:9:65
+ |
+LL | let _: const_generic_lib::Alias = const_generic_lib::Struct([0u8, 1u8, 2u8]);
+ | ^^^^^^^^^^^^^^^ expected an array with a fixed size of 2 elements, found one with 3 elements
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/const-generics/const-argument-cross-crate-mismatch.rs b/src/test/ui/const-generics/const-argument-cross-crate-mismatch.rs
index d863d097d5caf..9ae2ae50ba0ab 100644
--- a/src/test/ui/const-generics/const-argument-cross-crate-mismatch.rs
+++ b/src/test/ui/const-generics/const-argument-cross-crate-mismatch.rs
@@ -1,4 +1,5 @@
// aux-build:const_generic_lib.rs
+// revisions: full min
extern crate const_generic_lib;
diff --git a/src/test/ui/const-generics/const-argument-cross-crate.rs b/src/test/ui/const-generics/const-argument-cross-crate.rs
index 98cf39a7ee11c..fda3ec3eef799 100644
--- a/src/test/ui/const-generics/const-argument-cross-crate.rs
+++ b/src/test/ui/const-generics/const-argument-cross-crate.rs
@@ -1,4 +1,5 @@
// run-pass
+// revisions: full min
// aux-build:const_generic_lib.rs
extern crate const_generic_lib;
diff --git a/src/test/ui/const-generics/const_evaluatable_checked/feature-gate-const_evaluatable_checked.rs b/src/test/ui/const-generics/const_evaluatable_checked/feature-gate-const_evaluatable_checked.rs
new file mode 100644
index 0000000000000..941bd5e9e5d0a
--- /dev/null
+++ b/src/test/ui/const-generics/const_evaluatable_checked/feature-gate-const_evaluatable_checked.rs
@@ -0,0 +1,14 @@
+#![feature(const_generics)]
+#![allow(incomplete_features)]
+
+type Arr = [u8; N - 1];
+
+fn test() -> Arr where Arr: Default {
+ //~^ ERROR constant expression depends
+ Default::default()
+}
+
+fn main() {
+ let x = test::<33>();
+ assert_eq!(x, [0; 32]);
+}
diff --git a/src/test/ui/const-generics/const_evaluatable_checked/feature-gate-const_evaluatable_checked.stderr b/src/test/ui/const-generics/const_evaluatable_checked/feature-gate-const_evaluatable_checked.stderr
new file mode 100644
index 0000000000000..6e4a22a38b17c
--- /dev/null
+++ b/src/test/ui/const-generics/const_evaluatable_checked/feature-gate-const_evaluatable_checked.stderr
@@ -0,0 +1,10 @@
+error: constant expression depends on a generic parameter
+ --> $DIR/feature-gate-const_evaluatable_checked.rs:6:30
+ |
+LL | fn test() -> Arr where Arr: Default {
+ | ^^^^^^
+ |
+ = note: this may fail depending on what value the parameter takes
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/const-generics/const_evaluatable_checked/simple.rs b/src/test/ui/const-generics/const_evaluatable_checked/simple.rs
new file mode 100644
index 0000000000000..a7ead78b97bae
--- /dev/null
+++ b/src/test/ui/const-generics/const_evaluatable_checked/simple.rs
@@ -0,0 +1,14 @@
+// run-pass
+#![feature(const_generics, const_evaluatable_checked)]
+#![allow(incomplete_features)]
+
+type Arr = [u8; N - 1];
+
+fn test() -> Arr where Arr: Default {
+ Default::default()
+}
+
+fn main() {
+ let x = test::<33>();
+ assert_eq!(x, [0; 32]);
+}
diff --git a/src/test/ui/const-generics/const_evaluatable_checked/simple_fail.rs b/src/test/ui/const-generics/const_evaluatable_checked/simple_fail.rs
new file mode 100644
index 0000000000000..1edf1885dd281
--- /dev/null
+++ b/src/test/ui/const-generics/const_evaluatable_checked/simple_fail.rs
@@ -0,0 +1,12 @@
+#![feature(const_generics, const_evaluatable_checked)]
+#![allow(incomplete_features)]
+
+type Arr = [u8; N - 1]; //~ ERROR evaluation of constant
+
+fn test() -> Arr where Arr: Sized {
+ todo!()
+}
+
+fn main() {
+ test::<0>();
+}
diff --git a/src/test/ui/const-generics/const_evaluatable_checked/simple_fail.stderr b/src/test/ui/const-generics/const_evaluatable_checked/simple_fail.stderr
new file mode 100644
index 0000000000000..1ac5e1d95537a
--- /dev/null
+++ b/src/test/ui/const-generics/const_evaluatable_checked/simple_fail.stderr
@@ -0,0 +1,9 @@
+error[E0080]: evaluation of constant value failed
+ --> $DIR/simple_fail.rs:4:33
+ |
+LL | type Arr = [u8; N - 1];
+ | ^^^^^ attempt to compute `0_usize - 1_usize` which would overflow
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0080`.
diff --git a/src/test/ui/const-generics/defaults/complex-unord-param.min.stderr b/src/test/ui/const-generics/defaults/complex-unord-param.min.stderr
new file mode 100644
index 0000000000000..0574ddfb2557a
--- /dev/null
+++ b/src/test/ui/const-generics/defaults/complex-unord-param.min.stderr
@@ -0,0 +1,8 @@
+error: type parameters must be declared prior to const parameters
+ --> $DIR/complex-unord-param.rs:9:41
+ |
+LL | struct NestedArrays<'a, const N: usize, A: 'a, const M: usize, T:'a =u32> {
+ | ---------------------^----------------------^--------- help: reorder the parameters: lifetimes, then types, then consts: `<'a, A: 'a, T: 'a, const N: usize, const M: usize>`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/const-generics/defaults/complex-unord-param.rs b/src/test/ui/const-generics/defaults/complex-unord-param.rs
index 72967640a8e62..e83a96388c190 100644
--- a/src/test/ui/const-generics/defaults/complex-unord-param.rs
+++ b/src/test/ui/const-generics/defaults/complex-unord-param.rs
@@ -1,11 +1,13 @@
-// run-pass
+// [full] run-pass
+// revisions: full min
// Checks a complicated usage of unordered params
-
-#![feature(const_generics)]
-#![allow(incomplete_features)]
+#![cfg_attr(full, feature(const_generics))]
+#![cfg_attr(full, allow(incomplete_features))]
+#![cfg_attr(min, feature(min_const_generics))]
#![allow(dead_code)]
struct NestedArrays<'a, const N: usize, A: 'a, const M: usize, T:'a =u32> {
+ //[min]~^ ERROR type parameters must be declared prior to const parameters
args: &'a [&'a [T; M]; N],
specifier: A,
}
diff --git a/src/test/ui/const-generics/defaults/intermixed-lifetime.stderr b/src/test/ui/const-generics/defaults/intermixed-lifetime.full.stderr
similarity index 87%
rename from src/test/ui/const-generics/defaults/intermixed-lifetime.stderr
rename to src/test/ui/const-generics/defaults/intermixed-lifetime.full.stderr
index 0f6d7f1065af8..9cc3e9c0da665 100644
--- a/src/test/ui/const-generics/defaults/intermixed-lifetime.stderr
+++ b/src/test/ui/const-generics/defaults/intermixed-lifetime.full.stderr
@@ -1,11 +1,11 @@
error: lifetime parameters must be declared prior to const parameters
- --> $DIR/intermixed-lifetime.rs:6:28
+ --> $DIR/intermixed-lifetime.rs:7:28
|
LL | struct Foo(&'a (), T);
| -----------------^^---------- help: reorder the parameters: lifetimes, then consts and types: `<'a, const N: usize, T>`
error: lifetime parameters must be declared prior to type parameters
- --> $DIR/intermixed-lifetime.rs:9:37
+ --> $DIR/intermixed-lifetime.rs:11:37
|
LL | struct Bar(&'a (), T);
| --------------------------^^- help: reorder the parameters: lifetimes, then consts and types: `<'a, const N: usize, T>`
diff --git a/src/test/ui/const-generics/defaults/intermixed-lifetime.min.stderr b/src/test/ui/const-generics/defaults/intermixed-lifetime.min.stderr
new file mode 100644
index 0000000000000..4d80fdb5bcbc2
--- /dev/null
+++ b/src/test/ui/const-generics/defaults/intermixed-lifetime.min.stderr
@@ -0,0 +1,26 @@
+error: lifetime parameters must be declared prior to const parameters
+ --> $DIR/intermixed-lifetime.rs:7:28
+ |
+LL | struct Foo(&'a (), T);
+ | -----------------^^---------- help: reorder the parameters: lifetimes, then types, then consts: `<'a, T, const N: usize>`
+
+error: type parameters must be declared prior to const parameters
+ --> $DIR/intermixed-lifetime.rs:7:32
+ |
+LL | struct Foo(&'a (), T);
+ | ---------------------^------- help: reorder the parameters: lifetimes, then types, then consts: `<'a, T, const N: usize>`
+
+error: lifetime parameters must be declared prior to const parameters
+ --> $DIR/intermixed-lifetime.rs:11:37
+ |
+LL | struct Bar(&'a (), T);
+ | --------------------------^^- help: reorder the parameters: lifetimes, then types, then consts: `<'a, T, const N: usize>`
+
+error: type parameters must be declared prior to const parameters
+ --> $DIR/intermixed-lifetime.rs:11:28
+ |
+LL | struct Bar(&'a (), T);
+ | -----------------^----------- help: reorder the parameters: lifetimes, then types, then consts: `<'a, T, const N: usize>`
+
+error: aborting due to 4 previous errors
+
diff --git a/src/test/ui/const-generics/defaults/intermixed-lifetime.rs b/src/test/ui/const-generics/defaults/intermixed-lifetime.rs
index ea3a8c14b98cb..cc0d1c6c0c97c 100644
--- a/src/test/ui/const-generics/defaults/intermixed-lifetime.rs
+++ b/src/test/ui/const-generics/defaults/intermixed-lifetime.rs
@@ -1,12 +1,16 @@
+// revisions: full min
// Checks that lifetimes cannot be interspersed between consts and types.
-
-#![feature(const_generics)]
-#![allow(incomplete_features)]
+#![cfg_attr(full, feature(const_generics))]
+#![cfg_attr(full, allow(incomplete_features))]
+#![cfg_attr(min, feature(min_const_generics))]
struct Foo(&'a (), T);
//~^ Error lifetime parameters must be declared prior to const parameters
+//[min]~^^ Error type parameters must be declared prior to const parameters
struct Bar(&'a (), T);
-//~^ Error lifetime parameters must be declared prior to type parameters
+//[full]~^ Error lifetime parameters must be declared prior to type parameters
+//[min]~^^ Error type parameters must be declared prior to const parameters
+//[min]~| Error lifetime parameters must be declared prior to const parameters
fn main() {}
diff --git a/src/test/ui/const-generics/defaults/simple-defaults.min.stderr b/src/test/ui/const-generics/defaults/simple-defaults.min.stderr
new file mode 100644
index 0000000000000..59cc6f28af857
--- /dev/null
+++ b/src/test/ui/const-generics/defaults/simple-defaults.min.stderr
@@ -0,0 +1,8 @@
+error: type parameters must be declared prior to const parameters
+ --> $DIR/simple-defaults.rs:9:40
+ |
+LL | struct FixedOutput<'a, const N: usize, T=u32> {
+ | ---------------------^----- help: reorder the parameters: lifetimes, then types, then consts: `<'a, T, const N: usize>`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/const-generics/defaults/simple-defaults.rs b/src/test/ui/const-generics/defaults/simple-defaults.rs
index b282dfd37cc4a..78abe3519985b 100644
--- a/src/test/ui/const-generics/defaults/simple-defaults.rs
+++ b/src/test/ui/const-generics/defaults/simple-defaults.rs
@@ -1,10 +1,13 @@
-// run-pass
+// [full] run-pass
+// revisions: min full
// Checks some basic test cases for defaults.
-#![feature(const_generics)]
-#![allow(incomplete_features)]
+#![cfg_attr(full, feature(const_generics))]
+#![cfg_attr(full, allow(incomplete_features))]
+#![cfg_attr(min, feature(min_const_generics))]
#![allow(dead_code)]
struct FixedOutput<'a, const N: usize, T=u32> {
+ //[min]~^ ERROR type parameters must be declared prior to const parameters
out: &'a [T; N],
}
diff --git a/src/test/ui/const-generics/issues/auxiliary/const_generic_issues_lib.rs b/src/test/ui/const-generics/issues/auxiliary/const_generic_issues_lib.rs
index 59a4d345cbccb..7ea8d936d6141 100644
--- a/src/test/ui/const-generics/issues/auxiliary/const_generic_issues_lib.rs
+++ b/src/test/ui/const-generics/issues/auxiliary/const_generic_issues_lib.rs
@@ -1,4 +1,6 @@
-#![feature(const_generics)]
+#![cfg_attr(full, feature(const_generics))]
+#![cfg_attr(full, allow(incomplete_features))]
+#![cfg_attr(min, feature(min_const_generics))]
// All of these three items must be in `lib2` to reproduce the error
diff --git a/src/test/ui/const-generics/issues/issue-61935.full.stderr b/src/test/ui/const-generics/issues/issue-61935.full.stderr
new file mode 100644
index 0000000000000..b805bc0db7e55
--- /dev/null
+++ b/src/test/ui/const-generics/issues/issue-61935.full.stderr
@@ -0,0 +1,10 @@
+error: constant expression depends on a generic parameter
+ --> $DIR/issue-61935.rs:10:14
+ |
+LL | Self:FooImpl<{N==0}>
+ | ^^^^^^^^^^^^^^^
+ |
+ = note: this may fail depending on what value the parameter takes
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/const-generics/issues/issue-61935.min.stderr b/src/test/ui/const-generics/issues/issue-61935.min.stderr
new file mode 100644
index 0000000000000..e5715ec658c5c
--- /dev/null
+++ b/src/test/ui/const-generics/issues/issue-61935.min.stderr
@@ -0,0 +1,10 @@
+error: generic parameters must not be used inside of non trivial constant values
+ --> $DIR/issue-61935.rs:10:23
+ |
+LL | Self:FooImpl<{N==0}>
+ | ^ non-trivial anonymous constants must not depend on the parameter `N`
+ |
+ = help: it is currently only allowed to use either `N` or `{ N }` as generic constants
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/const-generics/issues/issue-61935.rs b/src/test/ui/const-generics/issues/issue-61935.rs
index 0d42ff1895cdb..64257da030943 100644
--- a/src/test/ui/const-generics/issues/issue-61935.rs
+++ b/src/test/ui/const-generics/issues/issue-61935.rs
@@ -1,12 +1,15 @@
-#![feature(const_generics)]
-//~^ WARN the feature `const_generics` is incomplete
+// revisions: full min
+#![cfg_attr(full, feature(const_generics))]
+#![cfg_attr(full, allow(incomplete_features))]
+#![cfg_attr(min, feature(min_const_generics))]
trait Foo {}
impl Foo for [(); N]
where
Self:FooImpl<{N==0}>
-//~^ERROR constant expression depends on a generic parameter
+//[full]~^ERROR constant expression depends on a generic parameter
+//[min]~^^ERROR generic parameters must not be used inside of non trivial constant values
{}
trait FooImpl{}
diff --git a/src/test/ui/const-generics/issues/issue-61935.stderr b/src/test/ui/const-generics/issues/issue-61935.stderr
deleted file mode 100644
index a785af5f008ea..0000000000000
--- a/src/test/ui/const-generics/issues/issue-61935.stderr
+++ /dev/null
@@ -1,19 +0,0 @@
-warning: the feature `const_generics` is incomplete and may not be safe to use and/or cause compiler crashes
- --> $DIR/issue-61935.rs:1:12
- |
-LL | #![feature(const_generics)]
- | ^^^^^^^^^^^^^^
- |
- = note: `#[warn(incomplete_features)]` on by default
- = note: see issue #44580 for more information
-
-error: constant expression depends on a generic parameter
- --> $DIR/issue-61935.rs:8:14
- |
-LL | Self:FooImpl<{N==0}>
- | ^^^^^^^^^^^^^^^
- |
- = note: this may fail depending on what value the parameter takes
-
-error: aborting due to previous error; 1 warning emitted
-
diff --git a/src/test/ui/const-generics/issues/issue-62187-encountered-polymorphic-const.rs b/src/test/ui/const-generics/issues/issue-62187-encountered-polymorphic-const.rs
index 2f3b5c5dc5b89..a8fa378035660 100644
--- a/src/test/ui/const-generics/issues/issue-62187-encountered-polymorphic-const.rs
+++ b/src/test/ui/const-generics/issues/issue-62187-encountered-polymorphic-const.rs
@@ -1,7 +1,9 @@
// run-pass
-#![feature(const_generics)]
-//~^ WARN the feature `const_generics` is incomplete
+// revisions: full min
+#![cfg_attr(full, feature(const_generics))]
+#![cfg_attr(full, allow(incomplete_features))]
+#![cfg_attr(min, feature(min_const_generics))]
pub trait BitLen: Sized {
const BIT_LEN: usize;
@@ -12,5 +14,5 @@ impl BitLen for [u8; L] {
}
fn main() {
- let foo = <[u8; 2]>::BIT_LEN; //~ WARN unused variable
+ let _foo = <[u8; 2]>::BIT_LEN;
}
diff --git a/src/test/ui/const-generics/issues/issue-62187-encountered-polymorphic-const.stderr b/src/test/ui/const-generics/issues/issue-62187-encountered-polymorphic-const.stderr
deleted file mode 100644
index a9abb877c094c..0000000000000
--- a/src/test/ui/const-generics/issues/issue-62187-encountered-polymorphic-const.stderr
+++ /dev/null
@@ -1,19 +0,0 @@
-warning: the feature `const_generics` is incomplete and may not be safe to use and/or cause compiler crashes
- --> $DIR/issue-62187-encountered-polymorphic-const.rs:3:12
- |
-LL | #![feature(const_generics)]
- | ^^^^^^^^^^^^^^
- |
- = note: `#[warn(incomplete_features)]` on by default
- = note: see issue #44580 for more information
-
-warning: unused variable: `foo`
- --> $DIR/issue-62187-encountered-polymorphic-const.rs:15:9
- |
-LL | let foo = <[u8; 2]>::BIT_LEN;
- | ^^^ help: if this is intentional, prefix it with an underscore: `_foo`
- |
- = note: `#[warn(unused_variables)]` on by default
-
-warning: 2 warnings emitted
-
diff --git a/src/test/ui/const-generics/issues/issue-62220.stderr b/src/test/ui/const-generics/issues/issue-62220.full.stderr
similarity index 90%
rename from src/test/ui/const-generics/issues/issue-62220.stderr
rename to src/test/ui/const-generics/issues/issue-62220.full.stderr
index d91d2bb326fc5..120aa8e4af5d2 100644
--- a/src/test/ui/const-generics/issues/issue-62220.stderr
+++ b/src/test/ui/const-generics/issues/issue-62220.full.stderr
@@ -1,5 +1,5 @@
error: constant expression depends on a generic parameter
- --> $DIR/issue-62220.rs:10:27
+ --> $DIR/issue-62220.rs:13:27
|
LL | pub fn trunc(self) -> (TruncatedVector, T) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/test/ui/const-generics/issues/issue-62220.min.stderr b/src/test/ui/const-generics/issues/issue-62220.min.stderr
new file mode 100644
index 0000000000000..943b689bf61af
--- /dev/null
+++ b/src/test/ui/const-generics/issues/issue-62220.min.stderr
@@ -0,0 +1,10 @@
+error: generic parameters must not be used inside of non trivial constant values
+ --> $DIR/issue-62220.rs:8:59
+ |
+LL | pub type TruncatedVector = Vector;
+ | ^ non-trivial anonymous constants must not depend on the parameter `N`
+ |
+ = help: it is currently only allowed to use either `N` or `{ N }` as generic constants
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/const-generics/issues/issue-62220.rs b/src/test/ui/const-generics/issues/issue-62220.rs
index 5c4a0d31a895d..acb13ad1170f2 100644
--- a/src/test/ui/const-generics/issues/issue-62220.rs
+++ b/src/test/ui/const-generics/issues/issue-62220.rs
@@ -1,14 +1,17 @@
-#![allow(incomplete_features)]
-#![feature(const_generics)]
+// revisions: full min
+#![cfg_attr(full, feature(const_generics))]
+#![cfg_attr(full, allow(incomplete_features))]
+#![cfg_attr(min, feature(min_const_generics))]
pub struct Vector([T; N]);
pub type TruncatedVector = Vector;
+//[min]~^ ERROR generic parameters must not be used inside of non trivial constant values
impl Vector {
/// Drop the last component and return the vector with one fewer dimension.
pub fn trunc(self) -> (TruncatedVector, T) {
- //~^ ERROR constant expression depends on a generic parameter
+ //[full]~^ ERROR constant expression depends on a generic parameter
unimplemented!()
}
}
diff --git a/src/test/ui/const-generics/issues/issue-62456.full.stderr b/src/test/ui/const-generics/issues/issue-62456.full.stderr
new file mode 100644
index 0000000000000..a8d44074db9d1
--- /dev/null
+++ b/src/test/ui/const-generics/issues/issue-62456.full.stderr
@@ -0,0 +1,10 @@
+error: constant expression depends on a generic parameter
+ --> $DIR/issue-62456.rs:7:20
+ |
+LL | let _ = [0u64; N + 1];
+ | ^^^^^
+ |
+ = note: this may fail depending on what value the parameter takes
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/const-generics/issues/issue-62456.min.stderr b/src/test/ui/const-generics/issues/issue-62456.min.stderr
new file mode 100644
index 0000000000000..335f0ead27871
--- /dev/null
+++ b/src/test/ui/const-generics/issues/issue-62456.min.stderr
@@ -0,0 +1,10 @@
+error: generic parameters must not be used inside of non trivial constant values
+ --> $DIR/issue-62456.rs:7:20
+ |
+LL | let _ = [0u64; N + 1];
+ | ^ non-trivial anonymous constants must not depend on the parameter `N`
+ |
+ = help: it is currently only allowed to use either `N` or `{ N }` as generic constants
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/const-generics/issues/issue-62456.rs b/src/test/ui/const-generics/issues/issue-62456.rs
index 37947ad1b331c..c96868c00a3d6 100644
--- a/src/test/ui/const-generics/issues/issue-62456.rs
+++ b/src/test/ui/const-generics/issues/issue-62456.rs
@@ -1,9 +1,12 @@
-#![feature(const_generics)]
-//~^ WARN the feature `const_generics` is incomplete
+// revisions: full min
+#![cfg_attr(full, feature(const_generics))]
+#![cfg_attr(full, allow(incomplete_features))]
+#![cfg_attr(min, feature(min_const_generics))]
fn foo() {
let _ = [0u64; N + 1];
- //~^ ERROR constant expression depends on a generic parameter
+ //[full]~^ ERROR constant expression depends on a generic parameter
+ //[min]~^^ ERROR generic parameters must not be used inside of non trivial constant values
}
fn main() {}
diff --git a/src/test/ui/const-generics/issues/issue-62456.stderr b/src/test/ui/const-generics/issues/issue-62456.stderr
deleted file mode 100644
index 0454fed670598..0000000000000
--- a/src/test/ui/const-generics/issues/issue-62456.stderr
+++ /dev/null
@@ -1,19 +0,0 @@
-warning: the feature `const_generics` is incomplete and may not be safe to use and/or cause compiler crashes
- --> $DIR/issue-62456.rs:1:12
- |
-LL | #![feature(const_generics)]
- | ^^^^^^^^^^^^^^
- |
- = note: `#[warn(incomplete_features)]` on by default
- = note: see issue #44580 for more information
-
-error: constant expression depends on a generic parameter
- --> $DIR/issue-62456.rs:5:20
- |
-LL | let _ = [0u64; N + 1];
- | ^^^^^
- |
- = note: this may fail depending on what value the parameter takes
-
-error: aborting due to previous error; 1 warning emitted
-
diff --git a/src/test/ui/const-generics/issues/issue-62504.stderr b/src/test/ui/const-generics/issues/issue-62504.full.stderr
similarity index 89%
rename from src/test/ui/const-generics/issues/issue-62504.stderr
rename to src/test/ui/const-generics/issues/issue-62504.full.stderr
index f09af76325e96..9c84f06ce9f74 100644
--- a/src/test/ui/const-generics/issues/issue-62504.stderr
+++ b/src/test/ui/const-generics/issues/issue-62504.full.stderr
@@ -1,5 +1,5 @@
error: constant expression depends on a generic parameter
- --> $DIR/issue-62504.rs:18:25
+ --> $DIR/issue-62504.rs:19:25
|
LL | ArrayHolder([0; Self::SIZE])
| ^^^^^^^^^^
diff --git a/src/test/ui/const-generics/issues/issue-62504.min.stderr b/src/test/ui/const-generics/issues/issue-62504.min.stderr
new file mode 100644
index 0000000000000..752df17aad614
--- /dev/null
+++ b/src/test/ui/const-generics/issues/issue-62504.min.stderr
@@ -0,0 +1,10 @@
+error: generic parameters must not be used inside of non trivial constant values
+ --> $DIR/issue-62504.rs:19:25
+ |
+LL | ArrayHolder([0; Self::SIZE])
+ | ^^^^^^^^^^ non-trivial anonymous constants must not depend on the parameter `Self`
+ |
+ = help: it is currently only allowed to use either `Self` or `{ Self }` as generic constants
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/const-generics/issues/issue-62504.rs b/src/test/ui/const-generics/issues/issue-62504.rs
index 4e05aadd3930f..b520dbe4e803b 100644
--- a/src/test/ui/const-generics/issues/issue-62504.rs
+++ b/src/test/ui/const-generics/issues/issue-62504.rs
@@ -1,7 +1,8 @@
-// Regression test for #62504
-
-#![feature(const_generics)]
+// revisions: full min
#![allow(incomplete_features)]
+#![cfg_attr(full, feature(const_generics))]
+#![cfg_attr(full, allow(incomplete_features))]
+#![cfg_attr(min, feature(min_const_generics))]
trait HasSize {
const SIZE: usize;
@@ -16,7 +17,8 @@ struct ArrayHolder([u32; X]);
impl ArrayHolder {
pub const fn new() -> Self {
ArrayHolder([0; Self::SIZE])
- //~^ ERROR constant expression depends on a generic parameter
+ //[full]~^ ERROR constant expression depends on a generic parameter
+ //[min]~^^ ERROR generic parameters must not be used inside of non trivial constant values
}
}
diff --git a/src/test/ui/const-generics/issues/issue-62579-no-match.min.stderr b/src/test/ui/const-generics/issues/issue-62579-no-match.min.stderr
new file mode 100644
index 0000000000000..6903b20fad63c
--- /dev/null
+++ b/src/test/ui/const-generics/issues/issue-62579-no-match.min.stderr
@@ -0,0 +1,11 @@
+error: `NoMatch` is forbidden as the type of a const generic parameter
+ --> $DIR/issue-62579-no-match.rs:10:17
+ |
+LL | fn foo() -> bool {
+ | ^^^^^^^
+ |
+ = note: the only supported types are integers, `bool` and `char`
+ = note: more complex types are supported with `#[feature(const_generics)]`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/const-generics/issues/issue-62579-no-match.rs b/src/test/ui/const-generics/issues/issue-62579-no-match.rs
index 7eaf5eea0787b..c9853aa9162e1 100644
--- a/src/test/ui/const-generics/issues/issue-62579-no-match.rs
+++ b/src/test/ui/const-generics/issues/issue-62579-no-match.rs
@@ -1,12 +1,14 @@
-// run-pass
-
-#![feature(const_generics)]
-//~^ WARN the feature `const_generics` is incomplete
+// [full] run-pass
+// revisions: full min
+#![cfg_attr(full, feature(const_generics))]
+#![cfg_attr(full, allow(incomplete_features))]
+#![cfg_attr(min, feature(min_const_generics))]
#[derive(PartialEq, Eq)]
struct NoMatch;
fn foo() -> bool {
+ //[min]~^ ERROR `NoMatch` is forbidden as the type of a const generic parameter
true
}
diff --git a/src/test/ui/const-generics/issues/issue-62579-no-match.stderr b/src/test/ui/const-generics/issues/issue-62579-no-match.stderr
deleted file mode 100644
index 9fb9b5b13d8d5..0000000000000
--- a/src/test/ui/const-generics/issues/issue-62579-no-match.stderr
+++ /dev/null
@@ -1,11 +0,0 @@
-warning: the feature `const_generics` is incomplete and may not be safe to use and/or cause compiler crashes
- --> $DIR/issue-62579-no-match.rs:3:12
- |
-LL | #![feature(const_generics)]
- | ^^^^^^^^^^^^^^
- |
- = note: `#[warn(incomplete_features)]` on by default
- = note: see issue #44580 for more information
-
-warning: 1 warning emitted
-
diff --git a/src/test/ui/const-generics/issues/issue-62878.stderr b/src/test/ui/const-generics/issues/issue-62878.full.stderr
similarity index 58%
rename from src/test/ui/const-generics/issues/issue-62878.stderr
rename to src/test/ui/const-generics/issues/issue-62878.full.stderr
index fe0990d8241fa..c8b9db8941098 100644
--- a/src/test/ui/const-generics/issues/issue-62878.stderr
+++ b/src/test/ui/const-generics/issues/issue-62878.full.stderr
@@ -1,37 +1,28 @@
error[E0770]: the type of const parameters must not depend on other generic parameters
- --> $DIR/issue-62878.rs:3:38
+ --> $DIR/issue-62878.rs:6:38
|
LL | fn foo() {}
| ^ the type must not depend on the parameter `N`
-warning: the feature `const_generics` is incomplete and may not be safe to use and/or cause compiler crashes
- --> $DIR/issue-62878.rs:1:12
- |
-LL | #![feature(const_generics)]
- | ^^^^^^^^^^^^^^
- |
- = note: `#[warn(incomplete_features)]` on by default
- = note: see issue #44580 for more information
-
error[E0107]: wrong number of const arguments: expected 2, found 1
- --> $DIR/issue-62878.rs:7:5
+ --> $DIR/issue-62878.rs:11:5
|
LL | foo::<_, {[1]}>();
| ^^^^^^^^^^^^^^^ expected 2 const arguments
error[E0107]: wrong number of type arguments: expected 0, found 1
- --> $DIR/issue-62878.rs:7:11
+ --> $DIR/issue-62878.rs:11:11
|
LL | foo::<_, {[1]}>();
| ^ unexpected type argument
error[E0308]: mismatched types
- --> $DIR/issue-62878.rs:7:15
+ --> $DIR/issue-62878.rs:11:15
|
LL | foo::<_, {[1]}>();
| ^^^ expected `usize`, found array `[{integer}; 1]`
-error: aborting due to 4 previous errors; 1 warning emitted
+error: aborting due to 4 previous errors
Some errors have detailed explanations: E0107, E0308, E0770.
For more information about an error, try `rustc --explain E0107`.
diff --git a/src/test/ui/const-generics/issues/issue-62878.min.stderr b/src/test/ui/const-generics/issues/issue-62878.min.stderr
new file mode 100644
index 0000000000000..34edd09b51565
--- /dev/null
+++ b/src/test/ui/const-generics/issues/issue-62878.min.stderr
@@ -0,0 +1,18 @@
+error[E0770]: the type of const parameters must not depend on other generic parameters
+ --> $DIR/issue-62878.rs:6:38
+ |
+LL | fn foo() {}
+ | ^ the type must not depend on the parameter `N`
+
+error: `[u8; _]` is forbidden as the type of a const generic parameter
+ --> $DIR/issue-62878.rs:6:33
+ |
+LL | fn foo() {}
+ | ^^^^^^^
+ |
+ = note: the only supported types are integers, `bool` and `char`
+ = note: more complex types are supported with `#[feature(const_generics)]`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0770`.
diff --git a/src/test/ui/const-generics/issues/issue-62878.rs b/src/test/ui/const-generics/issues/issue-62878.rs
index ccc05fdf100e7..0487dda2fe81d 100644
--- a/src/test/ui/const-generics/issues/issue-62878.rs
+++ b/src/test/ui/const-generics/issues/issue-62878.rs
@@ -1,11 +1,15 @@
-#![feature(const_generics)] //~ WARN the feature `const_generics` is incomplete
+// revisions: full min
+#![cfg_attr(full, feature(const_generics))]
+#![cfg_attr(full, allow(incomplete_features))]
+#![cfg_attr(min, feature(min_const_generics))]
fn foo() {}
//~^ ERROR the type of const parameters must not
+//[min]~| ERROR `[u8; _]` is forbidden as the type of a const generic parameter
fn main() {
foo::<_, {[1]}>();
- //~^ ERROR wrong number of const arguments
- //~| ERROR wrong number of type arguments
- //~| ERROR mismatched types
+ //[full]~^ ERROR wrong number of const arguments
+ //[full]~| ERROR wrong number of type arguments
+ //[full]~| ERROR mismatched types
}
diff --git a/src/test/ui/const-generics/issues/issue-67185-2.stderr b/src/test/ui/const-generics/issues/issue-67185-2.full.stderr
similarity index 82%
rename from src/test/ui/const-generics/issues/issue-67185-2.stderr
rename to src/test/ui/const-generics/issues/issue-67185-2.full.stderr
index 7d947a907a0ee..78c7ebff05985 100644
--- a/src/test/ui/const-generics/issues/issue-67185-2.stderr
+++ b/src/test/ui/const-generics/issues/issue-67185-2.full.stderr
@@ -1,14 +1,5 @@
-warning: the feature `const_generics` is incomplete and may not be safe to use and/or cause compiler crashes
- --> $DIR/issue-67185-2.rs:1:12
- |
-LL | #![feature(const_generics)]
- | ^^^^^^^^^^^^^^
- |
- = note: `#[warn(incomplete_features)]` on by default
- = note: see issue #44580 for more information
-
error[E0277]: the trait bound `[u16; 3]: Bar` is not satisfied
- --> $DIR/issue-67185-2.rs:15:1
+ --> $DIR/issue-67185-2.rs:17:1
|
LL | / trait Foo
LL | |
@@ -26,7 +17,7 @@ LL | | }
= help: add `#![feature(trivial_bounds)]` to the crate attributes to enable
error[E0277]: the trait bound `[[u16; 3]; 2]: Bar` is not satisfied
- --> $DIR/issue-67185-2.rs:15:1
+ --> $DIR/issue-67185-2.rs:17:1
|
LL | / trait Foo
LL | |
@@ -44,7 +35,7 @@ LL | | }
= help: add `#![feature(trivial_bounds)]` to the crate attributes to enable
error[E0277]: the trait bound `[u16; 3]: Bar` is not satisfied
- --> $DIR/issue-67185-2.rs:25:6
+ --> $DIR/issue-67185-2.rs:27:6
|
LL | trait Foo
| --- required by a bound in this
@@ -60,7 +51,7 @@ LL | impl Foo for FooImpl {}
<[u16; 4] as Bar>
error[E0277]: the trait bound `[[u16; 3]; 2]: Bar` is not satisfied
- --> $DIR/issue-67185-2.rs:25:6
+ --> $DIR/issue-67185-2.rs:27:6
|
LL | trait Foo
| --- required by a bound in this
@@ -76,7 +67,7 @@ LL | impl Foo for FooImpl {}
<[u16; 4] as Bar>
error[E0277]: the trait bound `[[u16; 3]; 2]: Bar` is not satisfied
- --> $DIR/issue-67185-2.rs:29:14
+ --> $DIR/issue-67185-2.rs:31:14
|
LL | trait Foo
| --- required by a bound in this
@@ -92,7 +83,7 @@ LL | fn f(_: impl Foo) {}
<[u16; 4] as Bar>
error[E0277]: the trait bound `[u16; 3]: Bar` is not satisfied
- --> $DIR/issue-67185-2.rs:29:14
+ --> $DIR/issue-67185-2.rs:31:14
|
LL | trait Foo
| --- required by a bound in this
@@ -107,6 +98,6 @@ LL | fn f(_: impl Foo) {}
<[[u16; 3]; 3] as Bar>
<[u16; 4] as Bar>
-error: aborting due to 6 previous errors; 1 warning emitted
+error: aborting due to 6 previous errors
For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/const-generics/issues/issue-67185-2.min.stderr b/src/test/ui/const-generics/issues/issue-67185-2.min.stderr
new file mode 100644
index 0000000000000..78c7ebff05985
--- /dev/null
+++ b/src/test/ui/const-generics/issues/issue-67185-2.min.stderr
@@ -0,0 +1,103 @@
+error[E0277]: the trait bound `[u16; 3]: Bar` is not satisfied
+ --> $DIR/issue-67185-2.rs:17:1
+ |
+LL | / trait Foo
+LL | |
+LL | | where
+LL | | [::Quaks; 2]: Bar,
+LL | | ::Quaks: Bar,
+LL | | {
+LL | | }
+ | |_^ the trait `Bar` is not implemented for `[u16; 3]`
+ |
+ = help: the following implementations were found:
+ <[[u16; 3]; 3] as Bar>
+ <[u16; 4] as Bar>
+ = help: see issue #48214
+ = help: add `#![feature(trivial_bounds)]` to the crate attributes to enable
+
+error[E0277]: the trait bound `[[u16; 3]; 2]: Bar` is not satisfied
+ --> $DIR/issue-67185-2.rs:17:1
+ |
+LL | / trait Foo
+LL | |
+LL | | where
+LL | | [::Quaks; 2]: Bar,
+LL | | ::Quaks: Bar,
+LL | | {
+LL | | }
+ | |_^ the trait `Bar` is not implemented for `[[u16; 3]; 2]`
+ |
+ = help: the following implementations were found:
+ <[[u16; 3]; 3] as Bar>
+ <[u16; 4] as Bar>
+ = help: see issue #48214
+ = help: add `#![feature(trivial_bounds)]` to the crate attributes to enable
+
+error[E0277]: the trait bound `[u16; 3]: Bar` is not satisfied
+ --> $DIR/issue-67185-2.rs:27:6
+ |
+LL | trait Foo
+ | --- required by a bound in this
+...
+LL | ::Quaks: Bar,
+ | --- required by this bound in `Foo`
+...
+LL | impl Foo for FooImpl {}
+ | ^^^ the trait `Bar` is not implemented for `[u16; 3]`
+ |
+ = help: the following implementations were found:
+ <[[u16; 3]; 3] as Bar>
+ <[u16; 4] as Bar>
+
+error[E0277]: the trait bound `[[u16; 3]; 2]: Bar` is not satisfied
+ --> $DIR/issue-67185-2.rs:27:6
+ |
+LL | trait Foo
+ | --- required by a bound in this
+...
+LL | [::Quaks; 2]: Bar,
+ | --- required by this bound in `Foo`
+...
+LL | impl Foo for FooImpl {}
+ | ^^^ the trait `Bar` is not implemented for `[[u16; 3]; 2]`
+ |
+ = help: the following implementations were found:
+ <[[u16; 3]; 3] as Bar>
+ <[u16; 4] as Bar>
+
+error[E0277]: the trait bound `[[u16; 3]; 2]: Bar` is not satisfied
+ --> $DIR/issue-67185-2.rs:31:14
+ |
+LL | trait Foo
+ | --- required by a bound in this
+...
+LL | [::Quaks; 2]: Bar,
+ | --- required by this bound in `Foo`
+...
+LL | fn f(_: impl Foo) {}
+ | ^^^ the trait `Bar` is not implemented for `[[u16; 3]; 2]`
+ |
+ = help: the following implementations were found:
+ <[[u16; 3]; 3] as Bar>
+ <[u16; 4] as Bar>
+
+error[E0277]: the trait bound `[u16; 3]: Bar` is not satisfied
+ --> $DIR/issue-67185-2.rs:31:14
+ |
+LL | trait Foo
+ | --- required by a bound in this
+...
+LL | ::Quaks: Bar,
+ | --- required by this bound in `Foo`
+...
+LL | fn f(_: impl Foo) {}
+ | ^^^ the trait `Bar` is not implemented for `[u16; 3]`
+ |
+ = help: the following implementations were found:
+ <[[u16; 3]; 3] as Bar>
+ <[u16; 4] as Bar>
+
+error: aborting due to 6 previous errors
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/const-generics/issues/issue-67185-2.rs b/src/test/ui/const-generics/issues/issue-67185-2.rs
index 111b718dd5efd..1176d0c690403 100644
--- a/src/test/ui/const-generics/issues/issue-67185-2.rs
+++ b/src/test/ui/const-generics/issues/issue-67185-2.rs
@@ -1,5 +1,7 @@
-#![feature(const_generics)]
-//~^ WARN the feature `const_generics` is incomplete
+// revisions: full min
+#![cfg_attr(full, feature(const_generics))]
+#![cfg_attr(full, allow(incomplete_features))]
+#![cfg_attr(min, feature(min_const_generics))]
trait Baz {
type Quaks;
diff --git a/src/test/ui/const-generics/issues/issue-67739.stderr b/src/test/ui/const-generics/issues/issue-67739.full.stderr
similarity index 100%
rename from src/test/ui/const-generics/issues/issue-67739.stderr
rename to src/test/ui/const-generics/issues/issue-67739.full.stderr
diff --git a/src/test/ui/const-generics/issues/issue-67739.min.stderr b/src/test/ui/const-generics/issues/issue-67739.min.stderr
new file mode 100644
index 0000000000000..1254ee7239dc7
--- /dev/null
+++ b/src/test/ui/const-generics/issues/issue-67739.min.stderr
@@ -0,0 +1,10 @@
+error: generic parameters must not be used inside of non trivial constant values
+ --> $DIR/issue-67739.rs:12:30
+ |
+LL | [0u8; mem::size_of::()];
+ | ^^^^^^^^^^^^^^^^ non-trivial anonymous constants must not depend on the parameter `Self`
+ |
+ = help: it is currently only allowed to use either `Self` or `{ Self }` as generic constants
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/const-generics/issues/issue-67739.rs b/src/test/ui/const-generics/issues/issue-67739.rs
index c8ee182123985..72bf3ee9602fc 100644
--- a/src/test/ui/const-generics/issues/issue-67739.rs
+++ b/src/test/ui/const-generics/issues/issue-67739.rs
@@ -1,7 +1,7 @@
-// Regression test for #67739
-
-#![allow(incomplete_features)]
-#![feature(const_generics)]
+// revisions: full min
+#![cfg_attr(full, feature(const_generics))]
+#![cfg_attr(full, allow(incomplete_features))]
+#![cfg_attr(min, feature(min_const_generics))]
use std::mem;
@@ -10,7 +10,8 @@ pub trait Trait {
fn associated_size(&self) -> usize {
[0u8; mem::size_of::()];
- //~^ ERROR constant expression depends on a generic parameter
+ //[full]~^ ERROR constant expression depends on a generic parameter
+ //[min]~^^ ERROR generic parameters must not be used inside of non trivial constant values
0
}
}
diff --git a/src/test/ui/const-generics/issues/issue-68366.stderr b/src/test/ui/const-generics/issues/issue-68366.full.stderr
similarity index 93%
rename from src/test/ui/const-generics/issues/issue-68366.stderr
rename to src/test/ui/const-generics/issues/issue-68366.full.stderr
index bba16f421535a..ac774f50c7493 100644
--- a/src/test/ui/const-generics/issues/issue-68366.stderr
+++ b/src/test/ui/const-generics/issues/issue-68366.full.stderr
@@ -1,5 +1,5 @@
error[E0207]: the const parameter `N` is not constrained by the impl trait, self type, or predicates
- --> $DIR/issue-68366.rs:10:13
+ --> $DIR/issue-68366.rs:12:13
|
LL | impl Collatz<{Some(N)}> {}
| ^ unconstrained const parameter
@@ -8,7 +8,7 @@ LL | impl Collatz<{Some(N)}> {}
= note: proving the result of expressions other than the parameter are unique is not supported
error[E0207]: the const parameter `N` is not constrained by the impl trait, self type, or predicates
- --> $DIR/issue-68366.rs:15:12
+ --> $DIR/issue-68366.rs:18:12
|
LL | impl Foo {}
| ^ unconstrained const parameter
diff --git a/src/test/ui/const-generics/issues/issue-68366.min.stderr b/src/test/ui/const-generics/issues/issue-68366.min.stderr
new file mode 100644
index 0000000000000..8d34bdc6ea0c8
--- /dev/null
+++ b/src/test/ui/const-generics/issues/issue-68366.min.stderr
@@ -0,0 +1,29 @@
+error: generic parameters must not be used inside of non trivial constant values
+ --> $DIR/issue-68366.rs:12:37
+ |
+LL | impl Collatz<{Some(N)}> {}
+ | ^ non-trivial anonymous constants must not depend on the parameter `N`
+ |
+ = help: it is currently only allowed to use either `N` or `{ N }` as generic constants
+
+error[E0207]: the const parameter `N` is not constrained by the impl trait, self type, or predicates
+ --> $DIR/issue-68366.rs:12:13
+ |
+LL | impl Collatz<{Some(N)}> {}
+ | ^ unconstrained const parameter
+ |
+ = note: expressions using a const parameter must map each value to a distinct output value
+ = note: proving the result of expressions other than the parameter are unique is not supported
+
+error[E0207]: the const parameter `N` is not constrained by the impl trait, self type, or predicates
+ --> $DIR/issue-68366.rs:18:12
+ |
+LL | impl Foo {}
+ | ^ unconstrained const parameter
+ |
+ = note: expressions using a const parameter must map each value to a distinct output value
+ = note: proving the result of expressions other than the parameter are unique is not supported
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0207`.
diff --git a/src/test/ui/const-generics/issues/issue-68366.rs b/src/test/ui/const-generics/issues/issue-68366.rs
index a06b99d6645ec..819fcaffea18c 100644
--- a/src/test/ui/const-generics/issues/issue-68366.rs
+++ b/src/test/ui/const-generics/issues/issue-68366.rs
@@ -2,13 +2,16 @@
// The note should relate to the fact that it cannot be shown forall N that it maps 1-1 to a new
// type.
-#![feature(const_generics)]
-#![allow(incomplete_features)]
+// revisions: full min
+#![cfg_attr(full, feature(const_generics))]
+#![cfg_attr(full, allow(incomplete_features))]
+#![cfg_attr(min, feature(min_const_generics))]
struct Collatz>;
impl Collatz<{Some(N)}> {}
//~^ ERROR the const parameter
+//[min]~^^ generic parameters must not be used inside of non trivial constant values
struct Foo;
diff --git a/src/test/ui/const-generics/issues/issue-72787.stderr b/src/test/ui/const-generics/issues/issue-72787.full.stderr
similarity index 88%
rename from src/test/ui/const-generics/issues/issue-72787.stderr
rename to src/test/ui/const-generics/issues/issue-72787.full.stderr
index ed892e46bbbed..b4c79d4171b7a 100644
--- a/src/test/ui/const-generics/issues/issue-72787.stderr
+++ b/src/test/ui/const-generics/issues/issue-72787.full.stderr
@@ -1,5 +1,5 @@
error: constant expression depends on a generic parameter
- --> $DIR/issue-72787.rs:9:32
+ --> $DIR/issue-72787.rs:11:32
|
LL | Condition<{ LHS <= RHS }>: True
| ^^^^
@@ -7,7 +7,7 @@ LL | Condition<{ LHS <= RHS }>: True
= note: this may fail depending on what value the parameter takes
error: constant expression depends on a generic parameter
- --> $DIR/issue-72787.rs:20:42
+ --> $DIR/issue-72787.rs:26:42
|
LL | IsLessOrEqual<{ 8 - I }, { 8 - J }>: True,
| ^^^^
@@ -15,7 +15,7 @@ LL | IsLessOrEqual<{ 8 - I }, { 8 - J }>: True,
= note: this may fail depending on what value the parameter takes
error: constant expression depends on a generic parameter
- --> $DIR/issue-72787.rs:20:42
+ --> $DIR/issue-72787.rs:26:42
|
LL | IsLessOrEqual<{ 8 - I }, { 8 - J }>: True,
| ^^^^
@@ -23,7 +23,7 @@ LL | IsLessOrEqual<{ 8 - I }, { 8 - J }>: True,
= note: this may fail depending on what value the parameter takes
error: constant expression depends on a generic parameter
- --> $DIR/issue-72787.rs:20:42
+ --> $DIR/issue-72787.rs:26:42
|
LL | IsLessOrEqual<{ 8 - I }, { 8 - J }>: True,
| ^^^^
@@ -31,7 +31,7 @@ LL | IsLessOrEqual<{ 8 - I }, { 8 - J }>: True,
= note: this may fail depending on what value the parameter takes
error: constant expression depends on a generic parameter
- --> $DIR/issue-72787.rs:20:42
+ --> $DIR/issue-72787.rs:26:42
|
LL | IsLessOrEqual<{ 8 - I }, { 8 - J }>: True,
| ^^^^
diff --git a/src/test/ui/const-generics/issues/issue-72787.min.stderr b/src/test/ui/const-generics/issues/issue-72787.min.stderr
new file mode 100644
index 0000000000000..d3e9887fe209c
--- /dev/null
+++ b/src/test/ui/const-generics/issues/issue-72787.min.stderr
@@ -0,0 +1,57 @@
+error: generic parameters must not be used inside of non trivial constant values
+ --> $DIR/issue-72787.rs:11:17
+ |
+LL | Condition<{ LHS <= RHS }>: True
+ | ^^^ non-trivial anonymous constants must not depend on the parameter `LHS`
+ |
+ = help: it is currently only allowed to use either `LHS` or `{ LHS }` as generic constants
+
+error: generic parameters must not be used inside of non trivial constant values
+ --> $DIR/issue-72787.rs:11:24
+ |
+LL | Condition<{ LHS <= RHS }>: True
+ | ^^^ non-trivial anonymous constants must not depend on the parameter `RHS`
+ |
+ = help: it is currently only allowed to use either `RHS` or `{ RHS }` as generic constants
+
+error: generic parameters must not be used inside of non trivial constant values
+ --> $DIR/issue-72787.rs:26:25
+ |
+LL | IsLessOrEqual<{ 8 - I }, { 8 - J }>: True,
+ | ^ non-trivial anonymous constants must not depend on the parameter `I`
+ |
+ = help: it is currently only allowed to use either `I` or `{ I }` as generic constants
+
+error: generic parameters must not be used inside of non trivial constant values
+ --> $DIR/issue-72787.rs:26:36
+ |
+LL | IsLessOrEqual<{ 8 - I }, { 8 - J }>: True,
+ | ^ non-trivial anonymous constants must not depend on the parameter `J`
+ |
+ = help: it is currently only allowed to use either `J` or `{ J }` as generic constants
+
+error[E0283]: type annotations needed
+ --> $DIR/issue-72787.rs:22:26
+ |
+LL | pub trait True {}
+ | -------------- required by this bound in `True`
+...
+LL | IsLessOrEqual: True,
+ | ^^^^ cannot infer type for struct `IsLessOrEqual`
+ |
+ = note: cannot satisfy `IsLessOrEqual: True`
+
+error[E0283]: type annotations needed
+ --> $DIR/issue-72787.rs:22:26
+ |
+LL | pub trait True {}
+ | -------------- required by this bound in `True`
+...
+LL | IsLessOrEqual: True,
+ | ^^^^ cannot infer type for struct `IsLessOrEqual`
+ |
+ = note: cannot satisfy `IsLessOrEqual: True`
+
+error: aborting due to 6 previous errors
+
+For more information about this error, try `rustc --explain E0283`.
diff --git a/src/test/ui/const-generics/issues/issue-72787.rs b/src/test/ui/const-generics/issues/issue-72787.rs
index a368c226ec338..45c20191c8848 100644
--- a/src/test/ui/const-generics/issues/issue-72787.rs
+++ b/src/test/ui/const-generics/issues/issue-72787.rs
@@ -1,5 +1,7 @@
-#![feature(const_generics)]
-#![allow(incomplete_features)]
+// revisions: full min
+#![cfg_attr(full, feature(const_generics))]
+#![cfg_attr(full, allow(incomplete_features))]
+#![cfg_attr(min, feature(min_const_generics))]
pub struct IsLessOrEqual;
pub struct Condition;
@@ -7,7 +9,9 @@ pub trait True {}
impl True for IsLessOrEqual where
Condition<{ LHS <= RHS }>: True
-//~^ Error constant expression depends on a generic parameter
+//[full]~^ Error constant expression depends on a generic parameter
+//[min]~^^ Error generic parameters must not be used inside of non trivial constant values
+//[min]~| Error generic parameters must not be used inside of non trivial constant values
{
}
impl True for Condition {}
@@ -16,12 +20,16 @@ struct S;
impl S
where
IsLessOrEqual: True,
+//[min]~^ Error type annotations needed [E0283]
+//[min]~| Error type annotations needed [E0283]
IsLessOrEqual: True,
IsLessOrEqual<{ 8 - I }, { 8 - J }>: True,
-//~^ Error constant expression depends on a generic parameter
-//~| Error constant expression depends on a generic parameter
-//~| Error constant expression depends on a generic parameter
-//~| Error constant expression depends on a generic parameter
+//[full]~^ constant expression depends on a generic parameter
+//[full]~| constant expression depends on a generic parameter
+//[full]~| constant expression depends on a generic parameter
+//[full]~| constant expression depends on a generic parameter
+//[min]~^^^^^ Error generic parameters must not be used inside of non trivial constant values
+//[min]~| Error generic parameters must not be used inside of non trivial constant values
// Condition<{ 8 - I <= 8 - J }>: True,
{
fn print() {
diff --git a/src/test/ui/const-generics/issues/issue-72819-generic-in-const-eval.stderr b/src/test/ui/const-generics/issues/issue-72819-generic-in-const-eval.full.stderr
similarity index 84%
rename from src/test/ui/const-generics/issues/issue-72819-generic-in-const-eval.stderr
rename to src/test/ui/const-generics/issues/issue-72819-generic-in-const-eval.full.stderr
index a9f664d0ac8c5..e4105a3df1c88 100644
--- a/src/test/ui/const-generics/issues/issue-72819-generic-in-const-eval.stderr
+++ b/src/test/ui/const-generics/issues/issue-72819-generic-in-const-eval.full.stderr
@@ -1,5 +1,5 @@
error: constant expression depends on a generic parameter
- --> $DIR/issue-72819-generic-in-const-eval.rs:7:47
+ --> $DIR/issue-72819-generic-in-const-eval.rs:9:47
|
LL | where Assert::<{N < usize::max_value() / 2}>: IsTrue,
| ^^^^^^
diff --git a/src/test/ui/const-generics/issues/issue-72819-generic-in-const-eval.min.stderr b/src/test/ui/const-generics/issues/issue-72819-generic-in-const-eval.min.stderr
new file mode 100644
index 0000000000000..48a1f0bd19c0a
--- /dev/null
+++ b/src/test/ui/const-generics/issues/issue-72819-generic-in-const-eval.min.stderr
@@ -0,0 +1,10 @@
+error: generic parameters must not be used inside of non trivial constant values
+ --> $DIR/issue-72819-generic-in-const-eval.rs:9:17
+ |
+LL | where Assert::<{N < usize::max_value() / 2}>: IsTrue,
+ | ^ non-trivial anonymous constants must not depend on the parameter `N`
+ |
+ = help: it is currently only allowed to use either `N` or `{ N }` as generic constants
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/const-generics/issues/issue-72819-generic-in-const-eval.rs b/src/test/ui/const-generics/issues/issue-72819-generic-in-const-eval.rs
index 225593c3178a5..b653b91d99d14 100644
--- a/src/test/ui/const-generics/issues/issue-72819-generic-in-const-eval.rs
+++ b/src/test/ui/const-generics/issues/issue-72819-generic-in-const-eval.rs
@@ -1,11 +1,14 @@
// Regression test for #72819: ICE due to failure in resolving the const generic in `Arr`'s type
// bounds.
+// revisions: full min
+#![cfg_attr(full, feature(const_generics))]
+#![cfg_attr(full, allow(incomplete_features))]
+#![cfg_attr(min, feature(min_const_generics))]
-#![feature(const_generics)]
-#![allow(incomplete_features)]
struct Arr
where Assert::<{N < usize::max_value() / 2}>: IsTrue,
-//~^ ERROR constant expression depends on a generic parameter
+//[full]~^ ERROR constant expression depends on a generic parameter
+//[min]~^^ ERROR generic parameters must not be used inside of non trivial constant values
{
}
diff --git a/src/test/ui/const-generics/issues/issue-73120.rs b/src/test/ui/const-generics/issues/issue-73120.rs
index aea4de39f79ce..c153a93cdef4f 100644
--- a/src/test/ui/const-generics/issues/issue-73120.rs
+++ b/src/test/ui/const-generics/issues/issue-73120.rs
@@ -1,3 +1,4 @@
+// revisions: full min
// check-pass
// aux-build:const_generic_issues_lib.rs
extern crate const_generic_issues_lib as lib2;
diff --git a/src/test/ui/issues/issue-76077-1.fixed b/src/test/ui/issues/issue-76077-1.fixed
new file mode 100644
index 0000000000000..8103a7ca47d4e
--- /dev/null
+++ b/src/test/ui/issues/issue-76077-1.fixed
@@ -0,0 +1,18 @@
+// run-rustfix
+#![allow(dead_code, unused_variables)]
+
+pub mod foo {
+ #[derive(Default)]
+ pub struct Foo { invisible: bool, }
+
+ #[derive(Default)]
+ pub struct Bar { pub visible: bool, invisible: bool, }
+}
+
+fn main() {
+ let foo::Foo { .. } = foo::Foo::default();
+ //~^ ERROR pattern requires `..` due to inaccessible fields
+
+ let foo::Bar { visible, .. } = foo::Bar::default();
+ //~^ ERROR pattern requires `..` due to inaccessible fields
+}
diff --git a/src/test/ui/issues/issue-76077-1.rs b/src/test/ui/issues/issue-76077-1.rs
new file mode 100644
index 0000000000000..730332853c124
--- /dev/null
+++ b/src/test/ui/issues/issue-76077-1.rs
@@ -0,0 +1,18 @@
+// run-rustfix
+#![allow(dead_code, unused_variables)]
+
+pub mod foo {
+ #[derive(Default)]
+ pub struct Foo { invisible: bool, }
+
+ #[derive(Default)]
+ pub struct Bar { pub visible: bool, invisible: bool, }
+}
+
+fn main() {
+ let foo::Foo {} = foo::Foo::default();
+ //~^ ERROR pattern requires `..` due to inaccessible fields
+
+ let foo::Bar { visible } = foo::Bar::default();
+ //~^ ERROR pattern requires `..` due to inaccessible fields
+}
diff --git a/src/test/ui/issues/issue-76077-1.stderr b/src/test/ui/issues/issue-76077-1.stderr
new file mode 100644
index 0000000000000..4557595529fa2
--- /dev/null
+++ b/src/test/ui/issues/issue-76077-1.stderr
@@ -0,0 +1,24 @@
+error: pattern requires `..` due to inaccessible fields
+ --> $DIR/issue-76077-1.rs:13:9
+ |
+LL | let foo::Foo {} = foo::Foo::default();
+ | ^^^^^^^^^^^
+ |
+help: ignore the inaccessible and unused fields
+ |
+LL | let foo::Foo { .. } = foo::Foo::default();
+ | ^^^^^^
+
+error: pattern requires `..` due to inaccessible fields
+ --> $DIR/issue-76077-1.rs:16:9
+ |
+LL | let foo::Bar { visible } = foo::Bar::default();
+ | ^^^^^^^^^^^^^^^^^^^^
+ |
+help: ignore the inaccessible and unused fields
+ |
+LL | let foo::Bar { visible, .. } = foo::Bar::default();
+ | ^^^^
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/issues/issue-76077.rs b/src/test/ui/issues/issue-76077.rs
new file mode 100644
index 0000000000000..1ecd37de2e14a
--- /dev/null
+++ b/src/test/ui/issues/issue-76077.rs
@@ -0,0 +1,10 @@
+pub mod foo {
+ pub struct Foo {
+ you_cant_use_this_field: bool,
+ }
+}
+
+fn main() {
+ foo::Foo {};
+ //~^ ERROR cannot construct `Foo` with struct literal syntax due to inaccessible fields
+}
diff --git a/src/test/ui/issues/issue-76077.stderr b/src/test/ui/issues/issue-76077.stderr
new file mode 100644
index 0000000000000..d834ec5e0edd2
--- /dev/null
+++ b/src/test/ui/issues/issue-76077.stderr
@@ -0,0 +1,8 @@
+error: cannot construct `Foo` with struct literal syntax due to inaccessible fields
+ --> $DIR/issue-76077.rs:8:5
+ |
+LL | foo::Foo {};
+ | ^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/unsafe-foreign-mod.rs b/src/test/ui/parser/unsafe-foreign-mod.rs
new file mode 100644
index 0000000000000..872af95bd225b
--- /dev/null
+++ b/src/test/ui/parser/unsafe-foreign-mod.rs
@@ -0,0 +1,9 @@
+unsafe extern {
+ //~^ ERROR extern block cannot be declared unsafe
+}
+
+unsafe extern "C" {
+ //~^ ERROR extern block cannot be declared unsafe
+}
+
+fn main() {}
diff --git a/src/test/ui/parser/unsafe-foreign-mod.stderr b/src/test/ui/parser/unsafe-foreign-mod.stderr
new file mode 100644
index 0000000000000..5e10988051ea0
--- /dev/null
+++ b/src/test/ui/parser/unsafe-foreign-mod.stderr
@@ -0,0 +1,14 @@
+error: extern block cannot be declared unsafe
+ --> $DIR/unsafe-foreign-mod.rs:1:1
+ |
+LL | unsafe extern {
+ | ^^^^^^
+
+error: extern block cannot be declared unsafe
+ --> $DIR/unsafe-foreign-mod.rs:5:1
+ |
+LL | unsafe extern "C" {
+ | ^^^^^^
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/parser/unsafe-mod.rs b/src/test/ui/parser/unsafe-mod.rs
new file mode 100644
index 0000000000000..7916d878ea585
--- /dev/null
+++ b/src/test/ui/parser/unsafe-mod.rs
@@ -0,0 +1,9 @@
+unsafe mod m {
+ //~^ ERROR module cannot be declared unsafe
+}
+
+unsafe mod n;
+//~^ ERROR module cannot be declared unsafe
+//~^^ ERROR file not found for module `n`
+
+fn main() {}
diff --git a/src/test/ui/parser/unsafe-mod.stderr b/src/test/ui/parser/unsafe-mod.stderr
new file mode 100644
index 0000000000000..259b2c1d61e08
--- /dev/null
+++ b/src/test/ui/parser/unsafe-mod.stderr
@@ -0,0 +1,23 @@
+error[E0583]: file not found for module `n`
+ --> $DIR/unsafe-mod.rs:5:1
+ |
+LL | unsafe mod n;
+ | ^^^^^^^^^^^^^
+ |
+ = help: to create the module `n`, create file "$DIR/n.rs"
+
+error: module cannot be declared unsafe
+ --> $DIR/unsafe-mod.rs:1:1
+ |
+LL | unsafe mod m {
+ | ^^^^^^
+
+error: module cannot be declared unsafe
+ --> $DIR/unsafe-mod.rs:5:1
+ |
+LL | unsafe mod n;
+ | ^^^^^^
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0583`.
diff --git a/src/test/ui/proc-macro/auxiliary/macro-only-syntax.rs b/src/test/ui/proc-macro/auxiliary/macro-only-syntax.rs
new file mode 100644
index 0000000000000..c72306c3d50b3
--- /dev/null
+++ b/src/test/ui/proc-macro/auxiliary/macro-only-syntax.rs
@@ -0,0 +1,89 @@
+// force-host
+// no-prefer-dynamic
+
+// These are tests for syntax that is accepted by the Rust parser but
+// unconditionally rejected semantically after macro expansion. Attribute macros
+// are permitted to accept such syntax as long as they replace it with something
+// that makes sense to Rust.
+//
+// We also inspect some of the spans to verify the syntax is not triggering the
+// lossy string reparse hack (https://github.com/rust-lang/rust/issues/43081).
+
+#![crate_type = "proc-macro"]
+#![feature(proc_macro_span)]
+
+extern crate proc_macro;
+use proc_macro::{token_stream, Delimiter, TokenStream, TokenTree};
+use std::path::Component;
+
+// unsafe mod m {
+// pub unsafe mod inner;
+// }
+#[proc_macro_attribute]
+pub fn expect_unsafe_mod(_attrs: TokenStream, input: TokenStream) -> TokenStream {
+ let tokens = &mut input.into_iter();
+ expect(tokens, "unsafe");
+ expect(tokens, "mod");
+ expect(tokens, "m");
+ let tokens = &mut expect_brace(tokens);
+ expect(tokens, "pub");
+ expect(tokens, "unsafe");
+ expect(tokens, "mod");
+ let ident = expect(tokens, "inner");
+ expect(tokens, ";");
+ check_useful_span(ident, "unsafe-mod.rs");
+ TokenStream::new()
+}
+
+// unsafe extern {
+// type T;
+// }
+#[proc_macro_attribute]
+pub fn expect_unsafe_foreign_mod(_attrs: TokenStream, input: TokenStream) -> TokenStream {
+ let tokens = &mut input.into_iter();
+ expect(tokens, "unsafe");
+ expect(tokens, "extern");
+ let tokens = &mut expect_brace(tokens);
+ expect(tokens, "type");
+ let ident = expect(tokens, "T");
+ expect(tokens, ";");
+ check_useful_span(ident, "unsafe-foreign-mod.rs");
+ TokenStream::new()
+}
+
+// unsafe extern "C++" {}
+#[proc_macro_attribute]
+pub fn expect_unsafe_extern_cpp_mod(_attrs: TokenStream, input: TokenStream) -> TokenStream {
+ let tokens = &mut input.into_iter();
+ expect(tokens, "unsafe");
+ expect(tokens, "extern");
+ let abi = expect(tokens, "\"C++\"");
+ expect_brace(tokens);
+ check_useful_span(abi, "unsafe-foreign-mod.rs");
+ TokenStream::new()
+}
+
+fn expect(tokens: &mut token_stream::IntoIter, expected: &str) -> TokenTree {
+ match tokens.next() {
+ Some(token) if token.to_string() == expected => token,
+ wrong => panic!("unexpected token: {:?}, expected `{}`", wrong, expected),
+ }
+}
+
+fn expect_brace(tokens: &mut token_stream::IntoIter) -> token_stream::IntoIter {
+ match tokens.next() {
+ Some(TokenTree::Group(group)) if group.delimiter() == Delimiter::Brace => {
+ group.stream().into_iter()
+ }
+ wrong => panic!("unexpected token: {:?}, expected `{{`", wrong),
+ }
+}
+
+fn check_useful_span(token: TokenTree, expected_filename: &str) {
+ let span = token.span();
+ assert!(span.start().column < span.end().column);
+
+ let source_path = span.source_file().path();
+ let filename = source_path.components().last().unwrap();
+ assert_eq!(filename, Component::Normal(expected_filename.as_ref()));
+}
diff --git a/src/test/ui/proc-macro/unsafe-foreign-mod.rs b/src/test/ui/proc-macro/unsafe-foreign-mod.rs
new file mode 100644
index 0000000000000..7bdfa93c21fc7
--- /dev/null
+++ b/src/test/ui/proc-macro/unsafe-foreign-mod.rs
@@ -0,0 +1,14 @@
+// run-pass
+// aux-build:macro-only-syntax.rs
+
+extern crate macro_only_syntax;
+
+#[macro_only_syntax::expect_unsafe_foreign_mod]
+unsafe extern {
+ type T;
+}
+
+#[macro_only_syntax::expect_unsafe_extern_cpp_mod]
+unsafe extern "C++" {}
+
+fn main() {}
diff --git a/src/test/ui/proc-macro/unsafe-mod.rs b/src/test/ui/proc-macro/unsafe-mod.rs
new file mode 100644
index 0000000000000..8ff6e352c53d0
--- /dev/null
+++ b/src/test/ui/proc-macro/unsafe-mod.rs
@@ -0,0 +1,13 @@
+// run-pass
+// aux-build:macro-only-syntax.rs
+
+#![feature(proc_macro_hygiene)]
+
+extern crate macro_only_syntax;
+
+#[macro_only_syntax::expect_unsafe_mod]
+unsafe mod m {
+ pub unsafe mod inner;
+}
+
+fn main() {}