2023-01-08 22:35:43 +00:00
use crate ::error ::{ TranslateError , TranslateErrorKind } ;
use crate ::fluent_bundle ::* ;
use crate ::translation ::Translate ;
use crate ::FluentBundle ;
2023-03-03 02:14:57 +00:00
use rustc_data_structures ::sync ::{ IntoDyn , Lrc } ;
2023-01-08 22:35:43 +00:00
use rustc_error_messages ::fluent_bundle ::resolver ::errors ::{ ReferenceKind , ResolverError } ;
use rustc_error_messages ::langid ;
use rustc_error_messages ::DiagnosticMessage ;
struct Dummy {
bundle : FluentBundle ,
}
impl Translate for Dummy {
fn fluent_bundle ( & self ) -> Option < & Lrc < FluentBundle > > {
None
}
fn fallback_fluent_bundle ( & self ) -> & FluentBundle {
& self . bundle
}
}
fn make_dummy ( ftl : & 'static str ) -> Dummy {
let resource = FluentResource ::try_new ( ftl . into ( ) ) . expect ( " Failed to parse an FTL string. " ) ;
let langid_en = langid! ( " en-US " ) ;
2023-01-08 23:23:27 +00:00
#[ cfg(parallel_compiler) ]
2023-03-03 02:14:57 +00:00
let mut bundle : FluentBundle =
IntoDyn ( crate ::fluent_bundle ::bundle ::FluentBundle ::new_concurrent ( vec! [ langid_en ] ) ) ;
2023-01-08 23:23:27 +00:00
#[ cfg(not(parallel_compiler)) ]
2023-03-03 02:14:57 +00:00
let mut bundle : FluentBundle =
IntoDyn ( crate ::fluent_bundle ::bundle ::FluentBundle ::new ( vec! [ langid_en ] ) ) ;
2023-01-08 22:35:43 +00:00
bundle . add_resource ( resource ) . expect ( " Failed to add FTL resources to the bundle. " ) ;
Dummy { bundle }
}
#[ test ]
fn wellformed_fluent ( ) {
let dummy = make_dummy ( " mir_build_borrow_of_moved_value = borrow of moved value
. label = value moved into ` { $name } ` here
. occurs_because_label = move occurs because ` { $name } ` has type ` { $ty } ` which does not implement the ` Copy ` trait
. value_borrowed_label = value borrowed here after move
. suggestion = borrow this binding in the pattern to avoid moving the value " );
let mut args = FluentArgs ::new ( ) ;
args . set ( " name " , " Foo " ) ;
args . set ( " ty " , " std::string::String " ) ;
{
let message = DiagnosticMessage ::FluentIdentifier (
" mir_build_borrow_of_moved_value " . into ( ) ,
Some ( " suggestion " . into ( ) ) ,
) ;
assert_eq! (
dummy . translate_message ( & message , & args ) . unwrap ( ) ,
" borrow this binding in the pattern to avoid moving the value "
) ;
}
{
let message = DiagnosticMessage ::FluentIdentifier (
" mir_build_borrow_of_moved_value " . into ( ) ,
Some ( " value_borrowed_label " . into ( ) ) ,
) ;
assert_eq! (
dummy . translate_message ( & message , & args ) . unwrap ( ) ,
" value borrowed here after move "
) ;
}
{
let message = DiagnosticMessage ::FluentIdentifier (
" mir_build_borrow_of_moved_value " . into ( ) ,
Some ( " occurs_because_label " . into ( ) ) ,
) ;
assert_eq! (
dummy . translate_message ( & message , & args ) . unwrap ( ) ,
" move occurs because ` \u{2068} Foo \u{2069} ` has type ` \u{2068} std::string::String \u{2069} ` which does not implement the `Copy` trait "
) ;
{
let message = DiagnosticMessage ::FluentIdentifier (
" mir_build_borrow_of_moved_value " . into ( ) ,
Some ( " label " . into ( ) ) ,
) ;
assert_eq! (
dummy . translate_message ( & message , & args ) . unwrap ( ) ,
" value moved into ` \u{2068} Foo \u{2069} ` here "
) ;
}
}
}
#[ test ]
fn misformed_fluent ( ) {
let dummy = make_dummy ( " mir_build_borrow_of_moved_value = borrow of moved value
. label = value moved into ` { name } ` here
. occurs_because_label = move occurs because ` { $oops } ` has type ` { $ty } ` which does not implement the ` Copy ` trait
. suggestion = borrow this binding in the pattern to avoid moving the value " );
let mut args = FluentArgs ::new ( ) ;
args . set ( " name " , " Foo " ) ;
args . set ( " ty " , " std::string::String " ) ;
{
let message = DiagnosticMessage ::FluentIdentifier (
" mir_build_borrow_of_moved_value " . into ( ) ,
Some ( " value_borrowed_label " . into ( ) ) ,
) ;
let err = dummy . translate_message ( & message , & args ) . unwrap_err ( ) ;
assert! (
matches! (
& err ,
TranslateError ::Two {
primary : box TranslateError ::One {
kind : TranslateErrorKind ::PrimaryBundleMissing ,
..
} ,
fallback : box TranslateError ::One {
kind : TranslateErrorKind ::AttributeMissing { attr : " value_borrowed_label " } ,
..
}
}
) ,
" {err:#?} "
) ;
assert_eq! (
format! ( " {err} " ) ,
" failed while formatting fluent string `mir_build_borrow_of_moved_value`: \n the attribute `value_borrowed_label` was missing \n help: add `.value_borrowed_label = <message>` \n "
) ;
}
{
let message = DiagnosticMessage ::FluentIdentifier (
" mir_build_borrow_of_moved_value " . into ( ) ,
Some ( " label " . into ( ) ) ,
) ;
let err = dummy . translate_message ( & message , & args ) . unwrap_err ( ) ;
if let TranslateError ::Two {
primary : box TranslateError ::One { kind : TranslateErrorKind ::PrimaryBundleMissing , .. } ,
fallback : box TranslateError ::One { kind : TranslateErrorKind ::Fluent { errs } , .. } ,
} = & err
& & let [ FluentError ::ResolverError ( ResolverError ::Reference (
ReferenceKind ::Message { id , .. }
| ReferenceKind ::Variable { id , .. } ,
) ) ] = & * * errs
& & id = = " name "
{ } else {
panic! ( " {err:#?} " )
} ;
assert_eq! (
format! ( " {err} " ) ,
" failed while formatting fluent string `mir_build_borrow_of_moved_value`: \n argument `name` exists but was not referenced correctly \n help: try using `{$name}` instead \n "
) ;
}
{
let message = DiagnosticMessage ::FluentIdentifier (
" mir_build_borrow_of_moved_value " . into ( ) ,
Some ( " occurs_because_label " . into ( ) ) ,
) ;
let err = dummy . translate_message ( & message , & args ) . unwrap_err ( ) ;
if let TranslateError ::Two {
primary : box TranslateError ::One { kind : TranslateErrorKind ::PrimaryBundleMissing , .. } ,
fallback : box TranslateError ::One { kind : TranslateErrorKind ::Fluent { errs } , .. } ,
} = & err
& & let [ FluentError ::ResolverError ( ResolverError ::Reference (
ReferenceKind ::Message { id , .. }
| ReferenceKind ::Variable { id , .. } ,
) ) ] = & * * errs
& & id = = " oops "
{ } else {
panic! ( " {err:#?} " )
} ;
assert_eq! (
format! ( " {err} " ) ,
" failed while formatting fluent string `mir_build_borrow_of_moved_value`: \n the fluent string has an argument `oops` that was not found. \n help: the arguments `name` and `ty` are available \n "
) ;
}
}