Auto merge of #107767 - matthiaskrgr:rollup-9m1qfso, r=matthiaskrgr
Rollup of 8 pull requests Successful merges: - #100599 (Add compiler error E0523 long description and test) - #107471 (rustdoc: do not include empty default-settings tag in HTML) - #107555 (Modify existing bounds if they exist) - #107662 (Turn projections into copies in CopyProp.) - #107695 (Add test for Future inflating arg size to 3x ) - #107700 (Run the tools builder on all PRs) - #107706 (Mark 'atomic_mut_ptr' methods const) - #107709 (Fix problem noticed in PR106859 with char -> u8 suggestion) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
bd39bbb4bb
36 changed files with 492 additions and 109 deletions
3
.github/workflows/ci.yml
vendored
3
.github/workflows/ci.yml
vendored
|
@ -60,9 +60,8 @@ jobs:
|
||||||
env: {}
|
env: {}
|
||||||
- name: x86_64-gnu-tools
|
- name: x86_64-gnu-tools
|
||||||
tidy: false
|
tidy: false
|
||||||
env:
|
|
||||||
CI_ONLY_WHEN_SUBMODULES_CHANGED: 1
|
|
||||||
os: ubuntu-20.04-xl
|
os: ubuntu-20.04-xl
|
||||||
|
env: {}
|
||||||
timeout-minutes: 600
|
timeout-minutes: 600
|
||||||
runs-on: "${{ matrix.os }}"
|
runs-on: "${{ matrix.os }}"
|
||||||
steps:
|
steps:
|
||||||
|
|
|
@ -803,6 +803,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||||
predicates
|
predicates
|
||||||
.iter()
|
.iter()
|
||||||
.map(|(param, constraint)| (param.name.as_str(), &**constraint, None)),
|
.map(|(param, constraint)| (param.name.as_str(), &**constraint, None)),
|
||||||
|
None,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -136,6 +136,7 @@ impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> {
|
||||||
¶m_ty.name.as_str(),
|
¶m_ty.name.as_str(),
|
||||||
&constraint,
|
&constraint,
|
||||||
None,
|
None,
|
||||||
|
None,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -286,6 +286,7 @@ E0519: include_str!("./error_codes/E0519.md"),
|
||||||
E0520: include_str!("./error_codes/E0520.md"),
|
E0520: include_str!("./error_codes/E0520.md"),
|
||||||
E0521: include_str!("./error_codes/E0521.md"),
|
E0521: include_str!("./error_codes/E0521.md"),
|
||||||
E0522: include_str!("./error_codes/E0522.md"),
|
E0522: include_str!("./error_codes/E0522.md"),
|
||||||
|
E0523: include_str!("./error_codes/E0523.md"),
|
||||||
E0524: include_str!("./error_codes/E0524.md"),
|
E0524: include_str!("./error_codes/E0524.md"),
|
||||||
E0525: include_str!("./error_codes/E0525.md"),
|
E0525: include_str!("./error_codes/E0525.md"),
|
||||||
E0527: include_str!("./error_codes/E0527.md"),
|
E0527: include_str!("./error_codes/E0527.md"),
|
||||||
|
@ -622,7 +623,6 @@ E0793: include_str!("./error_codes/E0793.md"),
|
||||||
// E0488, // lifetime of variable does not enclose its declaration
|
// E0488, // lifetime of variable does not enclose its declaration
|
||||||
// E0489, // type/lifetime parameter not in scope here
|
// E0489, // type/lifetime parameter not in scope here
|
||||||
// E0490, // removed: unreachable
|
// E0490, // removed: unreachable
|
||||||
E0523, // two dependencies have same (crate-name, disambiguator) but different SVH
|
|
||||||
// E0526, // shuffle indices are not constant
|
// E0526, // shuffle indices are not constant
|
||||||
// E0540, // multiple rustc_deprecated attributes
|
// E0540, // multiple rustc_deprecated attributes
|
||||||
// E0548, // replaced with a generic attribute input check
|
// E0548, // replaced with a generic attribute input check
|
||||||
|
|
|
@ -1,6 +1,21 @@
|
||||||
The compiler found multiple library files with the requested crate name.
|
The compiler found multiple library files with the requested crate name.
|
||||||
|
|
||||||
|
```compile_fail
|
||||||
|
// aux-build:crateresolve-1.rs
|
||||||
|
// aux-build:crateresolve-2.rs
|
||||||
|
// aux-build:crateresolve-3.rs
|
||||||
|
|
||||||
|
extern crate crateresolve;
|
||||||
|
//~^ ERROR multiple candidates for `rlib` dependency `crateresolve` found
|
||||||
|
|
||||||
|
fn main() {}
|
||||||
|
```
|
||||||
|
|
||||||
This error can occur in several different cases -- for example, when using
|
This error can occur in several different cases -- for example, when using
|
||||||
`extern crate` or passing `--extern` options without crate paths. It can also be
|
`extern crate` or passing `--extern` options without crate paths. It can also be
|
||||||
caused by caching issues with the build directory, in which case `cargo clean`
|
caused by caching issues with the build directory, in which case `cargo clean`
|
||||||
may help.
|
may help.
|
||||||
|
|
||||||
|
In the above example, there are three different library files, all of which
|
||||||
|
define the same crate name. Without providing a full path, there is no way for
|
||||||
|
the compiler to know which crate it should use.
|
||||||
|
|
25
compiler/rustc_error_codes/src/error_codes/E0523.md
Normal file
25
compiler/rustc_error_codes/src/error_codes/E0523.md
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
#### Note: this error code is no longer emitted by the compiler.
|
||||||
|
|
||||||
|
The compiler found multiple library files with the requested crate name.
|
||||||
|
|
||||||
|
```compile_fail
|
||||||
|
// aux-build:crateresolve-1.rs
|
||||||
|
// aux-build:crateresolve-2.rs
|
||||||
|
// aux-build:crateresolve-3.rs
|
||||||
|
|
||||||
|
extern crate crateresolve;
|
||||||
|
//~^ ERROR multiple candidates for `rlib` dependency `crateresolve` found
|
||||||
|
|
||||||
|
fn main() {}
|
||||||
|
```
|
||||||
|
|
||||||
|
This error can occur in several different cases -- for example, when using
|
||||||
|
`extern crate` or passing `--extern` options without crate paths. It can also be
|
||||||
|
caused by caching issues with the build directory, in which case `cargo clean`
|
||||||
|
may help.
|
||||||
|
|
||||||
|
In the above example, there are three different library files, all of which
|
||||||
|
define the same crate name. Without providing a full path, there is no way for
|
||||||
|
the compiler to know which crate it should use.
|
||||||
|
|
||||||
|
*Note that E0523 has been merged into E0464.*
|
|
@ -176,6 +176,7 @@ fn visit_implementation_of_copy(tcx: TyCtxt<'_>, impl_did: LocalDefId) {
|
||||||
bounds.iter().map(|(param, constraint, def_id)| {
|
bounds.iter().map(|(param, constraint, def_id)| {
|
||||||
(param.as_str(), constraint.as_str(), *def_id)
|
(param.as_str(), constraint.as_str(), *def_id)
|
||||||
}),
|
}),
|
||||||
|
None,
|
||||||
);
|
);
|
||||||
err.emit();
|
err.emit();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1457,6 +1457,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
generics,
|
generics,
|
||||||
diag,
|
diag,
|
||||||
vec![(param.name.as_str(), "Clone", Some(clone_trait_did))].into_iter(),
|
vec![(param.name.as_str(), "Clone", Some(clone_trait_did))].into_iter(),
|
||||||
|
None,
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
self.suggest_derive(diag, &[(trait_ref.to_predicate(self.tcx), None, None)]);
|
self.suggest_derive(diag, &[(trait_ref.to_predicate(self.tcx), None, None)]);
|
||||||
|
|
|
@ -1922,7 +1922,8 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
||||||
(ty::Uint(ty::UintTy::U8), ty::Char) => {
|
(ty::Uint(ty::UintTy::U8), ty::Char) => {
|
||||||
if let Ok(code) = self.tcx.sess().source_map().span_to_snippet(span)
|
if let Ok(code) = self.tcx.sess().source_map().span_to_snippet(span)
|
||||||
&& let Some(code) = code.strip_prefix('\'').and_then(|s| s.strip_suffix('\''))
|
&& let Some(code) = code.strip_prefix('\'').and_then(|s| s.strip_suffix('\''))
|
||||||
&& code.chars().next().map_or(false, |c| c.is_ascii())
|
&& !code.starts_with("\\u") // forbid all Unicode escapes
|
||||||
|
&& code.chars().next().map_or(false, |c| c.is_ascii()) // forbids literal Unicode characters beyond ASCII
|
||||||
{
|
{
|
||||||
err.span_suggestion(
|
err.span_suggestion(
|
||||||
span,
|
span,
|
||||||
|
|
|
@ -77,49 +77,86 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
||||||
(ty::Param(p), ty::Alias(ty::Projection, proj)) | (ty::Alias(ty::Projection, proj), ty::Param(p))
|
(ty::Param(p), ty::Alias(ty::Projection, proj)) | (ty::Alias(ty::Projection, proj), ty::Param(p))
|
||||||
if tcx.def_kind(proj.def_id) != DefKind::ImplTraitPlaceholder =>
|
if tcx.def_kind(proj.def_id) != DefKind::ImplTraitPlaceholder =>
|
||||||
{
|
{
|
||||||
let generics = tcx.generics_of(body_owner_def_id);
|
let p_def_id = tcx
|
||||||
let p_span = tcx.def_span(generics.type_param(p, tcx).def_id);
|
.generics_of(body_owner_def_id)
|
||||||
|
.type_param(p, tcx)
|
||||||
|
.def_id;
|
||||||
|
let p_span = tcx.def_span(p_def_id);
|
||||||
if !sp.contains(p_span) {
|
if !sp.contains(p_span) {
|
||||||
diag.span_label(p_span, "this type parameter");
|
diag.span_label(p_span, "this type parameter");
|
||||||
}
|
}
|
||||||
let hir = tcx.hir();
|
let hir = tcx.hir();
|
||||||
let mut note = true;
|
let mut note = true;
|
||||||
if let Some(generics) = generics
|
let parent = p_def_id
|
||||||
.type_param(p, tcx)
|
|
||||||
.def_id
|
|
||||||
.as_local()
|
.as_local()
|
||||||
.map(|id| hir.local_def_id_to_hir_id(id))
|
.and_then(|id| {
|
||||||
.and_then(|id| tcx.hir().find_parent(id))
|
let local_id = hir.local_def_id_to_hir_id(id);
|
||||||
.as_ref()
|
let generics = tcx.hir().find_parent(local_id)?.generics()?;
|
||||||
.and_then(|node| node.generics())
|
Some((id, generics))
|
||||||
|
});
|
||||||
|
if let Some((local_id, generics)) = parent
|
||||||
{
|
{
|
||||||
// Synthesize the associated type restriction `Add<Output = Expected>`.
|
// Synthesize the associated type restriction `Add<Output = Expected>`.
|
||||||
// FIXME: extract this logic for use in other diagnostics.
|
// FIXME: extract this logic for use in other diagnostics.
|
||||||
let (trait_ref, assoc_substs) = proj.trait_ref_and_own_substs(tcx);
|
let (trait_ref, assoc_substs) = proj.trait_ref_and_own_substs(tcx);
|
||||||
let path =
|
|
||||||
tcx.def_path_str_with_substs(trait_ref.def_id, trait_ref.substs);
|
|
||||||
let item_name = tcx.item_name(proj.def_id);
|
let item_name = tcx.item_name(proj.def_id);
|
||||||
let item_args = self.format_generic_args(assoc_substs);
|
let item_args = self.format_generic_args(assoc_substs);
|
||||||
|
|
||||||
let path = if path.ends_with('>') {
|
// Here, we try to see if there's an existing
|
||||||
format!(
|
// trait implementation that matches the one that
|
||||||
"{}, {}{} = {}>",
|
// we're suggesting to restrict. If so, find the
|
||||||
&path[..path.len() - 1],
|
// "end", whether it be at the end of the trait
|
||||||
item_name,
|
// or the end of the generic arguments.
|
||||||
item_args,
|
let mut matching_span = None;
|
||||||
p
|
let mut matched_end_of_args = false;
|
||||||
)
|
for bound in generics.bounds_for_param(local_id) {
|
||||||
|
let potential_spans = bound
|
||||||
|
.bounds
|
||||||
|
.iter()
|
||||||
|
.find_map(|bound| {
|
||||||
|
let bound_trait_path = bound.trait_ref()?.path;
|
||||||
|
let def_id = bound_trait_path.res.opt_def_id()?;
|
||||||
|
let generic_args = bound_trait_path.segments.iter().last().map(|path| path.args());
|
||||||
|
(def_id == trait_ref.def_id).then_some((bound_trait_path.span, generic_args))
|
||||||
|
});
|
||||||
|
|
||||||
|
if let Some((end_of_trait, end_of_args)) = potential_spans {
|
||||||
|
let args_span = end_of_args.and_then(|args| args.span());
|
||||||
|
matched_end_of_args = args_span.is_some();
|
||||||
|
matching_span = args_span
|
||||||
|
.or_else(|| Some(end_of_trait))
|
||||||
|
.map(|span| span.shrink_to_hi());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if matched_end_of_args {
|
||||||
|
// Append suggestion to the end of our args
|
||||||
|
let path = format!(", {}{} = {}",item_name, item_args, p);
|
||||||
|
note = !suggest_constraining_type_param(
|
||||||
|
tcx,
|
||||||
|
generics,
|
||||||
|
diag,
|
||||||
|
&format!("{}", proj.self_ty()),
|
||||||
|
&path,
|
||||||
|
None,
|
||||||
|
matching_span,
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
format!("{}<{}{} = {}>", path, item_name, item_args, p)
|
// Suggest adding a bound to an existing trait
|
||||||
};
|
// or if the trait doesn't exist, add the trait
|
||||||
note = !suggest_constraining_type_param(
|
// and the suggested bounds.
|
||||||
tcx,
|
let path = format!("<{}{} = {}>", item_name, item_args, p);
|
||||||
generics,
|
note = !suggest_constraining_type_param(
|
||||||
diag,
|
tcx,
|
||||||
&format!("{}", proj.self_ty()),
|
generics,
|
||||||
&path,
|
diag,
|
||||||
None,
|
&format!("{}", proj.self_ty()),
|
||||||
);
|
&path,
|
||||||
|
None,
|
||||||
|
matching_span,
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if note {
|
if note {
|
||||||
diag.note("you might be missing a type parameter or trait bound");
|
diag.note("you might be missing a type parameter or trait bound");
|
||||||
|
|
|
@ -356,7 +356,12 @@ impl<'a> CrateLoader<'a> {
|
||||||
for (_, other) in self.cstore.iter_crate_data() {
|
for (_, other) in self.cstore.iter_crate_data() {
|
||||||
// Same stable crate id but different SVH
|
// Same stable crate id but different SVH
|
||||||
if other.stable_crate_id() == root.stable_crate_id() && other.hash() != root.hash() {
|
if other.stable_crate_id() == root.stable_crate_id() && other.hash() != root.hash() {
|
||||||
return Err(CrateError::SymbolConflictsOthers(root.name()));
|
bug!(
|
||||||
|
"Previously returned E0523 here. \
|
||||||
|
See https://github.com/rust-lang/rust/pull/100599 for additional discussion.\
|
||||||
|
root.name() = {}.",
|
||||||
|
root.name()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -511,14 +511,6 @@ pub struct SymbolConflictsCurrent {
|
||||||
pub crate_name: Symbol,
|
pub crate_name: Symbol,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
|
||||||
#[diag(metadata_symbol_conflicts_others, code = "E0523")]
|
|
||||||
pub struct SymbolConflictsOthers {
|
|
||||||
#[primary_span]
|
|
||||||
pub span: Span,
|
|
||||||
pub crate_name: Symbol,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(metadata_stable_crate_id_collision)]
|
#[diag(metadata_stable_crate_id_collision)]
|
||||||
pub struct StableCrateIdCollision {
|
pub struct StableCrateIdCollision {
|
||||||
|
|
|
@ -945,7 +945,6 @@ pub(crate) enum CrateError {
|
||||||
ExternLocationNotFile(Symbol, PathBuf),
|
ExternLocationNotFile(Symbol, PathBuf),
|
||||||
MultipleCandidates(Symbol, CrateFlavor, Vec<PathBuf>),
|
MultipleCandidates(Symbol, CrateFlavor, Vec<PathBuf>),
|
||||||
SymbolConflictsCurrent(Symbol),
|
SymbolConflictsCurrent(Symbol),
|
||||||
SymbolConflictsOthers(Symbol),
|
|
||||||
StableCrateIdCollision(Symbol, Symbol),
|
StableCrateIdCollision(Symbol, Symbol),
|
||||||
DlOpen(String),
|
DlOpen(String),
|
||||||
DlSym(String),
|
DlSym(String),
|
||||||
|
@ -989,9 +988,6 @@ impl CrateError {
|
||||||
CrateError::SymbolConflictsCurrent(root_name) => {
|
CrateError::SymbolConflictsCurrent(root_name) => {
|
||||||
sess.emit_err(errors::SymbolConflictsCurrent { span, crate_name: root_name });
|
sess.emit_err(errors::SymbolConflictsCurrent { span, crate_name: root_name });
|
||||||
}
|
}
|
||||||
CrateError::SymbolConflictsOthers(root_name) => {
|
|
||||||
sess.emit_err(errors::SymbolConflictsOthers { span, crate_name: root_name });
|
|
||||||
}
|
|
||||||
CrateError::StableCrateIdCollision(crate_name0, crate_name1) => {
|
CrateError::StableCrateIdCollision(crate_name0, crate_name1) => {
|
||||||
sess.emit_err(errors::StableCrateIdCollision { span, crate_name0, crate_name1 });
|
sess.emit_err(errors::StableCrateIdCollision { span, crate_name0, crate_name1 });
|
||||||
}
|
}
|
||||||
|
|
|
@ -193,6 +193,9 @@ fn suggest_removing_unsized_bound(
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Suggest restricting a type param with a new bound.
|
/// Suggest restricting a type param with a new bound.
|
||||||
|
///
|
||||||
|
/// If `span_to_replace` is provided, then that span will be replaced with the
|
||||||
|
/// `constraint`. If one wasn't provided, then the full bound will be suggested.
|
||||||
pub fn suggest_constraining_type_param(
|
pub fn suggest_constraining_type_param(
|
||||||
tcx: TyCtxt<'_>,
|
tcx: TyCtxt<'_>,
|
||||||
generics: &hir::Generics<'_>,
|
generics: &hir::Generics<'_>,
|
||||||
|
@ -200,12 +203,14 @@ pub fn suggest_constraining_type_param(
|
||||||
param_name: &str,
|
param_name: &str,
|
||||||
constraint: &str,
|
constraint: &str,
|
||||||
def_id: Option<DefId>,
|
def_id: Option<DefId>,
|
||||||
|
span_to_replace: Option<Span>,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
suggest_constraining_type_params(
|
suggest_constraining_type_params(
|
||||||
tcx,
|
tcx,
|
||||||
generics,
|
generics,
|
||||||
err,
|
err,
|
||||||
[(param_name, constraint, def_id)].into_iter(),
|
[(param_name, constraint, def_id)].into_iter(),
|
||||||
|
span_to_replace,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -215,6 +220,7 @@ pub fn suggest_constraining_type_params<'a>(
|
||||||
generics: &hir::Generics<'_>,
|
generics: &hir::Generics<'_>,
|
||||||
err: &mut Diagnostic,
|
err: &mut Diagnostic,
|
||||||
param_names_and_constraints: impl Iterator<Item = (&'a str, &'a str, Option<DefId>)>,
|
param_names_and_constraints: impl Iterator<Item = (&'a str, &'a str, Option<DefId>)>,
|
||||||
|
span_to_replace: Option<Span>,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
let mut grouped = FxHashMap::default();
|
let mut grouped = FxHashMap::default();
|
||||||
param_names_and_constraints.for_each(|(param_name, constraint, def_id)| {
|
param_names_and_constraints.for_each(|(param_name, constraint, def_id)| {
|
||||||
|
@ -253,7 +259,9 @@ pub fn suggest_constraining_type_params<'a>(
|
||||||
let mut suggest_restrict = |span, bound_list_non_empty| {
|
let mut suggest_restrict = |span, bound_list_non_empty| {
|
||||||
suggestions.push((
|
suggestions.push((
|
||||||
span,
|
span,
|
||||||
if bound_list_non_empty {
|
if span_to_replace.is_some() {
|
||||||
|
constraint.clone()
|
||||||
|
} else if bound_list_non_empty {
|
||||||
format!(" + {}", constraint)
|
format!(" + {}", constraint)
|
||||||
} else {
|
} else {
|
||||||
format!(" {}", constraint)
|
format!(" {}", constraint)
|
||||||
|
@ -262,6 +270,11 @@ pub fn suggest_constraining_type_params<'a>(
|
||||||
))
|
))
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if let Some(span) = span_to_replace {
|
||||||
|
suggest_restrict(span, true);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// When the type parameter has been provided bounds
|
// When the type parameter has been provided bounds
|
||||||
//
|
//
|
||||||
// Message:
|
// Message:
|
||||||
|
|
|
@ -153,8 +153,9 @@ impl<'tcx> MutVisitor<'tcx> for Replacer<'_, 'tcx> {
|
||||||
|
|
||||||
fn visit_operand(&mut self, operand: &mut Operand<'tcx>, loc: Location) {
|
fn visit_operand(&mut self, operand: &mut Operand<'tcx>, loc: Location) {
|
||||||
if let Operand::Move(place) = *operand
|
if let Operand::Move(place) = *operand
|
||||||
&& let Some(local) = place.as_local()
|
// A move out of a projection of a copy is equivalent to a copy of the original projection.
|
||||||
&& !self.fully_moved.contains(local)
|
&& !place.has_deref()
|
||||||
|
&& !self.fully_moved.contains(place.local)
|
||||||
{
|
{
|
||||||
*operand = Operand::Copy(place);
|
*operand = Operand::Copy(place);
|
||||||
}
|
}
|
||||||
|
|
|
@ -679,6 +679,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
||||||
¶m_name,
|
¶m_name,
|
||||||
&constraint,
|
&constraint,
|
||||||
Some(trait_pred.def_id()),
|
Some(trait_pred.def_id()),
|
||||||
|
None,
|
||||||
) {
|
) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1087,6 +1088,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
||||||
param.name.as_str(),
|
param.name.as_str(),
|
||||||
"Clone",
|
"Clone",
|
||||||
Some(clone_trait),
|
Some(clone_trait),
|
||||||
|
None,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
err.span_suggestion_verbose(
|
err.span_suggestion_verbose(
|
||||||
|
|
|
@ -928,8 +928,8 @@ impl AtomicBool {
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
#[unstable(feature = "atomic_mut_ptr", reason = "recently added", issue = "66893")]
|
#[unstable(feature = "atomic_mut_ptr", reason = "recently added", issue = "66893")]
|
||||||
pub fn as_mut_ptr(&self) -> *mut bool {
|
pub const fn as_mut_ptr(&self) -> *mut bool {
|
||||||
self.v.get() as *mut bool
|
self.v.get().cast()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Fetches the value, and applies a function to it that returns an optional
|
/// Fetches the value, and applies a function to it that returns an optional
|
||||||
|
@ -1803,7 +1803,7 @@ impl<T> AtomicPtr<T> {
|
||||||
///
|
///
|
||||||
/// ```ignore (extern-declaration)
|
/// ```ignore (extern-declaration)
|
||||||
/// #![feature(atomic_mut_ptr)]
|
/// #![feature(atomic_mut_ptr)]
|
||||||
//// use std::sync::atomic::AtomicPtr;
|
/// use std::sync::atomic::AtomicPtr;
|
||||||
///
|
///
|
||||||
/// extern "C" {
|
/// extern "C" {
|
||||||
/// fn my_atomic_op(arg: *mut *mut u32);
|
/// fn my_atomic_op(arg: *mut *mut u32);
|
||||||
|
@ -1819,7 +1819,7 @@ impl<T> AtomicPtr<T> {
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
#[unstable(feature = "atomic_mut_ptr", reason = "recently added", issue = "66893")]
|
#[unstable(feature = "atomic_mut_ptr", reason = "recently added", issue = "66893")]
|
||||||
pub fn as_mut_ptr(&self) -> *mut *mut T {
|
pub const fn as_mut_ptr(&self) -> *mut *mut T {
|
||||||
self.p.get()
|
self.p.get()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2727,7 +2727,7 @@ macro_rules! atomic_int {
|
||||||
#[unstable(feature = "atomic_mut_ptr",
|
#[unstable(feature = "atomic_mut_ptr",
|
||||||
reason = "recently added",
|
reason = "recently added",
|
||||||
issue = "66893")]
|
issue = "66893")]
|
||||||
pub fn as_mut_ptr(&self) -> *mut $int_type {
|
pub const fn as_mut_ptr(&self) -> *mut $int_type {
|
||||||
self.v.get()
|
self.v.get()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -307,8 +307,6 @@ jobs:
|
||||||
- name: x86_64-gnu-tools
|
- name: x86_64-gnu-tools
|
||||||
<<: *job-linux-xl
|
<<: *job-linux-xl
|
||||||
tidy: false
|
tidy: false
|
||||||
env:
|
|
||||||
CI_ONLY_WHEN_SUBMODULES_CHANGED: 1
|
|
||||||
|
|
||||||
auto:
|
auto:
|
||||||
permissions:
|
permissions:
|
||||||
|
|
|
@ -1,46 +1,11 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
# Set the SKIP_JOB environment variable if this job is supposed to only run
|
# Set the SKIP_JOB environment variable if this job is not supposed to run on the current builder.
|
||||||
# when submodules are updated and they were not. The following time consuming
|
|
||||||
# tasks will be skipped when the environment variable is present.
|
|
||||||
|
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
IFS=$'\n\t'
|
IFS=$'\n\t'
|
||||||
|
|
||||||
source "$(cd "$(dirname "$0")" && pwd)/../shared.sh"
|
source "$(cd "$(dirname "$0")" && pwd)/../shared.sh"
|
||||||
|
|
||||||
if [[ -n "${CI_ONLY_WHEN_SUBMODULES_CHANGED-}" ]]; then
|
|
||||||
git fetch "https://github.com/$GITHUB_REPOSITORY" "$GITHUB_BASE_REF"
|
|
||||||
BASE_COMMIT="$(git merge-base FETCH_HEAD HEAD)"
|
|
||||||
|
|
||||||
echo "Searching for toolstate changes between $BASE_COMMIT and $(git rev-parse HEAD)"
|
|
||||||
|
|
||||||
if git diff "$BASE_COMMIT" | grep --quiet "^index .* 160000"; then
|
|
||||||
# Submodules pseudo-files inside git have the 160000 permissions, so when
|
|
||||||
# those files are present in the diff a submodule was updated.
|
|
||||||
echo "Submodules were updated"
|
|
||||||
elif ! (git diff --quiet "$BASE_COMMIT" -- \
|
|
||||||
src/tools/clippy src/tools/rustfmt src/tools/miri \
|
|
||||||
library/std/src/sys); then
|
|
||||||
# There is not an easy blanket search for subtrees. For now, manually list
|
|
||||||
# the subtrees.
|
|
||||||
# Also run this when the platform-specific parts of std change, in case
|
|
||||||
# that breaks Miri.
|
|
||||||
echo "Tool subtrees were updated"
|
|
||||||
elif ! (git diff --quiet "$BASE_COMMIT" -- \
|
|
||||||
tests/rustdoc-gui \
|
|
||||||
src/librustdoc \
|
|
||||||
src/ci/docker/host-x86_64/x86_64-gnu-tools/Dockerfile \
|
|
||||||
src/ci/docker/host-x86_64/x86_64-gnu-tools/browser-ui-test.version \
|
|
||||||
src/tools/rustdoc-gui); then
|
|
||||||
# There was a change in either rustdoc or in its GUI tests.
|
|
||||||
echo "Rustdoc was updated"
|
|
||||||
else
|
|
||||||
echo "Not executing this job since no submodules nor subtrees were updated"
|
|
||||||
ciCommandSetEnv SKIP_JOB 1
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ -n "${CI_ONLY_WHEN_CHANNEL-}" ]]; then
|
if [[ -n "${CI_ONLY_WHEN_CHANNEL-}" ]]; then
|
||||||
if [[ "${CI_ONLY_WHEN_CHANNEL}" = "$(cat src/ci/channel)" ]]; then
|
if [[ "${CI_ONLY_WHEN_CHANNEL}" = "$(cat src/ci/channel)" ]]; then
|
||||||
echo "The channel is the expected one"
|
echo "The channel is the expected one"
|
||||||
|
|
|
@ -23,11 +23,13 @@
|
||||||
{%- for theme in themes -%}
|
{%- for theme in themes -%}
|
||||||
<link rel="stylesheet" disabled href="{{page.root_path|safe}}{{theme}}{{page.resource_suffix}}.css"> {#- -#}
|
<link rel="stylesheet" disabled href="{{page.root_path|safe}}{{theme}}{{page.resource_suffix}}.css"> {#- -#}
|
||||||
{%- endfor -%}
|
{%- endfor -%}
|
||||||
|
{%- if !layout.default_settings.is_empty() -%}
|
||||||
<script id="default-settings" {# -#}
|
<script id="default-settings" {# -#}
|
||||||
{% for (k, v) in layout.default_settings %}
|
{% for (k, v) in layout.default_settings %}
|
||||||
data-{{k}}="{{v}}"
|
data-{{k}}="{{v}}"
|
||||||
{%- endfor -%}
|
{%- endfor -%}
|
||||||
></script> {#- -#}
|
></script> {#- -#}
|
||||||
|
{%- endif -%}
|
||||||
<script src="{{static_root_path|safe}}{{files.storage_js}}"></script> {#- -#}
|
<script src="{{static_root_path|safe}}{{files.storage_js}}"></script> {#- -#}
|
||||||
{%- if page.css_class.contains("crate") -%}
|
{%- if page.css_class.contains("crate") -%}
|
||||||
<script defer src="{{page.root_path|safe}}crates{{page.resource_suffix}}.js"></script> {#- -#}
|
<script defer src="{{page.root_path|safe}}crates{{page.resource_suffix}}.js"></script> {#- -#}
|
||||||
|
|
|
@ -31,7 +31,7 @@ const IGNORE_DOCTEST_CHECK: &[&str] = &["E0464", "E0570", "E0601", "E0602", "E06
|
||||||
|
|
||||||
// Error codes that don't yet have a UI test. This list will eventually be removed.
|
// Error codes that don't yet have a UI test. This list will eventually be removed.
|
||||||
const IGNORE_UI_TEST_CHECK: &[&str] =
|
const IGNORE_UI_TEST_CHECK: &[&str] =
|
||||||
&["E0461", "E0465", "E0476", "E0514", "E0523", "E0554", "E0640", "E0717", "E0729"];
|
&["E0461", "E0465", "E0476", "E0514", "E0554", "E0640", "E0717", "E0729"];
|
||||||
|
|
||||||
macro_rules! verbose_print {
|
macro_rules! verbose_print {
|
||||||
($verbose:expr, $($fmt:tt)*) => {
|
($verbose:expr, $($fmt:tt)*) => {
|
||||||
|
|
31
tests/mir-opt/copy-prop/move_projection.f.CopyProp.diff
Normal file
31
tests/mir-opt/copy-prop/move_projection.f.CopyProp.diff
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
- // MIR for `f` before CopyProp
|
||||||
|
+ // MIR for `f` after CopyProp
|
||||||
|
|
||||||
|
fn f(_1: Foo) -> bool {
|
||||||
|
let mut _0: bool; // return place in scope 0 at $DIR/move_projection.rs:+0:17: +0:21
|
||||||
|
let mut _2: Foo; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
|
||||||
|
let mut _3: u8; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
|
||||||
|
|
||||||
|
bb0: {
|
||||||
|
- _2 = _1; // scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
|
||||||
|
- _3 = move (_2.0: u8); // scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
|
||||||
|
- _0 = opaque::<Foo>(move _1) -> bb1; // scope 0 at $DIR/move_projection.rs:+6:13: +6:44
|
||||||
|
+ _3 = (_1.0: u8); // scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
|
||||||
|
+ _0 = opaque::<Foo>(_1) -> bb1; // scope 0 at $DIR/move_projection.rs:+6:13: +6:44
|
||||||
|
// mir::Constant
|
||||||
|
// + span: $DIR/move_projection.rs:19:28: 19:34
|
||||||
|
// + literal: Const { ty: fn(Foo) -> bool {opaque::<Foo>}, val: Value(<ZST>) }
|
||||||
|
}
|
||||||
|
|
||||||
|
bb1: {
|
||||||
|
_0 = opaque::<u8>(move _3) -> bb2; // scope 0 at $DIR/move_projection.rs:+9:13: +9:44
|
||||||
|
// mir::Constant
|
||||||
|
// + span: $DIR/move_projection.rs:22:28: 22:34
|
||||||
|
// + literal: Const { ty: fn(u8) -> bool {opaque::<u8>}, val: Value(<ZST>) }
|
||||||
|
}
|
||||||
|
|
||||||
|
bb2: {
|
||||||
|
return; // scope 0 at $DIR/move_projection.rs:+12:13: +12:21
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
34
tests/mir-opt/copy-prop/move_projection.rs
Normal file
34
tests/mir-opt/copy-prop/move_projection.rs
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
// unit-test: CopyProp
|
||||||
|
|
||||||
|
#![feature(custom_mir, core_intrinsics)]
|
||||||
|
#![allow(unused_assignments)]
|
||||||
|
extern crate core;
|
||||||
|
use core::intrinsics::mir::*;
|
||||||
|
|
||||||
|
fn opaque(_: impl Sized) -> bool { true }
|
||||||
|
|
||||||
|
struct Foo(u8);
|
||||||
|
|
||||||
|
#[custom_mir(dialect = "analysis", phase = "post-cleanup")]
|
||||||
|
fn f(a: Foo) -> bool {
|
||||||
|
mir!(
|
||||||
|
{
|
||||||
|
let b = a;
|
||||||
|
// This is a move out of a copy, so must become a copy of `a.0`.
|
||||||
|
let c = Move(b.0);
|
||||||
|
Call(RET, bb1, opaque(Move(a)))
|
||||||
|
}
|
||||||
|
bb1 = {
|
||||||
|
Call(RET, ret, opaque(Move(c)))
|
||||||
|
}
|
||||||
|
ret = {
|
||||||
|
Return()
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
assert!(f(Foo(0)));
|
||||||
|
}
|
||||||
|
|
||||||
|
// EMIT_MIR move_projection.f.CopyProp.diff
|
|
@ -34,7 +34,7 @@ fn ezmap(_1: Option<i32>) -> Option<i32> {
|
||||||
}
|
}
|
||||||
|
|
||||||
bb3: {
|
bb3: {
|
||||||
_4 = move ((_1 as Some).0: i32); // scope 1 at $DIR/simple_option_map_e2e.rs:7:14: 7:15
|
_4 = ((_1 as Some).0: i32); // scope 1 at $DIR/simple_option_map_e2e.rs:7:14: 7:15
|
||||||
StorageLive(_5); // scope 2 at $DIR/simple_option_map_e2e.rs:7:25: 7:29
|
StorageLive(_5); // scope 2 at $DIR/simple_option_map_e2e.rs:7:25: 7:29
|
||||||
_5 = Add(_4, const 1_i32); // scope 3 at $DIR/simple_option_map_e2e.rs:+1:16: +1:21
|
_5 = Add(_4, const 1_i32); // scope 3 at $DIR/simple_option_map_e2e.rs:+1:16: +1:21
|
||||||
_0 = Option::<i32>::Some(move _5); // scope 2 at $DIR/simple_option_map_e2e.rs:7:20: 7:30
|
_0 = Option::<i32>::Some(move _5); // scope 2 at $DIR/simple_option_map_e2e.rs:7:20: 7:30
|
||||||
|
|
|
@ -16,8 +16,8 @@ LL | for<'b> <Self as UnsafeCopy<'b, T>>::Item: std::ops::Deref<Target = T>,
|
||||||
| ^^^^^^^^^^ required by this bound in `UnsafeCopy`
|
| ^^^^^^^^^^ required by this bound in `UnsafeCopy`
|
||||||
help: consider further restricting this bound
|
help: consider further restricting this bound
|
||||||
|
|
|
|
||||||
LL | impl<T: Copy + std::ops::Deref + Deref<Target = T>> UnsafeCopy<'_, T> for T {
|
LL | impl<T: Copy + std::ops::Deref<Target = T>> UnsafeCopy<'_, T> for T {
|
||||||
| +++++++++++++++++++
|
| ++++++++++++
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
|
24
tests/ui/async-await/future-sizes/async-awaiting-fut.rs
Normal file
24
tests/ui/async-await/future-sizes/async-awaiting-fut.rs
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
// compile-flags: -Z print-type-sizes --crate-type lib
|
||||||
|
// edition:2021
|
||||||
|
// build-pass
|
||||||
|
// ignore-pass
|
||||||
|
|
||||||
|
async fn wait() {}
|
||||||
|
|
||||||
|
async fn big_fut(arg: [u8; 1024]) {}
|
||||||
|
|
||||||
|
async fn calls_fut(fut: impl std::future::Future<Output = ()>) {
|
||||||
|
loop {
|
||||||
|
wait().await;
|
||||||
|
if true {
|
||||||
|
return fut.await;
|
||||||
|
} else {
|
||||||
|
wait().await;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn test() {
|
||||||
|
let fut = big_fut([0u8; 1024]);
|
||||||
|
calls_fut(fut).await;
|
||||||
|
}
|
72
tests/ui/async-await/future-sizes/async-awaiting-fut.stdout
Normal file
72
tests/ui/async-await/future-sizes/async-awaiting-fut.stdout
Normal file
|
@ -0,0 +1,72 @@
|
||||||
|
print-type-size type: `[async fn body@$DIR/async-awaiting-fut.rs:21:21: 24:2]`: 3078 bytes, alignment: 1 bytes
|
||||||
|
print-type-size discriminant: 1 bytes
|
||||||
|
print-type-size variant `Unresumed`: 0 bytes
|
||||||
|
print-type-size variant `Suspend0`: 3077 bytes
|
||||||
|
print-type-size local `.__awaitee`: 3077 bytes, offset: 0 bytes, alignment: 1 bytes
|
||||||
|
print-type-size variant `Returned`: 0 bytes
|
||||||
|
print-type-size variant `Panicked`: 0 bytes
|
||||||
|
print-type-size type: `[async fn body@$DIR/async-awaiting-fut.rs:10:64: 19:2]`: 3077 bytes, alignment: 1 bytes
|
||||||
|
print-type-size discriminant: 1 bytes
|
||||||
|
print-type-size variant `Unresumed`: 2051 bytes
|
||||||
|
print-type-size padding: 1026 bytes
|
||||||
|
print-type-size upvar `.fut`: 1025 bytes, alignment: 1 bytes
|
||||||
|
print-type-size variant `Suspend0`: 2052 bytes
|
||||||
|
print-type-size local `.fut`: 1025 bytes, offset: 0 bytes, alignment: 1 bytes
|
||||||
|
print-type-size local `..generator_field4`: 1 bytes
|
||||||
|
print-type-size padding: 1 bytes
|
||||||
|
print-type-size upvar `.fut`: 1025 bytes, alignment: 1 bytes
|
||||||
|
print-type-size local `.__awaitee`: 1 bytes
|
||||||
|
print-type-size variant `Suspend1`: 3076 bytes
|
||||||
|
print-type-size padding: 1024 bytes
|
||||||
|
print-type-size local `..generator_field4`: 1 bytes, alignment: 1 bytes
|
||||||
|
print-type-size padding: 1 bytes
|
||||||
|
print-type-size upvar `.fut`: 1025 bytes, alignment: 1 bytes
|
||||||
|
print-type-size local `.__awaitee`: 1025 bytes
|
||||||
|
print-type-size variant `Suspend2`: 2052 bytes
|
||||||
|
print-type-size local `.fut`: 1025 bytes, offset: 0 bytes, alignment: 1 bytes
|
||||||
|
print-type-size local `..generator_field4`: 1 bytes
|
||||||
|
print-type-size padding: 1 bytes
|
||||||
|
print-type-size upvar `.fut`: 1025 bytes, alignment: 1 bytes
|
||||||
|
print-type-size local `.__awaitee`: 1 bytes
|
||||||
|
print-type-size variant `Returned`: 2051 bytes
|
||||||
|
print-type-size padding: 1026 bytes
|
||||||
|
print-type-size upvar `.fut`: 1025 bytes, alignment: 1 bytes
|
||||||
|
print-type-size variant `Panicked`: 2051 bytes
|
||||||
|
print-type-size padding: 1026 bytes
|
||||||
|
print-type-size upvar `.fut`: 1025 bytes, alignment: 1 bytes
|
||||||
|
print-type-size type: `std::mem::ManuallyDrop<[async fn body@$DIR/async-awaiting-fut.rs:10:64: 19:2]>`: 3077 bytes, alignment: 1 bytes
|
||||||
|
print-type-size field `.value`: 3077 bytes
|
||||||
|
print-type-size type: `std::mem::MaybeUninit<[async fn body@$DIR/async-awaiting-fut.rs:10:64: 19:2]>`: 3077 bytes, alignment: 1 bytes
|
||||||
|
print-type-size variant `MaybeUninit`: 3077 bytes
|
||||||
|
print-type-size field `.uninit`: 0 bytes
|
||||||
|
print-type-size field `.value`: 3077 bytes
|
||||||
|
print-type-size type: `[async fn body@$DIR/async-awaiting-fut.rs:8:35: 8:37]`: 1025 bytes, alignment: 1 bytes
|
||||||
|
print-type-size discriminant: 1 bytes
|
||||||
|
print-type-size variant `Unresumed`: 1024 bytes
|
||||||
|
print-type-size upvar `.arg`: 1024 bytes, offset: 0 bytes, alignment: 1 bytes
|
||||||
|
print-type-size variant `Returned`: 1024 bytes
|
||||||
|
print-type-size upvar `.arg`: 1024 bytes, offset: 0 bytes, alignment: 1 bytes
|
||||||
|
print-type-size variant `Panicked`: 1024 bytes
|
||||||
|
print-type-size upvar `.arg`: 1024 bytes, offset: 0 bytes, alignment: 1 bytes
|
||||||
|
print-type-size type: `std::mem::ManuallyDrop<[async fn body@$DIR/async-awaiting-fut.rs:8:35: 8:37]>`: 1025 bytes, alignment: 1 bytes
|
||||||
|
print-type-size field `.value`: 1025 bytes
|
||||||
|
print-type-size type: `std::mem::MaybeUninit<[async fn body@$DIR/async-awaiting-fut.rs:8:35: 8:37]>`: 1025 bytes, alignment: 1 bytes
|
||||||
|
print-type-size variant `MaybeUninit`: 1025 bytes
|
||||||
|
print-type-size field `.uninit`: 0 bytes
|
||||||
|
print-type-size field `.value`: 1025 bytes
|
||||||
|
print-type-size type: `[async fn body@$DIR/async-awaiting-fut.rs:6:17: 6:19]`: 1 bytes, alignment: 1 bytes
|
||||||
|
print-type-size discriminant: 1 bytes
|
||||||
|
print-type-size variant `Unresumed`: 0 bytes
|
||||||
|
print-type-size variant `Returned`: 0 bytes
|
||||||
|
print-type-size variant `Panicked`: 0 bytes
|
||||||
|
print-type-size type: `std::mem::ManuallyDrop<bool>`: 1 bytes, alignment: 1 bytes
|
||||||
|
print-type-size field `.value`: 1 bytes
|
||||||
|
print-type-size type: `std::mem::MaybeUninit<bool>`: 1 bytes, alignment: 1 bytes
|
||||||
|
print-type-size variant `MaybeUninit`: 1 bytes
|
||||||
|
print-type-size field `.uninit`: 0 bytes
|
||||||
|
print-type-size field `.value`: 1 bytes
|
||||||
|
print-type-size type: `std::task::Poll<()>`: 1 bytes, alignment: 1 bytes
|
||||||
|
print-type-size discriminant: 1 bytes
|
||||||
|
print-type-size variant `Ready`: 0 bytes
|
||||||
|
print-type-size field `.0`: 0 bytes
|
||||||
|
print-type-size variant `Pending`: 0 bytes
|
14
tests/ui/error-codes/E0523.rs
Normal file
14
tests/ui/error-codes/E0523.rs
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
// aux-build:crateresolve1-1.rs
|
||||||
|
// aux-build:crateresolve1-2.rs
|
||||||
|
// aux-build:crateresolve1-3.rs
|
||||||
|
|
||||||
|
// normalize-stderr-test: "\.nll/" -> "/"
|
||||||
|
// normalize-stderr-test: "\\\?\\" -> ""
|
||||||
|
// normalize-stderr-test: "(lib)?crateresolve1-([123])\.[a-z]+" -> "libcrateresolve1-$2.somelib"
|
||||||
|
|
||||||
|
// NOTE: This test is duplicated from `tests/ui/crate-loading/crateresolve1.rs`.
|
||||||
|
|
||||||
|
extern crate crateresolve1;
|
||||||
|
//~^ ERROR multiple candidates for `rlib` dependency `crateresolve1` found
|
||||||
|
|
||||||
|
fn main() {}
|
13
tests/ui/error-codes/E0523.stderr
Normal file
13
tests/ui/error-codes/E0523.stderr
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
error[E0464]: multiple candidates for `rlib` dependency `crateresolve1` found
|
||||||
|
--> $DIR/E0523.rs:11:1
|
||||||
|
|
|
||||||
|
LL | extern crate crateresolve1;
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: candidate #1: $TEST_BUILD_DIR/error-codes/E0523/auxiliary/libcrateresolve1-1.somelib
|
||||||
|
= note: candidate #2: $TEST_BUILD_DIR/error-codes/E0523/auxiliary/libcrateresolve1-2.somelib
|
||||||
|
= note: candidate #3: $TEST_BUILD_DIR/error-codes/E0523/auxiliary/libcrateresolve1-3.somelib
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0464`.
|
|
@ -15,8 +15,8 @@ LL | type Item<'a>: std::ops::Deref<Target = T>;
|
||||||
| ^^^^^^^^^^ required by this bound in `UnsafeCopy::Item`
|
| ^^^^^^^^^^ required by this bound in `UnsafeCopy::Item`
|
||||||
help: consider further restricting this bound
|
help: consider further restricting this bound
|
||||||
|
|
|
|
||||||
LL | impl<T: Copy + std::ops::Deref + Deref<Target = T>> UnsafeCopy<T> for T {
|
LL | impl<T: Copy + std::ops::Deref<Target = T>> UnsafeCopy<T> for T {
|
||||||
| +++++++++++++++++++
|
| ++++++++++++
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@ use std::ops::Add;
|
||||||
|
|
||||||
struct A<B>(B);
|
struct A<B>(B);
|
||||||
|
|
||||||
impl<B> Add for A<B> where B: Add + Add<Output = B> {
|
impl<B> Add for A<B> where B: Add<Output = B> {
|
||||||
type Output = Self;
|
type Output = Self;
|
||||||
|
|
||||||
fn add(self, rhs: Self) -> Self {
|
fn add(self, rhs: Self) -> Self {
|
||||||
|
@ -14,7 +14,7 @@ impl<B> Add for A<B> where B: Add + Add<Output = B> {
|
||||||
|
|
||||||
struct C<B>(B);
|
struct C<B>(B);
|
||||||
|
|
||||||
impl<B: Add + Add<Output = B>> Add for C<B> {
|
impl<B: Add<Output = B>> Add for C<B> {
|
||||||
type Output = Self;
|
type Output = Self;
|
||||||
|
|
||||||
fn add(self, rhs: Self) -> Self {
|
fn add(self, rhs: Self) -> Self {
|
||||||
|
@ -34,7 +34,7 @@ impl<B: std::ops::Add<Output = B>> Add for D<B> {
|
||||||
|
|
||||||
struct E<B>(B);
|
struct E<B>(B);
|
||||||
|
|
||||||
impl<B: Add + Add<Output = B>> Add for E<B> where B: Add<Output = B> {
|
impl<B: Add<Output = B>> Add for E<B> where B: Add<Output = B> {
|
||||||
//~^ ERROR equality constraints are not yet supported in `where` clauses
|
//~^ ERROR equality constraints are not yet supported in `where` clauses
|
||||||
type Output = Self;
|
type Output = Self;
|
||||||
|
|
||||||
|
|
|
@ -37,8 +37,8 @@ LL | struct A<B>(B);
|
||||||
| ^
|
| ^
|
||||||
help: consider further restricting this bound
|
help: consider further restricting this bound
|
||||||
|
|
|
|
||||||
LL | impl<B> Add for A<B> where B: Add + Add<Output = B> {
|
LL | impl<B> Add for A<B> where B: Add<Output = B> {
|
||||||
| +++++++++++++++++
|
| ++++++++++++
|
||||||
|
|
||||||
error[E0308]: mismatched types
|
error[E0308]: mismatched types
|
||||||
--> $DIR/missing-bounds.rs:21:14
|
--> $DIR/missing-bounds.rs:21:14
|
||||||
|
@ -60,8 +60,8 @@ LL | struct C<B>(B);
|
||||||
| ^
|
| ^
|
||||||
help: consider further restricting this bound
|
help: consider further restricting this bound
|
||||||
|
|
|
|
||||||
LL | impl<B: Add + Add<Output = B>> Add for C<B> {
|
LL | impl<B: Add<Output = B>> Add for C<B> {
|
||||||
| +++++++++++++++++
|
| ++++++++++++
|
||||||
|
|
||||||
error[E0369]: cannot add `B` to `B`
|
error[E0369]: cannot add `B` to `B`
|
||||||
--> $DIR/missing-bounds.rs:31:21
|
--> $DIR/missing-bounds.rs:31:21
|
||||||
|
@ -96,8 +96,8 @@ LL | struct E<B>(B);
|
||||||
| ^
|
| ^
|
||||||
help: consider further restricting this bound
|
help: consider further restricting this bound
|
||||||
|
|
|
|
||||||
LL | impl<B: Add + Add<Output = B>> Add for E<B> where <B as Add>::Output = B {
|
LL | impl<B: Add<Output = B>> Add for E<B> where <B as Add>::Output = B {
|
||||||
| +++++++++++++++++
|
| ++++++++++++
|
||||||
|
|
||||||
error: aborting due to 5 previous errors
|
error: aborting due to 5 previous errors
|
||||||
|
|
||||||
|
|
30
tests/ui/suggestions/restrict-existing-type-bounds.rs
Normal file
30
tests/ui/suggestions/restrict-existing-type-bounds.rs
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
pub trait TryAdd<Rhs = Self> {
|
||||||
|
type Error;
|
||||||
|
type Output;
|
||||||
|
|
||||||
|
fn try_add(self, rhs: Rhs) -> Result<Self::Output, Self::Error>;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: TryAdd> TryAdd for Option<T> {
|
||||||
|
type Error = <T as TryAdd>::Error;
|
||||||
|
type Output = Option<<T as TryAdd>::Output>;
|
||||||
|
|
||||||
|
fn try_add(self, rhs: Self) -> Result<Self::Output, Self::Error> {
|
||||||
|
Ok(self) //~ ERROR mismatched types
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Other<A>(A);
|
||||||
|
|
||||||
|
struct X;
|
||||||
|
|
||||||
|
impl<T: TryAdd<Error = X>> TryAdd for Other<T> {
|
||||||
|
type Error = <T as TryAdd>::Error;
|
||||||
|
type Output = Other<<T as TryAdd>::Output>;
|
||||||
|
|
||||||
|
fn try_add(self, rhs: Self) -> Result<Self::Output, Self::Error> {
|
||||||
|
Ok(self) //~ ERROR mismatched types
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
57
tests/ui/suggestions/restrict-existing-type-bounds.stderr
Normal file
57
tests/ui/suggestions/restrict-existing-type-bounds.stderr
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/restrict-existing-type-bounds.rs:13:12
|
||||||
|
|
|
||||||
|
LL | impl<T: TryAdd> TryAdd for Option<T> {
|
||||||
|
| - this type parameter
|
||||||
|
...
|
||||||
|
LL | Ok(self)
|
||||||
|
| -- ^^^^ expected `Option<<T as TryAdd>::Output>`, found `Option<T>`
|
||||||
|
| |
|
||||||
|
| arguments to this enum variant are incorrect
|
||||||
|
|
|
||||||
|
= note: expected enum `Option<<T as TryAdd>::Output>`
|
||||||
|
found enum `Option<T>`
|
||||||
|
help: the type constructed contains `Option<T>` due to the type of the argument passed
|
||||||
|
--> $DIR/restrict-existing-type-bounds.rs:13:9
|
||||||
|
|
|
||||||
|
LL | Ok(self)
|
||||||
|
| ^^^----^
|
||||||
|
| |
|
||||||
|
| this argument influences the type of `Ok`
|
||||||
|
note: tuple variant defined here
|
||||||
|
--> $SRC_DIR/core/src/result.rs:LL:COL
|
||||||
|
help: consider further restricting this bound
|
||||||
|
|
|
||||||
|
LL | impl<T: TryAdd<Output = T>> TryAdd for Option<T> {
|
||||||
|
| ++++++++++++
|
||||||
|
|
||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/restrict-existing-type-bounds.rs:26:12
|
||||||
|
|
|
||||||
|
LL | impl<T: TryAdd<Error = X>> TryAdd for Other<T> {
|
||||||
|
| - this type parameter
|
||||||
|
...
|
||||||
|
LL | Ok(self)
|
||||||
|
| -- ^^^^ expected `Other<<T as TryAdd>::Output>`, found `Other<T>`
|
||||||
|
| |
|
||||||
|
| arguments to this enum variant are incorrect
|
||||||
|
|
|
||||||
|
= note: expected struct `Other<<T as TryAdd>::Output>`
|
||||||
|
found struct `Other<T>`
|
||||||
|
help: the type constructed contains `Other<T>` due to the type of the argument passed
|
||||||
|
--> $DIR/restrict-existing-type-bounds.rs:26:9
|
||||||
|
|
|
||||||
|
LL | Ok(self)
|
||||||
|
| ^^^----^
|
||||||
|
| |
|
||||||
|
| this argument influences the type of `Ok`
|
||||||
|
note: tuple variant defined here
|
||||||
|
--> $SRC_DIR/core/src/result.rs:LL:COL
|
||||||
|
help: consider further restricting this bound
|
||||||
|
|
|
||||||
|
LL | impl<T: TryAdd<Error = X, Output = T>> TryAdd for Other<T> {
|
||||||
|
| ++++++++++++
|
||||||
|
|
||||||
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0308`.
|
|
@ -12,7 +12,19 @@ fn main() {
|
||||||
//~^ ERROR: mismatched types [E0308]
|
//~^ ERROR: mismatched types [E0308]
|
||||||
//~| HELP: if you meant to write a byte literal, prefix with `b`
|
//~| HELP: if you meant to write a byte literal, prefix with `b`
|
||||||
|
|
||||||
|
let _a: u8 = '\x20';
|
||||||
|
//~^ ERROR: mismatched types [E0308]
|
||||||
|
//~| HELP: if you meant to write a byte literal, prefix with `b`
|
||||||
|
|
||||||
|
// Do not issue the suggestion if the char literal is a Unicode escape
|
||||||
|
foo('\u{0080}');
|
||||||
|
//~^ ERROR: mismatched types [E0308]
|
||||||
|
|
||||||
// Do not issue the suggestion if the char literal isn't ASCII
|
// Do not issue the suggestion if the char literal isn't ASCII
|
||||||
let _t: u8 = '€';
|
let _t: u8 = '€';
|
||||||
//~^ ERROR: mismatched types [E0308]
|
//~^ ERROR: mismatched types [E0308]
|
||||||
|
|
||||||
|
// Do not issue the suggestion if the char literal isn't ASCII
|
||||||
|
foo('\u{1f980}');
|
||||||
|
//~^ ERROR: mismatched types [E0308]
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,13 +30,54 @@ LL | foo(b'#');
|
||||||
| ~~~~
|
| ~~~~
|
||||||
|
|
||||||
error[E0308]: mismatched types
|
error[E0308]: mismatched types
|
||||||
--> $DIR/type-mismatch-byte-literal.rs:16:18
|
--> $DIR/type-mismatch-byte-literal.rs:15:18
|
||||||
|
|
|
||||||
|
LL | let _a: u8 = '\x20';
|
||||||
|
| -- ^^^^^^ expected `u8`, found `char`
|
||||||
|
| |
|
||||||
|
| expected due to this
|
||||||
|
|
|
||||||
|
help: if you meant to write a byte literal, prefix with `b`
|
||||||
|
|
|
||||||
|
LL | let _a: u8 = b'\x20';
|
||||||
|
| ~~~~~~~
|
||||||
|
|
||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/type-mismatch-byte-literal.rs:20:9
|
||||||
|
|
|
||||||
|
LL | foo('\u{0080}');
|
||||||
|
| --- ^^^^^^^^^^ expected `u8`, found `char`
|
||||||
|
| |
|
||||||
|
| arguments to this function are incorrect
|
||||||
|
|
|
||||||
|
note: function defined here
|
||||||
|
--> $DIR/type-mismatch-byte-literal.rs:4:4
|
||||||
|
|
|
||||||
|
LL | fn foo(_t: u8) {}
|
||||||
|
| ^^^ ------
|
||||||
|
|
||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/type-mismatch-byte-literal.rs:24:18
|
||||||
|
|
|
|
||||||
LL | let _t: u8 = '€';
|
LL | let _t: u8 = '€';
|
||||||
| -- ^^^ expected `u8`, found `char`
|
| -- ^^^ expected `u8`, found `char`
|
||||||
| |
|
| |
|
||||||
| expected due to this
|
| expected due to this
|
||||||
|
|
||||||
error: aborting due to 3 previous errors
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/type-mismatch-byte-literal.rs:28:9
|
||||||
|
|
|
||||||
|
LL | foo('\u{1f980}');
|
||||||
|
| --- ^^^^^^^^^^^ expected `u8`, found `char`
|
||||||
|
| |
|
||||||
|
| arguments to this function are incorrect
|
||||||
|
|
|
||||||
|
note: function defined here
|
||||||
|
--> $DIR/type-mismatch-byte-literal.rs:4:4
|
||||||
|
|
|
||||||
|
LL | fn foo(_t: u8) {}
|
||||||
|
| ^^^ ------
|
||||||
|
|
||||||
|
error: aborting due to 6 previous errors
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0308`.
|
For more information about this error, try `rustc --explain E0308`.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue